8000 examples/rp2: Add pio_uart_rx.py example. · micropython/micropython@3ea05e4 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3ea05e4

Browse files
tjvrdpgeorge
authored andcommitted
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>
1 parent 7a9027f commit 3ea05e4

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

examples/rp2/pio_uart_rx.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Example using PIO to create a UART RX interface.
2+
#
3+
# To make it work you'll need a wire connecting GPIO4 and GPIO3.
4+
#
5+
# Demonstrates:
6+
# - PIO shifting in data on a pin
7+
# - PIO jmp(pin) instruction
8+
# - PIO irq handler
9+
# - using the second core via _thread
10+
11+
import _thread
12+
from machine import Pin, UART
13+
from rp2 import PIO, StateMachine, asm_pio
14+
15+
UART_BAUD = 9600
16+
17+
HARD_UART_TX_PIN = Pin(4, Pin.OUT)
18+
PIO_RX_PIN = Pin(3, Pin.IN, Pin.PULL_UP)
19+
20+
21+
@asm_pio(
22+
autopush=True,
23+
push_thresh=8,
24+
in_shiftdir=rp2.PIO.SHIFT_RIGHT,
25+
)
26+
def uart_rx_mini():
27+
# fmt: off
28+
# Wait for start bit
29+
wait(0, pin, 0)
30+
# Preload bit counter, delay until eye of first data bit
31+
set(x, 7) [10]
32+
# Loop 8 times
33+
label("bitloop")
34+
# Sample data
35+
in_(pins, 1)
36+
# Each iteration is 8 cycles
37+
jmp(x_dec, "bitloop") [6]
38+
# fmt: on
39+
40+
41+
@asm_pio(
42+
in_shiftdir=rp2.PIO.SHIFT_RIGHT,
43+
)
44+
def uart_rx():
45+
# fmt: off
46+
label("start")
47+
# Stall until start bit is asserted
48+
wait(0, pin, 0)
49+
# Preload bit counter, then delay until halfway through
50+
# the first data bit (12 cycles incl wait, set).
51+
set(x, 7) [10]
52+
label("bitloop")
53+
# Shift data bit into ISR
54+
in_(pins, 1)
55+
# Loop 8 times, each loop iteration is 8 cycles
56+
jmp(x_dec, "bitloop") [6]
57+
# Check stop bit (should be high)
58+
jmp(pin, "good_stop")
59+
# Either a framing error or a break. Set a sticky flag
60+
# and wait for line to return to idle state.
61+
irq(block, 4)
62+
wait(1, pin, 0)
63+
# Don't push data if we didn't see good framing.
64+
jmp("start")
65+
# No delay before returning to start; a little slack is
66+
# important in case the TX clock is slightly too fast.
67+
label("good_stop")
68+
push(block)
69+
# fmt: on
70+
71+
72+
# The handler for a UART break detected by the PIO.
73+
def handler(sm):
74+
print("break", time.ticks_ms(), end=" ")
75+
76+
77+
# Function for core1 to execute to write to the given UART.
78+
def core1_task(uart, text):
79+
uart.write(text)
80+
81+
82+
# Set up the hard UART we're going to use to print characters.
83+
uart = UART(1, UART_BAUD, tx=HARD_UART_TX_PIN)
84+
85+
for pio_prog in ("uart_rx_mini", "uart_rx"):
86+
# Set up the state machine we're going to use to receive the characters.
87+
sm = StateMachine(
88+
0,
89+
globals()[pio_prog],
90+
freq=8 * UART_BAUD,
91+
in_base=PIO_RX_PIN, # For WAIT, IN
92+
jmp_pin=PIO_RX_PIN, # For JMP
93+
)
94+
sm.irq(handler)
95+
sm.active(1)
96+
97+
# Tell core 1 to print some text to UART 1
98+
text = "Hello, world from PIO, using {}!".format(pio_prog)
99+
_thread.start_new_thread(core1_task, (uart, text))
100+
101+
# Echo characters received from PIO to the console.
102+
for i in range(len(text)):
103+
print(chr(sm.get() >> 24), end="")
104+
print()

0 commit comments

Comments
 (0)
0