Skip to content

Commit 0788698

Browse files
authored
Categorization / general cleanup (#344)
Mostly cleanup of the categorization superclasses. Also other minor cleanup: - Remove nonfunctional mounting holes and labels, these should be added to the layout as non-schematic footprints - Categorized into a new DeprecatedBlock - Remove type from component names for IMU and magnetometer - Add deprecation aliases - Add MultipackOpamp abstract block and MultipackOpampGenerator skeleton base block - Remove switch controller and fox project test cases, those probably aren't contributing to coverage but still taking time
1 parent f7edaae commit 0788698

File tree

94 files changed

+657
-54336
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+657
-54336
lines changed

edg/BoardTop.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,17 @@ class BoardTop(BaseBoardTop):
5151
pass
5252

5353

54-
class JlcToolingHoles(Mechanical, Block):
54+
class JlcToolingHole(InternalSubcircuit, FootprintBlock):
55+
def contents(self):
56+
super().contents()
57+
self.footprint(
58+
'H', 'edg:JlcToolingHole_1.152mm',
59+
{},
60+
datasheet='https://support.jlcpcb.com/article/92-how-to-add-tooling-holes-for-smt-assembly-order'
61+
)
62+
63+
64+
class JlcToolingHoles(InternalSubcircuit, Block):
5565
def contents(self):
5666
super().contents()
5767
self.th1 = self.Block(JlcToolingHole())

electronics_abstract_parts/AbstractAntenna.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77
@abstract_block
8-
class Antenna(Block):
8+
class Antenna(Interface, Block):
99
@init_in_parent
1010
def __init__(self, frequency: RangeLike, impedance: RangeLike = Range.all(), power: RangeLike = (0, 0*Watt)):
1111
super().__init__()

electronics_abstract_parts/AbstractOpamp.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Mapping
1+
from typing import Mapping, Tuple, List, NamedTuple
22

33
from electronics_model import *
44
from .Categories import Analog
@@ -29,3 +29,56 @@ def __init__(self) -> None:
2929

3030
class OpampElement(Opamp):
3131
"""Packed opamp element"""
32+
33+
34+
@abstract_block
35+
class MultipackOpamp(Analog, MultipackBlock):
36+
"""Base class for packed opamps - devices that have multiple opamps in a single package,
37+
with shared power and ground connections. Typically used with the multipack feature to
38+
fit individual opamps across the design hierarchy into one of these."""
39+
def __init__(self):
40+
super().__init__()
41+
self.elements = self.PackedPart(PackedBlockArray(OpampElement()))
42+
self.pwr = self.PackedExport(self.elements.ports_array(lambda x: x.pwr))
43+
self.gnd = self.PackedExport(self.elements.ports_array(lambda x: x.gnd))
44+
self.inp = self.PackedExport(self.elements.ports_array(lambda x: x.inp))
45+
self.inn = self.PackedExport(self.elements.ports_array(lambda x: x.inn))
46+
self.out = self.PackedExport(self.elements.ports_array(lambda x: x.out))
47+
48+
49+
@non_library
50+
class MultipackOpampGenerator(MultipackOpamp, GeneratorBlock):
51+
"""Skeleton base class that provides scaffolding for common packed opamp definitions"""
52+
class OpampPorts(NamedTuple):
53+
gnd: VoltageSink
54+
pwr: VoltageSink
55+
amps: List[Tuple[AnalogSink, AnalogSink, AnalogSource]] # amp-, amp+, out
56+
57+
def __init__(self):
58+
super().__init__()
59+
self.generator_param(self.pwr.requested(), self.gnd.requested(),
60+
self.inn.requested(), self.inp.requested(), self.out.requested())
61+
62+
def _make_multipack_opamp(self) -> OpampPorts:
63+
"""Generates the opamp as a block in self, including any application circuit components like decoupling capacitors.
64+
Returns (gnd, pwr, [(in-, in+, out)])."""
65+
raise NotImplementedError # implement me
66+
67+
def generate(self):
68+
super().generate()
69+
amp_ports = self._make_multipack_opamp()
70+
71+
self.gnd_merge = self.Block(PackedVoltageSource())
72+
self.pwr_merge = self.Block(PackedVoltageSource())
73+
self.connect(self.gnd_merge.pwr_out, amp_ports.gnd)
74+
self.connect(self.pwr_merge.pwr_out, amp_ports.pwr)
75+
76+
requested = self.get(self.pwr.requested())
77+
assert self.get(self.gnd.requested()) == self.get(self.inp.requested()) == \
78+
self.get(self.inn.requested()) == self.get(self.out.requested()) == requested
79+
for i, (amp_neg, amp_pos, amp_out) in zip(requested, amp_ports.amps):
80+
self.connect(self.pwr.append_elt(VoltageSink.empty(), i), self.pwr_merge.pwr_ins.request(i))
81+
self.connect(self.gnd.append_elt(VoltageSink.empty(), i), self.gnd_merge.pwr_ins.request(i))
82+
self.connect(self.inn.append_elt(AnalogSink.empty(), i), amp_neg)
83+
self.connect(self.inp.append_elt(AnalogSink.empty(), i), amp_pos)
84+
self.connect(self.out.append_elt(AnalogSource.empty(), i), amp_out)

electronics_abstract_parts/Categories.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ class Sensor(Block):
174174
pass
175175

176176

177+
@abstract_block
178+
class CurrentSensor(Sensor):
179+
pass
180+
181+
177182
@abstract_block
178183
class Accelerometer(Sensor):
179184
pass
@@ -200,13 +205,13 @@ class Magnetometer(Sensor):
200205

201206

202207
@abstract_block
203-
class DistanceSensor(Sensor):
208+
class Camera(Sensor):
209+
"""Imaging sensors, including visible / RGB, IR, and thermal."""
204210
pass
205211

206212

207213
@abstract_block
208-
class Mechanical(Block):
209-
"""Nonelectrical footprint, including plated and NPTH mounting holes."""
214+
class DistanceSensor(Sensor):
210215
pass
211216

212217

@@ -285,6 +290,20 @@ def contents(self):
285290

286291

287292
@abstract_block
288-
class Label(Block):
289-
"""Nonfunctional footprint, including copper and silkscreen labels."""
293+
class DeprecatedBlock(InternalBlock):
294+
"""Base class for blocks that are deprecated and planned to be removed"""
295+
pass
296+
297+
298+
@abstract_block
299+
class Label(DeprecatedBlock):
300+
"""DEPRECATED: non-circuit footprints should be added in layout as non-schematic items.
301+
Nonfunctional footprint, including copper and silkscreen labels."""
302+
pass
303+
304+
305+
@abstract_block
306+
class Mechanical(DeprecatedBlock):
307+
"""DEPRECATED: non-circuit footprints should be added in layout as non-schematic items.
308+
Nonelectrical footprint, including plated and NPTH mounting holes."""
290309
pass

electronics_abstract_parts/OpampCurrentSensor.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
from typing import Dict
22

33
from electronics_abstract_parts import CurrentSenseResistor, DifferentialAmplifier
4-
from .Categories import Sensor
4+
from .Categories import CurrentSensor
55
from .DummyDevices import ForcedAnalogSignal
66
from electronics_model import *
77

88

9-
class OpampCurrentSensor(Sensor, KiCadImportableBlock, Block):
9+
class OpampCurrentSensor(CurrentSensor, KiCadImportableBlock, Block):
1010
"""Current sensor block using a resistive sense element and an opamp-based differential amplifier.
1111
For a positive current (flowing from pwr_in -> pwr_out), this generates a positive voltage on the output.
1212
Output reference can be floating (eg, at Vdd/2) to allow bidirectional current sensing.
13+
14+
Discrete diffamp circuits generally have poor accuracy as a result of resistor tolerances, including
15+
very poor common-mode rejection.
1316
"""
1417
@init_in_parent
1518
def __init__(self, resistance: RangeLike, ratio: RangeLike, input_impedance: RangeLike):

electronics_abstract_parts/PowerCircuits.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
from .AbstractResistor import Resistor
44
from .AbstractFets import SwitchFet
55
from .GateDrivers import HalfBridgeDriver, HalfBridgeDriverIndependent, HalfBridgeDriverPwm
6+
from .Categories import PowerConditioner
67

78

89
@abstract_block_default(lambda: FetHalfBridgeIndependent)
9-
class HalfBridge(Block):
10+
class HalfBridge(PowerConditioner, Block):
1011
"""Half bridge circuit with logic-level inputs and current draw calculated from the output node.
1112
Two power rails: logic power (which can be used to power gate drivers), and the power rail."""
1213
def __init__(self):
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from electronics_model import *
2+
from .Categories import HumanInterface
3+
4+
5+
class FootprintToucbPad(FootprintBlock, HumanInterface):
6+
@init_in_parent
7+
def __init__(self, touch_footprint: StringLike):
8+
super().__init__()
9+
self.pad = self.Port(TouchPadPort(), [Input])
10+
self.touch_footprint = self.ArgParameter(touch_footprint)
11+
12+
def contents(self):
13+
super().contents()
14+
self.footprint('U', self.touch_footprint, {'1': self.pad})

electronics_abstract_parts/__init__.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
from .Categories import PowerConditioner, PowerSwitch, MotorDriver, BrushedMotorDriver, BldcDriver
1515
from .Categories import PowerSource, Connector, ProgrammingConnector
1616
from .Categories import HumanInterface, Display, Lcd, Oled, EInk, Light
17-
from .Categories import Sensor, Accelerometer, Gyroscope, Magnetometer, DistanceSensor, EnvironmentalSensor, LightSensor
18-
from .Categories import Label, Testing, TypedJumper, TypedTestPoint, InternalSubcircuit, Mechanical
17+
from .Categories import Sensor, CurrentSensor, Accelerometer, Gyroscope, Magnetometer, DistanceSensor, Camera, \
18+
EnvironmentalSensor, LightSensor
19+
from .Categories import Label, Testing, TypedJumper, TypedTestPoint, InternalSubcircuit, DeprecatedBlock, Mechanical
1920

2021
from .ESeriesUtil import ESeriesUtil
2122
from .SmdStandardPackage import SmdStandardPackage, SmdStandardPackageSelector
@@ -55,7 +56,7 @@
5556
from .AbstractSwitch import Switch, TactileSwitch, MechanicalKeyswitch, DigitalSwitch
5657
from .AbstractSwitch import RotaryEncoder, RotaryEncoderSwitch, DigitalRotaryEncoder, DigitalRotaryEncoderSwitch
5758
from .AbstractSwitch import DirectionSwitch, DirectionSwitchCenter, DigitalDirectionSwitch, DigitalDirectionSwitchCenter
58-
from .AbstractOpamp import Opamp, OpampElement
59+
from .AbstractOpamp import Opamp, OpampElement, MultipackOpamp, MultipackOpampGenerator
5960
from .OpampCircuits import OpampFollower, Amplifier, DifferentialAmplifier, IntegratorInverting
6061
from .AbstractSpiMemory import SpiMemory, SpiMemoryQspi
6162
from .OpampCurrentSensor import OpampCurrentSensor
@@ -77,6 +78,7 @@
7778
from .AbstractTestPoint import AnalogRfTestPoint
7879
from .AbstractJumper import Jumper, DigitalJumper
7980
from .PassiveConnector import PassiveConnector, FootprintPassiveConnector
81+
from .TouchPad import FootprintToucbPad
8082

8183
from .UsbConnectors import UsbConnector, UsbHostConnector, UsbDeviceConnector, UsbEsdDiode
8284
from .CanTransceiver import CanTransceiver, IsolatedCanTransceiver, CanEsdDiode

electronics_lib/BatteryProtector_S8261A.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from .JlcPart import JlcPart
33

44

5-
class BatteryProtector_S8261A_Device(InternalSubcircuit, JlcPart, FootprintBlock):
5+
class S8261A_Device(InternalSubcircuit, JlcPart, FootprintBlock):
66
def __init__(self) -> None:
77
super().__init__()
88

@@ -35,12 +35,14 @@ def contents(self) -> None:
3535
self.assign(self.lcsc_part, 'C28081')
3636
self.assign(self.actual_basic_part, False)
3737

38-
class BatteryProtector_S8261A(PowerConditioner, Block):
38+
class S8261A(PowerConditioner, Block):
39+
"""1-cell LiIon/LiPo Battery protection IC protecting against overcharge, overdischarge, over current.
40+
"""
3941
@init_in_parent
4042
def __init__(self) -> None:
4143
super().__init__()
4244

43-
self.ic = self.Block(BatteryProtector_S8261A_Device())
45+
self.ic = self.Block(S8261A_Device())
4446

4547
self.pwr_out = self.Port(VoltageSource.empty())
4648
self.gnd_out = self.Port(GroundSource.empty())

electronics_lib/BootstrapVoltageAdder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from electronics_abstract_parts import *
22

33

4-
class BootstrapVoltageAdder(KiCadSchematicBlock, Block):
4+
class BootstrapVoltageAdder(KiCadSchematicBlock, PowerConditioner, Block):
55
"""Bipolar (positive and negative) voltage adder using a switched cap circuit.
66
"""
77
@init_in_parent

0 commit comments

Comments
 (0)