From 5066c591dfd4f54bd2f4ea1fdd3ccf409c45e2e0 Mon Sep 17 00:00:00 2001 From: Richard Lin Date: Wed, 24 Apr 2024 16:39:27 -0700 Subject: [PATCH] Improve categorizations (again), add XIAO RP2040 (#345) Improve categorization - Better classification of DiscreteComponents instead of InternalSubcircuit - Remove InternalBlock from super-superclasses of some microcontrollers - anything inheriting InternalBlock (even transitively) is internal Add XIAO RP2040 and a basic keyboard example that uses the dev board. --- electronics_abstract_parts/AbstractFuse.py | 2 +- electronics_abstract_parts/AbstractJumper.py | 4 +- electronics_abstract_parts/Categories.py | 2 +- electronics_abstract_parts/IoController.py | 2 +- .../PassiveConnector.py | 2 +- electronics_lib/Microcontroller_Esp32.py | 4 +- electronics_lib/Microcontroller_Esp32c3.py | 6 +- electronics_lib/Microcontroller_Esp32s3.py | 4 +- electronics_lib/Microcontroller_Rp2040.py | 399 ++++++++++++------ electronics_lib/Microcontroller_nRF52840.py | 8 +- electronics_lib/RfModules.py | 2 +- electronics_lib/__init__.py | 2 +- examples/BasicKeyboard/BasicKeyboard.net | 193 +++++++++ examples/BasicKeyboard/BasicKeyboard.ref.net | 193 +++++++++ examples/test_basickeyboard.py | 36 ++ 15 files changed, 715 insertions(+), 144 deletions(-) create mode 100644 examples/BasicKeyboard/BasicKeyboard.net create mode 100644 examples/BasicKeyboard/BasicKeyboard.ref.net create mode 100644 examples/test_basickeyboard.py diff --git a/electronics_abstract_parts/AbstractFuse.py b/electronics_abstract_parts/AbstractFuse.py index 057316e9c..6db40bede 100644 --- a/electronics_abstract_parts/AbstractFuse.py +++ b/electronics_abstract_parts/AbstractFuse.py @@ -8,7 +8,7 @@ @abstract_block -class Fuse(InternalSubcircuit, Block): +class Fuse(DiscreteComponent, Block): @init_in_parent def __init__(self, trip_current: RangeLike, *, hold_current: RangeLike = RangeExpr.ALL, voltage: RangeLike = RangeExpr.ZERO) -> None: diff --git a/electronics_abstract_parts/AbstractJumper.py b/electronics_abstract_parts/AbstractJumper.py index fe8603c7d..a15d4f700 100644 --- a/electronics_abstract_parts/AbstractJumper.py +++ b/electronics_abstract_parts/AbstractJumper.py @@ -1,9 +1,9 @@ from electronics_model import * -from .Categories import InternalSubcircuit, TypedJumper +from .Categories import DiscreteComponent, TypedJumper @abstract_block -class Jumper(InternalSubcircuit, Block): +class Jumper(DiscreteComponent, Block): """A two-ported passive-typed jumper (a disconnect-able connection), though is treated as always connected for model purposes. diff --git a/electronics_abstract_parts/Categories.py b/electronics_abstract_parts/Categories.py index 23950d5da..86830ad1e 100644 --- a/electronics_abstract_parts/Categories.py +++ b/electronics_abstract_parts/Categories.py @@ -252,7 +252,7 @@ class InternalSubcircuit(InternalBlock): @abstract_block -class DiscreteComponent(InternalSubcircuit, Block): +class DiscreteComponent(InternalBlock): """Discrete component that typically provides untyped ports (not to be be used directly), as a component to be used in an application circuit.""" pass diff --git a/electronics_abstract_parts/IoController.py b/electronics_abstract_parts/IoController.py index 9cd061f23..024da9992 100644 --- a/electronics_abstract_parts/IoController.py +++ b/electronics_abstract_parts/IoController.py @@ -9,7 +9,7 @@ @abstract_block -class BaseIoController(PinMappable, InternalBlock, Block): +class BaseIoController(PinMappable, Block): """An abstract IO controller block, that takes power input and provides a grab-bag of common IOs. A base interface for microcontrollers and microcontroller-like devices (eg, FPGAs). Pin assignments are handled via refinements and can be assigned to pins' allocated names. diff --git a/electronics_abstract_parts/PassiveConnector.py b/electronics_abstract_parts/PassiveConnector.py index 41a3ab4b6..afa035df5 100644 --- a/electronics_abstract_parts/PassiveConnector.py +++ b/electronics_abstract_parts/PassiveConnector.py @@ -3,7 +3,7 @@ @abstract_block -class PassiveConnector(InternalSubcircuit, Block): +class PassiveConnector(DiscreteComponent, Block): """A base Block that is an elastic n-ported connector with passive type. Interface only, no implementation. diff --git a/electronics_lib/Microcontroller_Esp32.py b/electronics_lib/Microcontroller_Esp32.py index ae816b1e9..51740b529 100644 --- a/electronics_lib/Microcontroller_Esp32.py +++ b/electronics_lib/Microcontroller_Esp32.py @@ -140,7 +140,7 @@ def _io_pinmap(self) -> PinMapUtil: @abstract_block -class Esp32_Base(Esp32_Ios, InternalSubcircuit, GeneratorBlock): +class Esp32_Base(Esp32_Ios, GeneratorBlock): """Base class for ESP32 series microcontrollers with WiFi and Bluetooth (classic and LE) Chip datasheet: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf @@ -179,7 +179,7 @@ def _system_pinmap(self) -> Dict[str, CircuitPort]: }).remap(self.SYSTEM_PIN_REMAP) -class Esp32_Wroom_32_Device(Esp32_Base, FootprintBlock, JlcPart): +class Esp32_Wroom_32_Device(Esp32_Base, InternalSubcircuit, FootprintBlock, JlcPart): """ESP32-WROOM-32 module Module datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32e_esp32-wroom-32ue_datasheet_en.pdf diff --git a/electronics_lib/Microcontroller_Esp32c3.py b/electronics_lib/Microcontroller_Esp32c3.py index 740d1d2d1..fb761dff3 100644 --- a/electronics_lib/Microcontroller_Esp32c3.py +++ b/electronics_lib/Microcontroller_Esp32c3.py @@ -87,7 +87,7 @@ def _io_pinmap(self) -> PinMapUtil: @abstract_block -class Esp32c3_Base(Esp32c3_Ios, InternalSubcircuit, BaseIoControllerPinmapGenerator): +class Esp32c3_Base(Esp32c3_Ios, BaseIoControllerPinmapGenerator): """Base class for ESP32-C3 series devices, with RISC-V core, 2.4GHz WiF,i, BLE5. PlatformIO: use board ID esp32-c3-devkitm-1 @@ -127,7 +127,7 @@ def __init__(self, **kwargs) -> None: self.uart0 = self.Port(UartPort(dio_model), optional=True) -class Esp32c3_Wroom02_Device(Esp32c3_Base, FootprintBlock, JlcPart): +class Esp32c3_Wroom02_Device(Esp32c3_Base, InternalSubcircuit, FootprintBlock, JlcPart): """ESP32C module Module datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3-wroom-02_datasheet_en.pdf @@ -211,7 +211,7 @@ def generate(self) -> None: gnd=self.gnd, pwr=self.pwr, io=self.ic.en) -class Esp32c3_Device(Esp32c3_Base, FootprintBlock, JlcPart): +class Esp32c3_Device(Esp32c3_Base, InternalSubcircuit, FootprintBlock, JlcPart): """ESP32C3 with 4MB integrated flash TODO: support other part numbers, including without integrated flash """ diff --git a/electronics_lib/Microcontroller_Esp32s3.py b/electronics_lib/Microcontroller_Esp32s3.py index 5e80b9ef2..9bd767257 100644 --- a/electronics_lib/Microcontroller_Esp32s3.py +++ b/electronics_lib/Microcontroller_Esp32s3.py @@ -146,7 +146,7 @@ def _io_pinmap(self) -> PinMapUtil: @abstract_block -class Esp32s3_Base(Esp32s3_Ios, InternalSubcircuit, GeneratorBlock): +class Esp32s3_Base(Esp32s3_Ios, GeneratorBlock): """Base class for ESP32-S3 series microcontrollers with WiFi and Bluetooth (classic and LE) and AI acceleration @@ -180,7 +180,7 @@ def __init__(self, **kwargs) -> None: self.uart0 = self.Port(UartPort(dio_model), optional=True) # programming -class Esp32s3_Wroom_1_Device(Esp32s3_Base, FootprintBlock, JlcPart): +class Esp32s3_Wroom_1_Device(Esp32s3_Base, InternalSubcircuit, FootprintBlock, JlcPart): SYSTEM_PIN_REMAP: Dict[str, Union[str, List[str]]] = { 'VDD': '2', 'GND': ['1', '40', '41'], # 41 is EP diff --git a/electronics_lib/Microcontroller_Rp2040.py b/electronics_lib/Microcontroller_Rp2040.py index c23de281b..1767462b1 100644 --- a/electronics_lib/Microcontroller_Rp2040.py +++ b/electronics_lib/Microcontroller_Rp2040.py @@ -1,21 +1,191 @@ +from abc import abstractmethod from typing import * from electronics_abstract_parts import * from .JlcPart import JlcPart -class Rp2040_Device(IoControllerI2cTarget, IoControllerUsb, BaseIoControllerPinmapGenerator, InternalSubcircuit, +@non_library +class Rp2040_Interfaces(IoControllerI2cTarget, IoControllerUsb, BaseIoController): + """Defines base interfaces for ESP32C3 microcontrollers""" + + +@non_library +class Rp2040_Ios(Rp2040_Interfaces, BaseIoControllerPinmapGenerator): + """IOs definitions independent of infrastructural (e.g. power) pins.""" + RESOURCE_PIN_REMAP: Dict[str, str] # resource name in base -> pin name + + @abstractmethod + def _gnd_vddio(self) -> Tuple[Port[VoltageLink], Port[VoltageLink]]: + """Returns GND and VDDIO (either can be VoltageSink or VoltageSource).""" + ... + + def _iovdd_model(self): + return VoltageSink( + voltage_limits=(1.62, 3.63)*Volt, # Table 628 + current_draw=(1.2, 4.3)*mAmp + self.io_current_draw.upper() # Table 629 + ) + + def _dio_model(self, gnd: Port[VoltageLink], pwr: Port[VoltageLink]) -> DigitalBidir: + return DigitalBidir.from_supply( # table 4.4 + gnd, pwr, + voltage_limit_tolerance=(-0.3, 0.3) * Volt, + current_limits=(-12, 12)*mAmp, # by IOH / IOL modes + input_threshold_abs=(0.8, 2.0)*Volt, # for IOVdd=3.3, TODO other IOVdd ranges + pullup_capable=True, pulldown_capable=True + ) + + def _io_pinmap(self) -> PinMapUtil: + gnd, pwr = self._gnd_vddio() + dio_usb_model = dio_ft_model = dio_std_model = self._dio_model(gnd, pwr) + + adc_model = AnalogSink.from_supply( # Table 626 + gnd, pwr, + voltage_limit_tolerance=(0, 0), # ADC input voltage range + signal_limit_tolerance=(0, 0), # ADC input voltage range + impedance=(100, float('inf')) * kOhm + ) + + uart_model = UartPort(DigitalBidir.empty()) + spi_model = SpiController(DigitalBidir.empty()) + i2c_model = I2cController(DigitalBidir.empty()) + i2c_target_model = I2cTarget(DigitalBidir.empty()) + + return PinMapUtil([ + PinResource('GPIO0', {'GPIO0': dio_ft_model}), + PinResource('GPIO1', {'GPIO1': dio_ft_model}), + PinResource('GPIO2', {'GPIO2': dio_ft_model}), + PinResource('GPIO3', {'GPIO3': dio_ft_model}), + PinResource('GPIO4', {'GPIO4': dio_ft_model}), + PinResource('GPIO5', {'GPIO5': dio_ft_model}), + PinResource('GPIO6', {'GPIO6': dio_ft_model}), + PinResource('GPIO7', {'GPIO7': dio_ft_model}), + PinResource('GPIO8', {'GPIO8': dio_ft_model}), + PinResource('GPIO9', {'GPIO9': dio_ft_model}), + PinResource('GPIO10', {'GPIO10': dio_ft_model}), + PinResource('GPIO11', {'GPIO11': dio_ft_model}), + PinResource('GPIO12', {'GPIO12': dio_ft_model}), + PinResource('GPIO13', {'GPIO13': dio_ft_model}), + PinResource('GPIO14', {'GPIO14': dio_ft_model}), + PinResource('GPIO15', {'GPIO15': dio_ft_model}), + PinResource('GPIO16', {'GPIO16': dio_ft_model}), + PinResource('GPIO17', {'GPIO17': dio_ft_model}), + PinResource('GPIO18', {'GPIO18': dio_ft_model}), + PinResource('GPIO19', {'GPIO19': dio_ft_model}), + PinResource('GPIO20', {'GPIO20': dio_ft_model}), + PinResource('GPIO21', {'GPIO21': dio_ft_model}), + + PinResource('GPIO22', {'GPIO22': dio_ft_model}), + PinResource('GPIO23', {'GPIO23': dio_ft_model}), + PinResource('GPIO24', {'GPIO24': dio_ft_model}), + PinResource('GPIO25', {'GPIO25': dio_ft_model}), + + PinResource('GPIO26', {'GPIO26': dio_std_model, 'ADC0': adc_model}), + PinResource('GPIO27', {'GPIO27': dio_std_model, 'ADC1': adc_model}), + PinResource('GPIO28', {'GPIO28': dio_std_model, 'ADC2': adc_model}), + PinResource('GPIO29', {'GPIO29': dio_std_model, 'ADC3': adc_model}), + + # fixed-pin peripherals + PeripheralFixedPin('USB', UsbDevicePort(dio_usb_model), { + 'dm': 'USB_DM', 'dp': 'USB_DP' + }), + + # reassignable peripherals + PeripheralFixedResource('UART0', uart_model, { + 'tx': ['GPIO0', 'GPIO12', 'GPIO16', 'GPIO28'], + 'rx': ['GPIO1', 'GPIO13', 'GPIO17', 'GPIO29'] + }), + PeripheralFixedResource('UART1', uart_model, { + 'tx': ['GPIO4', 'GPIO8', 'GPIO20', 'GPIO24'], + 'rx': ['GPIO5', 'GPIO9', 'GPIO21', 'GPIO25'] + }), + + PeripheralFixedResource('SPI0', spi_model, { + 'miso': ['GPIO0', 'GPIO4', 'GPIO16', 'GPIO20'], # RX + 'sck': ['GPIO2', 'GPIO6', 'GPIO18', 'GPIO22'], + 'mosi': ['GPIO3', 'GPIO7', 'GPIO19', 'GPIO23'] # TX + }), + PeripheralFixedResource('SPI1', spi_model, { + 'miso': ['GPIO8', 'GPIO12', 'GPIO24', 'GPIO28'], # RX + 'sck': ['GPIO10', 'GPIO14', 'GPIO26'], + 'mosi': ['GPIO11', 'GPIO15', 'GPIO27'] # TX + }), + # SPI peripheral omitted, since TX tri-state is not tied to CS and must be controlled in software + PeripheralFixedResource('I2C0', i2c_model, { + 'sda': ['GPIO0', 'GPIO4', 'GPIO8', 'GPIO12', 'GPIO16', 'GPIO20', 'GPIO24', 'GPIO28'], + 'scl': ['GPIO1', 'GPIO5', 'GPIO9', 'GPIO13', 'GPIO17', 'GPIO21', 'GPIO25', 'GPIO20'] + }), + PeripheralFixedResource('I2C1', i2c_model, { + 'sda': ['GPIO2', 'GPIO6', 'GPIO10', 'GPIO14', 'GPIO18', 'GPIO22', 'GPIO24', 'GPIO26'], + 'scl': ['GPIO3', 'GPIO7', 'GPIO11', 'GPIO15', 'GPIO19', 'GPIO23', 'GPIO25', 'GPIO27'] + }), + PeripheralFixedResource('I2C0_T', i2c_target_model, { # TODO shared resource w/ I2C controller + 'sda': ['GPIO0', 'GPIO4', 'GPIO8', 'GPIO12', 'GPIO16', 'GPIO20', 'GPIO24', 'GPIO28'], + 'scl': ['GPIO1', 'GPIO5', 'GPIO9', 'GPIO13', 'GPIO17', 'GPIO21', 'GPIO25', 'GPIO20'] + }), + PeripheralFixedResource('I2C1_T', i2c_target_model, { # TODO shared resource w/ I2C controller + 'sda': ['GPIO2', 'GPIO6', 'GPIO10', 'GPIO14', 'GPIO18', 'GPIO22', 'GPIO24', 'GPIO26'], + 'scl': ['GPIO3', 'GPIO7', 'GPIO11', 'GPIO15', 'GPIO19', 'GPIO23', 'GPIO25', 'GPIO27'] + }), + + PeripheralFixedPin('SWD', SwdTargetPort(dio_std_model), { + 'swdio': 'SWDIO', 'swclk': 'SWCLK', + }), + ]).remap_pins(self.RESOURCE_PIN_REMAP) + + +class Rp2040_Device(Rp2040_Ios, BaseIoControllerPinmapGenerator, InternalSubcircuit, GeneratorBlock, JlcPart, FootprintBlock): + RESOURCE_PIN_REMAP = { + 'GPIO0': '2', + 'GPIO1': '3', + 'GPIO2': '4', + 'GPIO3': '5', + 'GPIO4': '6', + 'GPIO5': '7', + 'GPIO6': '8', + 'GPIO7': '9', + 'GPIO8': '11', + 'GPIO9': '12', + 'GPIO10': '13', + 'GPIO11': '14', + 'GPIO12': '15', + 'GPIO13': '16', + 'GPIO14': '17', + 'GPIO15': '18', + 'GPIO16': '27', + 'GPIO17': '28', + 'GPIO18': '29', + 'GPIO19': '30', + 'GPIO20': '31', + 'GPIO21': '32', + + 'GPIO22': '34', + 'GPIO23': '35', + 'GPIO24': '36', + 'GPIO25': '37', + + 'GPIO26': '38', + 'GPIO27': '39', + 'GPIO28': '40', + 'GPIO29': '41', + + 'USB_DM': '46', + 'USB_DP': '47', + + 'SWDIO': '25', + 'SWCLK': '24', + } + + def _gnd_vddio(self) -> Tuple[Port[VoltageLink], Port[VoltageLink]]: + return self.gnd, self.iovdd + def __init__(self, **kwargs) -> None: super().__init__(**kwargs) - self.pwr = self.Port(VoltageSink( - voltage_limits=(1.62, 3.63)*Volt, # Table 628 - current_draw=(1.2, 4.3)*mAmp + self.io_current_draw.upper() # Table 629 - ), [Power]) self.gnd = self.Port(Ground(), [Common]) + self.iovdd = self.Port(self._iovdd_model(), [Power]) - # note: IOVDD is self.pwr self.dvdd = self.Port(VoltageSink( # Digital Core voltage_limits=(0.99, 1.21)*Volt, # Table 628 current_draw=(0.18, 40)*mAmp, # Table 629 typ Dormant to Figure 171 approx max DVdd @@ -44,7 +214,7 @@ def __init__(self, **kwargs) -> None: self.qspi_sd3 = self.Port(DigitalBidir.empty()) self.xosc = self.Port(CrystalDriver(frequency_limits=(1, 15)*MHertz, # datasheet 2.15.2.2 - voltage_out=self.pwr.link().voltage), + voltage_out=self.iovdd.link().voltage), optional=True) self.swd = self.Port(SwdTargetPort.empty()) @@ -55,20 +225,12 @@ def contents(self) -> None: super().contents() # Port models - self._dio_ft_model = DigitalBidir.from_supply( # Table 624 - self.gnd, self.pwr, - voltage_limit_tolerance=(-0.3, 0.3) * Volt, - current_limits=(-12, 12)*mAmp, # by IOH / IOL modes - input_threshold_abs=(0.8, 2.0)*Volt, # for IOVdd=3.3, TODO other IOVdd ranges - pullup_capable=True, pulldown_capable=True - ) - self._dio_std_model = self._dio_ft_model # exactly the same characteristics - - self.qspi.init_from(SpiController(self._dio_std_model)) - self.qspi_cs.init_from(self._dio_std_model) - self.qspi_sd2.init_from(self._dio_std_model) - self.qspi_sd3.init_from(self._dio_std_model) - self.run.init_from(DigitalSink.from_bidir(self._dio_ft_model)) + dio_ft_model = dio_std_model = self._dio_model(self.gnd, self.iovdd) + self.qspi.init_from(SpiController(dio_std_model)) + self.qspi_cs.init_from(dio_std_model) + self.qspi_sd2.init_from(dio_std_model) + self.qspi_sd3.init_from(dio_std_model) + self.run.init_from(DigitalSink.from_bidir(dio_ft_model)) # Pin/peripheral resource definitions (table 3) def _system_pinmap(self) -> Dict[str, CircuitPort]: @@ -89,12 +251,12 @@ def _system_pinmap(self) -> Dict[str, CircuitPort]: '19': self.gnd, # TESTEN, connect to gnd - '1': self.pwr, # IOVdd - '10': self.pwr, - '22': self.pwr, - '33': self.pwr, - '42': self.pwr, - '49': self.pwr, + '1': self.iovdd, + '10': self.iovdd, + '22': self.iovdd, + '33': self.iovdd, + '42': self.iovdd, + '49': self.iovdd, '23': self.dvdd, '50': self.dvdd, @@ -106,103 +268,6 @@ def _system_pinmap(self) -> Dict[str, CircuitPort]: '57': self.gnd, # pad } - def _io_pinmap(self) -> PinMapUtil: - dio_usb_model = self._dio_ft_model # similar enough, main difference seems to be PUR/PDR resistance - - adc_model = AnalogSink.from_supply( # Table 626 - self.gnd, self.pwr, - voltage_limit_tolerance=(0, 0), # ADC input voltage range - signal_limit_tolerance=(0, 0), # ADC input voltage range - impedance=(100, float('inf')) * kOhm - ) - - uart_model = UartPort(DigitalBidir.empty()) - spi_model = SpiController(DigitalBidir.empty()) - i2c_model = I2cController(DigitalBidir.empty()) - i2c_target_model = I2cTarget(DigitalBidir.empty()) - - return PinMapUtil([ - PinResource('2', {'GPIO0': self._dio_ft_model}), - PinResource('3', {'GPIO1': self._dio_ft_model}), - PinResource('4', {'GPIO2': self._dio_ft_model}), - PinResource('5', {'GPIO3': self._dio_ft_model}), - PinResource('6', {'GPIO4': self._dio_ft_model}), - PinResource('7', {'GPIO5': self._dio_ft_model}), - PinResource('8', {'GPIO6': self._dio_ft_model}), - PinResource('9', {'GPIO7': self._dio_ft_model}), - PinResource('11', {'GPIO8': self._dio_ft_model}), - PinResource('12', {'GPIO9': self._dio_ft_model}), - PinResource('13', {'GPIO10': self._dio_ft_model}), - PinResource('14', {'GPIO11': self._dio_ft_model}), - PinResource('15', {'GPIO12': self._dio_ft_model}), - PinResource('16', {'GPIO13': self._dio_ft_model}), - PinResource('17', {'GPIO14': self._dio_ft_model}), - PinResource('18', {'GPIO15': self._dio_ft_model}), - PinResource('27', {'GPIO16': self._dio_ft_model}), - PinResource('28', {'GPIO17': self._dio_ft_model}), - PinResource('29', {'GPIO18': self._dio_ft_model}), - PinResource('30', {'GPIO19': self._dio_ft_model}), - PinResource('31', {'GPIO20': self._dio_ft_model}), - PinResource('32', {'GPIO21': self._dio_ft_model}), - - PinResource('34', {'GPIO22': self._dio_ft_model}), - PinResource('35', {'GPIO23': self._dio_ft_model}), - PinResource('36', {'GPIO24': self._dio_ft_model}), - PinResource('37', {'GPIO25': self._dio_ft_model}), - - PinResource('38', {'GPIO26': self._dio_std_model, 'ADC0': adc_model}), - PinResource('39', {'GPIO27': self._dio_std_model, 'ADC1': adc_model}), - PinResource('40', {'GPIO28': self._dio_std_model, 'ADC2': adc_model}), - PinResource('41', {'GPIO29': self._dio_std_model, 'ADC3': adc_model}), - - # fixed-pin peripherals - PeripheralFixedPin('USB', UsbDevicePort(dio_usb_model), { - 'dm': '46', 'dp': '47' - }), - - # reassignable peripherals - PeripheralFixedResource('UART0', uart_model, { - 'tx': ['GPIO0', 'GPIO12', 'GPIO16', 'GPIO28'], - 'rx': ['GPIO1', 'GPIO13', 'GPIO17', 'GPIO29'] - }), - PeripheralFixedResource('UART1', uart_model, { - 'tx': ['GPIO4', 'GPIO8', 'GPIO20', 'GPIO24'], - 'rx': ['GPIO5', 'GPIO9', 'GPIO21', 'GPIO25'] - }), - - PeripheralFixedResource('SPI0', spi_model, { - 'miso': ['GPIO0', 'GPIO4', 'GPIO16', 'GPIO20'], # RX - 'sck': ['GPIO2', 'GPIO6', 'GPIO18', 'GPIO22'], - 'mosi': ['GPIO3', 'GPIO7', 'GPIO19', 'GPIO23'] # TX - }), - PeripheralFixedResource('SPI1', spi_model, { - 'miso': ['GPIO8', 'GPIO12', 'GPIO24', 'GPIO28'], # RX - 'sck': ['GPIO10', 'GPIO14', 'GPIO26'], - 'mosi': ['GPIO11', 'GPIO15', 'GPIO27'] # TX - }), - # SPI peripheral omitted, since TX tri-state is not tied to CS and must be controlled in software - PeripheralFixedResource('I2C0', i2c_model, { - 'sda': ['GPIO0', 'GPIO4', 'GPIO8', 'GPIO12', 'GPIO16', 'GPIO20', 'GPIO24', 'GPIO28'], - 'scl': ['GPIO1', 'GPIO5', 'GPIO9', 'GPIO13', 'GPIO17', 'GPIO21', 'GPIO25', 'GPIO20'] - }), - PeripheralFixedResource('I2C1', i2c_model, { - 'sda': ['GPIO2', 'GPIO6', 'GPIO10', 'GPIO14', 'GPIO18', 'GPIO22', 'GPIO24', 'GPIO26'], - 'scl': ['GPIO3', 'GPIO7', 'GPIO11', 'GPIO15', 'GPIO19', 'GPIO23', 'GPIO25', 'GPIO27'] - }), - PeripheralFixedResource('I2C0_T', i2c_target_model, { # TODO shared resource w/ I2C controller - 'sda': ['GPIO0', 'GPIO4', 'GPIO8', 'GPIO12', 'GPIO16', 'GPIO20', 'GPIO24', 'GPIO28'], - 'scl': ['GPIO1', 'GPIO5', 'GPIO9', 'GPIO13', 'GPIO17', 'GPIO21', 'GPIO25', 'GPIO20'] - }), - PeripheralFixedResource('I2C1_T', i2c_target_model, { # TODO shared resource w/ I2C controller - 'sda': ['GPIO2', 'GPIO6', 'GPIO10', 'GPIO14', 'GPIO18', 'GPIO22', 'GPIO24', 'GPIO26'], - 'scl': ['GPIO3', 'GPIO7', 'GPIO11', 'GPIO15', 'GPIO19', 'GPIO23', 'GPIO25', 'GPIO27'] - }), - - PeripheralFixedPin('SWD', SwdTargetPort(self._dio_std_model), { - 'swdio': '25', 'swclk': '24', - }), - ]) - def generate(self) -> None: super().generate() @@ -243,7 +308,7 @@ def contents(self) -> None: UsbBitBang.digital_external_from_link(self.usb_rp.dp))) -class Rp2040(Resettable, IoControllerI2cTarget, IoControllerUsb, Microcontroller, IoControllerWithSwdTargetConnector, +class Rp2040(Resettable, Rp2040_Interfaces, Microcontroller, IoControllerWithSwdTargetConnector, WithCrystalGenerator, IoControllerPowerRequired, BaseIoControllerExportable, GeneratorBlock): DEFAULT_CRYSTAL_FREQUENCY = 12*MHertz(tol=0.005) @@ -305,3 +370,87 @@ def _make_export_vector(self, self_io: ExportType, inner_vector: Vector[ExportTy def _crystal_required(self) -> bool: # crystal needed for USB b/c tighter freq tolerance return len(self.get(self.usb.requested())) > 0 or super()._crystal_required() + + +class Xiao_Rp2040(IoControllerUsbOut, IoControllerPowerOut, Rp2040_Ios, IoController, GeneratorBlock, FootprintBlock): + """RP2040 development board, a tiny development (21x17.5mm) daughterboard. + Has an onboard USB connector, so this can also source power. + + Limited pins (only 11 for IOs, of which 6 are usable as the other 5 have boot requirements). + + Requires Seeed Studio's KiCad library for the footprint: https://github.com/Seeed-Studio/OPL_Kicad_Library + The 'Seeed Studio XIAO Series Library' must have been added as a footprint library of the same name. + + Pinning data: https://www.seeedstudio.com/blog/wp-content/uploads/2022/08/Seeed-Studio-XIAO-Series-Package-and-PCB-Design.pdf + """ + SYSTEM_PIN_REMAP: Dict[str, Union[str, List[str]]] = { + 'VDD': '12', + 'GND': '13', + 'VUSB': '14', + } + RESOURCE_PIN_REMAP = { + 'GPIO26': '1', + 'GPIO27': '2', + 'GPIO28': '3', + 'GPIO29': '4', + 'GPIO6': '5', + 'GPIO7': '6', + 'GPIO0': '7', + + 'GPIO1': '8', + 'GPIO2': '9', + 'GPIO4': '10', + 'GPIO3': '11', + } + + def _gnd_vddio(self) -> Tuple[Port[VoltageLink], Port[VoltageLink]]: + if self.get(self.gnd.is_connected()): # board sinks power + return self.gnd, self.pwr + else: + return self.gnd_out, self.pwr_out + + def _system_pinmap(self) -> Dict[str, CircuitPort]: + if self.get(self.gnd.is_connected()): # board sinks power + self.require(~self.vusb_out.is_connected(), "can't source USB power if source gnd not connected") + self.require(~self.pwr_out.is_connected(), "can't source 3v3 power if source gnd not connected") + self.require(~self.gnd_out.is_connected(), "can't source gnd if source gnd not connected") + return VariantPinRemapper({ + 'VDD': self.pwr, + 'GND': self.gnd, + }).remap(self.SYSTEM_PIN_REMAP) + else: # board sources power (default) + self.require(~self.pwr.is_connected(), "can't sink power if source gnd connected") + self.require(~self.gnd.is_connected(), "can't sink gnd if source gnd connected") + return VariantPinRemapper({ + 'VDD': self.pwr_out, + 'GND': self.gnd_out, + 'VUSB': self.vusb_out, + }).remap(self.SYSTEM_PIN_REMAP) + + def contents(self) -> None: + super().contents() + + self.gnd.init_from(Ground()) + self.pwr.init_from(self._iovdd_model()) + + self.gnd_out.init_from(GroundSource()) + self.vusb_out.init_from(VoltageSource( + voltage_out=UsbConnector.USB2_VOLTAGE_RANGE, + current_limits=UsbConnector.USB2_CURRENT_LIMITS + )) + self.pwr_out.init_from(VoltageSource( + voltage_out=3.3*Volt(tol=0.05), # tolerance is a guess + current_limits=UsbConnector.USB2_CURRENT_LIMITS + )) + + self.generator_param(self.gnd.is_connected()) + + def generate(self) -> None: + super().generate() + + self.footprint( + 'U', 'Seeed Studio XIAO Series Library:XIAO-Generic-Hybrid-14P-2.54-21X17.8MM', + self._make_pinning(), + mfr='', part='XIAO RP2040', + datasheet='https://www.seeedstudio.com/XIAO-RP2040-v1-0-p-5026.html' + ) diff --git a/electronics_lib/Microcontroller_nRF52840.py b/electronics_lib/Microcontroller_nRF52840.py index 52317dedd..519e54e68 100644 --- a/electronics_lib/Microcontroller_nRF52840.py +++ b/electronics_lib/Microcontroller_nRF52840.py @@ -12,7 +12,7 @@ class Nrf52840_Interfaces(IoControllerSpiPeripheral, IoControllerI2cTarget, IoCo @non_library -class Nrf52840_Ios(Nrf52840_Interfaces, BaseIoControllerPinmapGenerator, InternalSubcircuit, GeneratorBlock, FootprintBlock): +class Nrf52840_Ios(Nrf52840_Interfaces, BaseIoControllerPinmapGenerator, GeneratorBlock, FootprintBlock): """nRF52840 IO mappings https://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.7.pdf""" RESOURCE_PIN_REMAP: Dict[str, str] # resource name in base -> pin name @@ -170,7 +170,7 @@ def _io_pinmap(self) -> PinMapUtil: @abstract_block -class Nrf52840_Base(Nrf52840_Ios, InternalSubcircuit, GeneratorBlock): +class Nrf52840_Base(Nrf52840_Ios, GeneratorBlock): SYSTEM_PIN_REMAP: Dict[str, Union[str, List[str]]] # pin name in base -> pin name(s) def _gnd_vddio(self) -> Tuple[Port[VoltageLink], Port[VoltageLink]]: @@ -210,7 +210,7 @@ def __init__(self, **kwargs) -> None: self._io_ports.insert(0, self.swd) -class Holyiot_18010_Device(Nrf52840_Base): +class Holyiot_18010_Device(Nrf52840_Base, InternalSubcircuit): SYSTEM_PIN_REMAP: Dict[str, Union[str, List[str]]] = { 'Vdd': '14', 'Vss': ['1', '25', '37'], @@ -287,7 +287,7 @@ def generate(self): if self.get(self.reset.is_connected()): self.connect(self.reset, self.ic.nreset) -class Mdbt50q_1mv2_Device(Nrf52840_Base, JlcPart): +class Mdbt50q_1mv2_Device(Nrf52840_Base, InternalSubcircuit, JlcPart): SYSTEM_PIN_REMAP: Dict[str, Union[str, List[str]]] = { 'Vdd': ['28', '30'], # 28=Vdd, 30=VddH; 31=DccH is disconnected - from section 8.3 for input voltage <3.6v 'Vss': ['1', '2', '15', '33', '55'], diff --git a/electronics_lib/RfModules.py b/electronics_lib/RfModules.py index b9c4443f0..344bcdb42 100644 --- a/electronics_lib/RfModules.py +++ b/electronics_lib/RfModules.py @@ -83,7 +83,7 @@ def contents(self): class BlueSmirf(Interface, Radiofrequency, FootprintBlock): - """SlueSMiRF Gold/Silver""" + """BlueSMiRF Gold/Silver""" def __init__(self) -> None: super().__init__() diff --git a/electronics_lib/__init__.py b/electronics_lib/__init__.py index 3baf7a10f..cd617ca0e 100644 --- a/electronics_lib/__init__.py +++ b/electronics_lib/__init__.py @@ -85,7 +85,7 @@ from .Microcontroller_Esp32 import Esp32_Wroom_32, Freenove_Esp32_Wrover from .Microcontroller_Esp32s3 import Esp32s3_Wroom_1, Freenove_Esp32s3_Wroom from .Microcontroller_Esp32c3 import Esp32c3_Wroom02, Esp32c3, Xiao_Esp32c3 -from .Microcontroller_Rp2040 import Rp2040 +from .Microcontroller_Rp2040 import Rp2040, Xiao_Rp2040 from .Fpga_Ice40up import Ice40up5k_Sg48 from .IoExpander_Pcf8574 import Pcf8574 diff --git a/examples/BasicKeyboard/BasicKeyboard.net b/examples/BasicKeyboard/BasicKeyboard.net new file mode 100644 index 000000000..82103cd8f --- /dev/null +++ b/examples/BasicKeyboard/BasicKeyboard.net @@ -0,0 +1,193 @@ +(export (version D) +(components +(comp (ref "mcu") + (value "XIAO RP2040") + (footprint "Seeed Studio XIAO Series Library:XIAO-Generic-Hybrid-14P-2.54-21X17.8MM") + (property (name "Sheetname") (value "")) + (property (name "Sheetfile") (value "")) + (property (name "edg_path") (value "mcu")) + (property (name "edg_short_path") (value "mcu")) + (property (name "edg_refdes") (value "U1")) + (property (name "edg_part") (value "XIAO RP2040")) + (sheetpath (names "/") (tstamps "/")) + (tstamps "02850146")) +(comp (ref "sw.sw[0,0]") + (value "PG151101S11") + (footprint "Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MX") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.sw[0,0]")) + (property (name "edg_short_path") (value "sw.sw[0,0]")) + (property (name "edg_refdes") (value "SW1")) + (property (name "edg_part") (value "PG151101S11 (Kailh)")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "09be022f")) +(comp (ref "sw.d[0,0]") + (value "40V 550mV@1A 1A SMA(DO-214AC) Schottky Barrier Diodes (SBD) ROHS") + (footprint "Diode_SMD:D_SMA") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.d[0,0]")) + (property (name "edg_short_path") (value "sw.d[0,0]")) + (property (name "edg_refdes") (value "D1")) + (property (name "edg_part") (value "SS14 (MDD(Microdiode Electronics))")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "062601a9")) +(comp (ref "sw.sw[0,1]") + (value "PG151101S11") + (footprint "Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MX") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.sw[0,1]")) + (property (name "edg_short_path") (value "sw.sw[0,1]")) + (property (name "edg_refdes") (value "SW2")) + (property (name "edg_part") (value "PG151101S11 (Kailh)")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "09c00230")) +(comp (ref "sw.d[0,1]") + (value "40V 550mV@1A 1A SMA(DO-214AC) Schottky Barrier Diodes (SBD) ROHS") + (footprint "Diode_SMD:D_SMA") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.d[0,1]")) + (property (name "edg_short_path") (value "sw.d[0,1]")) + (property (name "edg_refdes") (value "D2")) + (property (name "edg_part") (value "SS14 (MDD(Microdiode Electronics))")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "062801aa")) +(comp (ref "sw.sw[0,2]") + (value "PG151101S11") + (footprint "Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MX") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.sw[0,2]")) + (property (name "edg_short_path") (value "sw.sw[0,2]")) + (property (name "edg_refdes") (value "SW3")) + (property (name "edg_part") (value "PG151101S11 (Kailh)")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "09c20231")) +(comp (ref "sw.d[0,2]") + (value "40V 550mV@1A 1A SMA(DO-214AC) Schottky Barrier Diodes (SBD) ROHS") + (footprint "Diode_SMD:D_SMA") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.d[0,2]")) + (property (name "edg_short_path") (value "sw.d[0,2]")) + (property (name "edg_refdes") (value "D3")) + (property (name "edg_part") (value "SS14 (MDD(Microdiode Electronics))")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "062a01ab")) +(comp (ref "sw.sw[1,0]") + (value "PG151101S11") + (footprint "Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MX") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.sw[1,0]")) + (property (name "edg_short_path") (value "sw.sw[1,0]")) + (property (name "edg_refdes") (value "SW4")) + (property (name "edg_part") (value "PG151101S11 (Kailh)")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "09c20230")) +(comp (ref "sw.d[1,0]") + (value "40V 550mV@1A 1A SMA(DO-214AC) Schottky Barrier Diodes (SBD) ROHS") + (footprint "Diode_SMD:D_SMA") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.d[1,0]")) + (property (name "edg_short_path") (value "sw.d[1,0]")) + (property (name "edg_refdes") (value "D4")) + (property (name "edg_part") (value "SS14 (MDD(Microdiode Electronics))")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "062a01aa")) +(comp (ref "sw.sw[1,1]") + (value "PG151101S11") + (footprint "Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MX") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.sw[1,1]")) + (property (name "edg_short_path") (value "sw.sw[1,1]")) + (property (name "edg_refdes") (value "SW5")) + (property (name "edg_part") (value "PG151101S11 (Kailh)")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "09c40231")) +(comp (ref "sw.d[1,1]") + (value "40V 550mV@1A 1A SMA(DO-214AC) Schottky Barrier Diodes (SBD) ROHS") + (footprint "Diode_SMD:D_SMA") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.d[1,1]")) + (property (name "edg_short_path") (value "sw.d[1,1]")) + (property (name "edg_refdes") (value "D5")) + (property (name "edg_part") (value "SS14 (MDD(Microdiode Electronics))")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "062c01ab")) +(comp (ref "sw.sw[1,2]") + (value "PG151101S11") + (footprint "Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MX") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.sw[1,2]")) + (property (name "edg_short_path") (value "sw.sw[1,2]")) + (property (name "edg_refdes") (value "SW6")) + (property (name "edg_part") (value "PG151101S11 (Kailh)")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "09c60232")) +(comp (ref "sw.d[1,2]") + (value "40V 550mV@1A 1A SMA(DO-214AC) Schottky Barrier Diodes (SBD) ROHS") + (footprint "Diode_SMD:D_SMA") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.d[1,2]")) + (property (name "edg_short_path") (value "sw.d[1,2]")) + (property (name "edg_refdes") (value "D6")) + (property (name "edg_part") (value "SS14 (MDD(Microdiode Electronics))")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "062e01ac"))) +(nets +(net (code 1) (name "mcu.gpio.0_0") + (node (ref mcu) (pin 7)) + (node (ref sw.sw[0,0]) (pin 2)) + (node (ref sw.sw[0,1]) (pin 2)) + (node (ref sw.sw[0,2]) (pin 2))) +(net (code 2) (name "mcu.gpio.0_1") + (node (ref mcu) (pin 8)) + (node (ref sw.sw[1,0]) (pin 2)) + (node (ref sw.sw[1,1]) (pin 2)) + (node (ref sw.sw[1,2]) (pin 2))) +(net (code 3) (name "mcu.gpio.1_0") + (node (ref mcu) (pin 9)) + (node (ref sw.d[0,0]) (pin 2)) + (node (ref sw.d[1,0]) (pin 2))) +(net (code 4) (name "mcu.gpio.1_1") + (node (ref mcu) (pin 11)) + (node (ref sw.d[0,1]) (pin 2)) + (node (ref sw.d[1,1]) (pin 2))) +(net (code 5) (name "mcu.gpio.1_2") + (node (ref mcu) (pin 10)) + (node (ref sw.d[0,2]) (pin 2)) + (node (ref sw.d[1,2]) (pin 2))) +(net (code 6) (name "mcu.pwr_out") + (node (ref mcu) (pin 12))) +(net (code 7) (name "mcu.gnd_out") + (node (ref mcu) (pin 13))) +(net (code 8) (name "mcu.vusb_out") + (node (ref mcu) (pin 14))) +(net (code 9) (name "sw.d[0,0].cathode") + (node (ref sw.d[0,0]) (pin 1)) + (node (ref sw.sw[0,0]) (pin 1))) +(net (code 10) (name "sw.d[0,1].cathode") + (node (ref sw.d[0,1]) (pin 1)) + (node (ref sw.sw[0,1]) (pin 1))) +(net (code 11) (name "sw.d[0,2].cathode") + (node (ref sw.d[0,2]) (pin 1)) + (node (ref sw.sw[0,2]) (pin 1))) +(net (code 12) (name "sw.d[1,0].cathode") + (node (ref sw.d[1,0]) (pin 1)) + (node (ref sw.sw[1,0]) (pin 1))) +(net (code 13) (name "sw.d[1,1].cathode") + (node (ref sw.d[1,1]) (pin 1)) + (node (ref sw.sw[1,1]) (pin 1))) +(net (code 14) (name "sw.d[1,2].cathode") + (node (ref sw.d[1,2]) (pin 1)) + (node (ref sw.sw[1,2]) (pin 1)))) +) \ No newline at end of file diff --git a/examples/BasicKeyboard/BasicKeyboard.ref.net b/examples/BasicKeyboard/BasicKeyboard.ref.net new file mode 100644 index 000000000..50e704eaf --- /dev/null +++ b/examples/BasicKeyboard/BasicKeyboard.ref.net @@ -0,0 +1,193 @@ +(export (version D) +(components +(comp (ref "U1") + (value "XIAO RP2040") + (footprint "Seeed Studio XIAO Series Library:XIAO-Generic-Hybrid-14P-2.54-21X17.8MM") + (property (name "Sheetname") (value "")) + (property (name "Sheetfile") (value "")) + (property (name "edg_path") (value "mcu")) + (property (name "edg_short_path") (value "mcu")) + (property (name "edg_refdes") (value "U1")) + (property (name "edg_part") (value "XIAO RP2040")) + (sheetpath (names "/") (tstamps "/")) + (tstamps "02850146")) +(comp (ref "SW1") + (value "PG151101S11") + (footprint "Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MX") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.sw[0,0]")) + (property (name "edg_short_path") (value "sw.sw[0,0]")) + (property (name "edg_refdes") (value "SW1")) + (property (name "edg_part") (value "PG151101S11 (Kailh)")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "09be022f")) +(comp (ref "D1") + (value "40V 550mV@1A 1A SMA(DO-214AC) Schottky Barrier Diodes (SBD) ROHS") + (footprint "Diode_SMD:D_SMA") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.d[0,0]")) + (property (name "edg_short_path") (value "sw.d[0,0]")) + (property (name "edg_refdes") (value "D1")) + (property (name "edg_part") (value "SS14 (MDD(Microdiode Electronics))")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "062601a9")) +(comp (ref "SW2") + (value "PG151101S11") + (footprint "Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MX") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.sw[0,1]")) + (property (name "edg_short_path") (value "sw.sw[0,1]")) + (property (name "edg_refdes") (value "SW2")) + (property (name "edg_part") (value "PG151101S11 (Kailh)")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "09c00230")) +(comp (ref "D2") + (value "40V 550mV@1A 1A SMA(DO-214AC) Schottky Barrier Diodes (SBD) ROHS") + (footprint "Diode_SMD:D_SMA") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.d[0,1]")) + (property (name "edg_short_path") (value "sw.d[0,1]")) + (property (name "edg_refdes") (value "D2")) + (property (name "edg_part") (value "SS14 (MDD(Microdiode Electronics))")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "062801aa")) +(comp (ref "SW3") + (value "PG151101S11") + (footprint "Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MX") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.sw[0,2]")) + (property (name "edg_short_path") (value "sw.sw[0,2]")) + (property (name "edg_refdes") (value "SW3")) + (property (name "edg_part") (value "PG151101S11 (Kailh)")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "09c20231")) +(comp (ref "D3") + (value "40V 550mV@1A 1A SMA(DO-214AC) Schottky Barrier Diodes (SBD) ROHS") + (footprint "Diode_SMD:D_SMA") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.d[0,2]")) + (property (name "edg_short_path") (value "sw.d[0,2]")) + (property (name "edg_refdes") (value "D3")) + (property (name "edg_part") (value "SS14 (MDD(Microdiode Electronics))")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "062a01ab")) +(comp (ref "SW4") + (value "PG151101S11") + (footprint "Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MX") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.sw[1,0]")) + (property (name "edg_short_path") (value "sw.sw[1,0]")) + (property (name "edg_refdes") (value "SW4")) + (property (name "edg_part") (value "PG151101S11 (Kailh)")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "09c20230")) +(comp (ref "D4") + (value "40V 550mV@1A 1A SMA(DO-214AC) Schottky Barrier Diodes (SBD) ROHS") + (footprint "Diode_SMD:D_SMA") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.d[1,0]")) + (property (name "edg_short_path") (value "sw.d[1,0]")) + (property (name "edg_refdes") (value "D4")) + (property (name "edg_part") (value "SS14 (MDD(Microdiode Electronics))")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "062a01aa")) +(comp (ref "SW5") + (value "PG151101S11") + (footprint "Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MX") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.sw[1,1]")) + (property (name "edg_short_path") (value "sw.sw[1,1]")) + (property (name "edg_refdes") (value "SW5")) + (property (name "edg_part") (value "PG151101S11 (Kailh)")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "09c40231")) +(comp (ref "D5") + (value "40V 550mV@1A 1A SMA(DO-214AC) Schottky Barrier Diodes (SBD) ROHS") + (footprint "Diode_SMD:D_SMA") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.d[1,1]")) + (property (name "edg_short_path") (value "sw.d[1,1]")) + (property (name "edg_refdes") (value "D5")) + (property (name "edg_part") (value "SS14 (MDD(Microdiode Electronics))")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "062c01ab")) +(comp (ref "SW6") + (value "PG151101S11") + (footprint "Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MX") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.sw[1,2]")) + (property (name "edg_short_path") (value "sw.sw[1,2]")) + (property (name "edg_refdes") (value "SW6")) + (property (name "edg_part") (value "PG151101S11 (Kailh)")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "09c60232")) +(comp (ref "D6") + (value "40V 550mV@1A 1A SMA(DO-214AC) Schottky Barrier Diodes (SBD) ROHS") + (footprint "Diode_SMD:D_SMA") + (property (name "Sheetname") (value "sw")) + (property (name "Sheetfile") (value "electronics_lib.SwitchMatrix.SwitchMatrix")) + (property (name "edg_path") (value "sw.d[1,2]")) + (property (name "edg_short_path") (value "sw.d[1,2]")) + (property (name "edg_refdes") (value "D6")) + (property (name "edg_part") (value "SS14 (MDD(Microdiode Electronics))")) + (sheetpath (names "/sw/") (tstamps "/015f00eb/")) + (tstamps "062e01ac"))) +(nets +(net (code 1) (name "mcu.gpio.0_0") + (node (ref U1) (pin 7)) + (node (ref SW1) (pin 2)) + (node (ref SW2) (pin 2)) + (node (ref SW3) (pin 2))) +(net (code 2) (name "mcu.gpio.0_1") + (node (ref U1) (pin 8)) + (node (ref SW4) (pin 2)) + (node (ref SW5) (pin 2)) + (node (ref SW6) (pin 2))) +(net (code 3) (name "mcu.gpio.1_0") + (node (ref U1) (pin 9)) + (node (ref D1) (pin 2)) + (node (ref D4) (pin 2))) +(net (code 4) (name "mcu.gpio.1_1") + (node (ref U1) (pin 11)) + (node (ref D2) (pin 2)) + (node (ref D5) (pin 2))) +(net (code 5) (name "mcu.gpio.1_2") + (node (ref U1) (pin 10)) + (node (ref D3) (pin 2)) + (node (ref D6) (pin 2))) +(net (code 6) (name "mcu.pwr_out") + (node (ref U1) (pin 12))) +(net (code 7) (name "mcu.gnd_out") + (node (ref U1) (pin 13))) +(net (code 8) (name "mcu.vusb_out") + (node (ref U1) (pin 14))) +(net (code 9) (name "sw.d[0,0].cathode") + (node (ref D1) (pin 1)) + (node (ref SW1) (pin 1))) +(net (code 10) (name "sw.d[0,1].cathode") + (node (ref D2) (pin 1)) + (node (ref SW2) (pin 1))) +(net (code 11) (name "sw.d[0,2].cathode") + (node (ref D3) (pin 1)) + (node (ref SW3) (pin 1))) +(net (code 12) (name "sw.d[1,0].cathode") + (node (ref D4) (pin 1)) + (node (ref SW4) (pin 1))) +(net (code 13) (name "sw.d[1,1].cathode") + (node (ref D5) (pin 1)) + (node (ref SW5) (pin 1))) +(net (code 14) (name "sw.d[1,2].cathode") + (node (ref D6) (pin 1)) + (node (ref SW6) (pin 1)))) +) \ No newline at end of file diff --git a/examples/test_basickeyboard.py b/examples/test_basickeyboard.py new file mode 100644 index 000000000..61078437e --- /dev/null +++ b/examples/test_basickeyboard.py @@ -0,0 +1,36 @@ +""" +Simple mechanical keyboard example design, using a socketed dev board + +Relies on footprints from external libraries. +In the KiCad Plugin and Content Manager, install the Keyswitch Kicad Library, +also on GitHub here https://github.com/perigoso/keyswitch-kicad-library +The project is set up to reference the third party library as installed by the KiCad +Plugin Manager, it does not need to be in your global library table. +""" + +import unittest + +from edg import * + + +class BasicKeyboard(SimpleBoardTop): + def contents(self) -> None: + super().contents() + + self.mcu = self.Block(Xiao_Rp2040()) + + self.sw = self.Block(SwitchMatrix(nrows=3, ncols=2)) + self.connect(self.sw.cols, self.mcu.gpio.request_vector()) + self.connect(self.sw.rows, self.mcu.gpio.request_vector()) + + def refinements(self) -> Refinements: + return super().refinements() + Refinements( + class_refinements=[ + (Switch, KailhSocket), + ], + ) + + +class BasicKeyboardTestCase(unittest.TestCase): + def test_design(self) -> None: + compile_board_inplace(BasicKeyboard)