Skip to content

Commit 89e2dfa

Browse files
authored
Merge pull request #45 from jepler/background-morse
add morse code background example
2 parents 64694f7 + 2c391ef commit 89e2dfa

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

examples/pioasm_background_morse.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# SPDX-FileCopyrightText: 2022 Jeff Epler, written for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
"""Demonstrate background writing, including loop writing, with morse code.
6+
7+
On any rp2040 board with board.LED, this will alternately send 'SOS' and 'TEST'
8+
via the LED, demonstrating that Python code continues to run while the morse
9+
code data is transmitted. Alternately, change one line below to make it send
10+
'TEST' forever in a loop, again while Python code continues to run.
11+
12+
The combination of "LED status" and duration is sent to the PIO as 16-bit number:
13+
The top bit is 1 if the LED is turned on and 0 otherwise. The other 15 bits form a delay
14+
value from 1 to 32767. A subset of the morse code 'alphabit' is created, with everthing
15+
based on the 'DIT duration' of about 128ms (1MHz / 32 / 4000).
16+
17+
https://en.wikipedia.org/wiki/Morse_code
18+
"""
19+
20+
import time
21+
import array
22+
from board import LED
23+
from rp2pio import StateMachine
24+
from adafruit_pioasm import Program
25+
26+
# This program turns the LED on or off depending on the first bit of the value,
27+
# then delays a length of time given by the next 15 bits of the value.
28+
# By correctly choosing the durations, a message in morse code can be sent.
29+
pio_code = Program(
30+
"""
31+
out x, 1
32+
mov pins, x
33+
out x, 15
34+
busy_wait:
35+
jmp x--, busy_wait [31]
36+
"""
37+
)
38+
39+
40+
# The top bit of the command is the LED value, on or off
41+
LED_ON = 0x8000
42+
LED_OFF = 0x0000
43+
44+
# The other 15 bits are a delay duration.
45+
# It must be the case that 4 * DIT_DURATION < 32768
46+
DIT_DURATION = 4000
47+
DAH_DURATION = 3 * DIT_DURATION
48+
49+
# Build up some elements of morse code, based on the wikipedia article.
50+
DIT = array.array("H", [LED_ON | DIT_DURATION, LED_OFF | DIT_DURATION])
51+
DAH = array.array("H", [LED_ON | DAH_DURATION, LED_OFF | DIT_DURATION])
52+
# That is, two more DAH-length gaps for a total of three
53+
LETTER_SPACE = array.array("H", [LED_OFF | (2 * DAH_DURATION)])
54+
# That is, four more DAH-length gaps (after a letter space) for a total of seven
55+
WORD_SPACE = array.array("H", [LED_OFF | (4 * DIT_DURATION)])
56+
57+
# Letters and words can be created by concatenating ("+") the elements
58+
E = DAH + LETTER_SPACE
59+
O = DAH + DAH + DAH + LETTER_SPACE
60+
S = DIT + DIT + DIT + LETTER_SPACE
61+
T = DIT + LETTER_SPACE
62+
SOS = S + O + S + WORD_SPACE
63+
TEST = T + E + S + T + WORD_SPACE
64+
65+
# 8 slots of the shortest possible led-off time
66+
# A background write is 'complete' as soon as all data has been placed
67+
# in the StateMachine's FIFO. This FIFO has either 4 or 8 entries.
68+
# By adding 8 very short "led off" times, we can have our 'sm.writing' test
69+
# tell us when the actual letter data has all been
70+
FILLER = array.array("H", [LED_OFF | 1]) * 8
71+
72+
sm = StateMachine(
73+
pio_code.assembled,
74+
frequency=1_000_000,
75+
first_out_pin=LED,
76+
pull_threshold=16,
77+
auto_pull=True,
78+
out_shift_right=False,
79+
)
80+
81+
# To simply repeat 'TEST' forever, change to 'if True':
82+
if False: # pylint: disable=using-constant-test
83+
print("Sending out TEST forever", end="")
84+
sm.background_write(loop=TEST)
85+
while True:
86+
print(end=".")
87+
time.sleep(0.1)
88+
89+
# But instead, let's alternate SOS and TEST, forever:
90+
91+
while True:
92+
for plain, morse in (
93+
("SOS", SOS),
94+
("TEST", TEST),
95+
):
96+
print(f"Sending out {plain}", end="")
97+
sm.background_write(morse + FILLER)
98+
while sm.writing:
99+
print(end=".")
100+
time.sleep(0.1)
101+
print()
102+
print("Message all sent to StateMachine")
103+
time.sleep(1)
104+
print()

0 commit comments

Comments
 (0)