/
pioasm_7seg.py
162 lines (130 loc) · 3.68 KB
/
pioasm_7seg.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# SPDX-FileCopyrightText: 2022 Jeff Epler, written for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""Drive a 7-segment display entirely from the PIO peripheral
By updating the buffer being written to the display, the shown digits can be changed.
The main program just counts up, looping back to 0000 after 9999.
This example is designed for a Raspberry Pi Pico and bare LED display. For
simplicity, it is wired without any current limiting resistors, instead relying
on a combination of the RP2040's pin drive strength and the 1/4 duty cycle to
limit LED current to an acceptable level, and longevity of the display was not
a priority.
Before integrating a variant of this example code in a project, evaluate
whether your design needs to add current-limiting resistors.
https://www.adafruit.com/product/4864
https://www.adafruit.com/product/865
Wiring:
* Pico GP15 to LED matrix 1 (E SEG)
* Pico GP14 to LED matrix 2 (D SEG)
* Pico GP13 to LED matrix 3 (DP SEG)
* Pico GP12 to LED matrix 4 (C SEG)
* Pico GP11 to LED matrix 5 (G SEG)
* Pico GP10 to LED matrix 6 (COM4)
* Pico GP9 to LED matrix 7 (COLON COM)
* Pico GP22 to LED matrix 8 (COLON SEG)
* Pico GP21 to LED matrix 9 (B SEG)
* Pico GP20 to LED matrix 10 (COM3)
* Pico GP19 to LED matrix 11 (COM2)
* Pico GP18 to LED matrix 12 (F SEG)
* Pico GP17 to LED matrix 13 (A SEG)
* Pico GP16 to LED matrix 14 (COM1)
"""
import array
import time
import board
import rp2pio
import adafruit_pioasm
_program = adafruit_pioasm.Program(
"""
out pins, 14 ; set the pins to their new state
"""
)
# Display Pins 1-7 are GP 15-9
# Display Pins 8-12 are GP 22-16
COM1_WT = 1 << 7
COM2_WT = 1 << 10
COM3_WT = 1 << 11
COM4_WT = 1 << 1
COMC_WT = 1 << 0
SEGA_WT = 1 << 8
SEGB_WT = 1 << 12
SEGC_WT = 1 << 3
SEGD_WT = 1 << 5
SEGE_WT = 1 << 6
SEGF_WT = 1 << 9
SEGG_WT = 1 << 2
SEGDP_WT = 1 << 4
SEGCOL_WT = 1 << 13
ALL_COM = COM1_WT | COM2_WT | COM3_WT | COM4_WT | COMC_WT
SEG_WT = [
SEGA_WT,
SEGB_WT,
SEGC_WT,
SEGD_WT,
SEGE_WT,
SEGF_WT,
SEGG_WT,
SEGDP_WT,
SEGCOL_WT,
]
COM_WT = [COM1_WT, COM2_WT, COM3_WT, COM4_WT, COMC_WT]
DIGITS = [
0b0111111, # 0
0b0000110, # 1
0b1011011, # 2
0b1001111, # 3
0b1100110, # 4
0b1101101, # 5
0b1111100, # 6
0b0000111, # 7
0b1111111, # 8
0b1101111, # 9
]
def make_digit_wt(v):
val = ALL_COM
seg = DIGITS[v]
for i in range(8):
if seg & (1 << i):
val |= SEG_WT[i]
return val
DIGITS_WT = [make_digit_wt(i) for i in range(10)]
class SMSevenSegment:
def __init__(self, first_pin=board.GP9):
self._buf = array.array("H", (DIGITS_WT[0] & ~COM_WT[i] for i in range(4)))
self._sm = rp2pio.StateMachine(
_program.assembled,
frequency=2000,
first_out_pin=first_pin,
out_pin_count=14,
auto_pull=True,
pull_threshold=14,
**_program.pio_kwargs,
)
self._sm.background_write(loop=self._buf)
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
self.deinit()
def deinit(self):
self._sm.deinit()
def __setitem__(self, i, v):
if v is None:
self._buf[i] = 0
else:
self._buf[i] = DIGITS_WT[v] & ~COM_WT[i]
def set_number(self, number):
for j in range(4):
self[3 - j] = number % 10
number //= 10
def count(start=0):
val = start
while True:
yield val
val += 1
def main():
with SMSevenSegment(board.GP9) as s:
for i in count():
s.set_number(i)
time.sleep(0.05)
if __name__ == "__main__":
main()