diff --git a/nanosoc_board/soclabs_pio/ft1248x1/ft1248x1_sm.pio b/nanosoc_board/soclabs_pio/ft1248x1/ft1248x1_sm.pio
index 09948d9467eeb774d8b8d16cc9f991f75b6c9c02..e3686007276e661a325a57d5578f161a5e78506d 100644
--- a/nanosoc_board/soclabs_pio/ft1248x1/ft1248x1_sm.pio
+++ b/nanosoc_board/soclabs_pio/ft1248x1/ft1248x1_sm.pio
@@ -5,7 +5,7 @@
 ; SPDX-License-Identifier: BSD-3-Clause
 ;
 ; dflynn@soton.ac.uk
-; FT1248 V8 Write Only (with status wait to start)
+; FT1248 v5-tx
 
 .program ft1248x1_sm
 
@@ -18,7 +18,7 @@
 ; capture FT1248x1 serial data packet
 ; - SM0 primary state machine
 ;  -> manual push 8-bits to RP-RXFIFO [FT Command + write data byte]
-;  <- pull 8-bits from RP-TXFIFO [FT Read data byte]
+;  ** strip out RP-TX channel code - RXE always empty
 ; side-signals: {MISO_PIN,MIOSIO_PIN} pin directions (opt update)
 ; MISO_PIN   :         OUT[1], SET [1],(SET_PINDIR [1]=1)
 ; MIOSIO_PIN : IN[0],  OUT[0], SET [0], SET_PINDIR [0]
@@ -27,33 +27,18 @@
 ;
 sm0:
 // set {MISO,MIOSIO} pins to outputs - as FT-FIFO status flags {RXE,TXF}
-// set RXE high (FT-RX FIFO Empty), TXF (FT-TX FIFO also full initally)
+// set RXE high (FT-RX FIFO Empty), but (FT-TX FIFO *not* full)
 // with explicit PINDIRS and side-set output values
-    set pindirs 0b11 side 0b11 // default flags 0x11 {RXE,TXF}, driven
-    set y, 31
-ft_wait:
-    jmp y--, ft_wait [3]
+    set pindirs 0b11 side 0b10 // default flags 0x10 {RXE,!TXF}, driven
 ft_status_loop:
-// check RP TXFIFO to see if empty (TXFIFO level <1 configuration)
-// use temp reg Y to capture a ZERO if TXFIFO level >= 1
-// and signal {RXE,!TXF} FT-TXFIFO not full
-    mov y, status side 0b10 // status is zero if NOT <1 i.e. char to send
-// if y=0 then update RXE status, else loop for activity
-    jmp !y, ft_rxrdy // if zero then clear RXE flag
 // to minimize latency use jmp on pin level, configured for SSN_PIN
     jmp pin ft_status_loop // loop if SSN_PIN still high
-// otherwise must be starting an FT transfer command
-    jmp ft_xfer // else start transfer a.s.a.p.
-ft_rxrdy:
-// There is a character for FT Read, so update status FT RXE FIFO flag
-// set RXE low (FT-RX FIFO *not* empty), and (FT-TX FIFO *not* full)
-// with explicit PINDIRS and side-set output values
-// wait until an FT read or write (when SSN becomes active low)
-    wait 0 gpio SSN_PIN side 0b10 // status={RXE,!TXF} was:status={!RXE,!TXF}
+// otherwise SSN low so must be starting an FT transfer command
+
 ft_xfer:
 // start of a transfer: must stop driving MIOSIO
 // Continue to drive MISO as zero for status and ACK
-    set pindirs 0b10 side 0b00  // MIOSIO pin becomes input, MISO driven 0
+    set pindirs 0b10 side 0b00  // MISO output (=0), MIOSIO pin becomes input
 // then start loop counter for 8 SCLK cycles of FT command
 // use Y register for counter
     set y, 7 // pindir input for MIOSIO_PIN
@@ -61,38 +46,28 @@ ft_cmd_loop:
 // wait for rising edge of SCLK
     wait 1 gpio SCLK_PIN
 // then wait a few cycles before sampling MIOSIO serial data bit
-// ISR configured to shift RIGHT (lsb-first)
+// ISR configured to shift left
+    in pins 1 [3]
 // then wait for falling edge of SCLK
     wait 0 gpio SCLK_PIN
-    in pins 1
 // loop until count == 0
     jmp y--, ft_cmd_loop
-// ISR now has {z, cmd[0:6]} in high 8-bits
-// OSR also configure to shift right, to keep consistent R/W bit ordering
-// so shifting is always out of OSR[0]
+// ISR now has {cmd[6:0],z} in low 8-bits
+// OSR also configure to shift left, to keep consistent R/W bit ordering
+// so shifting is always out of OSR[31]
 // To parse the command using OSR, need to bit reverse command in iSR
     mov osr, ::isr
-// OSR now contains {24'h000000, cmd[6:0], z}
+// OSR now contains {z, cmd[0:6], 24'b0}
 // where cmd[0] = 0 for FT write commend, 1 for FT read command
-// strip out the "HiZ" bit from bus turnaround protocol slot
+// strip out the "HiZ" bit from bust turnaround protocol slot
 // Use X register so direction is available later
     out x, 1 // shift out OSR (HiZ) lsbit
 // next shifted bit is command direction
     out x, 1 // x now = direction bit
-// X = 0 if FT write, 1 if FT read (no autodecrement to preserve X=0)
+// X = 0 if FT write, 1 if FT read
     jmp !x, ft_write
 ft_read:
-//// FT read command requires MIOSIO bus turnaround and RP TXFIFO data pulled
-//// use pull noblock but should never block as TXFIFO status indicated data ready
-//   pull noblock // manual pull char to read into OSR
-//// NOTE: in the error case where TXFIFO was empty, pull noblock instead
-////       loads OSR with X (=1 in this case)
-//// OSR = {24'h000000, txchar[7:0]}
-//// now enable MIOSIO output direction (keeping MISO output)
-    set pindirs, 0b11 side 0// MIOSIO pin becomes output for FT "read"
-//// Read command can now be flushed
-//    mov isr, null // flush ISR to avoid spurious read command data
-//// and prepare for serial data  loop (shift left from OSR[31])
+// not supported in v5-TX
     jmp ft_data_loop_init
 ft_write:
 // FT write command maintains MIOSIO as input for serial data in
@@ -107,20 +82,14 @@ ft_data_loop:
 // (and in the case FT Read captures the FT write data off the bidirectional pin)
 // Sampling triggered from rising-edge of clock
     wait 1 gpio SCLK_PIN
-// output data in case this is FT-read, using OSR[7:0], shifting right
-    out pins 1 ; serial output to MIOSIO_PIN for "read" - manual pull data
-// input data into ISR[31:24], shifting left
-// again wait until data is settled
+// input data into ISR[7:0], shifting left, after 3-clock delay for settlng
+    in pins 1 [3] ; serial input for MIOSIO_PIN "write" - no autopush
 // await falling edge of clock
     wait 0 gpio SCLK_PIN
-    in pins 1 ; serial input for MIOSIO_PIN "write" - build write data
 // and loop until 8th bit slot
     jmp y--, ft_data_loop
 ft_done:
-    set pindirs 0b11 side 0b11 // default flags 0x11 {RXE,TXF}, driven
     jmp x--, ft_xfer_end // if X was non-zero than was FT-read, so all done
-// shift RXD from ISR[31:24] to ISR[7:0]
-    in null, 24
 // if FT write now manually push the ISR contents to RP RXFIFO
     push noblock // not auto-push
 ft_xfer_end:
@@ -132,26 +101,24 @@ static inline void ft1248x1_sm_program_init(PIO pio, uint sm, uint offset) {
     pio_sm_config cfg_sm = ft1248x1_sm_program_get_default_config(offset);
 // SM0: status, command and TX0
     sm_config_set_in_pins(&cfg_sm, ft1248x1_sm_MIOSIO_PIN);
-    sm_config_set_in_shift(&cfg_sm, true, false,32); // SHR, no autopush
+    sm_config_set_in_shift(&cfg_sm, false, false,32); // SHL, no autopush
     sm_config_set_out_pins(&cfg_sm, ft1248x1_sm_MIOSIO_PIN, 1);
-    sm_config_set_out_shift(&cfg_sm, true, false,32); // SHR, no autopull
+    sm_config_set_out_shift(&cfg_sm, false, false,32); // SHL, no autopull
     sm_config_set_set_pins(&cfg_sm, ft1248x1_sm_MIOSIO_PIN, 1);
     sm_config_set_sideset_pins(&cfg_sm, ft1248x1_sm_MIOSIO_PIN);
     sm_config_set_sideset(&cfg_sm, 2, true, false); // drive enable, not pindir
     sm_config_set_jmp_pin(&cfg_sm, ft1248x1_sm_SSN_PIN);
 // when TX fifo is less than (n), y will become all-ones, otherwise all-zeroes
 //    sm_config_set_mov_status (&cfg_sm, STATUS_TX_LESSTHAN , 1 );
-    sm_config_set_mov_status (&cfg_sm, STATUS_RX_LESSTHAN , 4 );
 
     // Map the state machine's data pins
     pio_gpio_init(pio, ft1248x1_sm_MISO_PIN);
     pio_sm_set_consecutive_pindirs(pio, sm, ft1248x1_sm_MISO_PIN, 1, true); // always output
    // Connect PIO data bus (connect PIO to the pad)
     pio_gpio_init(pio, ft1248x1_sm_MIOSIO_PIN);
-    pio_sm_set_consecutive_pindirs(pio, sm, ft1248x1_sm_MIOSIO_PIN, 1, false); // inputinitially
+    pio_sm_set_consecutive_pindirs(pio, sm, ft1248x1_sm_MIOSIO_PIN, 1, false); // input in TX case
 
     // Load our configuration, and jump to the start of the program
-    // uint offset = pio_add_program(pio, &ft1248x1_sm_program); // single code image load
     pio_sm_init(pio, sm, offset, &cfg_sm);
 
    // Set the state machine running
@@ -166,7 +133,7 @@ from machine import Pin
 @rp2.asm_pio(
     in_base = ft1248x1_sm_MIOSIO_PIN,
     in_shiftdir = PIO.SHIFT_LEFT,
-    autopush=True, push_thresh=16,
+    autopush=False, push_thresh=8,
     out_base = ft1248x1_sm_MIOSIO_PIN,
     set_base = ft1248x1_sm_MIOSIO_PIN,
     jmp_pin = ft1248x1_sm_SSN_PIN,