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,