My Proof of Concept code shows 80 Mbps appearing feasible with '32N1' UART-style serial when over-clocked. That's reading the output pin as input so it doesn't take into account inter-chip connections nor having separate transmit and receive chips.More than likely you can get something like 40Mbps going.
That would be more than enough to get a 640 x 480 8-bit frame buffer from one chip to another at 20 fps.
I haven't tested it but I predict an 8-bit wide clocked transfer could effectively deliver a 2 Gbps transfer rate.
Code:
from machine import Pinfrom rp2 import asm_pio, PIO, StateMachineimport time# High-Speed '32N1' UART-style serial transfer# The minimum number of PIO cycles per bit is in effect 3. No matter if we# catch the falling edge of the start bit early in a cycle or late then we# should still sample a valid bit. And, after the last bit, should be back# in the stop bit ready for the next falling edge.# Start Lsb Msb Stop# ---. . . .---.---.---.---.---.---.---.---.---.---.---.---.# |___.___.___|___.___.___|___.___.___|___.___.___| |___.___## |-------------->|---------->| |---------->|# |-------------->|---------->| |---------->|# We use UART polarity of Idle High and Start Bit Low so it is compatible# with any hardware drivers intended for UART use. We also send Lsb first# and Msb last so the PIO code will work with fewer than 32 bits.# .-------------------------------------------------------------------------.# | Define configuration |# `-------------------------------------------------------------------------'# Use same pin for input and output for zero-linking testingTX_PIN = 0RX_PIN = TX_PIN# .-------------------------------------------------------------------------.# | Define operating speed, maximum baud rate |# `-------------------------------------------------------------------------'machine.freq(240_000_000)HZ = machine.freq()BAUD_RATE = HZ // 3def Show(n, u) : return "{:>11,} {:<3} - {:5.1f} M{}".format(n, u, n / 1_000_000, u) print("Operating speed : {}".format(Show(HZ, "Hz")))print("Transfer rate : {}".format(Show(BAUD_RATE, "bps")))# .-------------------------------------------------------------------------.# | Serial transmission |# `-------------------------------------------------------------------------'@asm_pio(sideset_init = PIO.OUT_HIGH, out_init = PIO.OUT_HIGH, out_shiftdir = PIO.SHIFT_RIGHT, fifo_join = PIO.JOIN_TX)def TxPio(BITS=32): # _____ # | | pull() .side(1) [2] # --.-- --^-- | # | 3 | set(x, BITS-1) .side(0) [2] # --.-- _____ | 3 label("tx_loop") # | 3 | | | out(pins, 1) # --^-- --.-- | 3 --.-- | jmp(x_dec, "tx_loop") [1] # |_____| |_____|# .-------------------------------------------------------------------------.# | Serial reception |# `-------------------------------------------------------------------------'@asm_pio(set_init = PIO.IN_LOW, in_shiftdir = PIO.SHIFT_RIGHT, fifo_join = PIO.JOIN_RX)def RxPio(BITS=32): # _____ # | | wait(0, pin, 0) # --.-- --^-- | set(x, BITS-1) [1] # | | label("rx_loop") # | 4 _____ | 3 nop() # | | | | in_(pins, 1) # --^-- --.-- | 3 --.-- | jmp(x_dec, "rx_loop") # |_____| | | push() # |_____|# .-------------------------------------------------------------------------.# | Initialise serial loop-back |# `-------------------------------------------------------------------------'# Need to initialise RX first to handle using same pin for TXrxPin = Pin(RX_PIN, Pin.IN, Pin.PULL_UP)rx = StateMachine(1, RxPio, freq = BAUD_RATE * 3, in_base = rxPin)txPin = Pin(TX_PIN, Pin.OUT, value=1)tx = StateMachine(0, TxPio, freq = BAUD_RATE * 3, sideset_base = txPin, out_base = txPin)# .-------------------------------------------------------------------------.# | Test loop-back |# `-------------------------------------------------------------------------'n = 0while True: # Slow things down so we get a chance to see what's happening time.sleep(1) print("") # Freeze TX so everything goes out as fast as possible as a burst tx.active(0) for k in range(8): tx.put(1 << n) n = (n + 1) & 31 # Enable RX and then enable TX to send data out as a burst rx.active(1) tx.active(1) while rx.rx_fifo(): print("{:08X}".format(rx.get()))
Code:
pi@Pi3B:~/pico/micropython/ports/picopython/modules-examples $ mptool run HighSpeedPioUart.pyExecuting 'HighSpeedPioUart.py' on the deviceOperating speed : 240,000,000 Hz - 240.0 MHzTransfer rate : 80,000,000 bps - 80.0 Mbps0000000100000002000000040000000800000010000000200000004000000080etc
Statistics: Posted by hippy — Tue Jul 09, 2024 12:13 pm