summaryrefslogtreecommitdiffstatshomepage
path: root/examples/rp2/pio_uart_rx.py
diff options
context:
space:
mode:
authorTim Radvan <tim@tjvr.org>2021-02-01 20:07:19 +0000
committerDamien George <damien@micropython.org>2021-02-02 11:33:51 +1100
commit3ea05e499d52beaecf4c9c54a67510ac031fe27b (patch)
treef007659565e1e39105252a8fc9a93209c1141795 /examples/rp2/pio_uart_rx.py
parent7a9027fd5d64868322b9a82b0ac47ac0eba0167d (diff)
downloadmicropython-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.py104
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()