-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New library parts and example boards: SX1262 LoRa, PN7160 NFC, FLIR L…
…epton thermal camera sensor (#384) Adds these libraries: - Bidirectional level shifter using two FETs , requires a directionality hint - A lot of RF library components / generators, including L networks, and a L network overlaid with a second-harmonic notch - Unit tests for these verified against online calculators - DiscreteRfWarning mixin, override-able assertion warning for discrete RF blocks - TLV757P high current SOT-23 LDOs - PN7160 NFC controller with analog frontend generator. Experimental, but tested working (though not necessary optimally tuned) - Unit tests for these verified against reference documents - SX1262 LoRa transceiver, based on the reference analog frontend architecture but with generators. The component values don't line up exactly but are in the right ballpark. Example boards: - Standing desk controller - flipped RX/TX as sent to fab, corrected in libraries and generator but not layout. Layout is still good enough since the level shifters are bidirectional. Level shifter resistor for the Neopixels also need to be 1k not 4.7k. - SX1262 LoRa transceiver / PN7160 NFC omnibus RF test board - missing the SX1262 BUSY pin connection, missing the PN7160 IRQ pin connection as sent to fab, corrected in libraries and generator but not layout. - FLIR Lepton test board - works with no modifications. Changes to existing libraries: - Add gnd to Antenna interface - Add RF connectors as antennas, including Amphenol901143 SMA-F connector - Add SOT-323 to BJTs, FETs - Un-comment DCR criteria for inductors - Fixes for new JlcParts parts selector libraries - Optional reset pull for OV2640, only generated if reset not externally connected - Expansion of SG8101 crystals to also 3.2x2.5mm devices - Add support for using strapping pins of ESP32-C3-WROOM module - More common default threshold for APX803s POR generator TODO - future work - Separate Shutdown-able and Resettable
- Loading branch information
Showing
77 changed files
with
106,642 additions
and
221 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
from ..electronics_model import * | ||
from .Categories import * | ||
from .AbstractResistor import PullupResistor | ||
from .AbstractFets import Fet | ||
from .DummyDevices import DummyVoltageSink | ||
|
||
class BidirectionaLevelShifter(Interface, GeneratorBlock): | ||
"""Bidirectional level shifter for low(ish) frequency signals. | ||
Circuit design from Phillips AN97055, https://cdn-shop.adafruit.com/datasheets/an97055.pdf | ||
When both sides are floating or driving high, the FET is off and the pullups provide the high signal. | ||
When the LV side drives low, the FET source goes to ground, putting the FET into conduction and pulling HV low. | ||
When the HV side drives low, the body diode pulls the FET source low, then goes into conduction. | ||
Use infinity resistance to not generate a resistor, for example if it is known there is already a resistor | ||
on that side. | ||
src_hint = 'lv' | 'hv' | '' determines the 'source' side to help the electronics model resolve directionality | ||
and does not affect circuit generation or functionality. | ||
If empty, both sides are assumed to be able to drive the shifter and must have voltages and output thresholds | ||
modeled. TODO: this mode may be brittle | ||
""" | ||
@init_in_parent | ||
def __init__(self, lv_res: RangeLike = 4.7*kOhm(tol=0.05), hv_res: RangeLike = 4.7*kOhm(tol=0.05), | ||
src_hint: StringLike = '') -> None: | ||
super().__init__() | ||
self.lv_pwr = self.Port(VoltageSink.empty()) | ||
self.lv_io = self.Port(DigitalBidir.empty()) | ||
self.hv_pwr = self.Port(VoltageSink.empty()) | ||
self.hv_io = self.Port(DigitalBidir.empty()) | ||
|
||
self.lv_res = self.ArgParameter(lv_res) | ||
self.hv_res = self.ArgParameter(hv_res) | ||
self.src_hint = self.ArgParameter(src_hint) | ||
self.generator_param(self.lv_res, self.hv_res, self.src_hint) | ||
|
||
def generate(self) -> None: | ||
super().generate() | ||
|
||
self.fet = self.Block(Fet.NFet( | ||
drain_voltage=self.hv_pwr.link().voltage.hull(self.hv_io.link().voltage), | ||
drain_current=self.lv_io.link().current_drawn.hull(self.hv_io.link().current_drawn), | ||
gate_voltage=self.lv_pwr.link().voltage - self.lv_io.link().voltage, | ||
rds_on=(0, 1)*Ohm # arbitrary | ||
)) | ||
|
||
if self.get(self.src_hint) == 'lv': # LV is source, HV model is incomplete | ||
lv_io_model = DigitalBidir( | ||
voltage_out=self.lv_pwr.link().voltage, # this is not driving, effectively only a pullup | ||
output_thresholds=self.lv_pwr.link().voltage.hull(-float('inf')) | ||
) | ||
else: # HV model is complete, can use its thresholds | ||
lv_io_model = DigitalBidir( | ||
voltage_out=self.lv_pwr.link().voltage.hull(self.hv_io.link().voltage.lower()), | ||
output_thresholds=self.lv_pwr.link().voltage.hull(self.hv_io.link().voltage.lower()) | ||
) | ||
|
||
if self.get(self.src_hint) == 'hv': # HV is source, LV model is incomplete | ||
hv_io_model = DigitalBidir( | ||
voltage_out=self.hv_pwr.link().voltage, # this is not driving, effectively only a pullup | ||
output_thresholds=self.hv_pwr.link().voltage.hull(-float('inf')) | ||
) | ||
else: # HV model is complete, can use its thresholds | ||
hv_io_model = DigitalBidir( | ||
voltage_out=self.hv_pwr.link().voltage.hull(self.lv_io.link().voltage.lower()), | ||
output_thresholds=self.hv_pwr.link().voltage.hull(self.lv_io.link().voltage.lower()) | ||
) | ||
|
||
self.connect(self.lv_io, self.fet.source.adapt_to(lv_io_model)) | ||
self.connect(self.hv_io, self.fet.drain.adapt_to(hv_io_model)) | ||
self.connect(self.lv_pwr, self.fet.gate.adapt_to(VoltageSink())) | ||
|
||
if self.get(self.lv_res) != RangeExpr.INF: | ||
self.lv_pu = self.Block(PullupResistor(self.lv_res)).connected(self.lv_pwr, self.lv_io) | ||
if self.get(self.hv_res) != RangeExpr.INF: | ||
self.hv_pu = self.Block(PullupResistor(self.hv_res)).connected(self.hv_pwr, self.hv_io) | ||
else: | ||
self.dummy_hv = self.Block(DummyVoltageSink()) # must be connected | ||
self.connect(self.dummy_hv.pwr, self.hv_pwr) |
Oops, something went wrong.