-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathtest_simon.py
More file actions
144 lines (125 loc) · 5.63 KB
/
test_simon.py
File metadata and controls
144 lines (125 loc) · 5.63 KB
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
import unittest
from typing_extensions import override
from edg import *
from .util import run_test_board
class DomeButtonConnector(Connector, FootprintBlock):
def __init__(self) -> None:
super().__init__()
self.led_a = self.Port(
DigitalSink(
voltage_limits=(0, 15) * Volt, # arbitrary +3v tolerance
current_draw=(0, 10) * mAmp, # TODO characterize current draw
)
)
self.led_k = self.Port(Ground(), [Common]) # TODO should be agnostic to high / low sided drive
self.sw2 = self.Port(Ground(), [Common])
self.sw1 = self.Port(DigitalSource.low_from_supply(self.sw2))
@override
def contents(self) -> None:
super().contents()
self.footprint(
"J",
"Connector_PinHeader_2.54mm:PinHeader_1x04_P2.54mm_Vertical",
{
"1": self.led_a,
"2": self.led_k,
"3": self.sw1,
"4": self.sw2,
},
mfr="Sparkfun",
part="COM-09181", # TODO different colors
)
class Simon(BoardTop):
@override
def contents(self) -> None:
super().contents()
self.mcu = self.Block(IoController())
mcu_pwr = self.mcu.with_mixin(IoControllerPowerOut())
mcu_usb = self.mcu.with_mixin(IoControllerUsbOut())
self.v5v = self.connect(mcu_usb.vusb_out)
self.v3v3 = self.connect(mcu_pwr.pwr_out)
self.gnd = self.connect(self.mcu.gnd)
with self.implicit_connect(
ImplicitConnect(self.v5v, [Power]),
ImplicitConnect(self.gnd, [Common]),
) as imp:
(self.spk_drv, self.spk), _ = self.chain(
self.mcu.with_mixin(IoControllerDac()).dac.request("spk"), imp.Block(Lm4871()), self.Block(Speaker())
)
with self.implicit_connect(
ImplicitConnect(self.v3v3, [Power]),
ImplicitConnect(self.gnd, [Common]),
) as imp:
self.rgb = imp.Block(IndicatorSinkRgbLed()) # status RGB
self.connect(self.mcu.gpio.request_vector("rgb"), self.rgb.signals)
(self.sw, self.sw_pull), _ = self.chain(
imp.Block(DigitalSwitch()), imp.Block(PullupResistor(10 * kOhm(tol=0.05))), self.mcu.gpio.request("sw")
)
self.btn = ElementDict[DomeButtonConnector]()
self.btn_pull = ElementDict[PullupResistor]()
self.btn_drv = ElementDict[HighSideSwitch]() # TODO move to 12v
self.btn_zeroed_current = ElementDict[HighSideSwitch]() # TODO move to 12v
for i in range(4):
conn = self.btn[i] = imp.Block(DomeButtonConnector())
pull = self.btn_pull[i] = imp.Block(PullupResistor(10 * kOhm(tol=0.05)))
self.connect(pull.io, conn.sw1, self.mcu.gpio.request(f"btn_sw{i}"))
self.pwr = self.Block(Ap3012(output_voltage=12 * Volt(tol=0.1)))
self.connect(self.v5v, self.pwr.pwr_in)
self.connect(self.gnd, self.pwr.gnd)
self.v12 = self.connect(self.pwr.pwr_out)
with self.implicit_connect(
ImplicitConnect(self.v12, [Power]),
ImplicitConnect(self.gnd, [Common]),
) as imp:
for i in range(4):
driver = self.btn_drv[i] = imp.Block(HighSideSwitch(frequency=(0.1, 1) * kHertz))
self.connect(self.mcu.gpio.request(f"btn_drv{i}"), driver.control)
if i == 0: # only one draws current, since we assume only one will be lit at any point in time
self.connect(driver.output.as_digital_source(), self.btn[i].led_a)
else:
(self.btn_zeroed_current[i],), _ = self.chain(
driver.output.as_digital_source(),
self.Block(ForcedDigitalSinkCurrentDraw((0, 0))),
self.btn[i].led_a,
)
@override
def refinements(self) -> Refinements:
return super().refinements() + Refinements(
instance_values=[
(
["mcu", "pin_assigns"],
[
"spk=24",
"rgb_red=15",
"rgb_green=14",
"rgb_blue=13",
"sw=27",
"btn_drv0=5",
"btn_sw0=6",
"btn_drv1=7",
"btn_sw1=8",
"btn_drv2=9",
"btn_sw2=10",
"btn_drv3=11",
"btn_sw3=12",
],
),
# JLC does not have frequency specs, must be checked TODO
(["pwr", "power_path", "inductor", "manual_frequency_rating"], Range.all()),
# keep netlist footprints as libraries change
(["btn_drv[0]", "drv", "footprint_spec"], "Package_TO_SOT_SMD:TO-252-2"),
(["btn_drv[1]", "drv", "footprint_spec"], ParamValue(["btn_drv[0]", "drv", "footprint_spec"])),
(["btn_drv[2]", "drv", "footprint_spec"], ParamValue(["btn_drv[0]", "drv", "footprint_spec"])),
(["btn_drv[3]", "drv", "footprint_spec"], ParamValue(["btn_drv[0]", "drv", "footprint_spec"])),
],
instance_refinements=[
(["mcu"], Nucleo_F303k8),
(["spk", "conn"], JstPhKVertical),
],
class_refinements=[
(Speaker, ConnectorSpeaker),
],
)
class SimonTestCase(unittest.TestCase):
def test_design(self) -> None:
run_test_board(Simon)