diff options
author | Tim Radvan <tim@tjvr.org> | 2021-02-01 20:07:19 +0000 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2021-02-02 11:33:51 +1100 |
commit | 3ea05e499d52beaecf4c9c54a67510ac031fe27b (patch) | |
tree | f007659565e1e39105252a8fc9a93209c1141795 /examples/rp2/pio_uart_rx.py | |
parent | 7a9027fd5d64868322b9a82b0ac47ac0eba0167d (diff) | |
download | micropython-3ea05e499d52beaecf4c9c54a67510ac031fe27b.tar.gz micropython-3ea05e499d52beaecf4c9c54a67510ac031fe27b.zip |
examples/rp2: Add pio_uart_rx.py example.
This was adapted from the `pio/uart_rx` example from the `pico-examples`
repository:
https://github.com/raspberrypi/pico-examples/blob/master/pio/uart_rx/uart_rx.pio
It demonstrates the `jmp_pin` feature in action.
Signed-off-by: Tim Radvan <tim@tjvr.org>
Diffstat (limited to 'examples/rp2/pio_uart_rx.py')
-rw-r--r-- | examples/rp2/pio_uart_rx.py | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/examples/rp2/pio_uart_rx.py b/examples/rp2/pio_uart_rx.py new file mode 100644 index 0000000000..41dfde3dad --- /dev/null +++ b/examples/rp2/pio_uart_rx.py @@ -0,0 +1,104 @@ +# Example using PIO to create a UART RX interface. +# +# To make it work you'll need a wire connecting GPIO4 and GPIO3. +# +# Demonstrates: +# - PIO shifting in data on a pin +# - PIO jmp(pin) instruction +# - PIO irq handler +# - using the second core via _thread + +import _thread +from machine import Pin, UART +from rp2 import PIO, StateMachine, asm_pio + +UART_BAUD = 9600 + +HARD_UART_TX_PIN = Pin(4, Pin.OUT) +PIO_RX_PIN = Pin(3, Pin.IN, Pin.PULL_UP) + + +@asm_pio( + autopush=True, + push_thresh=8, + in_shiftdir=rp2.PIO.SHIFT_RIGHT, +) +def uart_rx_mini(): + # fmt: off + # Wait for start bit + wait(0, pin, 0) + # Preload bit counter, delay until eye of first data bit + set(x, 7) [10] + # Loop 8 times + label("bitloop") + # Sample data + in_(pins, 1) + # Each iteration is 8 cycles + jmp(x_dec, "bitloop") [6] + # fmt: on + + +@asm_pio( + in_shiftdir=rp2.PIO.SHIFT_RIGHT, +) +def uart_rx(): + # fmt: off + label("start") + # Stall until start bit is asserted + wait(0, pin, 0) + # Preload bit counter, then delay until halfway through + # the first data bit (12 cycles incl wait, set). + set(x, 7) [10] + label("bitloop") + # Shift data bit into ISR + in_(pins, 1) + # Loop 8 times, each loop iteration is 8 cycles + jmp(x_dec, "bitloop") [6] + # Check stop bit (should be high) + jmp(pin, "good_stop") + # Either a framing error or a break. Set a sticky flag + # and wait for line to return to idle state. + irq(block, 4) + wait(1, pin, 0) + # Don't push data if we didn't see good framing. + jmp("start") + # No delay before returning to start; a little slack is + # important in case the TX clock is slightly too fast. + label("good_stop") + push(block) + # fmt: on + + +# The handler for a UART break detected by the PIO. +def handler(sm): + print("break", time.ticks_ms(), end=" ") + + +# Function for core1 to execute to write to the given UART. +def core1_task(uart, text): + uart.write(text) + + +# Set up the hard UART we're going to use to print characters. +uart = UART(1, UART_BAUD, tx=HARD_UART_TX_PIN) + +for pio_prog in ("uart_rx_mini", "uart_rx"): + # Set up the state machine we're going to use to receive the characters. + sm = StateMachine( + 0, + globals()[pio_prog], + freq=8 * UART_BAUD, + in_base=PIO_RX_PIN, # For WAIT, IN + jmp_pin=PIO_RX_PIN, # For JMP + ) + sm.irq(handler) + sm.active(1) + + # Tell core 1 to print some text to UART 1 + text = "Hello, world from PIO, using {}!".format(pio_prog) + _thread.start_new_thread(core1_task, (uart, text)) + + # Echo characters received from PIO to the console. + for i in range(len(text)): + print(chr(sm.get() >> 24), end="") + print() |