Repository navigation
PIO
All of the LTC decoding is done in the PIO blocks, each has it's own task. Communincation between the PIO is via their in/out pins, and with interrupts.
The microPython script needs to monitor the FIFOs, to keep them feed or emptied.
# Start-up/Trigger
sm.append(rp2.StateMachine(0, start_from_pin, freq=sm_freq,
jmp_pin=machine.Pin(21))) # Sync from RX LTC
# TX State Machines
sm.append(rp2.StateMachine(1, blink_led, freq=sm_freq,
set_base=machine.Pin(25))) # LED on Pico board + GPIO26
sm.append(rp2.StateMachine(2, buffer_out, freq=sm_freq,
out_base=machine.Pin(20))) # Output of 'raw' bitstream
sm.append(rp2.StateMachine(3, encode_dmc, freq=sm_freq,
jmp_pin=machine.Pin(20),
in_base=machine.Pin(13), # same as pin as out
out_base=machine.Pin(13))) # Encoded LTC Output
# RX State Machines
sm.append(rp2.StateMachine(4, decode_dmc, freq=sm_freq,
jmp_pin=machine.Pin(18), # LTC Input ...
in_base=machine.Pin(18), # ... from 'other' device
set_base=machine.Pin(19))) # Decoded LTC Input
sm.append(rp2.StateMachine(5, sync_and_read, freq=sm_freq,
jmp_pin=machine.Pin(19),
in_base=machine.Pin(19),
out_base=machine.Pin(21),
set_base=machine.Pin(21))) # 'sync' from RX bitstream
Triggers start up, either automatically or from a pin. This sends IRQ to all of the TX machines so that they start in unison. All of the PIO run at the same clock rate, which (at preset) is 16x the LTC bit clock.
Although they run at the same clock speed, the RX machines are not necessarily synchronized with the TX machines.
The FIFO for this PIO is used to determine whether or not to flash the LED.
The blink pattern (typically 'on' for 1/2 frame, 'off' for rest) is described by a sequence of bits in a shift pattern, which is clocked out through the duration of the frame.
The 2nd (alternative) version is used for assisting MTC output, which needs a 'quarter clock' for the midi data. This uses the secondary LED output for this purpose.
The FIFO for this PIO contains the bit data for the LTC frame, it is pre-computed by the Python code and pushed into the FIFO as alternatively 2x and 3x 32bit words.
The PIO code just plays out this bit stream, with the rate determined by the fractional division of the CPU clock.
Takes the bit stream and 'modulates' it into LTC stream (Differential Manchester Encoding).
The alternate version outputs 2 parallel outputs, which are used on PT-Thrifty as differential outputs and as a 'cheap' way to generate a low voltage output without the need for a programmable op-amp.
Receives the LTC stream (from the 'other device') and 'demodulates' it into a raw stream. Uses a IRQ to signal the start of each bit, helping the reader keep sync.
Takes the 'raw' bit stream, and processes in 2 halves... firstly uses a shift like arrangement to clock the data into the ISR and then compares value with the Sync word.
Value of Sync word is pre-loaded to Y via the FIFO. As the PIO does not have math functions, it
double-clocks into the ISR, and can then use the jmp(X != Y) function to evaluate Sync word.
When a Sync is found, it then clocks data portion into the ISR and pushes into the RX FIFO, as two 32bit words. It does not send Sync word to FIFO.
It also sends a sync pulse on it's output pin, this is used to trigger the TX machine(s) when we are Jamming to received LTC.
A very simple 'loop-back' which uses the FIFOs to track which output frame is in process. The CPU writes the 'raw' Timecode value (in time with the LTC bit-stream), and this is read back in the CPU interrupt service routine (when the LTC frame output completes).
This is a 'cheap' way to count the TX frames out of the device.