diff --git a/src/faebryk/library/RP2040.py b/src/faebryk/library/RP2040.py index de4f6323..1e99c667 100644 --- a/src/faebryk/library/RP2040.py +++ b/src/faebryk/library/RP2040.py @@ -13,49 +13,427 @@ class RP2040(Module): - io_vdd: F.ElectricPower - adc_vdd: F.ElectricPower - core_vdd: F.ElectricPower - vreg_in: F.ElectricPower - vreg_out: F.ElectricPower - power_vusb: F.ElectricPower + class PIO(F.ElectricLogic): + pass + + class ADC(F.SignalElectrical): + pass + + class PWM(ModuleInterface): + A: F.ElectricLogic + B: F.ElectricLogic + + class CoreRegulator(Module): + power_in: F.ElectricPower + power_out: F.ElectricPower + + def __preinit__(self): + F.ElectricLogic.connect_all_module_references(self, gnd_only=True) + + # TODO get tolerance + self.power_out.voltage.merge(F.Range.from_center_rel(1.1 * P.V, 0.05)) + self.power_in.voltage.merge(F.Range(1.8 * P.V, 3.3 * P.V)) + + class Pinmux(Module): + def __init__(self, mcu: "RP2040"): + self._mcu = mcu + + def __preinit__(self): + # TODO + x = self._mcu + matrix = { + x.gpio[0]: [ + x.spi[0].miso, + x.uart[0].tx, + x.i2c[0].sda, + x.pwm[0].A, + x.gpio_digital[0], # TODO is this correct? + x.pio[0], + x.pio[1], + None, + "USB OVCUR DET", # TODO + ], + x.gpio[1]: [ + x.spi[0].csn, + x.uart[0].rx, + x.i2c[0].scl, + x.pwm[0].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS DET", + ], + x.gpio[2]: [ + x.spi[0].sclk, + x.uart[0].cts, + x.i2c[1].sda, + x.pwm[1].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS EN", + ], + x.gpio[3]: [ + x.spi[0].mosi, + x.uart[0].rts, + x.i2c[1].scl, + x.pwm[1].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB OVCUR DET", + ], + x.gpio[4]: [ + x.spi[0].miso, + x.uart[1].tx, + x.i2c[0].sda, + x.pwm[2].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS DET", + ], + x.gpio[5]: [ + x.spi[0].csn, + x.uart[1].rx, + x.i2c[0].scl, + x.pwm[2].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS EN", + ], + x.gpio[6]: [ + x.spi[0].sclk, + x.uart[1].cts, + x.i2c[1].sda, + x.pwm[3].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB OVCUR DET", + ], + x.gpio[7]: [ + x.spi[0].mosi, + x.uart[1].rts, + x.i2c[1].scl, + x.pwm[3].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS DET", + ], + x.gpio[8]: [ + x.spi[1].miso, + x.uart[0].tx, + x.i2c[0].sda, + x.pwm[4].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS EN", + ], + x.gpio[9]: [ + x.spi[1].csn, + x.uart[0].rx, + x.i2c[0].scl, + x.pwm[4].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB OVCUR DET", + ], + x.gpio[10]: [ + x.spi[1].sclk, + x.uart[0].cts, + x.i2c[1].sda, + x.pwm[5].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS DET", + ], + x.gpio[11]: [ + x.spi[1].mosi, + x.uart[0].rts, + x.i2c[1].scl, + x.pwm[5].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS EN", + ], + x.gpio[12]: [ + x.spi[1].miso, + x.uart[1].tx, + x.i2c[0].sda, + x.pwm[6].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB OVCUR DET", + ], + x.gpio[13]: [ + x.spi[1].csn, + x.uart[1].rx, + x.i2c[0].scl, + x.pwm[6].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS DET", + ], + x.gpio[14]: [ + x.spi[1].sclk, + x.uart[1].cts, + x.i2c[1].sda, + x.pwm[7].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS EN", + ], + x.gpio[15]: [ + x.spi[1].mosi, + x.uart[1].rts, + x.i2c[1].scl, + x.pwm[7].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB OVCUR DET", + ], + x.gpio[16]: [ + x.spi[0].miso, + x.uart[0].tx, + x.i2c[0].sda, + x.pwm[0].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS DET", + ], + x.gpio[17]: [ + x.spi[0].csn, + x.uart[0].rx, + x.i2c[0].scl, + x.pwm[0].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS EN", + ], + x.gpio[18]: [ + x.spi[0].sclk, + x.uart[0].cts, + x.i2c[1].sda, + x.pwm[1].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB OVCUR DET", + ], + x.gpio[19]: [ + x.spi[0].mosi, + x.uart[0].rts, + x.i2c[1].scl, + x.pwm[1].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS DET", + ], + x.gpio[20]: [ + x.spi[0].miso, + x.uart[1].tx, + x.i2c[0].sda, + x.pwm[2].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS EN", + ], + x.gpio[21]: [ + x.spi[0].csn, + x.uart[1].rx, + x.i2c[0].scl, + x.pwm[2].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + x.clock.gpout0, + "USB OVCUR DET", + ], + x.gpio[22]: [ + x.spi[0].sclk, + x.uart[1].cts, + x.i2c[1].sda, + x.pwm[3].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + x.clock.gpin1, + "USB VBUS DET", + ], + x.gpio[23]: [ + x.spi[0].mosi, + x.uart[1].rts, + x.i2c[1].scl, + x.pwm[3].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + x.clock.gpout1, + "USB VBUS EN", + ], + x.gpio[24]: [ + x.spi[1].miso, + x.uart[0].tx, + x.i2c[0].sda, + x.pwm[4].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + x.clock.gpout2, + "USB OVCUR DET", + ], + x.gpio[25]: [ + x.spi[1].csn, + x.uart[0].rx, + x.i2c[0].scl, + x.pwm[4].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + x.clock.gpout3, + "USB VBUS DET", + ], + x.gpio[26]: [ + x.spi[1].sclk, + x.uart[0].cts, + x.i2c[1].sda, + x.pwm[5].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS EN", + ], + x.gpio[27]: [ + x.spi[1].mosi, + x.uart[0].rts, + x.i2c[1].scl, + x.pwm[5].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB OVCUR DET", + ], + x.gpio[28]: [ + x.spi[1].miso, + x.uart[1].tx, + x.i2c[0].sda, + x.pwm[6].A, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS DET", + ], + x.gpio[29]: [ + x.spi[1].csn, + x.uart[1].rx, + x.i2c[0].scl, + x.pwm[6].B, + x.gpio_digital[0], + x.pio[0], + x.pio[1], + None, + "USB VBUS EN", + ], + } + + # power + power_io: F.ElectricPower + power_adc: F.ElectricPower + power_core: F.ElectricPower + power_usb: F.ElectricPower + core_regulator: CoreRegulator + gpio = L.list_field(30, F.Electrical) - run: F.ElectricLogic - usb: F.USB2_0 + gpio_soft = L.list_field(6, F.Electrical) + + # IO qspi = L.f_field(F.MultiSPI)(data_lane_count=4) - xin: F.Electrical - xout: F.Electrical - test: F.Electrical swd: F.SWD - # TODO: these peripherals and more can be mapped to different pins - i2c: F.I2C - uart: F.UART_Base + xtal_if: F.XtalIF + + run: F.ElectricLogic + usb: F.USB2_0 + factory_test_enable: F.Electrical + + # peripherals + spi = L.list_field(2, F.SPI) + pwm = L.list_field(8, F.PWM) + i2c = L.list_field(2, F.I2C) + uart = L.list_field(2, F.UART_Base) + pio = L.list_field(2, PIO) + adc = L.list_field(4, ADC) + gpio_digital = L.list_field(30 + 6, F.Electrical) def __preinit__(self): - # TODO - return - # decouple power rails and connect GNDs toghether - gnd = self.io_vdd.lv - for pwrrail in [ - self.io_vdd, - self.adc_vdd, - self.core_vdd, - self.vreg_in, - self.vreg_out, - self.usb.usb_if.buspower, - ]: - pwrrail.lv.connect(gnd) - pwrrail.decoupled.decouple() - - # set parameters - self.vreg_out.voltage.merge(1.1 * P.V) - self.io_vdd.voltage.merge(3.3 * P.V) - - F.ElectricLogic.connect_all_node_references( - self.get_children(direct_only=True, types=ModuleInterface).difference( - {self.adc_vdd, self.core_vdd} - ) - ) + # TODO get tolerance + self.power_adc.voltage.merge(F.Range.from_center_rel(3.3 * P.V, 0.05)) + self.power_usb.voltage.merge(F.Range.from_center_rel(3.3 * P.V, 0.05)) + self.power_core.voltage.merge(F.Range.from_center_rel(1.1 * P.V, 0.05)) + self.power_io.voltage.merge(F.Range(1.8 * P.V, 3.3 * P.V)) + + F.ElectricLogic.connect_all_module_references(self, gnd_only=True) + + # QSPI pins reusable for soft gpio + self.qspi.data[3].signal.connect(self.gpio_soft[0]) + self.qspi.clk.signal.connect(self.gpio_soft[1]) + self.qspi.data[0].signal.connect(self.gpio_soft[2]) + self.qspi.data[2].signal.connect(self.gpio_soft[3]) + self.qspi.data[1].signal.connect(self.gpio_soft[4]) + self.qspi.cs.signal.connect(self.gpio_soft[5]) + + # ADC pins shared with GPIO + self.adc[0].signal.connect(self.gpio[26]) + self.adc[1].signal.connect(self.gpio[27]) + self.adc[2].signal.connect(self.gpio[28]) + self.adc[3].signal.connect(self.gpio[29]) + + F.ElectricLogic.connect_all_node_references([self.power_adc] + self.adc) + + @L.rt_field + def pinmux(self): + return self.Pinmux(self) + + @L.rt_field + def decoupled(self): + return F.can_be_decoupled_rails(self.power_io, self.power_core) designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") datasheet = L.f_field(F.has_datasheet_defined)( @@ -66,7 +444,7 @@ def __preinit__(self): def attach_to_footprint(self): return F.can_attach_to_footprint_via_pinmap( { - "1": self.io_vdd.hv, + "1": self.power_io.hv, "2": self.gpio[0], "3": self.gpio[1], "4": self.gpio[2], @@ -75,7 +453,7 @@ def attach_to_footprint(self): "7": self.gpio[5], "8": self.gpio[6], "9": self.gpio[7], - "10": self.io_vdd.hv, + "10": self.power_io.hv, "11": self.gpio[8], "12": self.gpio[9], "13": self.gpio[10], @@ -84,11 +462,11 @@ def attach_to_footprint(self): "16": self.gpio[13], "17": self.gpio[14], "18": self.gpio[15], - "19": self.xin, - "20": self.xout, - "21": self.test, - "22": self.io_vdd.hv, - "23": self.core_vdd.hv, + "19": self.xtal_if.xin, + "20": self.xtal_if.xout, + "21": self.factory_test_enable, + "22": self.power_io.hv, + "23": self.power_core.hv, "24": self.swd.clk.signal, "25": self.swd.dio.signal, "26": self.run.signal, @@ -98,7 +476,7 @@ def attach_to_footprint(self): "30": self.gpio[19], "31": self.gpio[20], "32": self.gpio[21], - "33": self.io_vdd.hv, + "33": self.power_io.hv, "34": self.gpio[22], "35": self.gpio[23], "36": self.gpio[24], @@ -107,21 +485,21 @@ def attach_to_footprint(self): "39": self.gpio[27], "40": self.gpio[28], "41": self.gpio[29], - "42": self.io_vdd.hv, - "43": self.adc_vdd.hv, - "44": self.vreg_in.hv, - "45": self.vreg_out.hv, + "42": self.power_io.hv, + "43": self.power_adc.hv, + "44": self.core_regulator.power_in.hv, + "45": self.core_regulator.power_out.hv, "46": self.usb.usb_if.d.n, "47": self.usb.usb_if.d.p, "48": self.usb.usb_if.buspower.hv, - "49": self.io_vdd.hv, - "50": self.core_vdd.hv, + "49": self.power_io.hv, + "50": self.power_core.hv, "51": self.qspi.data[3].signal, "52": self.qspi.clk.signal, "53": self.qspi.data[0].signal, "54": self.qspi.data[2].signal, "55": self.qspi.data[1].signal, "56": self.qspi.cs.signal, - "57": self.io_vdd.lv, + "57": self.power_io.lv, } ) diff --git a/src/faebryk/library/RP2040_Reference_Design.py b/src/faebryk/library/RP2040_Reference_Design.py index 7873e96c..c7659ded 100644 --- a/src/faebryk/library/RP2040_Reference_Design.py +++ b/src/faebryk/library/RP2040_Reference_Design.py @@ -79,14 +79,14 @@ def __preinit__(self): # connect rp2040 power rails for pwrrail in [ - self.rp2040.io_vdd, - self.rp2040.adc_vdd, - self.rp2040.vreg_in, + self.rp2040.power_io, + self.rp2040.power_adc, + self.rp2040.power_core_regulator_in, self.rp2040.usb.usb_if.buspower, ]: pwrrail.connect(power_3v3) - self.rp2040.vreg_out.connect(self.rp2040.core_vdd) + self.rp2040.power_core_regulator_out.connect(self.rp2040.power_core) # connect flash self.flash.spi.connect(self.rp2040.qspi) diff --git a/src/faebryk/library/XtalIF.py b/src/faebryk/library/XtalIF.py new file mode 100644 index 00000000..0397f0ae --- /dev/null +++ b/src/faebryk/library/XtalIF.py @@ -0,0 +1,37 @@ +# This file is part of the faebryk project +# SPDX-License-Identifier: MIT + +import logging + +import faebryk.library._F as F # noqa: F401 +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.libs.library import L # noqa: F401 +from faebryk.libs.units import P # noqa: F401 + +logger = logging.getLogger(__name__) + + +class XtalIF(ModuleInterface): + """ + TODO: Docstring describing your module + """ + + # ---------------------------------------- + # modules, interfaces, parameters + # ---------------------------------------- + xin: F.Electrical + xout: F.Electrical + + # ---------------------------------------- + # traits + # ---------------------------------------- + + def __preinit__(self): + # ------------------------------------ + # connections + # ------------------------------------ + + # ------------------------------------ + # parametrization + # ------------------------------------ + pass diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index f62ca0db..fdd45a70 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -73,6 +73,7 @@ from faebryk.library.is_representable_by_single_value_defined import is_representable_by_single_value_defined from faebryk.library.DifferentialPair import DifferentialPair from faebryk.library.SPI import SPI +from faebryk.library.XtalIF import XtalIF from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic from faebryk.library.LogicOps import LogicOps from faebryk.library.can_attach_to_footprint import can_attach_to_footprint @@ -145,10 +146,12 @@ from faebryk.library.RS485_Bus_Protection import RS485_Bus_Protection from faebryk.library.SignalElectrical import SignalElectrical from faebryk.library.USB_Type_C_Receptacle_16_pin import USB_Type_C_Receptacle_16_pin +from faebryk.library.can_be_decoupled_rails import can_be_decoupled_rails from faebryk.library.ButtonCell import ButtonCell from faebryk.library.PoweredLED import PoweredLED from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.FilterElectricalLC import FilterElectricalLC +from faebryk.library.PWM import PWM from faebryk.library.ElectricLogicGate import ElectricLogicGate from faebryk.library.GenericBusProtection import GenericBusProtection from faebryk.library.I2C import I2C diff --git a/src/faebryk/library/can_be_decoupled_rails.py b/src/faebryk/library/can_be_decoupled_rails.py new file mode 100644 index 00000000..32a88df6 --- /dev/null +++ b/src/faebryk/library/can_be_decoupled_rails.py @@ -0,0 +1,19 @@ +# This file is part of the faebryk project +# SPDX-License-Identifier: MIT + +import logging + +import faebryk.library._F as F + +logger = logging.getLogger(__name__) + + +class can_be_decoupled_rails(F.can_be_decoupled.impl()): + def __init__(self, *rails: F.ElectricPower): + assert rails + self._rails = rails + + def decouple(self) -> F.Capacitor: + caps = [rail.decoupled.decouple() for rail in self._rails] + # TODO + return caps[0]