diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f7e7956498d68..4db04e1d0eddb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,7 +28,7 @@ repos: lib/mbedtls_errors/generate_errors.diff ) - repo: https://github.com/codespell-project/codespell - rev: v2.2.4 + rev: v2.4.1 hooks: - id: codespell args: [-w] diff --git a/extmod/vfs_blockdev.c b/extmod/vfs_blockdev.c index f1187b9bbf2f5..0cd3cc6f0c631 100644 --- a/extmod/vfs_blockdev.c +++ b/extmod/vfs_blockdev.c @@ -63,7 +63,16 @@ void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) { #endif #if CIRCUITPY_SDIOIO if (mp_obj_get_type(bdev) == &sdioio_SDCard_type) { - // TODO: Enable native blockdev for SDIO too. + self->flags |= MP_BLOCKDEV_FLAG_NATIVE | MP_BLOCKDEV_FLAG_HAVE_IOCTL; + self->readblocks[0] = mp_const_none; + self->readblocks[1] = bdev; + self->readblocks[2] = (mp_obj_t)sdioio_sdcard_readblocks; // native version + self->writeblocks[0] = mp_const_none; + self->writeblocks[1] = bdev; + self->writeblocks[2] = (mp_obj_t)sdioio_sdcard_writeblocks; // native version + self->u.ioctl[0] = mp_const_none; + self->u.ioctl[1] = bdev; + self->u.ioctl[2] = (mp_obj_t)sdioio_sdcard_ioctl; // native version } #endif if (self->u.ioctl[0] != MP_OBJ_NULL) { diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index bcc7d1dd1ca9d..670ef5dcf0e4c 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -119,7 +119,8 @@ msgstr "" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/usb_host/Port.c #: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/microcontroller/Pin.c shared-module/max3421e/Max3421E.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/microcontroller/Pin.c +#: shared-module/max3421e/Max3421E.c msgid "%q in use" msgstr "" @@ -132,7 +133,7 @@ msgid "%q indices must be integers, not %s" msgstr "" #: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c -#: shared-module/bitbangio/SPI.c +#: shared-bindings/digitalio/DigitalInOutProtocol.c msgid "%q init failed" msgstr "" @@ -235,6 +236,14 @@ msgstr "" msgid "%q must be power of 2" msgstr "" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' attribute" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' method" +msgstr "" + #: shared-bindings/wifi/Monitor.c msgid "%q out of bounds" msgstr "" @@ -304,7 +313,7 @@ msgstr "" msgid "'%q' argument required" msgstr "" -#: py/proto.c +#: py/proto.c shared-bindings/digitalio/DigitalInOutProtocol.c msgid "'%q' object does not support '%q'" msgstr "" @@ -766,6 +775,10 @@ msgstr "" msgid "Cannot create a new Adapter; use _bleio.adapter;" msgstr "" +#: shared-module/i2cioexpander/IOExpander.c +msgid "Cannot deinitialize board IOExpander" +msgstr "" + #: shared-bindings/displayio/Bitmap.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c @@ -800,6 +813,7 @@ msgid "Cannot remount path when visible via USB." msgstr "" #: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c msgid "Cannot set value when direction is input." msgstr "" @@ -939,6 +953,7 @@ msgid "Done" msgstr "" #: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c msgid "Drive mode not used when direction is input." msgstr "" @@ -1277,8 +1292,8 @@ msgstr "" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c -#: shared-bindings/mipidsi/Display.c shared-bindings/pwmio/PWMOut.c -#: shared-bindings/supervisor/__init__.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/mipidsi/Display.c +#: shared-bindings/pwmio/PWMOut.c shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c #: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" @@ -1880,6 +1895,7 @@ msgid "Publishers can only be created from a parent node" msgstr "" #: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c msgid "Pull not used when direction is output." msgstr "" @@ -2539,6 +2555,10 @@ msgstr "" msgid "a bytes-like object is required" msgstr "" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "address out of range" +msgstr "" + #: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "" @@ -3814,6 +3834,10 @@ msgstr "" msgid "not supported for input types" msgstr "" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "num_pins must be 8 or 16" +msgstr "" + #: extmod/ulab/code/numpy/create.c msgid "number of points must be at least 2" msgstr "" @@ -3827,6 +3851,10 @@ msgstr "" msgid "object '%s' isn't a tuple or list" msgstr "" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "object does not support DigitalInOut protocol" +msgstr "" + #: py/obj.c msgid "object doesn't support item assignment" msgstr "" diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index 336c04fe039f9..b74c921bae3ac 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -187,7 +187,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { } // Write data to the device selected by address -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { int ret; @@ -202,14 +202,14 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, }; ret = MXC_I2C_MasterTransaction(&wr_req); if (ret) { - return MP_EIO; + return -MP_EIO; } return 0; } // Read into buffer from the device selected by address -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, +mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { @@ -226,14 +226,14 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, ret = MXC_I2C_MasterTransaction(&rd_req); if (ret) { // Return I/O error - return MP_EIO; + return -MP_EIO; } return 0; } // Write the bytes from out_data to the device selected by address -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { @@ -249,7 +249,7 @@ uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, }; ret = MXC_I2C_MasterTransaction(&wr_rd_req); if (ret) { - return MP_EIO; + return -MP_EIO; } return 0; diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 9582eff212d60..f8f420fda803a 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -169,7 +169,7 @@ LIBS += -lm endif ifeq ($(CHIP_FAMILY), samd21) -LDFLAGS += -mthumb -mcpu=cortex-m0plus -Lasf/thirdparty/CMSIS/Lib/GCC/ +LDFLAGS += -mthumb -mcpu=cortex-m0plus -Lasf/thirdparty/CMSIS/Lib/GCC/ # codespell:ignore thirdparty BOOTLOADER_SIZE := 0x2000 else ifeq ($(CHIP_FAMILY), samd51) LDFLAGS += -mthumb -mcpu=cortex-m4 diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_sercom_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_sercom_config.h index 5979d1ee9979f..157db0d3f7fbd 100644 --- a/ports/atmel-samd/asf4_conf/samd21/hpl_sercom_config.h +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_sercom_config.h @@ -431,7 +431,7 @@ // <0x2=>8x arithmetic // <0x3=>8x fractional // <0x3=>3x -// How many over-sampling bits used when samling data state +// How many over-sampling bits used when sampling data state // usart_arch_sampr #ifndef CONF_SERCOM_2_USART_SAMPR #define CONF_SERCOM_2_USART_SAMPR 0x0 diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_sercom_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_sercom_config.h index e05560e635823..6dd21277b78d0 100644 --- a/ports/atmel-samd/asf4_conf/samd51/hpl_sercom_config.h +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_sercom_config.h @@ -431,7 +431,7 @@ // <0x2=>8x arithmetic // <0x3=>8x fractional // <0x3=>3x -// How many over-sampling bits used when samling data state +// How many over-sampling bits used when sampling data state // usart_arch_sampr #ifndef CONF_SERCOM_2_USART_SAMPR #define CONF_SERCOM_2_USART_SAMPR 0x0 diff --git a/ports/atmel-samd/asf4_conf/same51/hpl_sercom_config.h b/ports/atmel-samd/asf4_conf/same51/hpl_sercom_config.h index e05560e635823..6dd21277b78d0 100644 --- a/ports/atmel-samd/asf4_conf/same51/hpl_sercom_config.h +++ b/ports/atmel-samd/asf4_conf/same51/hpl_sercom_config.h @@ -431,7 +431,7 @@ // <0x2=>8x arithmetic // <0x3=>8x fractional // <0x3=>3x -// How many over-sampling bits used when samling data state +// How many over-sampling bits used when sampling data state // usart_arch_sampr #ifndef CONF_SERCOM_2_USART_SAMPR #define CONF_SERCOM_2_USART_SAMPR 0x0 diff --git a/ports/atmel-samd/asf4_conf/same54/hpl_sercom_config.h b/ports/atmel-samd/asf4_conf/same54/hpl_sercom_config.h index e05560e635823..6dd21277b78d0 100644 --- a/ports/atmel-samd/asf4_conf/same54/hpl_sercom_config.h +++ b/ports/atmel-samd/asf4_conf/same54/hpl_sercom_config.h @@ -431,7 +431,7 @@ // <0x2=>8x arithmetic // <0x3=>8x fractional // <0x3=>3x -// How many over-sampling bits used when samling data state +// How many over-sampling bits used when sampling data state // usart_arch_sampr #ifndef CONF_SERCOM_2_USART_SAMPR #define CONF_SERCOM_2_USART_SAMPR 0x0 diff --git a/ports/atmel-samd/boards/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c index 637129a0e9d5e..fd5ad5485120f 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c @@ -54,9 +54,9 @@ void board_init(void) { common_hal_busio_spi_never_reset(spi); common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PA28, // Command or data - &pin_PA01, // Chip select - &pin_PA27, // Reset + MP_OBJ_FROM_PTR(&pin_PA28), // Command or data + MP_OBJ_FROM_PTR(&pin_PA01), // Chip select + MP_OBJ_FROM_PTR(&pin_PA27), // Reset 12000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/hallowing_m4_express/board.c b/ports/atmel-samd/boards/hallowing_m4_express/board.c index bfef5fbcd75dd..c7217b70b0a97 100644 --- a/ports/atmel-samd/boards/hallowing_m4_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m4_express/board.c @@ -35,9 +35,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PB31, // TFT_DC Command or data - &pin_PA27, // TFT_CS Chip select - &pin_PB30, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PB31), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PA27), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PB30), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/monster_m4sk/board.c b/ports/atmel-samd/boards/monster_m4sk/board.c index 1d4fd69b7f708..1c143ad92701f 100644 --- a/ports/atmel-samd/boards/monster_m4sk/board.c +++ b/ports/atmel-samd/boards/monster_m4sk/board.c @@ -35,9 +35,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PA07, // TFT_DC Command or data - &pin_PA06, // TFT_CS Chip select - &pin_PA04, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PA07), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PA06), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PA04), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/openbook_m4/board.c b/ports/atmel-samd/boards/openbook_m4/board.c index fb75cac3a4ee7..ebabfb84e9bfa 100644 --- a/ports/atmel-samd/boards/openbook_m4/board.c +++ b/ports/atmel-samd/boards/openbook_m4/board.c @@ -44,9 +44,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PB05, // EPD_DC Command or data - &pin_PB07, // EPD_CS Chip select - &pin_PA00, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_PB05), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_PB07), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_PA00), // EPD_RST Reset 1000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/pewpew_lcd/board.c b/ports/atmel-samd/boards/pewpew_lcd/board.c index 6a10132e11dc2..d60efd39bf752 100644 --- a/ports/atmel-samd/boards/pewpew_lcd/board.c +++ b/ports/atmel-samd/boards/pewpew_lcd/board.c @@ -54,9 +54,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PA19, // TFT_DC Command or data - &pin_PA17, // TFT_CS Chip select - &pin_PA18, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PA19), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PA17), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PA18), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/pewpew_m4/board.c b/ports/atmel-samd/boards/pewpew_m4/board.c index 2007d755c694a..ac67b82a3dc7a 100644 --- a/ports/atmel-samd/boards/pewpew_m4/board.c +++ b/ports/atmel-samd/boards/pewpew_m4/board.c @@ -83,9 +83,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PA16, // TFT_DC Command or data - &pin_PA11, // TFT_CS Chip select - &pin_PA17, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PA16), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PA11), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PA17), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c index 545918374e270..e938e96e19e3c 100644 --- a/ports/atmel-samd/boards/pybadge/board.c +++ b/ports/atmel-samd/boards/pybadge/board.c @@ -56,9 +56,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PB05, // TFT_DC Command or data - &pin_PB07, // TFT_CS Chip select - &pin_PA00, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PB05), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PB07), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PA00), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/pygamer/board.c b/ports/atmel-samd/boards/pygamer/board.c index 53275ac686a15..fcf6aff0e6556 100644 --- a/ports/atmel-samd/boards/pygamer/board.c +++ b/ports/atmel-samd/boards/pygamer/board.c @@ -57,9 +57,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PB05, // TFT_DC Command or data - &pin_PB12, // TFT_CS Chip select - &pin_PA00, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PB05), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PB12), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PA00), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c b/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c index d3d1ae3a956ff..1ee80c9878604 100644 --- a/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c +++ b/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c @@ -52,9 +52,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PC06, // TFT_DC Command or data - &pin_PB21, // TFT_CS Chip select - &pin_PC07, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PC06), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PB21), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PC07), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/ugame10/board.c b/ports/atmel-samd/boards/ugame10/board.c index bbf3839c516fb..78d03a3fd9a02 100644 --- a/ports/atmel-samd/boards/ugame10/board.c +++ b/ports/atmel-samd/boards/ugame10/board.c @@ -53,9 +53,9 @@ void board_init(void) { busio_spi_obj_t *spi = common_hal_board_create_spi(0); common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PA09, // Command or data - &pin_PA08, // Chip select - NULL, // Reset + MP_OBJ_FROM_PTR(&pin_PA09), // Command or data + MP_OBJ_FROM_PTR(&pin_PA08), // Chip select + MP_OBJ_NULL, // Reset 24000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c index da108709feaff..700c3e4aba24b 100644 --- a/ports/atmel-samd/common-hal/busio/I2C.c +++ b/ports/atmel-samd/common-hal/busio/I2C.c @@ -176,7 +176,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +static mp_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { uint16_t attempts = ATTEMPTS; @@ -197,17 +197,17 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, if (status == I2C_OK) { return 0; } else if (status == I2C_ERR_BAD_ADDRESS) { - return MP_ENODEV; + return -MP_ENODEV; } - return MP_EIO; + return -MP_EIO; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { uint16_t attempts = ATTEMPTS; @@ -228,14 +228,14 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, if (status == ERR_NONE) { return 0; } else if (status == I2C_ERR_BAD_ADDRESS) { - return MP_ENODEV; + return -MP_ENODEV; } - return MP_EIO; + return -MP_EIO; } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } diff --git a/ports/atmel-samd/common-hal/sdioio/SDCard.c b/ports/atmel-samd/common-hal/sdioio/SDCard.c index 8ff1a391bb265..af3610c89e9a1 100644 --- a/ports/atmel-samd/common-hal/sdioio/SDCard.c +++ b/ports/atmel-samd/common-hal/sdioio/SDCard.c @@ -9,6 +9,7 @@ #include "py/runtime.h" #include "common-hal/microcontroller/Pin.h" +#include "extmod/vfs.h" #include "shared-bindings/sdioio/SDCard.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/__init__.h" @@ -170,43 +171,85 @@ static void debug_print_state(sdioio_sdcard_obj_t *self, const char *what, sd_mm #endif } -int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { - check_for_deinit(self); - check_whole_block(bufinfo); +mp_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); wait_write_complete(self); self->state_programming = true; - sd_mmc_err_t r = sd_mmc_init_write_blocks(0, start_block, bufinfo->len / 512); + sd_mmc_err_t r = sd_mmc_init_write_blocks(0, start_block, num_blocks); if (r != SD_MMC_OK) { debug_print_state(self, "sd_mmc_init_write_blocks", r); - return -EIO; + return -MP_EIO; } - r = sd_mmc_start_write_blocks(bufinfo->buf, bufinfo->len / 512); + r = sd_mmc_start_write_blocks(buf, num_blocks); if (r != SD_MMC_OK) { debug_print_state(self, "sd_mmc_start_write_blocks", r); - return -EIO; + return -MP_EIO; } - // debug_print_state(self, "after writeblocks OK"); return 0; } -int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +mp_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { check_for_deinit(self); check_whole_block(bufinfo); + + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +mp_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); wait_write_complete(self); - sd_mmc_err_t r = sd_mmc_init_read_blocks(0, start_block, bufinfo->len / 512); + sd_mmc_err_t r = sd_mmc_init_read_blocks(0, start_block, num_blocks); if (r != SD_MMC_OK) { debug_print_state(self, "sd_mmc_init_read_blocks", r); - return -EIO; + return -MP_EIO; } - r = sd_mmc_start_read_blocks(bufinfo->buf, bufinfo->len / 512); + r = sd_mmc_start_read_blocks(buf, num_blocks); if (r != SD_MMC_OK) { debug_print_state(self, "sd_mmc_start_read_blocks", r); - return -EIO; + return -MP_EIO; } sd_mmc_wait_end_of_write_blocks(0); return 0; } +mp_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { + check_for_deinit(self); + check_whole_block(bufinfo); + + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_readblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, + mp_int_t *out_value) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + *out_value = 0; + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_DEINIT: + case MP_BLOCKDEV_IOCTL_SYNC: + // SDIO operations are synchronous, no action needed + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + *out_value = common_hal_sdioio_sdcard_get_count(self); + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + *out_value = 512; // SD cards use 512-byte sectors + return true; + + default: + return false; // Unsupported command + } +} + bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t frequency, uint8_t bits) { check_for_deinit(self); return true; diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index 861ef37464633..c095220d0a3f2 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -14,6 +14,8 @@ CIRCUITPY_LTO = 1 CIRCUITPY_KEYPAD_DEMUX ?= 0 CIRCUITPY_LVFONTIO ?= 0 +CIRCUITPY_DIGITALINOUT_PROTOCOL = 0 + ###################################################################### # Put samd21-only choices here. diff --git a/ports/atmel-samd/sd_mmc/sd_mmc.c b/ports/atmel-samd/sd_mmc/sd_mmc.c index 60b4d9f8985a1..6724e88f42a7a 100644 --- a/ports/atmel-samd/sd_mmc/sd_mmc.c +++ b/ports/atmel-samd/sd_mmc/sd_mmc.c @@ -160,9 +160,9 @@ static struct sd_mmc_card sd_mmc_cards[CONF_SD_MMC_MEM_CNT]; /** HAL driver instance */ static void *sd_mmc_hal; -/** Index of current slot configurated */ +/** Index of current slot configured */ static uint8_t sd_mmc_slot_sel; -/** Pointer on current slot configurated */ +/** Pointer on current slot configured */ static struct sd_mmc_card *sd_mmc_card; /** Number of block to read or write on the current transfer */ static uint16_t sd_mmc_nb_block_to_tranfer = 0; @@ -238,7 +238,7 @@ static bool mmc_mci_op_cond(void) { uint32_t retry, resp; /* - * Timeout 1s = 400KHz / ((6+6)*8) cylces = 4200 retry + * Timeout 1s = 400KHz / ((6+6)*8) cycles = 4200 retry * 6 = cmd byte size * 6 = response byte size */ @@ -277,7 +277,7 @@ static bool sd_mci_op_cond(uint8_t v2) { uint32_t arg, retry, resp; /* - * Timeout 1s = 400KHz / ((6+6+6+6)*8) cylces = 2100 retry + * Timeout 1s = 400KHz / ((6+6+6+6)*8) cycles = 2100 retry * 6 = cmd byte size * 6 = response byte size * 6 = cmd byte size @@ -339,7 +339,7 @@ static bool sdio_op_cond(void) { /* * Wait card ready - * Timeout 1s = 400KHz / ((6+4)*8) cylces = 5000 retry + * Timeout 1s = 400KHz / ((6+4)*8) cycles = 5000 retry * 6 = cmd byte size * 4(SPI) 6(MCI) = response byte size */ @@ -1292,13 +1292,13 @@ static bool sd_mmc_mci_install_mmc(void) { void sd_mmc_init(void *hal, sd_mmc_detect_t *card_detects, sd_mmc_detect_t *wp_detects) { /* GPIO will be used to detect card and write protect. - * The related clocks and pinmux must be configurated in good + * The related clocks and pinmux must be configured in good * condition. */ for (uint8_t slot = 0; slot < CONF_SD_MMC_MEM_CNT; slot++) { sd_mmc_cards[slot].state = SD_MMC_CARD_STATE_NO_CARD; } - sd_mmc_slot_sel = 0xFF; /* No slot configurated */ + sd_mmc_slot_sel = 0xFF; /* No slot configured */ sd_mmc_hal = hal; _cd = card_detects; _wp = wp_detects; diff --git a/ports/atmel-samd/sd_mmc/sd_mmc.h b/ports/atmel-samd/sd_mmc/sd_mmc.h index cdc98e7108e2e..7b70a631164d5 100644 --- a/ports/atmel-samd/sd_mmc/sd_mmc.h +++ b/ports/atmel-samd/sd_mmc/sd_mmc.h @@ -113,7 +113,7 @@ typedef struct sd_mmc_detect { uint16_t val; /**< Detection value */ } sd_mmc_detect_t; -/** This SD MMC stack uses the maximum block size autorized (512 bytes) */ +/** This SD MMC stack uses the maximum block size authorized (512 bytes) */ #define SD_MMC_BLOCK_SIZE 512 /** diff --git a/ports/broadcom/common-hal/busio/I2C.c b/ports/broadcom/common-hal/busio/I2C.c index 6a77cec08af83..cdc986f05ae29 100644 --- a/ports/broadcom/common-hal/busio/I2C.c +++ b/ports/broadcom/common-hal/busio/I2C.c @@ -137,7 +137,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { // Discussion of I2C implementation is here: https://github.com/raspberrypi/linux/issues/254 -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +static mp_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { COMPLETE_MEMORY_READS; self->peripheral->S_b.DONE = true; @@ -182,7 +182,7 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, while (self->peripheral->S_b.ERR == 1) { RUN_BACKGROUND_TASKS; } - return MP_ENODEV; + return -MP_ENODEV; } if (loop_len < len) { @@ -192,19 +192,19 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, return 0; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { COMPLETE_MEMORY_READS; self->peripheral->A_b.ADDR = addr; if (self->finish_write) { self->finish_write = false; if (self->peripheral->S_b.ERR == 1) { - return MP_ENODEV; + return -MP_ENODEV; } self->peripheral->FIFO_b.DATA = self->last_write_data; } else { @@ -236,15 +236,15 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, while (self->peripheral->S_b.ERR == 1) { RUN_BACKGROUND_TASKS; } - return MP_ENODEV; + return -MP_ENODEV; } return 0; } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } diff --git a/ports/broadcom/common-hal/sdioio/SDCard.c b/ports/broadcom/common-hal/sdioio/SDCard.c index f87d40cd8dcab..5dc405bdc18e8 100644 --- a/ports/broadcom/common-hal/sdioio/SDCard.c +++ b/ports/broadcom/common-hal/sdioio/SDCard.c @@ -11,6 +11,7 @@ #include "py/runtime.h" #include "common-hal/microcontroller/Pin.h" +#include "extmod/vfs.h" #include "shared-bindings/sdioio/SDCard.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/__init__.h" @@ -304,44 +305,95 @@ static void check_whole_block(mp_buffer_info_t *bufinfo) { } } -int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +// Native function for VFS blockdev layer +mp_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); if (!self->init) { - return -EIO; + return -MP_EIO; } - check_whole_block(bufinfo); self->state_programming = true; COMPLETE_MEMORY_READS; - sdmmc_err_t error = sdmmc_write_sectors(&self->card_info, bufinfo->buf, - start_block, bufinfo->len / 512); + sdmmc_err_t error = sdmmc_write_sectors(&self->card_info, buf, + start_block, num_blocks); COMPLETE_MEMORY_READS; if (error != SDMMC_OK) { mp_printf(&mp_plat_print, "write sectors result %d\n", error); - return -EIO; + return -MP_EIO; } return 0; } -int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +mp_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { if (!self->init) { - return -EIO; + return -MP_EIO; } check_whole_block(bufinfo); + + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +mp_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (!self->init) { + return -MP_EIO; + } COMPLETE_MEMORY_READS; - sdmmc_err_t error = sdmmc_read_sectors(&self->card_info, bufinfo->buf, - start_block, bufinfo->len / 512); + sdmmc_err_t error = sdmmc_read_sectors(&self->card_info, buf, + start_block, num_blocks); COMPLETE_MEMORY_READS; if (error != SDMMC_OK) { - mp_printf(&mp_plat_print, "read sectors result %d when reading block %d for %d\n", error, start_block, bufinfo->len / 512); - return -EIO; + mp_printf(&mp_plat_print, "read sectors result %d when reading block %d for %d\n", error, start_block, num_blocks); + return -MP_EIO; } return 0; } +mp_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { + if (!self->init) { + return -MP_EIO; + } + check_whole_block(bufinfo); + + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_readblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, + mp_int_t *out_value) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + *out_value = 0; + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_DEINIT: + case MP_BLOCKDEV_IOCTL_SYNC: + // SDIO operations are synchronous, no action needed + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + *out_value = common_hal_sdioio_sdcard_get_count(self); + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + *out_value = 512; // SD cards use 512-byte sectors + return true; + + default: + return false; // Unsupported command + } +} + bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t frequency, uint8_t bits) { if (!self->init) { return false; diff --git a/ports/cxd56/common-hal/busio/I2C.c b/ports/cxd56/common-hal/busio/I2C.c index fb33c242a0367..c8b32b6a023b0 100644 --- a/ports/cxd56/common-hal/busio/I2C.c +++ b/ports/cxd56/common-hal/busio/I2C.c @@ -91,7 +91,7 @@ bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { return I2C_TRANSFER(self->i2c_dev, &msg, 1) < 0 ? false : true; } -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, const uint8_t *data, size_t len, bool stop) { +static mp_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, const uint8_t *data, size_t len, bool stop) { struct i2c_msg_s msg; msg.frequency = self->frequency; @@ -102,12 +102,12 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addre return -I2C_TRANSFER(self->i2c_dev, &msg, 1); } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, uint8_t *data, size_t len) { +mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, uint8_t *data, size_t len) { struct i2c_msg_s msg; msg.frequency = self->frequency; @@ -118,9 +118,9 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, uint8 return -I2C_TRANSFER(self->i2c_dev, &msg, 1); } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } diff --git a/ports/cxd56/common-hal/sdioio/SDCard.c b/ports/cxd56/common-hal/sdioio/SDCard.c index aa1d137177066..95dde482dde0c 100644 --- a/ports/cxd56/common-hal/sdioio/SDCard.c +++ b/ports/cxd56/common-hal/sdioio/SDCard.c @@ -8,6 +8,7 @@ #include #include +#include "extmod/vfs.h" #include "py/mperrno.h" #include "py/runtime.h" @@ -95,22 +96,73 @@ static void check_whole_block(mp_buffer_info_t *bufinfo) { } } -int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +// Native function for VFS blockdev layer +mp_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + int result = self->inode->u.i_bops->read(self->inode, buf, start_block, num_blocks); + if (result < 0) { + return -MP_EIO; + } + return 0; +} + +mp_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { if (common_hal_sdioio_sdcard_deinited(self)) { raise_deinited_error(); } check_whole_block(bufinfo); - return self->inode->u.i_bops->read(self->inode, bufinfo->buf, start_block, bufinfo->len / 512); + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_readblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); } -int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +// Native function for VFS blockdev layer +mp_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + int result = self->inode->u.i_bops->write(self->inode, buf, start_block, num_blocks); + if (result < 0) { + return -MP_EIO; + } + return 0; +} + +mp_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { if (common_hal_sdioio_sdcard_deinited(self)) { raise_deinited_error(); } check_whole_block(bufinfo); - return self->inode->u.i_bops->write(self->inode, bufinfo->buf, start_block, bufinfo->len / 512); + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, + mp_int_t *out_value) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + *out_value = 0; + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_DEINIT: + case MP_BLOCKDEV_IOCTL_SYNC: + // SDIO operations are synchronous, no action needed + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + *out_value = common_hal_sdioio_sdcard_get_count(self); + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + *out_value = 512; // SD cards use 512-byte sectors + return true; + + default: + return false; // Unsupported command + } } void common_hal_sdioio_sdcard_never_reset(sdioio_sdcard_obj_t *self) { diff --git a/ports/cxd56/mkspk/clefia.c b/ports/cxd56/mkspk/clefia.c index e946ee5348a5a..d36f638fa0b0d 100644 --- a/ports/cxd56/mkspk/clefia.c +++ b/ports/cxd56/mkspk/clefia.c @@ -466,16 +466,16 @@ int clefiakeyset(unsigned char *rk, const unsigned char *skey) { void clefiaencrypt(unsigned char *ct, const unsigned char *pt, const unsigned char *rk, const int r) { - unsigned char rin[16]; + unsigned char r_in[16]; unsigned char rout[16]; - bytecpy(rin, pt, 16); + bytecpy(r_in, pt, 16); - bytexor(rin + 4, rin + 4, rk + 0, 4); /* initial key whitening */ - bytexor(rin + 12, rin + 12, rk + 4, 4); + bytexor(r_in + 4, r_in + 4, rk + 0, 4); /* initial key whitening */ + bytexor(r_in + 12, r_in + 12, rk + 4, 4); rk += 8; - clefiagfn4(rout, rin, rk, r); /* GFN_{4,r} */ + clefiagfn4(rout, r_in, rk, r); /* GFN_{4,r} */ bytecpy(ct, rout, 16); bytexor(ct + 4, ct + 4, rk + r * 8 + 0, 4); /* final key whitening */ diff --git a/ports/espressif/boards/adafruit_esp32s3_camera/board.c b/ports/espressif/boards/adafruit_esp32s3_camera/board.c index e0c357f04c80f..d8b0832d3d043 100644 --- a/ports/espressif/boards/adafruit_esp32s3_camera/board.c +++ b/ports/espressif/boards/adafruit_esp32s3_camera/board.c @@ -37,9 +37,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO40, // TFT_DC Command or data - &pin_GPIO39, // TFT_CS Chip select - &pin_GPIO38, // TFT_RESET Reset + MP_OBJ_FROM_PTR(&pin_GPIO40), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO39), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO38), // TFT_RESET Reset 40000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/board.c index e554be121dbef..1fe3fd6280021 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/board.c @@ -57,9 +57,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO40, // DC - &pin_GPIO42, // CS - &pin_GPIO41, // RST + MP_OBJ_FROM_PTR(&pin_GPIO40), // DC + MP_OBJ_FROM_PTR(&pin_GPIO42), // CS + MP_OBJ_FROM_PTR(&pin_GPIO41), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c index 1ebb357aed5bd..22af4caa652b7 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c @@ -57,9 +57,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO39, // DC - &pin_GPIO7, // CS - &pin_GPIO40, // RST + MP_OBJ_FROM_PTR(&pin_GPIO39), // DC + MP_OBJ_FROM_PTR(&pin_GPIO7), // CS + MP_OBJ_FROM_PTR(&pin_GPIO40), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/board.c index e554be121dbef..1fe3fd6280021 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/board.c @@ -57,9 +57,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO40, // DC - &pin_GPIO42, // CS - &pin_GPIO41, // RST + MP_OBJ_FROM_PTR(&pin_GPIO40), // DC + MP_OBJ_FROM_PTR(&pin_GPIO42), // CS + MP_OBJ_FROM_PTR(&pin_GPIO41), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s3_tft/board.c index e3569d864e73c..587c742a64f36 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_tft/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s3_tft/board.c @@ -57,9 +57,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO39, // DC - &pin_GPIO7, // CS - &pin_GPIO40, // RST + MP_OBJ_FROM_PTR(&pin_GPIO39), // DC + MP_OBJ_FROM_PTR(&pin_GPIO7), // CS + MP_OBJ_FROM_PTR(&pin_GPIO40), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/adafruit_funhouse/board.c b/ports/espressif/boards/adafruit_funhouse/board.c index 061a6abf0d8ca..83499f5a49229 100644 --- a/ports/espressif/boards/adafruit_funhouse/board.c +++ b/ports/espressif/boards/adafruit_funhouse/board.c @@ -37,9 +37,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO39, // TFT_DC Command or data - &pin_GPIO40, // TFT_CS Chip select - &pin_GPIO41, // TFT_RESET Reset + MP_OBJ_FROM_PTR(&pin_GPIO39), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO40), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO41), // TFT_RESET Reset 5000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c index d37233b7f2420..dc117deee632e 100644 --- a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c +++ b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c @@ -206,9 +206,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO7, // EPD_DC Command or data - &pin_GPIO8, // EPD_CS Chip select - &pin_GPIO6, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO7), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO8), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO6), // EPD_RST Reset 4000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/elecrow_crowpanel_3.5/board.c b/ports/espressif/boards/elecrow_crowpanel_3.5/board.c index 3adfb512e3f27..0748e03fce88b 100755 --- a/ports/espressif/boards/elecrow_crowpanel_3.5/board.c +++ b/ports/espressif/boards/elecrow_crowpanel_3.5/board.c @@ -54,8 +54,8 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO2, // TFT_DC Command or data - &pin_GPIO15, // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO2), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO15), // TFT_CS Chip select NULL, // TFT_RST Reset 20000000, // Baudrate 0, // Polarity diff --git a/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c index 04f5f92f85ba9..c292ea113aa3f 100644 --- a/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c +++ b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c @@ -56,9 +56,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO46, // EPD_DC Command or data - &pin_GPIO45, // EPD_CS Chip select - &pin_GPIO47, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO46), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO45), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO47), // EPD_RST Reset 1000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/espressif_esp32s3_box/board.c b/ports/espressif/boards/espressif_esp32s3_box/board.c index 54edb47bac33d..a27411fd79c16 100644 --- a/ports/espressif/boards/espressif_esp32s3_box/board.c +++ b/ports/espressif/boards/espressif_esp32s3_box/board.c @@ -31,9 +31,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO4, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select - &pin_GPIO48, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO4), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO48), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/espressif_esp32s3_box_lite/board.c b/ports/espressif/boards/espressif_esp32s3_box_lite/board.c index e675c0f915b6d..48a49e03bc3e6 100644 --- a/ports/espressif/boards/espressif_esp32s3_box_lite/board.c +++ b/ports/espressif/boards/espressif_esp32s3_box_lite/board.c @@ -32,9 +32,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO4, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select - &pin_GPIO48, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO4), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO48), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/espressif_esp32s3_eye/board.c b/ports/espressif/boards/espressif_esp32s3_eye/board.c index c48c9428cf468..09a05cc72c446 100644 --- a/ports/espressif/boards/espressif_esp32s3_eye/board.c +++ b/ports/espressif/boards/espressif_esp32s3_eye/board.c @@ -56,8 +56,8 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO43, // DC - &pin_GPIO44, // CS + MP_OBJ_FROM_PTR(&pin_GPIO43), // DC + MP_OBJ_FROM_PTR(&pin_GPIO44), // CS NULL, // no reset pin 40000000, // baudrate 0, // polarity diff --git a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c index 94d08bb56c817..3b5aa06b6767e 100644 --- a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c +++ b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c @@ -59,9 +59,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO4, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select - &pin_GPIO8, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO4), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO8), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/hardkernel_odroid_go/board.c b/ports/espressif/boards/hardkernel_odroid_go/board.c index 647fcd740eba3..5a8b6ccaefee9 100644 --- a/ports/espressif/boards/hardkernel_odroid_go/board.c +++ b/ports/espressif/boards/hardkernel_odroid_go/board.c @@ -51,8 +51,8 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO21, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO21), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select NULL, // TFT_RST Reset 40000000, // Baudrate 0, // Polarity diff --git a/ports/espressif/boards/heltec_vision_master_e290/board.c b/ports/espressif/boards/heltec_vision_master_e290/board.c index 9749f5c704881..5a102c7119bd0 100644 --- a/ports/espressif/boards/heltec_vision_master_e290/board.c +++ b/ports/espressif/boards/heltec_vision_master_e290/board.c @@ -54,9 +54,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO4, // EPD_DC Command or data - &pin_GPIO3, // EPD_CS Chip select - &pin_GPIO5, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO4), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO3), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO5), // EPD_RST Reset 1000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/heltec_wireless_paper/board.c b/ports/espressif/boards/heltec_wireless_paper/board.c index c796a9be8843d..38f6472e085e6 100644 --- a/ports/espressif/boards/heltec_wireless_paper/board.c +++ b/ports/espressif/boards/heltec_wireless_paper/board.c @@ -94,9 +94,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO5, // EPD_DC Command or data - &pin_GPIO4, // EPD_CS Chip select - &pin_GPIO6, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO5), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO4), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO6), // EPD_RST Reset 1000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/hexky_s2/board.c b/ports/espressif/boards/hexky_s2/board.c index c1e1801fed659..41f97796be4fb 100644 --- a/ports/espressif/boards/hexky_s2/board.c +++ b/ports/espressif/boards/hexky_s2/board.c @@ -57,9 +57,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO34, // DC - &pin_GPIO33, // CS - &pin_GPIO41, // RST + MP_OBJ_FROM_PTR(&pin_GPIO34), // DC + MP_OBJ_FROM_PTR(&pin_GPIO33), // CS + MP_OBJ_FROM_PTR(&pin_GPIO41), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/hiibot_iots2/board.c b/ports/espressif/boards/hiibot_iots2/board.c index e9941cbc3685c..e4bff05822c33 100644 --- a/ports/espressif/boards/hiibot_iots2/board.c +++ b/ports/espressif/boards/hiibot_iots2/board.c @@ -62,8 +62,8 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO35, // DC - &pin_GPIO36, // CS + MP_OBJ_FROM_PTR(&pin_GPIO35), // DC + MP_OBJ_FROM_PTR(&pin_GPIO36), // CS NULL, // NO RST ? 40000000, // baudrate 0, // polarity diff --git a/ports/espressif/boards/lilygo_tdeck/board.c b/ports/espressif/boards/lilygo_tdeck/board.c index 91a2f6d2ad702..a1008f2173f89 100644 --- a/ports/espressif/boards/lilygo_tdeck/board.c +++ b/ports/espressif/boards/lilygo_tdeck/board.c @@ -32,8 +32,8 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO11, // TFT_DC Command or data - &pin_GPIO12, // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO11), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO12), // TFT_CS Chip select NULL, // TFT_RST Reset 60000000, // Baudrate 0, // Polarity diff --git a/ports/espressif/boards/lilygo_tdisplay_s3_pro/board.c b/ports/espressif/boards/lilygo_tdisplay_s3_pro/board.c index ede20df200fa9..0782e2161ca8a 100644 --- a/ports/espressif/boards/lilygo_tdisplay_s3_pro/board.c +++ b/ports/espressif/boards/lilygo_tdisplay_s3_pro/board.c @@ -34,9 +34,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO9, // TFT_DC Command or data - &pin_GPIO39, // TFT_CS Chip select - &pin_GPIO47, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO9), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO39), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO47), // TFT_RST Reset 40000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/lilygo_tdongle_s3/board.c b/ports/espressif/boards/lilygo_tdongle_s3/board.c index 8907dc7fe9828..ede75a5842e35 100644 --- a/ports/espressif/boards/lilygo_tdongle_s3/board.c +++ b/ports/espressif/boards/lilygo_tdongle_s3/board.c @@ -60,9 +60,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO2, // DC - &pin_GPIO4, // CS - &pin_GPIO1, // RST + MP_OBJ_FROM_PTR(&pin_GPIO2), // DC + MP_OBJ_FROM_PTR(&pin_GPIO4), // CS + MP_OBJ_FROM_PTR(&pin_GPIO1), // RST 10000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/lilygo_tembed_esp32s3/board.c b/ports/espressif/boards/lilygo_tembed_esp32s3/board.c index 698e6980eceef..46e2ecf863c19 100644 --- a/ports/espressif/boards/lilygo_tembed_esp32s3/board.c +++ b/ports/espressif/boards/lilygo_tembed_esp32s3/board.c @@ -32,9 +32,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO13, // TFT_DC Command or data - &pin_GPIO10, // TFT_CS Chip select - &pin_GPIO9, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO13), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO10), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO9), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/lilygo_tqt_pro_nopsram/board.c b/ports/espressif/boards/lilygo_tqt_pro_nopsram/board.c index c7e711aee66a5..fe72222a22cbe 100644 --- a/ports/espressif/boards/lilygo_tqt_pro_nopsram/board.c +++ b/ports/espressif/boards/lilygo_tqt_pro_nopsram/board.c @@ -57,9 +57,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO6, // DC - &pin_GPIO5, // CS - &pin_GPIO1, // RST + MP_OBJ_FROM_PTR(&pin_GPIO6), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO1), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/lilygo_tqt_pro_psram/board.c b/ports/espressif/boards/lilygo_tqt_pro_psram/board.c index c7e711aee66a5..fe72222a22cbe 100644 --- a/ports/espressif/boards/lilygo_tqt_pro_psram/board.c +++ b/ports/espressif/boards/lilygo_tqt_pro_psram/board.c @@ -57,9 +57,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO6, // DC - &pin_GPIO5, // CS - &pin_GPIO1, // RST + MP_OBJ_FROM_PTR(&pin_GPIO6), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO1), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c b/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c index 2b77e24b91e7b..6fcfb5c19a479 100644 --- a/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c +++ b/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c @@ -62,9 +62,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO37, // DC - &pin_GPIO34, // CS - &pin_GPIO38, // RST + MP_OBJ_FROM_PTR(&pin_GPIO37), // DC + MP_OBJ_FROM_PTR(&pin_GPIO34), // CS + MP_OBJ_FROM_PTR(&pin_GPIO38), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c index 97574398ca2c1..8ed5462a2d364 100644 --- a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c @@ -42,9 +42,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO16, // DC - &pin_GPIO5, // CS - &pin_GPIO23, // RST + MP_OBJ_FROM_PTR(&pin_GPIO16), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO23), // RST 24000000, // baudrate (default from the driver) // 40000000, 0, // polarity diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/board.c b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/board.c index 2d3cb64d4559c..a90cc5eb66adb 100644 --- a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/board.c +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/board.c @@ -41,9 +41,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO16, // DC - &pin_GPIO5, // CS - &pin_GPIO23, // RST + MP_OBJ_FROM_PTR(&pin_GPIO16), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO23), // RST 24000000, // baudrate (default from the driver) // 40000000, 0, // polarity diff --git a/ports/espressif/boards/lilygo_twatch_2020_v3/board.c b/ports/espressif/boards/lilygo_twatch_2020_v3/board.c index 266515c2338e6..e88a82ea24f5b 100644 --- a/ports/espressif/boards/lilygo_twatch_2020_v3/board.c +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/board.c @@ -46,8 +46,8 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO5, // CS + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS NULL, // RST 24000000, // baudrate 0, // polarity diff --git a/ports/espressif/boards/lilygo_twatch_s3/board.c b/ports/espressif/boards/lilygo_twatch_s3/board.c index 51f5933d177ec..801914a4991c0 100644 --- a/ports/espressif/boards/lilygo_twatch_s3/board.c +++ b/ports/espressif/boards/lilygo_twatch_s3/board.c @@ -108,8 +108,8 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO38, // DC - &pin_GPIO12, // CS + MP_OBJ_FROM_PTR(&pin_GPIO38), // DC + MP_OBJ_FROM_PTR(&pin_GPIO12), // CS NULL, // RST 40000000, // baudrate 0, // polarity diff --git a/ports/espressif/boards/lolin_s3_mini_pro/board.c b/ports/espressif/boards/lolin_s3_mini_pro/board.c index cd5a083dbdba1..39e645bc7b553 100644 --- a/ports/espressif/boards/lolin_s3_mini_pro/board.c +++ b/ports/espressif/boards/lolin_s3_mini_pro/board.c @@ -39,9 +39,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO36, // DC - &pin_GPIO35, // CS - &pin_GPIO34, // RST + MP_OBJ_FROM_PTR(&pin_GPIO36), // DC + MP_OBJ_FROM_PTR(&pin_GPIO35), // CS + MP_OBJ_FROM_PTR(&pin_GPIO34), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_atoms3/board.c b/ports/espressif/boards/m5stack_atoms3/board.c index df620976b61b4..3dbd8a1a2b8b6 100644 --- a/ports/espressif/boards/m5stack_atoms3/board.c +++ b/ports/espressif/boards/m5stack_atoms3/board.c @@ -39,9 +39,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO33, // DC - &pin_GPIO15, // CS - &pin_GPIO34, // RST + MP_OBJ_FROM_PTR(&pin_GPIO33), // DC + MP_OBJ_FROM_PTR(&pin_GPIO15), // CS + MP_OBJ_FROM_PTR(&pin_GPIO34), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_cardputer/board.c b/ports/espressif/boards/m5stack_cardputer/board.c index 6fdc2f8ea5c46..00630cd36d291 100644 --- a/ports/espressif/boards/m5stack_cardputer/board.c +++ b/ports/espressif/boards/m5stack_cardputer/board.c @@ -50,9 +50,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO34, // DC - &pin_GPIO37, // CS - &pin_GPIO33, // RST + MP_OBJ_FROM_PTR(&pin_GPIO34), // DC + MP_OBJ_FROM_PTR(&pin_GPIO37), // CS + MP_OBJ_FROM_PTR(&pin_GPIO33), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_cardputer_ros/board.c b/ports/espressif/boards/m5stack_cardputer_ros/board.c index 6fdc2f8ea5c46..00630cd36d291 100644 --- a/ports/espressif/boards/m5stack_cardputer_ros/board.c +++ b/ports/espressif/boards/m5stack_cardputer_ros/board.c @@ -50,9 +50,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO34, // DC - &pin_GPIO37, // CS - &pin_GPIO33, // RST + MP_OBJ_FROM_PTR(&pin_GPIO34), // DC + MP_OBJ_FROM_PTR(&pin_GPIO37), // CS + MP_OBJ_FROM_PTR(&pin_GPIO33), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_core2/board.c b/ports/espressif/boards/m5stack_core2/board.c index 9d5c2bd650a51..2d63436235af1 100644 --- a/ports/espressif/boards/m5stack_core2/board.c +++ b/ports/espressif/boards/m5stack_core2/board.c @@ -318,9 +318,9 @@ static bool display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO15, // DC - &pin_GPIO5, // CS - NULL, // RST + MP_OBJ_FROM_PTR(&pin_GPIO15), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_NULL, // RST 32000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_core_basic/board.c b/ports/espressif/boards/m5stack_core_basic/board.c index 4ae128817a116..5a18d33e52767 100644 --- a/ports/espressif/boards/m5stack_core_basic/board.c +++ b/ports/espressif/boards/m5stack_core_basic/board.c @@ -42,9 +42,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO14, // CS - &pin_GPIO33, // RST + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO14), // CS + MP_OBJ_FROM_PTR(&pin_GPIO33), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_core_fire/board.c b/ports/espressif/boards/m5stack_core_fire/board.c index 4ae128817a116..5a18d33e52767 100644 --- a/ports/espressif/boards/m5stack_core_fire/board.c +++ b/ports/espressif/boards/m5stack_core_fire/board.c @@ -42,9 +42,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO14, // CS - &pin_GPIO33, // RST + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO14), // CS + MP_OBJ_FROM_PTR(&pin_GPIO33), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_cores3/board.c b/ports/espressif/boards/m5stack_cores3/board.c index f49d634999730..c14be4ae0d142 100644 --- a/ports/espressif/boards/m5stack_cores3/board.c +++ b/ports/espressif/boards/m5stack_cores3/board.c @@ -45,9 +45,9 @@ static bool display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO35, // DC - &pin_GPIO3, // CS - NULL, // RST + MP_OBJ_FROM_PTR(&pin_GPIO35), // DC + MP_OBJ_FROM_PTR(&pin_GPIO3), // CS + MP_OBJ_NULL, // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_dial/board.c b/ports/espressif/boards/m5stack_dial/board.c index 4e7cf4b0240a9..6214255612bd2 100644 --- a/ports/espressif/boards/m5stack_dial/board.c +++ b/ports/espressif/boards/m5stack_dial/board.c @@ -49,9 +49,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO4, // DC - &pin_GPIO7, // CS - &pin_GPIO8, // RST + MP_OBJ_FROM_PTR(&pin_GPIO4), // DC + MP_OBJ_FROM_PTR(&pin_GPIO7), // CS + MP_OBJ_FROM_PTR(&pin_GPIO8), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_dinmeter/board.c b/ports/espressif/boards/m5stack_dinmeter/board.c index cd49318fd1cec..37fafa994dc4d 100644 --- a/ports/espressif/boards/m5stack_dinmeter/board.c +++ b/ports/espressif/boards/m5stack_dinmeter/board.c @@ -51,9 +51,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO4, // DC - &pin_GPIO7, // CS - &pin_GPIO8, // RST + MP_OBJ_FROM_PTR(&pin_GPIO4), // DC + MP_OBJ_FROM_PTR(&pin_GPIO7), // CS + MP_OBJ_FROM_PTR(&pin_GPIO8), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_stick_c/board.c b/ports/espressif/boards/m5stack_stick_c/board.c index 641d2d1db7e78..491ddead86035 100644 --- a/ports/espressif/boards/m5stack_stick_c/board.c +++ b/ports/espressif/boards/m5stack_stick_c/board.c @@ -154,9 +154,9 @@ static bool display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO23, // DC - &pin_GPIO5, // CS - &pin_GPIO18, // RST + MP_OBJ_FROM_PTR(&pin_GPIO23), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO18), // RST 10000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_stick_c_plus/board.c b/ports/espressif/boards/m5stack_stick_c_plus/board.c index eec6a20826030..8902521db8e3f 100644 --- a/ports/espressif/boards/m5stack_stick_c_plus/board.c +++ b/ports/espressif/boards/m5stack_stick_c_plus/board.c @@ -154,9 +154,9 @@ static bool display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO23, // DC - &pin_GPIO5, // CS - &pin_GPIO18, // RST + MP_OBJ_FROM_PTR(&pin_GPIO23), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO18), // RST 10000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_stick_c_plus2/board.c b/ports/espressif/boards/m5stack_stick_c_plus2/board.c index a50e38df09e46..d84faa1888d21 100644 --- a/ports/espressif/boards/m5stack_stick_c_plus2/board.c +++ b/ports/espressif/boards/m5stack_stick_c_plus2/board.c @@ -50,9 +50,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO14, // DC - &pin_GPIO5, // CS - &pin_GPIO12, // RST + MP_OBJ_FROM_PTR(&pin_GPIO14), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO12), // RST 10000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/morpheans_morphesp-240/board.c b/ports/espressif/boards/morpheans_morphesp-240/board.c index 5b1c3f82bbbdb..44266cce6ed9f 100644 --- a/ports/espressif/boards/morpheans_morphesp-240/board.c +++ b/ports/espressif/boards/morpheans_morphesp-240/board.c @@ -138,9 +138,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO14, // DC - &pin_GPIO10, // CS - &pin_GPIO9, // RST + MP_OBJ_FROM_PTR(&pin_GPIO14), // DC + MP_OBJ_FROM_PTR(&pin_GPIO10), // CS + MP_OBJ_FROM_PTR(&pin_GPIO9), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/oxocard_artwork/board.c b/ports/espressif/boards/oxocard_artwork/board.c index a27cdb7003bdc..5fe8e8145583a 100644 --- a/ports/espressif/boards/oxocard_artwork/board.c +++ b/ports/espressif/boards/oxocard_artwork/board.c @@ -43,9 +43,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO15, // CS - &pin_GPIO4, // RST + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO15), // CS + MP_OBJ_FROM_PTR(&pin_GPIO4), // RST 24000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/oxocard_connect/board.c b/ports/espressif/boards/oxocard_connect/board.c index 89be45c82262e..2c01381147437 100644 --- a/ports/espressif/boards/oxocard_connect/board.c +++ b/ports/espressif/boards/oxocard_connect/board.c @@ -44,9 +44,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO15, // CS - &pin_GPIO4, // RST + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO15), // CS + MP_OBJ_FROM_PTR(&pin_GPIO4), // RST 24000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/oxocard_galaxy/board.c b/ports/espressif/boards/oxocard_galaxy/board.c index a27cdb7003bdc..5fe8e8145583a 100644 --- a/ports/espressif/boards/oxocard_galaxy/board.c +++ b/ports/espressif/boards/oxocard_galaxy/board.c @@ -43,9 +43,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO15, // CS - &pin_GPIO4, // RST + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO15), // CS + MP_OBJ_FROM_PTR(&pin_GPIO4), // RST 24000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/oxocard_science/board.c b/ports/espressif/boards/oxocard_science/board.c index a27cdb7003bdc..5fe8e8145583a 100644 --- a/ports/espressif/boards/oxocard_science/board.c +++ b/ports/espressif/boards/oxocard_science/board.c @@ -43,9 +43,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO15, // CS - &pin_GPIO4, // RST + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO15), // CS + MP_OBJ_FROM_PTR(&pin_GPIO4), // RST 24000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/spotpear_esp32c3_lcd_1_44/board.c b/ports/espressif/boards/spotpear_esp32c3_lcd_1_44/board.c index 89bcbf6b8dd7f..f4288ae45ace5 100644 --- a/ports/espressif/boards/spotpear_esp32c3_lcd_1_44/board.c +++ b/ports/espressif/boards/spotpear_esp32c3_lcd_1_44/board.c @@ -42,9 +42,9 @@ static bool display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO0, // DC - &pin_GPIO2, // CS - &pin_GPIO5, // RST + MP_OBJ_FROM_PTR(&pin_GPIO0), // DC + MP_OBJ_FROM_PTR(&pin_GPIO2), // CS + MP_OBJ_FROM_PTR(&pin_GPIO5), // RST 10000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/board.c b/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/board.c index 6299402e8e07a..30879e714045d 100644 --- a/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/board.c +++ b/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/board.c @@ -39,9 +39,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO2, // DC - &pin_GPIO3, // CS - &pin_GPIO10, // RST + MP_OBJ_FROM_PTR(&pin_GPIO2), // DC + MP_OBJ_FROM_PTR(&pin_GPIO3), // CS + MP_OBJ_FROM_PTR(&pin_GPIO10), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/sqfmi_watchy/board.c b/ports/espressif/boards/sqfmi_watchy/board.c index 297190b53e200..9cea4e9809598 100644 --- a/ports/espressif/boards/sqfmi_watchy/board.c +++ b/ports/espressif/boards/sqfmi_watchy/board.c @@ -150,9 +150,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO10, // EPD_DC Command or data - &pin_GPIO5, // EPD_CS Chip select - &pin_GPIO9, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO10), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO9), // EPD_RST Reset 2000000, // Baudrate 0, // Polarity 0 // Phase diff --git a/ports/espressif/boards/sunton_esp32_2424S012/board.c b/ports/espressif/boards/sunton_esp32_2424S012/board.c index c313ded863764..731694a4e1b8a 100644 --- a/ports/espressif/boards/sunton_esp32_2424S012/board.c +++ b/ports/espressif/boards/sunton_esp32_2424S012/board.c @@ -105,9 +105,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO2, // DC - &pin_GPIO10, // CS - NULL, // RST + MP_OBJ_FROM_PTR(&pin_GPIO2), // DC + MP_OBJ_FROM_PTR(&pin_GPIO10), // CS + MP_OBJ_NULL, // RST 80000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/sunton_esp32_2432S024C/board.c b/ports/espressif/boards/sunton_esp32_2432S024C/board.c index 8b4201d88e81d..a43b5ad65a032 100644 --- a/ports/espressif/boards/sunton_esp32_2432S024C/board.c +++ b/ports/espressif/boards/sunton_esp32_2432S024C/board.c @@ -50,9 +50,9 @@ static void display_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO2, // TFT_DC Command or data - &pin_GPIO15, // TFT_CS Chip select - NULL, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO2), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO15), // TFT_CS Chip select + MP_OBJ_NULL, // TFT_RST Reset 6000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/sunton_esp32_2432S024C/pins.c b/ports/espressif/boards/sunton_esp32_2432S024C/pins.c index a69f3150e9248..6544017cd999c 100644 --- a/ports/espressif/boards/sunton_esp32_2432S024C/pins.c +++ b/ports/espressif/boards/sunton_esp32_2432S024C/pins.c @@ -46,7 +46,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO5) }, - // ILI9341 dsplay (spi) + // ILI9341 display (spi) { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_LCD_MISO), MP_ROM_PTR(&pin_GPIO12) }, { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_GPIO14) }, diff --git a/ports/espressif/boards/sunton_esp32_2432S028/board.c b/ports/espressif/boards/sunton_esp32_2432S028/board.c index b249c45dd8fa2..7380e252410ac 100644 --- a/ports/espressif/boards/sunton_esp32_2432S028/board.c +++ b/ports/espressif/boards/sunton_esp32_2432S028/board.c @@ -50,9 +50,9 @@ static void display_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO2, // TFT_DC Command or data - &pin_GPIO15, // TFT_CS Chip select - NULL, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO2), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO15), // TFT_CS Chip select + MP_OBJ_NULL, // TFT_RST Reset 6000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/sunton_esp32_2432S028/pins.c b/ports/espressif/boards/sunton_esp32_2432S028/pins.c index b852ab11e04c2..7791c1685eb38 100644 --- a/ports/espressif/boards/sunton_esp32_2432S028/pins.c +++ b/ports/espressif/boards/sunton_esp32_2432S028/pins.c @@ -45,7 +45,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO5) }, - // ILI9341 dsplay (spi) + // ILI9341 display (spi) { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_LCD_MISO), MP_ROM_PTR(&pin_GPIO12) }, { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_GPIO14) }, diff --git a/ports/espressif/boards/sunton_esp32_2432S032C/board.c b/ports/espressif/boards/sunton_esp32_2432S032C/board.c index b2160e0aa4f34..48e206040d819 100644 --- a/ports/espressif/boards/sunton_esp32_2432S032C/board.c +++ b/ports/espressif/boards/sunton_esp32_2432S032C/board.c @@ -43,9 +43,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO2, // TFT_DC - &pin_GPIO15, // TFT_CS - NULL, // TFT_RST + MP_OBJ_FROM_PTR(&pin_GPIO2), // TFT_DC + MP_OBJ_FROM_PTR(&pin_GPIO15), // TFT_CS + MP_OBJ_NULL, // TFT_RST 26600000, // Baudrate 0, // Polarity 0 // Phase diff --git a/ports/espressif/boards/vidi_x/board.c b/ports/espressif/boards/vidi_x/board.c index e53dfd82ad9de..7ba7094b91778 100644 --- a/ports/espressif/boards/vidi_x/board.c +++ b/ports/espressif/boards/vidi_x/board.c @@ -51,9 +51,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO21, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select - NULL, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO21), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select + MP_OBJ_NULL, // TFT_RST Reset 40000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/board.c b/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/board.c index 7dd0e0c0fa2ab..e56c096e40371 100644 --- a/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/board.c +++ b/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/board.c @@ -48,9 +48,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO15, // DC - &pin_GPIO14, // CS - &pin_GPIO21, // RST + MP_OBJ_FROM_PTR(&pin_GPIO15), // DC + MP_OBJ_FROM_PTR(&pin_GPIO14), // CS + MP_OBJ_FROM_PTR(&pin_GPIO21), // RST 80000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c index cb6fb3103382e..0bf710ec34c69 100644 --- a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c +++ b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c @@ -61,9 +61,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO18, // DC - &pin_GPIO9, // CS - &pin_GPIO21, // RST + MP_OBJ_FROM_PTR(&pin_GPIO18), // DC + MP_OBJ_FROM_PTR(&pin_GPIO9), // CS + MP_OBJ_FROM_PTR(&pin_GPIO21), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/waveshare_esp32_s3_geek/board.c b/ports/espressif/boards/waveshare_esp32_s3_geek/board.c index 414188fb46a52..0ce447532642c 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_geek/board.c +++ b/ports/espressif/boards/waveshare_esp32_s3_geek/board.c @@ -38,9 +38,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO8, // TFT_DC - &pin_GPIO10, // TFT_CS - &pin_GPIO9, // TFT_RST + MP_OBJ_FROM_PTR(&pin_GPIO8), // TFT_DC + MP_OBJ_FROM_PTR(&pin_GPIO10), // TFT_CS + MP_OBJ_FROM_PTR(&pin_GPIO9), // TFT_RST 50000000, // Baudrate 0, // Polarity 0 // Phase diff --git a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/board.c b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/board.c index 36990c8556691..ee47ccb0bc96e 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/board.c +++ b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/board.c @@ -105,9 +105,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO8, // DC - &pin_GPIO9, // CS - &pin_GPIO12, // RST + MP_OBJ_FROM_PTR(&pin_GPIO8), // DC + MP_OBJ_FROM_PTR(&pin_GPIO9), // CS + MP_OBJ_FROM_PTR(&pin_GPIO12), // RST 80000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/board.c b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/board.c index f3dd38522f74f..4ecf87948ad04 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/board.c +++ b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/board.c @@ -48,9 +48,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO41, // DC - &pin_GPIO42, // CS - &pin_GPIO39, // RST + MP_OBJ_FROM_PTR(&pin_GPIO41), // DC + MP_OBJ_FROM_PTR(&pin_GPIO42), // CS + MP_OBJ_FROM_PTR(&pin_GPIO39), // RST 80000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/board.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/board.c index 4c037ce8df057..1bdd74e77ee68 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/board.c +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/board.c @@ -94,9 +94,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO45, // DC - &pin_GPIO21, // CS - &pin_GPIO40, // RST + MP_OBJ_FROM_PTR(&pin_GPIO45), // DC + MP_OBJ_FROM_PTR(&pin_GPIO21), // CS + MP_OBJ_FROM_PTR(&pin_GPIO40), // RST 80000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/board.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/board.c index e7a6b86440ee5..71e2d745623b9 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/board.c +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/board.c @@ -34,9 +34,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO42, // DC - &pin_GPIO45, // CS - &pin_GPIO0, // RST + MP_OBJ_FROM_PTR(&pin_GPIO42), // DC + MP_OBJ_FROM_PTR(&pin_GPIO45), // CS + MP_OBJ_FROM_PTR(&pin_GPIO0), // RST // 24000000, 40000000, // baudrate 0, // polarity diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/board.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/board.c index deb764b80a5f7..49177f48fe7d9 100755 --- a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/board.c +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/board.c @@ -34,9 +34,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO41, // DC - &pin_GPIO42, // CS - &pin_GPIO39, // RST + MP_OBJ_FROM_PTR(&pin_GPIO41), // DC + MP_OBJ_FROM_PTR(&pin_GPIO42), // CS + MP_OBJ_FROM_PTR(&pin_GPIO39), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/yoto_mini_2024/board.c b/ports/espressif/boards/yoto_mini_2024/board.c new file mode 100644 index 0000000000000..fb6a96a957d06 --- /dev/null +++ b/ports/espressif/boards/yoto_mini_2024/board.c @@ -0,0 +1,203 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "board.h" + +#include "supervisor/board.h" + +#include "extmod/vfs_fat.h" + +#include "py/mpstate.h" + +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/i2cioexpander/IOExpander.h" +#include "shared-bindings/i2cioexpander/IOPin.h" +#include "shared-bindings/sdioio/SDCard.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" + +#include "supervisor/filesystem.h" + +static sdioio_sdcard_obj_t sdmmc; +static mp_vfs_mount_t _sdcard_vfs; +static fs_user_mount_t _sdcard_usermount; +static i2cioexpander_ioexpander_obj_t ioexpander; + +#define DELAY 0x80 + +// This is a GC9306. +uint8_t display_init_sequence[] = { + 0xfe, 0, + 0xef, 0, + + // // sw reset + // 0x01, 0 | DELAY, 150, + // normal display mode on + // 0x13, 0, + // display and color format settings + 0x36, 1, 0x48, // Memory access control. mini does 0x48, not 0, 2, 3, 4 or 6 + 0x3A, 1 | DELAY, 0x55, 10, // COLMOD. mini does 0x06 + 0xa4, 2, 0x44, 0x44, // power control 7 + 0xa5, 2, 0x42, 0x42, + 0xaa, 2, 0x88, 0x88, + 0xae, 1, 0x2b, + 0xe8, 2, 0x22, 0x0b, // frame rate + 0xe3, 2, 0x01, 0x10, + 0xff, 1, 0x61, + 0xac, 1, 0x00, + 0xad, 1, 0x33, + 0xaf, 1, 0x77, + 0xa6, 2, 0x1c, 0x1c, // power control 2 + 0xa7, 2, 0x1c, 0x1c, // power control 3 + 0xa8, 2, 0x10, 0x10, // power control 4 + 0xa9, 2, 0x0d, 0x0d, // power control 5 + 0xf0, 6, 0x02, 0x01, 0x00, 0x00, 0x00, 0x05, // Gamma settings + 0xf1, 6, 0x01, 0x02, 0x00, 0x06, 0x10, 0x0e, + 0xf2, 6, 0x03, 0x11, 0x28, 0x02, 0x00, 0x48, + 0xf3, 6, 0x0c, 0x11, 0x30, 0x00, 0x00, 0x46, + 0xf4, 6, 0x05, 0x1f, 0x1f, 0x36, 0x30, 0x0f, + 0xf5, 6, 0x04, 0x1d, 0x1a, 0x38, 0x3f, 0x0f, // Last gamma setting + 0x35, 1, 0x00, + 0x44, 2, 0x00, 0x0a, // set tear scan line + 0x21, 0, // display inversion on + // sleep out + 0x11, 0 | DELAY, 255, + + // display on + 0x29, 0 | DELAY, 255, +}; + +void board_init(void) { + // Wait for everything to start + mp_hal_delay_ms(300); + + // Initialize the board's peripherals here. + busio_i2c_obj_t *i2c = MP_OBJ_TO_PTR(common_hal_board_create_i2c(0)); + + // Initialize the IOExpander + ioexpander.base.type = &i2cioexpander_ioexpander_type; + common_hal_i2cioexpander_ioexpander_construct( + &ioexpander, + MP_OBJ_FROM_PTR(i2c), + 0x20, // I2C address + 16, // Number of pins + 2, // Output register + 0, // Input register + 6); // Direction register + + board_set(MP_QSTR_IOEXPANDER, MP_OBJ_FROM_PTR(&ioexpander)); + board_set(MP_QSTR_PLUG_STATUS, ioexpander.pins->items[8 + 5]); + board_set(MP_QSTR_CHARGE_STATUS, ioexpander.pins->items[8 + 7]); + board_set(MP_QSTR_POWER_BUTTON, ioexpander.pins->items[8 + 3]); + board_set(MP_QSTR_ENC1_BUTTON, ioexpander.pins->items[5]); + board_set(MP_QSTR_ENC2_BUTTON, ioexpander.pins->items[4]); + board_set(MP_QSTR_HEADPHONE_DETECT, ioexpander.pins->items[8 + 1]); + board_set(MP_QSTR_PACTRL, ioexpander.pins->items[6]); + board_set(MP_QSTR_DISPLAY_CS, ioexpander.pins->items[0]); + board_set(MP_QSTR_DISPLAY_DC, ioexpander.pins->items[1]); + board_set(MP_QSTR_DISPLAY_RESET, ioexpander.pins->items[2]); + + board_set(MP_QSTR_LEVEL_CONVERTER, ioexpander.pins->items[3]); + board_set(MP_QSTR_LEVEL_POWER_ENABLE, ioexpander.pins->items[8 + 4]); + board_set(MP_QSTR_LEVEL_VINHOLD, ioexpander.pins->items[8 + 6]); + + board_set(MP_QSTR_TILT, ioexpander.pins->items[8 + 2]); + + // Only on some variants + board_set(MP_QSTR_RTC_INT, ioexpander.pins->items[7]); + + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander.pins->items[2]), true, DRIVE_MODE_PUSH_PULL); + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander.pins->items[3]), true, DRIVE_MODE_PUSH_PULL); + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander.pins->items[6]), true, DRIVE_MODE_PUSH_PULL); + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander.pins->items[14]), true, DRIVE_MODE_PUSH_PULL); + + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + ioexpander.pins->items[1], // DC + ioexpander.pins->items[0], // CS + ioexpander.pins->items[2], // RST + 25000000, // baudrate + 0, // polarity + 0 // phase + ); + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 240, // width (after rotation) + 240, // height (after rotation) + 0, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO26, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); + + digitalinout_result_t sd_enable_res = common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander.pins->items[12]), false, DRIVE_MODE_PUSH_PULL); + if (sd_enable_res != DIGITALINOUT_OK) { + mp_printf(&mp_plat_print, "Failed to initialize IOExpander. Skipping SD card\n"); + return; + } + + sdmmc.base.type = &sdioio_SDCard_type; + const mcu_pin_obj_t *data_pins[4] = {MP_ROM_PTR(&pin_GPIO2), MP_ROM_PTR(&pin_GPIO4), MP_ROM_PTR(&pin_GPIO12), MP_ROM_PTR(&pin_GPIO13)}; + common_hal_sdioio_sdcard_construct(&sdmmc, MP_ROM_PTR(&pin_GPIO14), MP_ROM_PTR(&pin_GPIO15), 4, data_pins, 25 * 1000000); + + fs_user_mount_t *vfs = &_sdcard_usermount; + vfs->base.type = &mp_fat_vfs_type; + vfs->fatfs.drv = vfs; + + // Initialise underlying block device + vfs->blockdev.block_size = FF_MIN_SS; // default, will be populated by call to MP_BLOCKDEV_IOCTL_BLOCK_SIZE + mp_vfs_blockdev_init(&vfs->blockdev, &sdmmc); + + // mount the block device so the VFS methods can be used + FRESULT res = f_mount(&vfs->fatfs); + if (res != FR_OK) { + common_hal_sdioio_sdcard_deinit(&sdmmc); + return; + } + common_hal_sdioio_sdcard_never_reset(&sdmmc); + + filesystem_set_concurrent_write_protection(vfs, true); + filesystem_set_writable_by_usb(vfs, false); + + mp_vfs_mount_t *sdcard_vfs = &_sdcard_vfs; + sdcard_vfs->str = "/sd"; + sdcard_vfs->len = 3; + sdcard_vfs->obj = MP_OBJ_FROM_PTR(&_sdcard_usermount); + sdcard_vfs->next = MP_STATE_VM(vfs_mount_table); + MP_STATE_VM(vfs_mount_table) = sdcard_vfs; +} diff --git a/ports/espressif/boards/yoto_mini_2024/board.h b/ports/espressif/boards/yoto_mini_2024/board.h new file mode 100644 index 0000000000000..1e40b62b047db --- /dev/null +++ b/ports/espressif/boards/yoto_mini_2024/board.h @@ -0,0 +1,3 @@ +#include "py/obj.h" + +extern void board_set(qstr key, mp_obj_t value); diff --git a/ports/espressif/boards/yoto_mini_2024/mpconfigboard.h b/ports/espressif/boards/yoto_mini_2024/mpconfigboard.h new file mode 100644 index 0000000000000..4fcc2afaae870 --- /dev/null +++ b/ports/espressif/boards/yoto_mini_2024/mpconfigboard.h @@ -0,0 +1,28 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Yoto Mini 2024" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define CIRCUITPY_MUTABLE_BOARD (1) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO25, .sda = &pin_GPIO21}} +#define CIRCUITPY_BOARD_I2C_SPEED (400000) + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO23, .mosi = &pin_GPIO22, .miso = NULL}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO17, .rx = &pin_GPIO16}} + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/yoto_mini_2024/mpconfigboard.mk b/ports/espressif/boards/yoto_mini_2024/mpconfigboard.mk new file mode 100644 index 0000000000000..356e7015a04fa --- /dev/null +++ b/ports/espressif/boards/yoto_mini_2024/mpconfigboard.mk @@ -0,0 +1,14 @@ +CIRCUITPY_CREATOR_ID = 0x40100000 +CIRCUITPY_CREATION_ID = 0x00320002 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 40m + +CIRCUITPY_I2CIOEXPANDER = 1 diff --git a/ports/espressif/boards/yoto_mini_2024/pins.c b/ports/espressif/boards/yoto_mini_2024/pins.c new file mode 100644 index 0000000000000..d4ff3b4863fb5 --- /dev/null +++ b/ports/espressif/boards/yoto_mini_2024/pins.c @@ -0,0 +1,79 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT +// + +#include "board.h" + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static mp_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_MUTABLE_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + { MP_ROM_QSTR(MP_QSTR_ENC1A), MP_OBJ_FROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_ENC1B), MP_OBJ_FROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_ENC2A), MP_OBJ_FROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_ENC2B), MP_OBJ_FROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_OBJ_FROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_OBJ_FROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY_SCK), MP_OBJ_FROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_MOSI), MP_OBJ_FROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_NFC_IN), MP_OBJ_FROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_OBJ_FROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_NFC_OUT), MP_OBJ_FROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_OBJ_FROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_OBJ_FROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_I2S_BIT_CLOCK), MP_OBJ_FROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_I2S_BCLK), MP_OBJ_FROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WORD_SELECT), MP_OBJ_FROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCLK), MP_OBJ_FROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DOUT), MP_OBJ_FROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_IOEXPANDER_INT), MP_OBJ_FROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_OBJ_FROM_PTR(&displays[0].display)}, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_OBJ_FROM_PTR(&board_i2c_obj) }, + + // Filled in by board_init() + { MP_ROM_QSTR(MP_QSTR_IOEXPANDER), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_PLUG_STATUS), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_CHARGE_STATUS), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_POWER_BUTTON), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_ENC1_BUTTON), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_ENC2_BUTTON), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_HEADPHONE_DETECT), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_PACTRL), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_CS), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_DC), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_RESET), mp_const_none }, + + { MP_ROM_QSTR(MP_QSTR_LEVEL_CONVERTER), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_LEVEL_POWER_ENABLE), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_LEVEL_VINHOLD), mp_const_none }, + + { MP_ROM_QSTR(MP_QSTR_TILT), mp_const_none }, + + // Only on some variants + { MP_ROM_QSTR(MP_QSTR_RTC_INT), mp_const_none }, + +}; +MP_DEFINE_MUTABLE_DICT(board_module_globals, board_module_globals_table); + +void board_set(qstr q, mp_obj_t value) { + mp_obj_t key = MP_OBJ_NEW_QSTR(q); + for (size_t i = 0; i < MP_ARRAY_SIZE(board_module_globals_table); i++) { + if (board_module_globals_table[i].key == key) { + board_module_globals_table[i].value = value; + return; + } + } +} diff --git a/ports/espressif/boards/yoto_mini_2024/sdkconfig b/ports/espressif/boards/yoto_mini_2024/sdkconfig new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/ports/espressif/boards/yoto_player_v3/board.c b/ports/espressif/boards/yoto_player_v3/board.c new file mode 100644 index 0000000000000..fd6ee40b9f32e --- /dev/null +++ b/ports/espressif/boards/yoto_player_v3/board.c @@ -0,0 +1,148 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "board.h" + +#include "supervisor/board.h" + +#include "extmod/vfs_fat.h" + +#include "py/mpstate.h" + +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/i2cioexpander/IOExpander.h" +#include "shared-bindings/i2cioexpander/IOPin.h" +#include "shared-bindings/sdioio/SDCard.h" + +#include "supervisor/filesystem.h" + +static sdioio_sdcard_obj_t sdmmc; +static mp_vfs_mount_t _sdcard_vfs; +static fs_user_mount_t _sdcard_usermount; +static i2cioexpander_ioexpander_obj_t ioexpander0; // First chip (p0/p1) +static i2cioexpander_ioexpander_obj_t ioexpander1; // Second chip (p2/p3) + +void board_init(void) { + // Wait for everything to start + mp_hal_delay_ms(300); + + // Initialize the board's peripherals here. + busio_i2c_obj_t *i2c = MP_OBJ_TO_PTR(common_hal_board_create_i2c(0)); + + // Initialize the IOExpanders + // V3/V3-E uses two PI4IOE5V6416 chips (16 pins each) + // First chip (0x20): p0 (pins 0-7), p1 (pins 8-15) + ioexpander0.base.type = &i2cioexpander_ioexpander_type; + common_hal_i2cioexpander_ioexpander_construct( + &ioexpander0, + MP_OBJ_FROM_PTR(i2c), + 0x20, // I2C address for first chip + 16, // Number of pins + 2, // Output register + 0, // Input register + 6); // Direction register + + // Second chip (0x21): p2 (pins 0-7), p3 (pins 8-15) + ioexpander1.base.type = &i2cioexpander_ioexpander_type; + common_hal_i2cioexpander_ioexpander_construct( + &ioexpander1, + MP_OBJ_FROM_PTR(i2c), + 0x21, // I2C address for second chip + 16, // Number of pins + 2, // Output register + 0, // Input register + 6); // Direction register + + board_set(MP_QSTR_IOEXPANDER0, MP_OBJ_FROM_PTR(&ioexpander0)); + board_set(MP_QSTR_IOEXPANDER1, MP_OBJ_FROM_PTR(&ioexpander1)); + + // Battery and charging (from first chip - p0/p1) + board_set(MP_QSTR_BATTERY_ALERT, ioexpander0.pins->items[6]); // IOX.0.6 + board_set(MP_QSTR_QI_STATUS, ioexpander0.pins->items[7]); // IOX.0.7 + board_set(MP_QSTR_QI_I2C_INT, ioexpander0.pins->items[0]); // IOX.0.0 + board_set(MP_QSTR_USB_STATUS, ioexpander0.pins->items[8 + 0]); // IOX.1.0 + board_set(MP_QSTR_CHARGE_STATUS, ioexpander0.pins->items[8 + 4]); // IOX.1.4 + + // Buttons (from first chip - p0/p1) + board_set(MP_QSTR_POWER_BUTTON, ioexpander0.pins->items[8 + 3]); // IOX.1.3 + board_set(MP_QSTR_ENC1_BUTTON, ioexpander0.pins->items[5]); // IOX.0.5 + board_set(MP_QSTR_ENC2_BUTTON, ioexpander0.pins->items[4]); // IOX.0.4 + + // Audio (from first chip - p0/p1 and second chip - p2/p3) + board_set(MP_QSTR_HEADPHONE_DETECT, ioexpander0.pins->items[8 + 1]); // IOX.1.1 + board_set(MP_QSTR_PACTRL, ioexpander1.pins->items[4]); // IOX.2.4 + + // Display - V3/V3-E uses ht16d35x with 4 CS lines (from second chip - p2) + board_set(MP_QSTR_DISPLAY_CS0, ioexpander1.pins->items[0]); // IOX.2.0 + board_set(MP_QSTR_DISPLAY_CS1, ioexpander1.pins->items[1]); // IOX.2.1 + board_set(MP_QSTR_DISPLAY_CS2, ioexpander1.pins->items[2]); // IOX.2.2 + board_set(MP_QSTR_DISPLAY_CS3, ioexpander1.pins->items[3]); // IOX.2.3 + + // Power control (from second chip - p2/p3) + board_set(MP_QSTR_LEVEL_CONVERTER, ioexpander1.pins->items[8 + 0]); // IOX.3.0 + board_set(MP_QSTR_LEVEL_POWER_ENABLE, ioexpander1.pins->items[5]); // IOX.2.5 + board_set(MP_QSTR_LEVEL_VINHOLD, ioexpander1.pins->items[8 + 1]); // IOX.3.1 + board_set(MP_QSTR_LEVEL_VOUTEN, ioexpander1.pins->items[8 + 3]); // IOX.3.3 + + // Sensors (from first chip - p0/p1) + board_set(MP_QSTR_TILT, ioexpander0.pins->items[8 + 2]); // IOX.1.2 + board_set(MP_QSTR_RTC_INT, ioexpander0.pins->items[1]); // IOX.0.1 + + // Qi charging control (V3-E, from second chip - p2/p3) + board_set(MP_QSTR_QI_CHARGE_ENABLE, ioexpander1.pins->items[6]); // IOX.2.6 + board_set(MP_QSTR_USB_CHARGE_ENABLE, ioexpander1.pins->items[7]); // IOX.2.7 + board_set(MP_QSTR_QI_ENABLE_5W, ioexpander1.pins->items[8 + 5]); // IOX.3.5 + + // Output pin 3 high. Not clear why. + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander0.pins->items[3]), true, DRIVE_MODE_PUSH_PULL); + + // Initialize output pins + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[0]), true, DRIVE_MODE_PUSH_PULL); // DISPLAY_CS0 (IOX.2.0) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[1]), true, DRIVE_MODE_PUSH_PULL); // DISPLAY_CS1 (IOX.2.1) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[2]), true, DRIVE_MODE_PUSH_PULL); // DISPLAY_CS2 (IOX.2.2) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[3]), true, DRIVE_MODE_PUSH_PULL); // DISPLAY_CS3 (IOX.2.3) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[4]), true, DRIVE_MODE_PUSH_PULL); // PACTRL (IOX.2.4) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[5]), false, DRIVE_MODE_PUSH_PULL); // LEVEL_POWER_ENABLE (IOX.2.5) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[6]), true, DRIVE_MODE_PUSH_PULL); // QI_CHARGE_ENABLE + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[7]), false, DRIVE_MODE_PUSH_PULL); // USB_CHARGE_ENABLE + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[8 + 0]), true, DRIVE_MODE_PUSH_PULL); // LEVEL_CONVERTER (IOX.3.0) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[8 + 1]), true, DRIVE_MODE_PUSH_PULL); // VINHOLD (IOX.3.1) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[8 + 3]), true, DRIVE_MODE_PUSH_PULL); // VOUTEN (IOX.3.3) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[8 + 5]), false, DRIVE_MODE_PUSH_PULL); // QI_ENABLE_5W (IOX.3.5) + + // Initialize SD card + // V3/V3-E uses single-line SD (sd1 mode), not 4-line (sd4 mode) like Mini + sdmmc.base.type = &sdioio_SDCard_type; + const mcu_pin_obj_t *data_pins[1] = {MP_ROM_PTR(&pin_GPIO2)}; + common_hal_sdioio_sdcard_construct(&sdmmc, MP_ROM_PTR(&pin_GPIO14), MP_ROM_PTR(&pin_GPIO15), 1, data_pins, 25 * 1000000); + + fs_user_mount_t *vfs = &_sdcard_usermount; + vfs->base.type = &mp_fat_vfs_type; + vfs->fatfs.drv = vfs; + + // Initialise underlying block device + vfs->blockdev.block_size = FF_MIN_SS; // default, will be populated by call to MP_BLOCKDEV_IOCTL_BLOCK_SIZE + mp_vfs_blockdev_init(&vfs->blockdev, &sdmmc); + + // mount the block device so the VFS methods can be used + FRESULT res = f_mount(&vfs->fatfs); + if (res != FR_OK) { + common_hal_sdioio_sdcard_deinit(&sdmmc); + return; + } + common_hal_sdioio_sdcard_never_reset(&sdmmc); + + filesystem_set_concurrent_write_protection(vfs, true); + filesystem_set_writable_by_usb(vfs, false); + + mp_vfs_mount_t *sdcard_vfs = &_sdcard_vfs; + sdcard_vfs->str = "/sd"; + sdcard_vfs->len = 3; + sdcard_vfs->obj = MP_OBJ_FROM_PTR(&_sdcard_usermount); + sdcard_vfs->next = MP_STATE_VM(vfs_mount_table); + MP_STATE_VM(vfs_mount_table) = sdcard_vfs; +} diff --git a/ports/espressif/boards/yoto_player_v3/board.h b/ports/espressif/boards/yoto_player_v3/board.h new file mode 100644 index 0000000000000..1e40b62b047db --- /dev/null +++ b/ports/espressif/boards/yoto_player_v3/board.h @@ -0,0 +1,3 @@ +#include "py/obj.h" + +extern void board_set(qstr key, mp_obj_t value); diff --git a/ports/espressif/boards/yoto_player_v3/mpconfigboard.h b/ports/espressif/boards/yoto_player_v3/mpconfigboard.h new file mode 100644 index 0000000000000..1660c4881f98a --- /dev/null +++ b/ports/espressif/boards/yoto_player_v3/mpconfigboard.h @@ -0,0 +1,28 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Yoto Player V3" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define CIRCUITPY_MUTABLE_BOARD (1) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO25, .sda = &pin_GPIO21}} +#define CIRCUITPY_BOARD_I2C_SPEED (400000) + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO23, .mosi = &pin_GPIO22, .miso = &pin_GPIO26}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO17, .rx = &pin_GPIO16}} + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/yoto_player_v3/mpconfigboard.mk b/ports/espressif/boards/yoto_player_v3/mpconfigboard.mk new file mode 100644 index 0000000000000..a1b940316c40a --- /dev/null +++ b/ports/espressif/boards/yoto_player_v3/mpconfigboard.mk @@ -0,0 +1,14 @@ +CIRCUITPY_CREATOR_ID = 0x40100000 +CIRCUITPY_CREATION_ID = 0x00320001 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 40m + +CIRCUITPY_I2CIOEXPANDER = 1 diff --git a/ports/espressif/boards/yoto_player_v3/pins.c b/ports/espressif/boards/yoto_player_v3/pins.c new file mode 100644 index 0000000000000..0862a020fdfce --- /dev/null +++ b/ports/espressif/boards/yoto_player_v3/pins.c @@ -0,0 +1,104 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT +// + +#include "board.h" + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static mp_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_MUTABLE_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + // Encoder 1: V3-E uses GPIO26/13, V3 uses GPIO35/13 + { MP_ROM_QSTR(MP_QSTR_ENC1A), MP_OBJ_FROM_PTR(&pin_GPIO26) }, // V3-E: GPIO26, V3: GPIO35 + { MP_ROM_QSTR(MP_QSTR_ENC1A_V3), MP_OBJ_FROM_PTR(&pin_GPIO35) }, // V3-E: GPIO26, V3: GPIO35 + { MP_ROM_QSTR(MP_QSTR_ENC1B), MP_OBJ_FROM_PTR(&pin_GPIO13) }, + + // Encoder 2: Both V3 and V3-E use GPIO27/4 + { MP_ROM_QSTR(MP_QSTR_ENC2A), MP_OBJ_FROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_ENC2B), MP_OBJ_FROM_PTR(&pin_GPIO4) }, + + // Light sensor (V3/V3-E) + { MP_ROM_QSTR(MP_QSTR_LIGHT_SENSOR), MP_OBJ_FROM_PTR(&pin_GPIO36) }, + + // Temperature sensors (V3/V3-E) + { MP_ROM_QSTR(MP_QSTR_TEMP_SENSOR), MP_OBJ_FROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_QI_RX_TEMP_SENSOR), MP_OBJ_FROM_PTR(&pin_GPIO35) }, // V3-E only + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_OBJ_FROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_OBJ_FROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY_SCK), MP_OBJ_FROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_OBJ_FROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_MOSI), MP_OBJ_FROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_OBJ_FROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_MISO), MP_OBJ_FROM_PTR(&pin_GPIO26) }, // V3/V3-E have MISO + { MP_ROM_QSTR(MP_QSTR_MISO), MP_OBJ_FROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_NFC_IN), MP_OBJ_FROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_OBJ_FROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_NFC_OUT), MP_OBJ_FROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_OBJ_FROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_OBJ_FROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_I2S_BIT_CLOCK), MP_OBJ_FROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_I2S_BCLK), MP_OBJ_FROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WORD_SELECT), MP_OBJ_FROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCLK), MP_OBJ_FROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DOUT), MP_OBJ_FROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_IOEXPANDER_INT), MP_OBJ_FROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_OBJ_FROM_PTR(&board_i2c_obj) }, + + // Filled in by board_init() + { MP_ROM_QSTR(MP_QSTR_IOEXPANDER0), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_IOEXPANDER1), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_BATTERY_ALERT), mp_const_none }, // IOX.0.6 + { MP_ROM_QSTR(MP_QSTR_QI_STATUS), mp_const_none }, // IOX.0.7 + { MP_ROM_QSTR(MP_QSTR_USB_STATUS), mp_const_none }, // IOX.1.0 + { MP_ROM_QSTR(MP_QSTR_CHARGE_STATUS), mp_const_none }, // IOX.1.4 + { MP_ROM_QSTR(MP_QSTR_POWER_BUTTON), mp_const_none }, // IOX.1.3 + { MP_ROM_QSTR(MP_QSTR_ENC1_BUTTON), mp_const_none }, // IOX.0.5 + { MP_ROM_QSTR(MP_QSTR_ENC2_BUTTON), mp_const_none }, // IOX.0.4 + { MP_ROM_QSTR(MP_QSTR_HEADPHONE_DETECT), mp_const_none }, // IOX.1.1 + { MP_ROM_QSTR(MP_QSTR_PACTRL), mp_const_none }, // IOX.2.4 + // V3/V3-E use ht16d35x display with 4 CS lines + { MP_ROM_QSTR(MP_QSTR_DISPLAY_CS0), mp_const_none }, // IOX.2.0 + { MP_ROM_QSTR(MP_QSTR_DISPLAY_CS1), mp_const_none }, // IOX.2.1 + { MP_ROM_QSTR(MP_QSTR_DISPLAY_CS2), mp_const_none }, // IOX.2.2 + { MP_ROM_QSTR(MP_QSTR_DISPLAY_CS3), mp_const_none }, // IOX.2.3 + + { MP_ROM_QSTR(MP_QSTR_LEVEL_CONVERTER), mp_const_none }, // IOX.3.0 + { MP_ROM_QSTR(MP_QSTR_LEVEL_POWER_ENABLE), mp_const_none }, // IOX.2.5 + { MP_ROM_QSTR(MP_QSTR_LEVEL_VINHOLD), mp_const_none }, // IOX.3.1 + { MP_ROM_QSTR(MP_QSTR_LEVEL_VOUTEN), mp_const_none }, // IOX.3.3 + + { MP_ROM_QSTR(MP_QSTR_TILT), mp_const_none }, // IOX.1.2 + { MP_ROM_QSTR(MP_QSTR_RTC_INT), mp_const_none }, // IOX.0.1 + + // Qi charging pins (V3-E) + { MP_ROM_QSTR(MP_QSTR_QI_CHARGE_ENABLE), mp_const_none }, // IOX.2.6 + { MP_ROM_QSTR(MP_QSTR_QI_ENABLE_5W), mp_const_none }, // IOX.3.5 + { MP_ROM_QSTR(MP_QSTR_QI_I2C_INT), mp_const_none }, // IOX.0.0 + + // USB-C charging pins (V3/V3-E) + { MP_ROM_QSTR(MP_QSTR_USB_CHARGE_ENABLE), mp_const_none }, // IOX.2.7 + +}; +MP_DEFINE_MUTABLE_DICT(board_module_globals, board_module_globals_table); + +void board_set(qstr q, mp_obj_t value) { + mp_obj_t key = MP_OBJ_NEW_QSTR(q); + for (size_t i = 0; i < MP_ARRAY_SIZE(board_module_globals_table); i++) { + if (board_module_globals_table[i].key == key) { + board_module_globals_table[i].value = value; + return; + } + } +} diff --git a/ports/espressif/boards/yoto_player_v3/sdkconfig b/ports/espressif/boards/yoto_player_v3/sdkconfig new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/ports/espressif/common-hal/_bleio/Adapter.c b/ports/espressif/common-hal/_bleio/Adapter.c index f604e02c20007..352d01372a91c 100644 --- a/ports/espressif/common-hal/_bleio/Adapter.c +++ b/ports/espressif/common-hal/_bleio/Adapter.c @@ -384,7 +384,7 @@ static int _connect_event(struct ble_gap_event *event, void *self_in) { // connection and need a new tuple. self->connection_objs = NULL; } else { - // The loop waiting for the connection to be comnpleted will stop when _connection_status changes. + // The loop waiting for the connection to be completed will stop when _connection_status changes. _connection_status = -event->connect.status; } break; diff --git a/ports/espressif/common-hal/busio/I2C.c b/ports/espressif/common-hal/busio/I2C.c index 9ef3877ea92ed..723fa7d740000 100644 --- a/ports/espressif/common-hal/busio/I2C.c +++ b/ports/espressif/common-hal/busio/I2C.c @@ -169,16 +169,16 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -static uint8_t convert_esp_err(esp_err_t result) { +static mp_errno_t convert_esp_err(esp_err_t result) { switch (result) { case ESP_OK: return 0; case ESP_FAIL: - return MP_ENODEV; + return -MP_ENODEV; case ESP_ERR_TIMEOUT: - return MP_ETIMEDOUT; + return -MP_ETIMEDOUT; default: - return MP_EIO; + return -MP_EIO; } } @@ -189,7 +189,7 @@ static size_t _transaction_duration_ms(size_t frequency, size_t len) { return (len + 1) / bytes_per_ms + 1000; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { +mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { i2c_device_config_t dev_config = { .dev_addr_length = I2C_ADDR_BIT_LEN_7, .device_address = addr, @@ -202,7 +202,7 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const u return convert_esp_err(result); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { +mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { i2c_device_config_t dev_config = { .dev_addr_length = I2C_ADDR_BIT_LEN_7, .device_address = addr, @@ -215,7 +215,7 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t return convert_esp_err(result); } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { i2c_device_config_t dev_config = { .dev_addr_length = I2C_ADDR_BIT_LEN_7, diff --git a/ports/espressif/common-hal/pulseio/PulseOut.c b/ports/espressif/common-hal/pulseio/PulseOut.c index 68cb64b5e60e1..8995043b8259c 100644 --- a/ports/espressif/common-hal/pulseio/PulseOut.c +++ b/ports/espressif/common-hal/pulseio/PulseOut.c @@ -69,7 +69,7 @@ void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t *self, uint16_t *pu // Circuitpython allows 16 bit pulse values, while ESP32 only allows 15 bits // Thus, we use entire items for one pulse, rather than switching inside each item for (size_t i = 0; i < length; i++) { - // Setting the RMT duration to 0 has undefined behavior, so avoid that pre-emptively. + // Setting the RMT duration to 0 has undefined behavior, so avoid that preemptively. if (pulses[i] == 0) { continue; } diff --git a/ports/espressif/common-hal/sdioio/SDCard.c b/ports/espressif/common-hal/sdioio/SDCard.c index 87ba32f802095..f774561816258 100644 --- a/ports/espressif/common-hal/sdioio/SDCard.c +++ b/ports/espressif/common-hal/sdioio/SDCard.c @@ -10,6 +10,7 @@ #include "driver/sdmmc_host.h" #include "ports/espressif/esp-idf/components/sdmmc/include/sdmmc_cmd.h" +#include "extmod/vfs.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/util.h" #include "shared-bindings/sdioio/SDCard.h" @@ -168,32 +169,73 @@ static void check_whole_block(mp_buffer_info_t *bufinfo, int sector_size) { } } -int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { - common_hal_sdioio_sdcard_check_for_deinit(self); - check_whole_block(bufinfo, self->card.csd.sector_size); - esp_err_t err; - ESP_LOGI(TAG, "in common_hal_sdioio_sdcard_writeblocks"); - // err = sdmmc_io_write_blocks(&self->card, 1, start_block, bufinfo->buf, bufinfo->len); - err = sdmmc_write_sectors(&self->card, bufinfo->buf, start_block, bufinfo->len / self->card.csd.sector_size); +mp_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + ESP_LOGI(TAG, "in sdioio_sdcard_writeblocks"); + esp_err_t err = sdmmc_write_sectors(&self->card, buf, start_block, num_blocks); if (err != ESP_OK) { ESP_LOGW(TAG, "Failed to write blocks with err 0x%X", err); + return -MP_EIO; } return 0; } -int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +mp_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { common_hal_sdioio_sdcard_check_for_deinit(self); check_whole_block(bufinfo, self->card.csd.sector_size); - esp_err_t err; - ESP_LOGI(TAG, "in common_hal_sdioio_sdcard_readblocks"); - // err = sdmmc_io_read_blocks(&self->card, 1, start_block, bufinfo->buf, bufinfo->len); - err = sdmmc_read_sectors(&self->card, bufinfo->buf, start_block, bufinfo->len / self->card.csd.sector_size); + + uint32_t num_blocks = bufinfo->len / self->card.csd.sector_size; + return sdioio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +mp_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + ESP_LOGI(TAG, "in sdioio_sdcard_readblocks"); + esp_err_t err = sdmmc_read_sectors(&self->card, buf, start_block, num_blocks); if (err != ESP_OK) { ESP_LOGW(TAG, "Failed to read blocks with err 0x%X", err); + return -MP_EIO; } return 0; } +mp_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { + common_hal_sdioio_sdcard_check_for_deinit(self); + check_whole_block(bufinfo, self->card.csd.sector_size); + + uint32_t num_blocks = bufinfo->len / self->card.csd.sector_size; + return sdioio_sdcard_readblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, + mp_int_t *out_value) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + *out_value = 0; + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_DEINIT: + case MP_BLOCKDEV_IOCTL_SYNC: + // SDIO operations are synchronous, no action needed + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + *out_value = common_hal_sdioio_sdcard_get_count(self); + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + *out_value = 512; // SD cards use 512-byte sectors + return true; + + default: + return false; // Unsupported command + } +} + bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t frequency, uint8_t bits) { return true; } diff --git a/ports/espressif/mpconfigport.mk b/ports/espressif/mpconfigport.mk index a967b8a4f15f5..67f8ca2987bd8 100644 --- a/ports/espressif/mpconfigport.mk +++ b/ports/espressif/mpconfigport.mk @@ -103,9 +103,6 @@ ifeq ($(IDF_TARGET),esp32) CIRCUITPY_ALARM_TOUCH = 1 CIRCUITPY_RGBMATRIX = 0 -# SDMMC not supported yet -CIRCUITPY_SDIOIO = 0 - # Has no USB CIRCUITPY_USB_DEVICE = 0 diff --git a/ports/espressif/tools/update_sdkconfig.py b/ports/espressif/tools/update_sdkconfig.py index 8837d84321b30..209b976b881e9 100644 --- a/ports/espressif/tools/update_sdkconfig.py +++ b/ports/espressif/tools/update_sdkconfig.py @@ -321,7 +321,7 @@ def update(debug, board, update_all): # noqa: C901: too complex if print_debug: print(" " * len(current_group), i, config_string.strip()) - # Some files are `rsource`d into another kconfig with $IDF_TARGET as + # Some files are `rsource`d into another kconfig with $IDF_TARGET as # codespell:ignore rsource # part of the path. kconfiglib doesn't show this as a reference so # we have to look ourselves. target_reference = target in item.name_and_loc diff --git a/ports/mimxrt10xx/common-hal/busio/I2C.c b/ports/mimxrt10xx/common-hal/busio/I2C.c index 132b3083212a1..38777f2c9038c 100644 --- a/ports/mimxrt10xx/common-hal/busio/I2C.c +++ b/ports/mimxrt10xx/common-hal/busio/I2C.c @@ -201,7 +201,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +static mp_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { lpi2c_master_transfer_t xfer = { 0 }; @@ -215,15 +215,15 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, return 0; } - return MP_EIO; + return -MP_EIO; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { lpi2c_master_transfer_t xfer = { 0 }; @@ -237,12 +237,12 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, return 0; } - return MP_EIO; + return -MP_EIO; } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } diff --git a/ports/nordic/boards/clue_nrf52840_express/board.c b/ports/nordic/boards/clue_nrf52840_express/board.c index e2cd8a324bab7..0b331b63a9612 100644 --- a/ports/nordic/boards/clue_nrf52840_express/board.c +++ b/ports/nordic/boards/clue_nrf52840_express/board.c @@ -34,9 +34,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_P0_13, // TFT_DC Command or data - &pin_P0_12, // TFT_CS Chip select - &pin_P1_03, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_P0_13), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_P0_12), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_P1_03), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/nordic/boards/hiibot_bluefi/board.c b/ports/nordic/boards/hiibot_bluefi/board.c index 73430d675eb2d..7a681140ddbc4 100644 --- a/ports/nordic/boards/hiibot_bluefi/board.c +++ b/ports/nordic/boards/hiibot_bluefi/board.c @@ -34,9 +34,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_P0_27, // TFT_DC Command or data - &pin_P0_05, // TFT_CS Chip select - NULL, // no TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_P0_27), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_P0_05), // TFT_CS Chip select + MP_OBJ_NULL, // no TFT_RST Reset // &pin_P1_14, // TFT_RST Reset 60000000, // Baudrate 0, // Polarity diff --git a/ports/nordic/boards/makerdiary_nrf52840_m2_devkit/board.c b/ports/nordic/boards/makerdiary_nrf52840_m2_devkit/board.c index 64199b98009f0..4f9c051478ac3 100644 --- a/ports/nordic/boards/makerdiary_nrf52840_m2_devkit/board.c +++ b/ports/nordic/boards/makerdiary_nrf52840_m2_devkit/board.c @@ -35,9 +35,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_P0_08, // TFT_DC Command or data - &pin_P0_06, // TFT_CS Chip select - &pin_P1_09, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_P0_08), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_P0_06), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_P1_09), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/nordic/boards/ohs2020_badge/board.c b/ports/nordic/boards/ohs2020_badge/board.c index ea716006cb4bf..d16d99473f014 100644 --- a/ports/nordic/boards/ohs2020_badge/board.c +++ b/ports/nordic/boards/ohs2020_badge/board.c @@ -34,9 +34,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_P0_08, // TFT_DC Command or data - &pin_P0_14, // TFT_CS Chip select - &pin_P0_13, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_P0_08), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_P0_14), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_P0_13), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/nordic/common-hal/busio/I2C.c b/ports/nordic/common-hal/busio/I2C.c index 3558fad165ba6..904d35cae3d0b 100644 --- a/ports/nordic/common-hal/busio/I2C.c +++ b/ports/nordic/common-hal/busio/I2C.c @@ -47,18 +47,18 @@ void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { never_reset_pin_number(self->sda_pin_number); } -static uint8_t twi_error_to_mp(const nrfx_err_t err) { +static mp_errno_t twi_error_to_mp(const nrfx_err_t err) { switch (err) { case NRFX_ERROR_DRV_TWI_ERR_ANACK: - return MP_ENODEV; + return -MP_ENODEV; case NRFX_ERROR_BUSY: - return MP_EBUSY; + return -MP_EBUSY; case NRFX_ERROR_INVALID_ADDR: case NRFX_ERROR_DRV_TWI_ERR_DNACK: case NRFX_ERROR_DRV_TWI_ERR_OVERRUN: - return MP_EIO; + return -MP_EIO; case NRFX_ERROR_TIMEOUT: - return MP_ETIMEDOUT; + return -MP_ETIMEDOUT; default: break; } @@ -258,9 +258,9 @@ static nrfx_err_t _twim_xfer_with_timeout(busio_i2c_obj_t *self, nrfx_twim_xfer_ } } -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) { +static mp_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) { if (len == 0) { - return common_hal_busio_i2c_probe(self, addr) ? 0 : MP_ENODEV; + return common_hal_busio_i2c_probe(self, addr) ? 0 : -MP_ENODEV; } nrfx_err_t err = NRFX_SUCCESS; @@ -286,11 +286,11 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, return twi_error_to_mp(err); } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { +mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { +mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { if (len == 0) { return 0; } @@ -317,9 +317,9 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t return twi_error_to_mp(err); } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } diff --git a/ports/raspberrypi/boards/adafruit_floppsy_rp2040/board.c b/ports/raspberrypi/boards/adafruit_floppsy_rp2040/board.c index 5056a4d9c7a15..882bc9a1a9e0b 100644 --- a/ports/raspberrypi/boards/adafruit_floppsy_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_floppsy_rp2040/board.c @@ -34,9 +34,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - CIRCUITPY_BOARD_TFT_DC, - CIRCUITPY_BOARD_TFT_CS, - NULL, // TFT_RESET Reset + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_TFT_DC), + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_TFT_CS), + MP_OBJ_NULL, // TFT_RESET Reset 40000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c b/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c index 673d9303d6b55..ec37b398e229f 100644 --- a/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c @@ -29,7 +29,7 @@ uint8_t display_init_sequence[] = { 0xda, 1, 0x12, // com pins 0x81, 1, 0xff, // contrast 255 0xd9, 1, 0x1f, // pre/dis-charge 2DCLKs/2CLKs - 0xdb, 1, 0x20, // VCOM deslect 0.770 + 0xdb, 1, 0x20, // VCOM select 0.770 0x20, 1, 0x20, 0x33, 0, // VPP 9V 0xa6, 0, // not inverted @@ -46,9 +46,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO24, // Command or data - &pin_GPIO22, // Chip select - &pin_GPIO23, // Reset + MP_OBJ_FROM_PTR(&pin_GPIO24), // Command or data + MP_OBJ_FROM_PTR(&pin_GPIO22), // Chip select + MP_OBJ_FROM_PTR(&pin_GPIO23), // Reset 10000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c b/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c index 35e128627bc0b..f091c4b05a8ad 100644 --- a/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c +++ b/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c @@ -212,9 +212,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO11, // DEFAULT_SPI_BUS_DC, // EPD_DC Command or data - &pin_GPIO13, // DEFAULT_SPI_BUS_CS, // EPD_CS Chip select - &pin_GPIO10, // DEFAULT_SPI_BUS_RESET, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO11), // DEFAULT_SPI_BUS_DC, // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO13), // DEFAULT_SPI_BUS_CS, // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO10), // DEFAULT_SPI_BUS_RESET, // EPD_RST Reset 1000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/hack_club_sprig/board.c b/ports/raspberrypi/boards/hack_club_sprig/board.c index 40711c554452e..94c5a7c5be9ec 100644 --- a/ports/raspberrypi/boards/hack_club_sprig/board.c +++ b/ports/raspberrypi/boards/hack_club_sprig/board.c @@ -62,9 +62,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - CIRCUITPY_BOARD_TFT_DC, - CIRCUITPY_BOARD_TFT_CS, - CIRCUITPY_BOARD_TFT_RESET, + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_TFT_DC), + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_TFT_CS), + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_TFT_RESET), 30000000, 0, 0); diff --git a/ports/raspberrypi/boards/heiafr_picomo_v2/board.c b/ports/raspberrypi/boards/heiafr_picomo_v2/board.c index 8c60341489fa1..3824c5959f5ee 100644 --- a/ports/raspberrypi/boards/heiafr_picomo_v2/board.c +++ b/ports/raspberrypi/boards/heiafr_picomo_v2/board.c @@ -51,9 +51,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO16, // TFT_DC Command or data - &pin_GPIO17, // TFT_CS Chip select - NULL, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO16), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO17), // TFT_CS Chip select + MP_OBJ_NULL, // TFT_RST Reset 62500000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/heiafr_picomo_v3/board.c b/ports/raspberrypi/boards/heiafr_picomo_v3/board.c index 8c60341489fa1..3824c5959f5ee 100644 --- a/ports/raspberrypi/boards/heiafr_picomo_v3/board.c +++ b/ports/raspberrypi/boards/heiafr_picomo_v3/board.c @@ -51,9 +51,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO16, // TFT_DC Command or data - &pin_GPIO17, // TFT_CS Chip select - NULL, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO16), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO17), // TFT_CS Chip select + MP_OBJ_NULL, // TFT_RST Reset 62500000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/lilygo_t_display_rp2040/board.c b/ports/raspberrypi/boards/lilygo_t_display_rp2040/board.c index 78cc912130e79..67e63daed1d67 100644 --- a/ports/raspberrypi/boards/lilygo_t_display_rp2040/board.c +++ b/ports/raspberrypi/boards/lilygo_t_display_rp2040/board.c @@ -63,9 +63,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO1, // DC - &pin_GPIO5, // CS - NULL, // RST (Reset pin tie to 0, do not set here) + MP_OBJ_FROM_PTR(&pin_GPIO1), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_NULL, // RST (Reset pin tie to 0, do not set here) 40000000, // baudrate 1, // polarity 0 // phase diff --git a/ports/raspberrypi/boards/pajenicko_picopad/board.c b/ports/raspberrypi/boards/pajenicko_picopad/board.c index 0ca13b3ec2e1b..d8f9392262383 100644 --- a/ports/raspberrypi/boards/pajenicko_picopad/board.c +++ b/ports/raspberrypi/boards/pajenicko_picopad/board.c @@ -51,9 +51,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO17, // TFT_DC Command or data - &pin_GPIO21, // TFT_CS Chip select - &pin_GPIO20, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO17), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO21), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO20), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/pimoroni_badger2040/board.c b/ports/raspberrypi/boards/pimoroni_badger2040/board.c index 07cc512b9a58e..80eddb49e1330 100644 --- a/ports/raspberrypi/boards/pimoroni_badger2040/board.c +++ b/ports/raspberrypi/boards/pimoroni_badger2040/board.c @@ -263,9 +263,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO20, // EPD_DC Command or data - &pin_GPIO17, // EPD_CS Chip select - &pin_GPIO21, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO20), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO17), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO21), // EPD_RST Reset 1200000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/pimoroni_badger2040w/board.c b/ports/raspberrypi/boards/pimoroni_badger2040w/board.c index b992bcd6a1e37..ef5da7ceabcb7 100644 --- a/ports/raspberrypi/boards/pimoroni_badger2040w/board.c +++ b/ports/raspberrypi/boards/pimoroni_badger2040w/board.c @@ -263,9 +263,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO20, // EPD_DC Command or data - &pin_GPIO17, // EPD_CS Chip select - &pin_GPIO21, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO20), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO17), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO21), // EPD_RST Reset 1200000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c index 4bf7518c6a8df..58c54334d59af 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c @@ -58,9 +58,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO28, // EPD_DC Command or data - &pin_GPIO17, // EPD_CS Chip select - &pin_GPIO27, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO28), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO17), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO27), // EPD_RST Reset 1000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c index 763a91a255569..fc6ca67f3ae65 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c @@ -117,9 +117,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO28, // EPD_DC Command or data - &pin_GPIO17, // EPD_CS Chip select - &pin_GPIO27, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO28), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO17), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO27), // EPD_RST Reset 1000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/pimoroni_picosystem/board.c b/ports/raspberrypi/boards/pimoroni_picosystem/board.c index 40756b56426e4..e5956e43ed110 100644 --- a/ports/raspberrypi/boards/pimoroni_picosystem/board.c +++ b/ports/raspberrypi/boards/pimoroni_picosystem/board.c @@ -51,9 +51,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO9, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select - &pin_GPIO4, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO9), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO4), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/ugame22/board.c b/ports/raspberrypi/boards/ugame22/board.c index 6b8152b14eedf..ed17a13ebc105 100644 --- a/ports/raspberrypi/boards/ugame22/board.c +++ b/ports/raspberrypi/boards/ugame22/board.c @@ -52,9 +52,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO4, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select - &pin_GPIO1, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO4), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO1), // TFT_RST Reset 80000000L, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/waveshare_rp2040_geek/board.c b/ports/raspberrypi/boards/waveshare_rp2040_geek/board.c index 71269f0d1852f..431840fb0c5c1 100644 --- a/ports/raspberrypi/boards/waveshare_rp2040_geek/board.c +++ b/ports/raspberrypi/boards/waveshare_rp2040_geek/board.c @@ -37,9 +37,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO8, // TFT_DC - &pin_GPIO9, // TFT_CS - &pin_GPIO12, // TFT_RST + MP_OBJ_FROM_PTR(&pin_GPIO8), // TFT_DC + MP_OBJ_FROM_PTR(&pin_GPIO9), // TFT_CS + MP_OBJ_FROM_PTR(&pin_GPIO12), // TFT_RST 50000000, // Baudrate 0, // Polarity 0 // Phase diff --git a/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/board.c b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/board.c index f17ca53d72464..44d279da43fed 100644 --- a/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/board.c +++ b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/board.c @@ -60,9 +60,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO8, // DC - &pin_GPIO9, // CS - &pin_GPIO12, // RST + MP_OBJ_FROM_PTR(&pin_GPIO8), // DC + MP_OBJ_FROM_PTR(&pin_GPIO9), // CS + MP_OBJ_FROM_PTR(&pin_GPIO12), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/raspberrypi/boards/waveshare_rp2350_geek/board.c b/ports/raspberrypi/boards/waveshare_rp2350_geek/board.c index 71269f0d1852f..431840fb0c5c1 100644 --- a/ports/raspberrypi/boards/waveshare_rp2350_geek/board.c +++ b/ports/raspberrypi/boards/waveshare_rp2350_geek/board.c @@ -37,9 +37,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO8, // TFT_DC - &pin_GPIO9, // TFT_CS - &pin_GPIO12, // TFT_RST + MP_OBJ_FROM_PTR(&pin_GPIO8), // TFT_DC + MP_OBJ_FROM_PTR(&pin_GPIO9), // TFT_CS + MP_OBJ_FROM_PTR(&pin_GPIO12), // TFT_RST 50000000, // Baudrate 0, // Polarity 0 // Phase diff --git a/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/board.c b/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/board.c index f17ca53d72464..44d279da43fed 100644 --- a/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/board.c +++ b/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/board.c @@ -60,9 +60,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO8, // DC - &pin_GPIO9, // CS - &pin_GPIO12, // RST + MP_OBJ_FROM_PTR(&pin_GPIO8), // DC + MP_OBJ_FROM_PTR(&pin_GPIO9), // CS + MP_OBJ_FROM_PTR(&pin_GPIO12), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/raspberrypi/common-hal/busio/I2C.c b/ports/raspberrypi/common-hal/busio/I2C.c index 0f7e023f0e9c5..41df0eac72429 100644 --- a/ports/raspberrypi/common-hal/busio/I2C.c +++ b/ports/raspberrypi/common-hal/busio/I2C.c @@ -86,7 +86,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, // // Do not use the default supplied clock stretching timeout here. // It is too short for some devices. Use the busio timeout instead. - shared_module_bitbangio_i2c_construct(&self->bitbangio_i2c, scl, sda, + shared_module_bitbangio_i2c_construct(&self->bitbangio_i2c, MP_OBJ_FROM_PTR(scl), MP_OBJ_FROM_PTR(sda), frequency, BUS_TIMEOUT_US); self->baudrate = i2c_init(self->peripheral, frequency); @@ -144,7 +144,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +static mp_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { if (len == 0) { // The RP2040 I2C peripheral will not perform 0 byte writes. @@ -174,20 +174,20 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, } switch (result) { case PICO_ERROR_GENERIC: - return MP_ENODEV; + return -MP_ENODEV; case PICO_ERROR_TIMEOUT: - return MP_ETIMEDOUT; + return -MP_ETIMEDOUT; default: - return MP_EIO; + return -MP_EIO; } } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { size_t result = i2c_read_timeout_us(self->peripheral, addr, data, len, false, BUS_TIMEOUT_US); if (result == len) { @@ -195,17 +195,17 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, } switch (result) { case PICO_ERROR_GENERIC: - return MP_ENODEV; + return -MP_ENODEV; case PICO_ERROR_TIMEOUT: - return MP_ETIMEDOUT; + return -MP_ETIMEDOUT; default: - return MP_EIO; + return -MP_EIO; } } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } diff --git a/ports/raspberrypi/common-hal/socketpool/Socket.c b/ports/raspberrypi/common-hal/socketpool/Socket.c index aeab1498510a0..0543fd53dc3e5 100644 --- a/ports/raspberrypi/common-hal/socketpool/Socket.c +++ b/ports/raspberrypi/common-hal/socketpool/Socket.c @@ -251,7 +251,7 @@ static void _lwip_tcp_err_unaccepted(void *arg, err_t err) { // because it's only ever used by lwIP if tcp_connect is called on the TCP PCB. socketpool_socket_obj_t *socket = (socketpool_socket_obj_t *)pcb->connected; - // Array is not volatile because thiss callback is executed within the lwIP context + // Array is not volatile because this callback is executed within the lwIP context uint8_t alloc = socket->incoming.connection.alloc; struct tcp_pcb **tcp_array = (struct tcp_pcb **)lwip_socket_incoming_array(socket); diff --git a/ports/raspberrypi/mpconfigport.mk b/ports/raspberrypi/mpconfigport.mk index bbce13d13811f..8401c5d75453a 100644 --- a/ports/raspberrypi/mpconfigport.mk +++ b/ports/raspberrypi/mpconfigport.mk @@ -30,6 +30,7 @@ CIRCUITPY_FREQUENCYIO = 0 # Use PWM internally CIRCUITPY_I2CTARGET = 1 +CIRCUITPY_I2CIOEXPANDER = 1 CIRCUITPY_NVM = 1 # Use PIO internally CIRCUITPY_PULSEIO ?= 1 diff --git a/ports/renode/common-hal/busio/I2C.c b/ports/renode/common-hal/busio/I2C.c index c94f63cb880e3..0b01b6e79369d 100644 --- a/ports/renode/common-hal/busio/I2C.c +++ b/ports/renode/common-hal/busio/I2C.c @@ -44,19 +44,19 @@ bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return 0; } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { - return MP_EIO; + return -MP_EIO; } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - return MP_EIO; + return -MP_EIO; } void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { diff --git a/ports/silabs/common-hal/_bleio/Characteristic.c b/ports/silabs/common-hal/_bleio/Characteristic.c index 37fb792cd4d75..a707b0ef1acc3 100644 --- a/ports/silabs/common-hal/_bleio/Characteristic.c +++ b/ports/silabs/common-hal/_bleio/Characteristic.c @@ -249,7 +249,7 @@ size_t common_hal_bleio_characteristic_get_value( return 0; } -// Get max length of charateristic +// Get max length of characteristic size_t common_hal_bleio_characteristic_get_max_length( bleio_characteristic_obj_t *self) { return self->max_length; @@ -373,7 +373,7 @@ void common_hal_bleio_characteristic_add_descriptor( // This indicates the new added descriptor shall be started. sc = sl_bt_gattdb_start_characteristic(gattdb_session, self->handle); if (SL_STATUS_OK != sc) { - mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Start charateristic fail.")); + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Start characteristic fail.")); return; } diff --git a/ports/silabs/common-hal/_bleio/Service.c b/ports/silabs/common-hal/_bleio/Service.c index abc8ffe74edff..50f0c4593a67e 100644 --- a/ports/silabs/common-hal/_bleio/Service.c +++ b/ports/silabs/common-hal/_bleio/Service.c @@ -128,7 +128,7 @@ bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) { return self->uuid; } -// Get tuple charateristic of service +// Get tuple characteristic of service mp_obj_tuple_t *common_hal_bleio_service_get_characteristics( bleio_service_obj_t *self) { return mp_obj_new_tuple(self->characteristic_list->len, @@ -210,19 +210,19 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, } if (SL_STATUS_OK != sc) { - mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Add charateristic fail.")); + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Add characteristic fail.")); } sc = sl_bt_gattdb_start_characteristic(gattdb_session, characteristic->handle); if (SL_STATUS_OK != sc) { - mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Start charateristic fail.")); + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Start characteristic fail.")); return; } sc = sl_bt_gattdb_commit(gattdb_session); if (SL_STATUS_OK != sc) { - mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Commit charateristic fail.")); + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Commit characteristic fail.")); return; } mp_obj_list_append(self->characteristic_list, diff --git a/ports/silabs/common-hal/busio/I2C.c b/ports/silabs/common-hal/busio/I2C.c index ae18f561c502f..85f3e63a6dbe6 100644 --- a/ports/silabs/common-hal/busio/I2C.c +++ b/ports/silabs/common-hal/busio/I2C.c @@ -145,7 +145,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { } // Write data to the device selected by address -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { I2C_TransferSeq_TypeDef seq; @@ -159,13 +159,13 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, ret = I2CSPM_Transfer(self->i2cspm, &seq); if (ret != i2cTransferDone) { - return MP_EIO; + return -MP_EIO; } return 0; } // Read into buffer from the device selected by address -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, +mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { @@ -180,13 +180,13 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, ret = I2CSPM_Transfer(self->i2cspm, &seq); if (ret != i2cTransferDone) { - return MP_EIO; + return -MP_EIO; } return 0; } // Write the bytes from out_data to the device selected by address, -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { @@ -204,7 +204,7 @@ uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, ret = I2CSPM_Transfer(self->i2cspm, &seq); if (ret != i2cTransferDone) { - return MP_EIO; + return -MP_EIO; } return 0; } diff --git a/ports/stm/boards/espruino_pico/README.md b/ports/stm/boards/espruino_pico/README.md index 86df1ad32a380..d930e9aeca30c 100644 --- a/ports/stm/boards/espruino_pico/README.md +++ b/ports/stm/boards/espruino_pico/README.md @@ -12,4 +12,4 @@ The Espruino Pico is normally updated via a bootloader activated by the Espruino - Restart the board. -To reinstall Espruino, follow the same steps with the latest Espruino Pico binary from espruino.com/binaries. This will reinstall the usual Espruino bootloader. You must un-short the BOOT0/BTN jumper to re-use the original Espruino Bootloader again. If you used a Pencil mark then you may need to use cleaning fluid and a small brush to totally clear out the graphite. +To reinstall Espruino, follow the same steps with the latest Espruino Pico binary from espruino.com/binaries. This will reinstall the usual Espruino bootloader. You must un-short the BOOT0/BTN jumper to reuse the original Espruino Bootloader again. If you used a Pencil mark then you may need to use cleaning fluid and a small brush to totally clear out the graphite. diff --git a/ports/stm/boards/espruino_wifi/README.MD b/ports/stm/boards/espruino_wifi/README.MD index cc78811f1c7e0..cebe99bf6d1a8 100644 --- a/ports/stm/boards/espruino_wifi/README.MD +++ b/ports/stm/boards/espruino_wifi/README.MD @@ -12,4 +12,4 @@ The Espruino Wifi is normally updated via a bootloader activated by the Espruino - Restart the board. -To reinstall Espruino, follow the same steps with the latest Espruino Wifi binary from espruino.com/binaries. This will reinstall the usual Espruino bootloader. You must un-short the BOOT0/BTN jumper to re-use the original Espruino Bootloader again. If you used a Pencil mark then you may need to use cleaning fluid and a small brush to totally clear out the graphite. +To reinstall Espruino, follow the same steps with the latest Espruino Wifi binary from espruino.com/binaries. This will reinstall the usual Espruino bootloader. You must un-short the BOOT0/BTN jumper to reuse the original Espruino Bootloader again. If you used a Pencil mark then you may need to use cleaning fluid and a small brush to totally clear out the graphite. diff --git a/ports/stm/boards/meowbit_v121/board.c b/ports/stm/boards/meowbit_v121/board.c index 181f433a372b9..c3c745f64a14d 100644 --- a/ports/stm/boards/meowbit_v121/board.c +++ b/ports/stm/boards/meowbit_v121/board.c @@ -55,9 +55,9 @@ void board_init(void) { busio_spi_obj_t *internal_spi = &supervisor_flash_spi_bus; common_hal_fourwire_fourwire_construct(bus, internal_spi, - &pin_PA08, // Command or data - &pin_PB12, // Chip select - &pin_PB10, // Reset + MP_OBJ_FROM_PTR(&pin_PA08), // Command or data + MP_OBJ_FROM_PTR(&pin_PB12), // Chip select + MP_OBJ_FROM_PTR(&pin_PB10), // Reset 24000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/stm/boards/meowbit_v121/mpconfigboard.mk b/ports/stm/boards/meowbit_v121/mpconfigboard.mk index 3a128fb8343cc..74759abed5483 100644 --- a/ports/stm/boards/meowbit_v121/mpconfigboard.mk +++ b/ports/stm/boards/meowbit_v121/mpconfigboard.mk @@ -37,4 +37,6 @@ CIRCUITPY_ZLIB = 0 CIRCUITPY_STAGE = 1 +CIRCUITPY_DIGITALINOUT_PROTOCOL = 0 + FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/meowbit diff --git a/ports/stm/common-hal/busio/I2C.c b/ports/stm/common-hal/busio/I2C.c index e6957989cc72c..5277bffe1fcd2 100644 --- a/ports/stm/common-hal/busio/I2C.c +++ b/ports/stm/common-hal/busio/I2C.c @@ -212,7 +212,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +static mp_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { HAL_StatusTypeDef result; if (!transmit_stop_bit) { @@ -234,19 +234,19 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, result = HAL_I2C_Master_Transmit(&(self->handle), (uint16_t)(addr << 1), (uint8_t *)data, (uint16_t)len, 500); } - return result == HAL_OK ? 0 : MP_EIO; + return result == HAL_OK ? 0 : -MP_EIO; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { if (!self->frame_in_prog) { return HAL_I2C_Master_Receive(&(self->handle), (uint16_t)(addr << 1), data, (uint16_t)len, 500) - == HAL_OK ? 0 : MP_EIO; + == HAL_OK ? 0 : -MP_EIO; } else { HAL_StatusTypeDef result = HAL_I2C_Master_Seq_Receive_IT(&(self->handle), (uint16_t)(addr << 1), (uint8_t *)data, @@ -259,9 +259,9 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, } } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } diff --git a/ports/stm/common-hal/sdioio/SDCard.c b/ports/stm/common-hal/sdioio/SDCard.c index 92e552c2e8984..d8cfdb1131885 100644 --- a/ports/stm/common-hal/sdioio/SDCard.c +++ b/ports/stm/common-hal/sdioio/SDCard.c @@ -6,6 +6,8 @@ #include #include "shared-bindings/sdioio/SDCard.h" + +#include "extmod/vfs.h" #include "py/mperrno.h" #include "py/runtime.h" @@ -239,9 +241,10 @@ static void check_for_deinit(sdioio_sdcard_obj_t *self) { } } -int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { - check_for_deinit(self); - check_whole_block(bufinfo); +// Native function for VFS blockdev layer +mp_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); wait_write_complete(self); self->state_programming = true; common_hal_mcu_disable_interrupts(); @@ -251,17 +254,27 @@ int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t sta #else uint32_t time_out = 1000; #endif - HAL_StatusTypeDef r = HAL_SD_WriteBlocks(&self->handle, bufinfo->buf, start_block, bufinfo->len / 512, time_out); + HAL_StatusTypeDef r = HAL_SD_WriteBlocks(&self->handle, buf, start_block, num_blocks, time_out); common_hal_mcu_enable_interrupts(); if (r != HAL_OK) { - return -EIO; + return -MP_EIO; } return 0; } -int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +mp_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { check_for_deinit(self); check_whole_block(bufinfo); + + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +mp_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); wait_write_complete(self); common_hal_mcu_disable_interrupts(); #ifdef STM32H750xx @@ -270,14 +283,48 @@ int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t star #else uint32_t time_out = 1000; #endif - HAL_StatusTypeDef r = HAL_SD_ReadBlocks(&self->handle, bufinfo->buf, start_block, bufinfo->len / 512, time_out); + HAL_StatusTypeDef r = HAL_SD_ReadBlocks(&self->handle, buf, start_block, num_blocks, time_out); common_hal_mcu_enable_interrupts(); if (r != HAL_OK) { - return -EIO; + return -MP_EIO; } return 0; } +mp_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { + check_for_deinit(self); + check_whole_block(bufinfo); + + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_readblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, + mp_int_t *out_value) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + *out_value = 0; + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_DEINIT: + case MP_BLOCKDEV_IOCTL_SYNC: + // SDIO operations are synchronous, no action needed + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + *out_value = common_hal_sdioio_sdcard_get_count(self); + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + *out_value = 512; // SD cards use 512-byte sectors + return true; + + default: + return false; // Unsupported command + } +} + bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t frequency, uint8_t bits) { check_for_deinit(self); return true; diff --git a/ports/stm/peripherals/stm32l4/stm32l4r5xx/gpio.c b/ports/stm/peripherals/stm32l4/stm32l4r5xx/gpio.c index 18fe8b760a267..a4adc58e42a0a 100644 --- a/ports/stm/peripherals/stm32l4/stm32l4r5xx/gpio.c +++ b/ports/stm/peripherals/stm32l4/stm32l4r5xx/gpio.c @@ -17,7 +17,7 @@ void stm32_peripherals_gpio_init(void) { __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); - // These ports are not used on the Swan R5 but may need to be enabeld on other boards + // These ports are not used on the Swan R5 but may need to be enabled on other boards // __HAL_RCC_GPIOH_CLK_ENABLE(); // __HAL_RCC_GPIOI_CLK_ENABLE(); diff --git a/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml index 5c1e64aedc70b..334cf4001ebe9 100644 --- a/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml @@ -51,6 +51,7 @@ gifio = false gnss = false hashlib = false i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false i2ctarget = false imagecapture = false ipaddress = false diff --git a/ports/zephyr-cp/boards/nordic/nrf54h20dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf54h20dk/autogen_board_info.toml index 2cd411fbc0651..40edb7b705827 100644 --- a/ports/zephyr-cp/boards/nordic/nrf54h20dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nordic/nrf54h20dk/autogen_board_info.toml @@ -51,6 +51,7 @@ gifio = false gnss = false hashlib = false i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false i2ctarget = false imagecapture = false ipaddress = false diff --git a/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml index 227e4a2f6c187..509f14cd20d26 100644 --- a/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml @@ -51,6 +51,7 @@ gifio = false gnss = false hashlib = false i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false i2ctarget = false imagecapture = false ipaddress = false diff --git a/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml index 104a21115251a..3b0ecedcc6385 100644 --- a/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml @@ -51,6 +51,7 @@ gifio = false gnss = false hashlib = false i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false i2ctarget = false imagecapture = false ipaddress = false diff --git a/ports/zephyr-cp/boards/nxp/frdm_mcxn947/autogen_board_info.toml b/ports/zephyr-cp/boards/nxp/frdm_mcxn947/autogen_board_info.toml index f22d066fe64c2..7e03594f1d1ec 100644 --- a/ports/zephyr-cp/boards/nxp/frdm_mcxn947/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nxp/frdm_mcxn947/autogen_board_info.toml @@ -51,6 +51,7 @@ gifio = false gnss = false hashlib = false i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false i2ctarget = false imagecapture = false ipaddress = false diff --git a/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/autogen_board_info.toml b/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/autogen_board_info.toml index 1768f33118079..4398a38ab8799 100644 --- a/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/autogen_board_info.toml @@ -51,6 +51,7 @@ gifio = false gnss = false hashlib = false i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false i2ctarget = false imagecapture = false ipaddress = false diff --git a/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml b/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml index 0a4bf3ce19fca..d60e8eb4b26f1 100644 --- a/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml @@ -51,6 +51,7 @@ gifio = false gnss = false hashlib = false i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false i2ctarget = false imagecapture = false ipaddress = false diff --git a/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml b/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml index 518af74c405d9..8743994bbc72a 100644 --- a/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml @@ -51,6 +51,7 @@ gifio = false gnss = false hashlib = false i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false i2ctarget = false imagecapture = false ipaddress = false diff --git a/ports/zephyr-cp/boards/st/nucleo_n657x0_q/autogen_board_info.toml b/ports/zephyr-cp/boards/st/nucleo_n657x0_q/autogen_board_info.toml index 9806cd8a8116b..9b10fbe3c2d86 100644 --- a/ports/zephyr-cp/boards/st/nucleo_n657x0_q/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/st/nucleo_n657x0_q/autogen_board_info.toml @@ -51,6 +51,7 @@ gifio = false gnss = false hashlib = false i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false i2ctarget = false imagecapture = false ipaddress = false diff --git a/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml b/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml index 01e3314fa5ab4..ef54f4bb0f7fb 100644 --- a/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml @@ -51,6 +51,7 @@ gifio = false gnss = false hashlib = false i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false i2ctarget = false imagecapture = false ipaddress = false diff --git a/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml b/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml index 9ec442d4cfabf..30ac22d00ccd7 100644 --- a/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml @@ -51,6 +51,7 @@ gifio = false gnss = false hashlib = false i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false i2ctarget = false imagecapture = false ipaddress = false diff --git a/ports/zephyr-cp/common-hal/busio/I2C.c b/ports/zephyr-cp/common-hal/busio/I2C.c index 49def727a53ca..d26fc2828cdfd 100644 --- a/ports/zephyr-cp/common-hal/busio/I2C.c +++ b/ports/zephyr-cp/common-hal/busio/I2C.c @@ -73,34 +73,34 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { k_mutex_unlock(&self->mutex); } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { if (common_hal_busio_i2c_deinited(self)) { - return MP_EIO; + return -MP_EIO; } int ret = i2c_write(self->i2c_device, data, len, addr); if (ret != 0) { // Map Zephyr error codes to errno if (ret == -ENOTSUP) { - return MP_EOPNOTSUPP; + return -MP_EOPNOTSUPP; } else if (ret == -EIO || ret == -ENXIO) { - return MP_EIO; + return -MP_EIO; } else if (ret == -EBUSY) { - return MP_EBUSY; + return -MP_EBUSY; } - return MP_EIO; + return -MP_EIO; } return 0; } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { if (common_hal_busio_i2c_deinited(self)) { - return MP_EIO; + return -MP_EIO; } if (len == 0) { @@ -111,23 +111,23 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, if (ret != 0) { // Map Zephyr error codes to errno if (ret == -ENOTSUP) { - return MP_EOPNOTSUPP; + return -MP_EOPNOTSUPP; } else if (ret == -EIO || ret == -ENXIO) { - return MP_EIO; + return -MP_EIO; } else if (ret == -EBUSY) { - return MP_EBUSY; + return -MP_EBUSY; } - return MP_EIO; + return -MP_EIO; } return 0; } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { if (common_hal_busio_i2c_deinited(self)) { - return MP_EIO; + return -MP_EIO; } // Use i2c_write_read for combined transaction with repeated start @@ -135,13 +135,13 @@ uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, if (ret != 0) { // Map Zephyr error codes to errno if (ret == -ENOTSUP) { - return MP_EOPNOTSUPP; + return -MP_EOPNOTSUPP; } else if (ret == -EIO || ret == -ENXIO) { - return MP_EIO; + return -MP_EIO; } else if (ret == -EBUSY) { - return MP_EBUSY; + return -MP_EBUSY; } - return MP_EIO; + return -MP_EIO; } return 0; diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 56c836cb3a490..5760dbd9eb188 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -255,6 +255,9 @@ endif ifeq ($(CIRCUITPY_I2CTARGET),1) SRC_PATTERNS += i2ctarget/% endif +ifeq ($(CIRCUITPY_I2CIOEXPANDER),1) +SRC_PATTERNS += i2cioexpander/% +endif ifeq ($(CIRCUITPY_IMAGECAPTURE),1) SRC_PATTERNS += imagecapture/% endif @@ -612,6 +615,7 @@ $(filter $(SRC_PATTERNS), \ canio/Match.c \ codeop/__init__.c \ countio/Edge.c \ + digitalio/DigitalInOutProtocol.c \ digitalio/Direction.c \ digitalio/DriveMode.c \ digitalio/Pull.c \ @@ -725,6 +729,9 @@ SRC_SHARED_MODULE_ALL = \ dotclockframebuffer/__init__.c \ epaperdisplay/__init__.c \ epaperdisplay/EPaperDisplay.c \ + i2cioexpander/IOExpander.c \ + i2cioexpander/IOPin.c \ + i2cioexpander/__init__.c \ floppyio/__init__.c \ fontio/BuiltinFont.c \ fontio/__init__.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 386d1ee3d1e12..6266f75ceae68 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -317,10 +317,17 @@ typedef long mp_off_t; // Default board buses. +#ifndef CIRCUITPY_MUTABLE_BOARD +#define CIRCUITPY_MUTABLE_BOARD (0) +#endif + #ifndef CIRCUITPY_BOARD_I2C #if defined(DEFAULT_I2C_BUS_SCL) && defined(DEFAULT_I2C_BUS_SDA) #define CIRCUITPY_BOARD_I2C (1) #define CIRCUITPY_BOARD_I2C_PIN {{.scl = DEFAULT_I2C_BUS_SCL, .sda = DEFAULT_I2C_BUS_SDA}} +#ifndef CIRCUITPY_BOARD_I2C_SPEED +#define CIRCUITPY_BOARD_I2C_SPEED (100000) +#endif #else #define CIRCUITPY_BOARD_I2C (0) #endif diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 9bbe5691dfb3b..8e0992f0418f3 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -241,6 +241,12 @@ CFLAGS += -DCIRCUITPY_CYW43=$(CIRCUITPY_CYW43) CIRCUITPY_DIGITALIO ?= 1 CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO) +# Enable the DigitalInOut protocol on the native DigitalInOut type. +# This allows other C code to use DigitalInOut objects polymorphically. +# Disable on small builds to save space. +CIRCUITPY_DIGITALINOUT_PROTOCOL ?= $(CIRCUITPY_FULL_BUILD) +CFLAGS += -DCIRCUITPY_DIGITALINOUT_PROTOCOL=$(CIRCUITPY_DIGITALINOUT_PROTOCOL) + CIRCUITPY_COPROC ?= 0 CFLAGS += -DCIRCUITPY_COPROC=$(CIRCUITPY_COPROC) @@ -346,6 +352,9 @@ CFLAGS += -DCIRCUITPY_HASHLIB_MBEDTLS_ONLY=$(CIRCUITPY_HASHLIB_MBEDTLS_ONLY) CIRCUITPY_I2CTARGET ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_I2CTARGET=$(CIRCUITPY_I2CTARGET) +CIRCUITPY_I2CIOEXPANDER ?= 0 +CFLAGS += -DCIRCUITPY_I2CIOEXPANDER=$(CIRCUITPY_I2CIOEXPANDER) + CIRCUITPY_IMAGECAPTURE ?= 0 CFLAGS += -DCIRCUITPY_IMAGECAPTURE=$(CIRCUITPY_IMAGECAPTURE) diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index 45cc896f9252e..998328bf1d250 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -51,7 +51,7 @@ 954: "kappa", 8656: "lArr", 955: "lambda", 9001: "lang", 171: "laquo", 8592: "larr", 8968: "lceil", 8220: "ldquo", 8804: "le", 8970: "lfloor", 8727: "lowast", 9674: "loz", 8206: "lrm", 8249: "lsaquo", 8216: "lsquo", 60: "lt", 175: "macr", 8212: "mdash", 181: "micro", 183: "middot", 8722: "minus", - 956: "mu", 8711: "nabla", 160: "nbsp", 8211: "ndash", 8800: "ne", 8715: "ni", 172: "not", 8713: "notin", + 956: "mu", 8711: "nabla", 160: "nbsp", 8211: "ndash", 8800: "ne", 8715: "ni", 172: "not", 8713: "notin", # codespell:ignore notin 8836: "nsub", 241: "ntilde", 957: "nu", 243: "oacute", 244: "ocirc", 339: "oelig", 242: "ograve", 8254: "oline", 969: "omega", 959: "omicron", 8853: "oplus", 8744: "or", 170: "ordf", 186: "ordm", 248: "oslash", 245: "otilde", 8855: "otimes", 246: "ouml", 182: "para", 8706: "part", 8240: "permil", diff --git a/py/mperrno.h b/py/mperrno.h index 9e4ecd9419c66..f1fee77b22e2c 100644 --- a/py/mperrno.h +++ b/py/mperrno.h @@ -143,6 +143,8 @@ #endif +typedef int mp_errno_t; + #if MICROPY_PY_ERRNO #include "py/obj.h" diff --git a/py/mpz.c b/py/mpz.c index 7d8bc03ca8610..046d4fcdd5a03 100644 --- a/py/mpz.c +++ b/py/mpz.c @@ -782,15 +782,15 @@ void mpz_set_from_float(mpz_t *z, mp_float_t src) { // 2 <= value const int dig_cnt = (adj_exp + 1 + (DIG_SIZE - 1)) / DIG_SIZE; const unsigned int rem = adj_exp % DIG_SIZE; - int dig_ind, shft; + int dig_ind, shift; mp_float_uint_t frc = u.p.frc | ((mp_float_uint_t)1 << MP_FLOAT_FRAC_BITS); if (adj_exp < MP_FLOAT_FRAC_BITS) { - shft = 0; + shift = 0; dig_ind = 0; frc >>= MP_FLOAT_FRAC_BITS - adj_exp; } else { - shft = (rem - MP_FLOAT_FRAC_BITS) % DIG_SIZE; + shift = (rem - MP_FLOAT_FRAC_BITS) % DIG_SIZE; dig_ind = (adj_exp - MP_FLOAT_FRAC_BITS) / DIG_SIZE; } mpz_need_dig(z, dig_cnt); @@ -798,9 +798,9 @@ void mpz_set_from_float(mpz_t *z, mp_float_t src) { if (dig_ind != 0) { memset(z->dig, 0, dig_ind * sizeof(mpz_dig_t)); } - if (shft != 0) { - z->dig[dig_ind++] = (frc << shft) & DIG_MASK; - frc >>= DIG_SIZE - shft; + if (shift != 0) { + z->dig[dig_ind++] = (frc << shift) & DIG_MASK; + frc >>= DIG_SIZE - shift; } #if DIG_SIZE < (MP_FLOAT_FRAC_BITS + 1) while (dig_ind != dig_cnt) { diff --git a/shared-bindings/aurora_epaper/aurora_framebuffer.c b/shared-bindings/aurora_epaper/aurora_framebuffer.c index f1bb169328463..49e0b34a85616 100644 --- a/shared-bindings/aurora_epaper/aurora_framebuffer.c +++ b/shared-bindings/aurora_epaper/aurora_framebuffer.c @@ -64,7 +64,7 @@ //| ) -> None: //| """Create a framebuffer for the Aurora CoG display. //| -//| .. note:: Displays of size 1.9" and 2.6" are not tested, and may exibit unexpected behavior. +//| .. note:: Displays of size 1.9" and 2.6" are not tested, and may exhibit unexpected behavior. //| //| :param busio.SPI spi_bus: The SPI bus that the display is connected to //| :param microcontroller.Pin chip_select: The pin connected to the displays chip select input diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c index d1a200d39b52f..ddd8824eb58ed 100644 --- a/shared-bindings/bitbangio/I2C.c +++ b/shared-bindings/bitbangio/I2C.c @@ -22,8 +22,8 @@ //| //| def __init__( //| self, -//| scl: microcontroller.Pin, -//| sda: microcontroller.Pin, +//| scl: Union[microcontroller.Pin, digitalio.DigitalInOutProtocol], +//| sda: Union[microcontroller.Pin, digitalio.DigitalInOutProtocol], //| *, //| frequency: int = 400000, //| timeout: int = 255, @@ -40,8 +40,8 @@ //| bit unpacking. Instead, use an existing driver or make one with //| :ref:`Register ` data descriptors. //| -//| :param ~microcontroller.Pin scl: The clock pin -//| :param ~microcontroller.Pin sda: The data pin +//| :param ~microcontroller.Pin scl: The clock pin or DigitalInOut object +//| :param ~microcontroller.Pin sda: The data pin or DigitalInOut object //| :param int frequency: The clock frequency of the bus //| :param int timeout: The maximum clock stretching timeout in microseconds""" //| ... @@ -57,11 +57,8 @@ static mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *scl = validate_obj_is_free_pin(args[ARG_scl].u_obj, MP_QSTR_scl); - const mcu_pin_obj_t *sda = validate_obj_is_free_pin(args[ARG_sda].u_obj, MP_QSTR_sda); - bitbangio_i2c_obj_t *self = mp_obj_malloc_with_finaliser(bitbangio_i2c_obj_t, &bitbangio_i2c_type); - shared_module_bitbangio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int); + shared_module_bitbangio_i2c_construct(self, args[ARG_scl].u_obj, args[ARG_sda].u_obj, args[ARG_frequency].u_int, args[ARG_timeout].u_int); return (mp_obj_t)self; } diff --git a/shared-bindings/bitbangio/I2C.h b/shared-bindings/bitbangio/I2C.h index 022be3692a6cf..cc9cd21b6012a 100644 --- a/shared-bindings/bitbangio/I2C.h +++ b/shared-bindings/bitbangio/I2C.h @@ -16,8 +16,8 @@ extern const mp_obj_type_t bitbangio_i2c_type; // Initializes the hardware peripheral. extern void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self, - const mcu_pin_obj_t *scl, - const mcu_pin_obj_t *sda, + mp_obj_t scl, + mp_obj_t sda, uint32_t frequency, uint32_t us_timeout); diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c index 8938ae4898d56..f2e635b47bb86 100644 --- a/shared-bindings/bitbangio/SPI.c +++ b/shared-bindings/bitbangio/SPI.c @@ -33,9 +33,9 @@ //| //| def __init__( //| self, -//| clock: microcontroller.Pin, -//| MOSI: Optional[microcontroller.Pin] = None, -//| MISO: Optional[microcontroller.Pin] = None, +//| clock: Union[microcontroller.Pin, digitalio.DigitalInOutProtocol], +//| MOSI: Optional[Union[microcontroller.Pin, digitalio.DigitalInOutProtocol]] = None, +//| MISO: Optional[Union[microcontroller.Pin, digitalio.DigitalInOutProtocol]] = None, //| ) -> None: //| """Construct an SPI object on the given pins. //| @@ -48,9 +48,9 @@ //| :ref:`Register ` data descriptors. //| //| -//| :param ~microcontroller.Pin clock: the pin to use for the clock. -//| :param ~microcontroller.Pin MOSI: the Main Out Selected In pin. -//| :param ~microcontroller.Pin MISO: the Main In Selected Out pin.""" +//| :param ~microcontroller.Pin clock: the pin to use for the clock or DigitalInOut object +//| :param ~microcontroller.Pin MOSI: the Main Out Selected In pin or DigitalInOut object +//| :param ~microcontroller.Pin MISO: the Main In Selected Out pin or DigitalInOut object""" //| ... //| @@ -65,12 +65,8 @@ static mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj, MP_QSTR_clock); - const mcu_pin_obj_t *mosi = validate_obj_is_free_pin_or_none(args[ARG_MOSI].u_obj, MP_QSTR_mosi); - const mcu_pin_obj_t *miso = validate_obj_is_free_pin_or_none(args[ARG_MISO].u_obj, MP_QSTR_miso); - bitbangio_spi_obj_t *self = mp_obj_malloc(bitbangio_spi_obj_t, &bitbangio_spi_type); - shared_module_bitbangio_spi_construct(self, clock, mosi, miso); + shared_module_bitbangio_spi_construct(self, args[ARG_clock].u_obj, args[ARG_MOSI].u_obj, args[ARG_MISO].u_obj); return (mp_obj_t)self; } diff --git a/shared-bindings/bitbangio/SPI.h b/shared-bindings/bitbangio/SPI.h index dbe821683b0a2..19ec05152ad37 100644 --- a/shared-bindings/bitbangio/SPI.h +++ b/shared-bindings/bitbangio/SPI.h @@ -16,8 +16,7 @@ extern const mp_obj_type_t bitbangio_spi_type; // Construct an underlying SPI object. extern void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self, - const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, - const mcu_pin_obj_t *miso); + mp_obj_t clock, mp_obj_t mosi, mp_obj_t miso); extern void shared_module_bitbangio_spi_deinit(bitbangio_spi_obj_t *self); extern bool shared_module_bitbangio_spi_deinited(bitbangio_spi_obj_t *self); diff --git a/shared-bindings/board/__init__.h b/shared-bindings/board/__init__.h index fbc39317a30ce..4334309973005 100644 --- a/shared-bindings/board/__init__.h +++ b/shared-bindings/board/__init__.h @@ -11,7 +11,11 @@ #include "shared-bindings/microcontroller/Pin.h" // for the pin definitions +#if CIRCUITPY_MUTABLE_BOARD +extern mp_obj_dict_t board_module_globals; +#else extern const mp_obj_dict_t board_module_globals; +#endif static const MP_DEFINE_STR_OBJ(board_module_id_obj, CIRCUITPY_BOARD_ID); mp_obj_t common_hal_board_get_i2c(const mp_int_t instance); @@ -38,3 +42,7 @@ MP_DECLARE_CONST_FUN_OBJ_0(board_uart_obj); #define CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS \ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_board) }, \ { MP_ROM_QSTR(MP_QSTR_board_id), MP_ROM_PTR(&board_module_id_obj) }, + +#define CIRCUITPYTHON_MUTABLE_BOARD_DICT_STANDARD_ITEMS \ + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_board) }, \ + { MP_ROM_QSTR(MP_QSTR_board_id), MP_OBJ_FROM_PTR(&board_module_id_obj) }, diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c index 165b6a5ba936b..34c02349deb3d 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -228,10 +228,10 @@ static mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, start *= stride_in_bytes; length *= stride_in_bytes; - uint8_t status = + mp_errno_t status = common_hal_busio_i2c_read(self, args[ARG_address].u_int, ((uint8_t *)bufinfo.buf) + start, length); if (status != 0) { - mp_raise_OSError(status); + mp_raise_OSError(-status); } return mp_const_none; @@ -290,11 +290,11 @@ static mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_ma length *= stride_in_bytes; // do the transfer - uint8_t status = + mp_errno_t status = common_hal_busio_i2c_write(self, args[ARG_address].u_int, ((uint8_t *)bufinfo.buf) + start, length); if (status != 0) { - mp_raise_OSError(status); + mp_raise_OSError(-status); } return mp_const_none; @@ -377,10 +377,10 @@ static mp_obj_t busio_i2c_writeto_then_readfrom(size_t n_args, const mp_obj_t *p in_start *= in_stride_in_bytes; in_length *= in_stride_in_bytes; - uint8_t status = common_hal_busio_i2c_write_read(self, args[ARG_address].u_int, + mp_errno_t status = common_hal_busio_i2c_write_read(self, args[ARG_address].u_int, ((uint8_t *)out_bufinfo.buf) + out_start, out_length, ((uint8_t *)in_bufinfo.buf) + in_start, in_length); if (status != 0) { - mp_raise_OSError(status); + mp_raise_OSError(-status); } return mp_const_none; diff --git a/shared-bindings/busio/I2C.h b/shared-bindings/busio/I2C.h index 55f2d0f010850..e7293ce861752 100644 --- a/shared-bindings/busio/I2C.h +++ b/shared-bindings/busio/I2C.h @@ -7,6 +7,7 @@ #pragma once #include "py/obj.h" +#include "py/mperrno.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/busio/I2C.h" @@ -35,17 +36,17 @@ extern void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self); // Probe the bus to see if a device acknowledges the given address. extern bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr); -// Write to the device and return 0 on success or an appropriate error code from mperrno.h -extern uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, +// Write to the device and return 0 on success or a negative error code from mperrno.h +extern mp_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, const uint8_t *data, size_t len); // Reads memory of the i2c device picking up where it left off and return 0 on -// success or an appropriate error code from mperrno.h -extern uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, +// success or a negative error code from mperrno.h +extern mp_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, uint8_t *data, size_t len); // Do a write and then a read in the same I2C transaction. -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t address, +mp_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t address, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len); // This is used by the supervisor to claim I2C devices indefinitely. diff --git a/shared-bindings/canio/__init__.c b/shared-bindings/canio/__init__.c index c65b119ff2401..2300a6652dd6b 100644 --- a/shared-bindings/canio/__init__.c +++ b/shared-bindings/canio/__init__.c @@ -36,7 +36,7 @@ //| //| Other implementations of the CAN device may exist (for instance, attached //| via an SPI bus). If so their constructor arguments may differ, but -//| otherwise we encourage implementors to follow the API that the core uses. +//| otherwise we encourage implementers to follow the API that the core uses. //| //| For more information on working with this module, refer to //| `this Learn Guide on using it `_. diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c index a29fdcc371ca9..50cbc3bc36d62 100644 --- a/shared-bindings/digitalio/DigitalInOut.c +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -17,6 +17,7 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" #include "shared-bindings/digitalio/Direction.h" #include "shared-bindings/digitalio/DriveMode.h" #include "shared-bindings/digitalio/Pull.h" @@ -341,12 +342,91 @@ static const mp_rom_map_elem_t digitalio_digitalinout_locals_dict_table[] = { static MP_DEFINE_CONST_DICT(digitalio_digitalinout_locals_dict, digitalio_digitalinout_locals_dict_table); +// Protocol implementation - thin wrappers to match protocol signature +void digitalinout_deinit(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_digitalio_digitalinout_deinit(self); +} + +bool digitalinout_deinited(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_deinited(self); +} + +digitalinout_result_t digitalinout_switch_to_input(mp_obj_t self_in, digitalio_pull_t pull) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_switch_to_input(self, pull); +} + +digitalinout_result_t digitalinout_switch_to_output(mp_obj_t self_in, bool value, digitalio_drive_mode_t drive_mode) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_switch_to_output(self, value, drive_mode); +} + +digitalio_direction_t digitalinout_get_direction(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_get_direction(self); +} + +mp_errno_t digitalinout_set_value(mp_obj_t self_in, bool value) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_digitalio_digitalinout_set_value(self, value); + return 0; +} + +mp_errno_t digitalinout_get_value(mp_obj_t self_in, bool *value) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + *value = common_hal_digitalio_digitalinout_get_value(self); + return 0; +} + +digitalinout_result_t digitalinout_set_drive_mode(mp_obj_t self_in, digitalio_drive_mode_t drive_mode) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_set_drive_mode(self, drive_mode); +} + +digitalio_drive_mode_t digitalinout_get_drive_mode(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_get_drive_mode(self); +} + +digitalinout_result_t digitalinout_set_pull(mp_obj_t self_in, digitalio_pull_t pull) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_set_pull(self, pull); +} + +digitalio_pull_t digitalinout_get_pull(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_get_pull(self); +} + +#if CIRCUITPY_DIGITALINOUT_PROTOCOL +static const digitalinout_p_t digitalinout_digitalinout_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_DigitalInOut) + .deinit = digitalinout_deinit, + .deinited = digitalinout_deinited, + .switch_to_input = digitalinout_switch_to_input, + .switch_to_output = digitalinout_switch_to_output, + .get_direction = digitalinout_get_direction, + .get_value = digitalinout_get_value, + .set_value = digitalinout_set_value, + .get_drive_mode = digitalinout_get_drive_mode, + .set_drive_mode = digitalinout_set_drive_mode, + .get_pull = digitalinout_get_pull, + .set_pull = digitalinout_set_pull, +}; +#endif + MP_DEFINE_CONST_OBJ_TYPE( digitalio_digitalinout_type, MP_QSTR_DigitalInOut, MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, make_new, digitalio_digitalinout_make_new, locals_dict, &digitalio_digitalinout_locals_dict + #if CIRCUITPY_DIGITALINOUT_PROTOCOL + , + protocol, &digitalinout_digitalinout_proto + #endif ); // Helper for validating digitalio.DigitalInOut arguments diff --git a/shared-bindings/digitalio/DigitalInOut.h b/shared-bindings/digitalio/DigitalInOut.h index f030e27a60b98..ad38cbec6a4d2 100644 --- a/shared-bindings/digitalio/DigitalInOut.h +++ b/shared-bindings/digitalio/DigitalInOut.h @@ -28,6 +28,9 @@ typedef enum { #endif } digitalinout_result_t; +// Include protocol after types are defined +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" + typedef enum { DIGITALINOUT_REG_READ, DIGITALINOUT_REG_WRITE, @@ -54,3 +57,16 @@ digitalio_digitalinout_obj_t *assert_digitalinout(mp_obj_t obj); volatile uint32_t *common_hal_digitalio_digitalinout_get_reg(digitalio_digitalinout_obj_t *self, digitalinout_reg_op_t op, uint32_t *mask); bool common_hal_digitalio_has_reg_op(digitalinout_reg_op_t op); + +// Protocol wrapper functions - always available for direct calls +void digitalinout_deinit(mp_obj_t self_in); +bool digitalinout_deinited(mp_obj_t self_in); +digitalinout_result_t digitalinout_switch_to_input(mp_obj_t self_in, digitalio_pull_t pull); +digitalinout_result_t digitalinout_switch_to_output(mp_obj_t self_in, bool value, digitalio_drive_mode_t drive_mode); +digitalio_direction_t digitalinout_get_direction(mp_obj_t self_in); +mp_errno_t digitalinout_set_value(mp_obj_t self_in, bool value); +mp_errno_t digitalinout_get_value(mp_obj_t self_in, bool *value); +digitalinout_result_t digitalinout_set_drive_mode(mp_obj_t self_in, digitalio_drive_mode_t drive_mode); +digitalio_drive_mode_t digitalinout_get_drive_mode(mp_obj_t self_in); +digitalinout_result_t digitalinout_set_pull(mp_obj_t self_in, digitalio_pull_t pull); +digitalio_pull_t digitalinout_get_pull(mp_obj_t self_in); diff --git a/shared-bindings/digitalio/DigitalInOutProtocol.c b/shared-bindings/digitalio/DigitalInOutProtocol.c new file mode 100644 index 0000000000000..df64fd729c29b --- /dev/null +++ b/shared-bindings/digitalio/DigitalInOutProtocol.c @@ -0,0 +1,397 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" + +#include "py/obj.h" +#include "py/objtype.h" +#include "py/proto.h" +#include "py/runtime.h" +#include "py/nlr.h" +#include "py/gc.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/Direction.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/digitalio/Pull.h" +#include "shared-bindings/util.h" +#include "supervisor/port_heap.h" + +//| from typing import Protocol, Optional +//| +//| class DigitalInOutProtocol(Protocol): +//| """Protocol for digital input/output pin control. +//| +//| Any object that implements this protocol can be used as a digital pin, +//| providing compatibility with code expecting a `digitalio.DigitalInOut`. +//| """ +//| +//| def deinit(self) -> None: +//| """Deinitialize the pin and release hardware resources.""" +//| ... +//| +//| def deinited(self) -> bool: +//| """Check whether the pin has been deinitialized. +//| +//| :return: True if deinitialized, False otherwise +//| """ +//| ... +//| +//| def switch_to_input(self, pull: Optional[digitalio.Pull] = None) -> None: +//| """Configure the pin as a digital input. +//| +//| :param pull: Pull resistor configuration (UP, DOWN, or None) +//| """ +//| ... +//| +//| def switch_to_output( +//| self, +//| value: bool = False, +//| drive_mode: digitalio.DriveMode = digitalio.DriveMode.PUSH_PULL +//| ) -> None: +//| """Configure the pin as a digital output. +//| +//| :param value: Initial output value (default False) +//| :param drive_mode: Output drive mode (PUSH_PULL or OPEN_DRAIN) +//| """ +//| ... +//| +//| @property +//| def direction(self) -> digitalio.Direction: +//| """The pin direction (INPUT or OUTPUT).""" +//| ... +//| +//| @direction.setter +//| def direction(self, value: digitalio.Direction) -> None: +//| ... +//| +//| @property +//| def value(self) -> bool: +//| """The digital logic level of the pin.""" +//| ... +//| +//| @value.setter +//| def value(self, val: bool) -> None: +//| ... +//| +//| @property +//| def pull(self) -> Optional[digitalio.Pull]: +//| """The pull resistor configuration for inputs (UP, DOWN, or None).""" +//| ... +//| +//| @pull.setter +//| def pull(self, pul: Optional[digitalio.Pull]) -> None: +//| ... +//| +//| @property +//| def drive_mode(self) -> digitalio.DriveMode: +//| """The drive mode for outputs (PUSH_PULL or OPEN_DRAIN).""" +//| ... +//| +//| @drive_mode.setter +//| def drive_mode(self, mode: digitalio.DriveMode) -> None: +//| ... +//| +// C Implementation Notes: +// ----------------------- +// For C implementations, define a digitalinout_p_t protocol structure and assign it +// to your type's protocol field in MP_DEFINE_CONST_OBJ_TYPE. +// +// Example: +// static const digitalinout_p_t my_type_proto = { +// MP_PROTO_IMPLEMENT(MP_QSTR_DigitalInOut) +// .construct = my_construct_func, +// .deinit = my_deinit_func, +// .deinited = my_deinited_func, +// .switch_to_input = my_switch_to_input_func, +// .switch_to_output = my_switch_to_output_func, +// .get_direction = my_get_direction_func, +// .get_value = my_get_value_func, +// .set_value = my_set_value_func, +// .get_drive_mode = my_get_drive_mode_func, +// .set_drive_mode = my_set_drive_mode_func, +// .get_pull = my_get_pull_func, +// .set_pull = my_set_pull_func, +// }; +// +// MP_DEFINE_CONST_OBJ_TYPE( +// my_type, +// MP_QSTR_MyType, +// MP_TYPE_FLAG_NONE, +// make_new, my_make_new, +// protocol, &my_type_proto +// ); +// +// See shared-bindings/digitalio/DigitalInOut.c for a complete example. +// + +#if CIRCUITPY_DIGITALINOUT_PROTOCOL +static void check_object_has_method(mp_obj_t obj, qstr method_name) { + mp_obj_t dest[2]; + mp_load_method_protected(obj, method_name, dest, true); + if (dest[0] == MP_OBJ_NULL) { + mp_raise_TypeError_varg(MP_ERROR_TEXT("%q object missing '%q' method"), MP_OBJ_TO_PTR(obj), method_name); + } +} + +static void check_object_has_attr(mp_obj_t obj, qstr attr_name) { + mp_obj_t dest[2]; + mp_load_method_protected(obj, attr_name, dest, true); + if (dest[0] == MP_OBJ_NULL) { + mp_raise_TypeError_varg(MP_ERROR_TEXT("%q object missing '%q' attribute"), MP_OBJ_TO_PTR(obj), attr_name); + } +} +#endif + +mp_obj_t digitalinout_protocol_from_pin( + mp_obj_t pin_or_dio, + qstr arg_name, + bool allow_none, + bool use_port_allocation, + bool *out_owns_pin) { + + *out_owns_pin = false; + + // Handle None case + if (allow_none && pin_or_dio == mp_const_none) { + return mp_const_none; + } + + // Check if it's a Pin + if (mp_obj_is_type(pin_or_dio, &mcu_pin_type)) { + // Validate the pin is free + const mcu_pin_obj_t *pin; + if (allow_none) { + pin = validate_obj_is_free_pin_or_none(pin_or_dio, arg_name); + if (pin == NULL) { + return mp_const_none; + } + } else { + pin = validate_obj_is_free_pin(pin_or_dio, arg_name); + } + + // Allocate and construct a DigitalInOut object + // Use port_malloc if GC is not available or if forced + digitalio_digitalinout_obj_t *dio; + if (use_port_allocation) { + dio = port_malloc(sizeof(digitalio_digitalinout_obj_t), false); + } else { + dio = m_malloc(sizeof(digitalio_digitalinout_obj_t)); + } + dio->base.type = &digitalio_digitalinout_type; + mp_obj_t dio_obj = MP_OBJ_FROM_PTR(dio); + *out_owns_pin = true; + + digitalinout_result_t result = common_hal_digitalio_digitalinout_construct(dio_obj, pin); + if (result != DIGITALINOUT_OK) { + // Free the allocation on error + if (use_port_allocation) { + port_free(dio); + } + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q init failed"), arg_name); + } + return dio_obj; + } + + #if CIRCUITPY_DIGITALINOUT_PROTOCOL + // Check if it natively implements the DigitalInOutProtocol + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, pin_or_dio); + if (proto != NULL) { + // Native protocol support - use it directly + return pin_or_dio; + } + + // Verify the object has the required methods/attributes + check_object_has_method(pin_or_dio, MP_QSTR_deinit); + check_object_has_method(pin_or_dio, MP_QSTR_switch_to_input); + check_object_has_method(pin_or_dio, MP_QSTR_switch_to_output); + check_object_has_attr(pin_or_dio, MP_QSTR_deinited); + check_object_has_attr(pin_or_dio, MP_QSTR_direction); + check_object_has_attr(pin_or_dio, MP_QSTR_value); + check_object_has_attr(pin_or_dio, MP_QSTR_drive_mode); + check_object_has_attr(pin_or_dio, MP_QSTR_pull); + + // Object has all required attributes - use it as DigitalInOutProtocol + return pin_or_dio; + #else + mp_raise_TypeError_varg(MP_ERROR_TEXT("'%q' object does not support '%q'"), + mp_obj_get_type_qstr(pin_or_dio), MP_QSTR_DigitalInOut); + #endif +} + +// These functions are only used when CIRCUITPY_DIGITALINOUT_PROTOCOL is enabled. +// Otherwise, the digitalinout_* functions are called directly. +#if CIRCUITPY_DIGITALINOUT_PROTOCOL +void digitalinout_protocol_deinit(mp_obj_t self) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, self); + if (proto && proto->deinit) { + proto->deinit(self); + return; + } + + // Fallback to Python method call + mp_obj_t dest[2]; + mp_load_method_maybe(self, MP_QSTR_deinit, dest); + if (dest[0] != MP_OBJ_NULL) { + mp_call_method_n_kw(0, 0, dest); + return; + } +} + +bool digitalinout_protocol_deinited(mp_obj_t self) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->deinited) { + return proto->deinited(self); + } + + // Try as attribute + mp_obj_t attr = mp_load_attr(self, MP_QSTR_deinited); + return mp_obj_is_true(attr); +} + +digitalinout_result_t digitalinout_protocol_switch_to_input(mp_obj_t self, digitalio_pull_t pull) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->switch_to_input) { + return proto->switch_to_input(self, pull); + } + + // Fallback to Python method call + mp_obj_t dest[3]; + mp_load_method_maybe(self, MP_QSTR_switch_to_input, dest); + if (dest[0] != MP_OBJ_NULL) { + mp_obj_t pull_obj = mp_const_none; + if (pull == PULL_UP) { + pull_obj = MP_OBJ_FROM_PTR(&digitalio_pull_up_obj); + } else if (pull == PULL_DOWN) { + pull_obj = MP_OBJ_FROM_PTR(&digitalio_pull_down_obj); + } + dest[2] = pull_obj; + mp_call_method_n_kw(1, 0, dest); + return DIGITALINOUT_OK; + } + + return DIGITALINOUT_PIN_BUSY; +} + +digitalinout_result_t digitalinout_protocol_switch_to_output(mp_obj_t self, bool value, digitalio_drive_mode_t drive_mode) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->switch_to_output) { + return proto->switch_to_output(self, value, drive_mode); + } + + // Fallback to Python method call + mp_obj_t dest[4]; + mp_load_method_maybe(self, MP_QSTR_switch_to_output, dest); + if (dest[0] != MP_OBJ_NULL) { + dest[2] = mp_obj_new_bool(value); + dest[3] = (drive_mode == DRIVE_MODE_PUSH_PULL) ? + MP_OBJ_FROM_PTR(&digitalio_drive_mode_push_pull_obj) : + MP_OBJ_FROM_PTR(&digitalio_drive_mode_open_drain_obj); + mp_call_method_n_kw(2, 0, dest); + return DIGITALINOUT_OK; + } + + mp_raise_TypeError(MP_ERROR_TEXT("object does not support DigitalInOut protocol")); +} + +digitalio_direction_t digitalinout_protocol_get_direction(mp_obj_t self) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->get_direction) { + return proto->get_direction(self); + } + + // Fallback to Python attribute access + mp_obj_t direction = mp_load_attr(self, MP_QSTR_direction); + if (direction == MP_ROM_PTR(&digitalio_direction_input_obj)) { + return DIRECTION_INPUT; + } + return DIRECTION_OUTPUT; +} + +mp_errno_t digitalinout_protocol_set_value(mp_obj_t self, bool value) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->set_value) { + return proto->set_value(self, value); + } + + // Fallback to Python attribute assignment + mp_store_attr(self, MP_QSTR_value, mp_obj_new_bool(value)); + return 0; +} + +mp_errno_t digitalinout_protocol_get_value(mp_obj_t self, bool *value) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->get_value) { + return proto->get_value(self, value); + } + + // Fallback to Python attribute access + *value = mp_obj_is_true(mp_load_attr(self, MP_QSTR_value)); + return 0; +} + +digitalinout_result_t digitalinout_protocol_set_drive_mode(mp_obj_t self, digitalio_drive_mode_t drive_mode) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->set_drive_mode) { + return proto->set_drive_mode(self, drive_mode); + } + + // Fallback to Python attribute assignment + mp_obj_t drive_mode_obj = (drive_mode == DRIVE_MODE_PUSH_PULL) ? + MP_OBJ_FROM_PTR(&digitalio_drive_mode_push_pull_obj) : + MP_OBJ_FROM_PTR(&digitalio_drive_mode_open_drain_obj); + mp_store_attr(self, MP_QSTR_drive_mode, drive_mode_obj); + return DIGITALINOUT_OK; +} + +digitalio_drive_mode_t digitalinout_protocol_get_drive_mode(mp_obj_t self) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->get_drive_mode) { + return proto->get_drive_mode(self); + } + + // Fallback to Python attribute access + mp_obj_t drive_mode = mp_load_attr(self, MP_QSTR_drive_mode); + if (drive_mode == MP_ROM_PTR(&digitalio_drive_mode_open_drain_obj)) { + return DRIVE_MODE_OPEN_DRAIN; + } + return DRIVE_MODE_PUSH_PULL; +} + +digitalinout_result_t digitalinout_protocol_set_pull(mp_obj_t self, digitalio_pull_t pull) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->set_pull) { + return proto->set_pull(self, pull); + } + + // Fallback to Python attribute assignment + mp_obj_t pull_obj = mp_const_none; + if (pull == PULL_UP) { + pull_obj = MP_OBJ_FROM_PTR(&digitalio_pull_up_obj); + } else if (pull == PULL_DOWN) { + pull_obj = MP_OBJ_FROM_PTR(&digitalio_pull_down_obj); + } + mp_store_attr(self, MP_QSTR_pull, pull_obj); + return DIGITALINOUT_OK; +} + +digitalio_pull_t digitalinout_protocol_get_pull(mp_obj_t self) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->get_pull) { + return proto->get_pull(self); + } + + // Fallback to Python attribute access + mp_obj_t pull = mp_load_attr(self, MP_QSTR_pull); + if (pull == MP_OBJ_FROM_PTR(&digitalio_pull_up_obj)) { + return PULL_UP; + } else if (pull == MP_OBJ_FROM_PTR(&digitalio_pull_down_obj)) { + return PULL_DOWN; + } + return PULL_NONE; +} + +#endif // CIRCUITPY_DIGITALINOUT_PROTOCOL diff --git a/shared-bindings/digitalio/DigitalInOutProtocol.h b/shared-bindings/digitalio/DigitalInOutProtocol.h new file mode 100644 index 0000000000000..798cb6a9de1eb --- /dev/null +++ b/shared-bindings/digitalio/DigitalInOutProtocol.h @@ -0,0 +1,83 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "py/obj.h" +#include "py/proto.h" +#include "py/mperrno.h" +#include "shared-bindings/digitalio/Direction.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/digitalio/Pull.h" + +// Protocol structure for DigitalInOut implementations +// Note: mcu_pin_obj_t and digitalinout_result_t are defined by files that include this header +typedef struct _digitalinout_p_t { + MP_PROTOCOL_HEAD // MP_QSTR_DigitalInOut + void (*deinit)(mp_obj_t self); + bool (*deinited)(mp_obj_t self); + digitalinout_result_t (*switch_to_input)(mp_obj_t self, digitalio_pull_t pull); + digitalinout_result_t (*switch_to_output)(mp_obj_t self, bool value, digitalio_drive_mode_t drive_mode); + digitalio_direction_t (*get_direction)(mp_obj_t self); + mp_errno_t (*set_value)(mp_obj_t self, bool value); // Return 0 if ok + mp_errno_t (*get_value)(mp_obj_t self, bool *value); // Return 0 if ok + digitalinout_result_t (*set_drive_mode)(mp_obj_t self, digitalio_drive_mode_t drive_mode); + digitalio_drive_mode_t (*get_drive_mode)(mp_obj_t self); + digitalinout_result_t (*set_pull)(mp_obj_t self, digitalio_pull_t pull); + digitalio_pull_t (*get_pull)(mp_obj_t self); +} digitalinout_p_t; + +// Protocol helper functions +// These functions work with any object that implements the DigitalInOut protocol, +// either through native C protocol or Python attributes/methods. + +// Converts a Pin or DigitalInOutProtocol to a DigitalInOutProtocol object. +// If pin_or_dio is a Pin, allocates and initializes a DigitalInOut object. +// If pin_or_dio is already a DigitalInOutProtocol, returns it directly. +// If allow_none is true and pin_or_dio is None, returns None. +// If force_port_allocation is true, uses port_malloc instead of GC allocation. +// Sets *out_owns_pin to true if a new DigitalInOut was allocated (caller must deinit and free). +// Returns the DigitalInOutProtocol object to use. +// Raises an exception on error. +// Note: To free allocated objects, deinit first, then use gc_ptr_on_heap() to determine +// if port_free() should be called (if not on heap) or let GC handle it (if on heap). +mp_obj_t digitalinout_protocol_from_pin( + mp_obj_t pin_or_dio, + qstr arg_name, + bool allow_none, + bool force_port_allocation, + bool *out_owns_pin); + +#if CIRCUITPY_DIGITALINOUT_PROTOCOL +// Protocol helper functions that do protocol lookup or Python fallback +void digitalinout_protocol_deinit(mp_obj_t self); +bool digitalinout_protocol_deinited(mp_obj_t self); +digitalinout_result_t digitalinout_protocol_switch_to_input(mp_obj_t self, digitalio_pull_t pull); +digitalinout_result_t digitalinout_protocol_switch_to_output(mp_obj_t self, bool value, digitalio_drive_mode_t drive_mode); +digitalio_direction_t digitalinout_protocol_get_direction(mp_obj_t self); +mp_errno_t digitalinout_protocol_set_value(mp_obj_t self, bool value); +mp_errno_t digitalinout_protocol_get_value(mp_obj_t self, bool *value); +digitalinout_result_t digitalinout_protocol_set_drive_mode(mp_obj_t self, digitalio_drive_mode_t drive_mode); +digitalio_drive_mode_t digitalinout_protocol_get_drive_mode(mp_obj_t self); +digitalinout_result_t digitalinout_protocol_set_pull(mp_obj_t self, digitalio_pull_t pull); +digitalio_pull_t digitalinout_protocol_get_pull(mp_obj_t self); +#else +// When protocol is disabled, map directly to native DigitalInOut functions +#define digitalinout_protocol_deinit digitalinout_deinit +#define digitalinout_protocol_deinited digitalinout_deinited +#define digitalinout_protocol_switch_to_input digitalinout_switch_to_input +#define digitalinout_protocol_switch_to_output digitalinout_switch_to_output +#define digitalinout_protocol_get_direction digitalinout_get_direction +#define digitalinout_protocol_set_value digitalinout_set_value +#define digitalinout_protocol_get_value digitalinout_get_value +#define digitalinout_protocol_set_drive_mode digitalinout_set_drive_mode +#define digitalinout_protocol_get_drive_mode digitalinout_get_drive_mode +#define digitalinout_protocol_set_pull digitalinout_set_pull +#define digitalinout_protocol_get_pull digitalinout_get_pull +#endif diff --git a/shared-bindings/fourwire/FourWire.c b/shared-bindings/fourwire/FourWire.c index 083cf21a00367..608645aaebf0b 100644 --- a/shared-bindings/fourwire/FourWire.c +++ b/shared-bindings/fourwire/FourWire.c @@ -30,9 +30,9 @@ //| self, //| spi_bus: busio.SPI, //| *, -//| command: Optional[microcontroller.Pin], -//| chip_select: Optional[microcontroller.Pin], -//| reset: Optional[microcontroller.Pin] = None, +//| command: Optional[Union[microcontroller.Pin, digitalio.DigitalInOutProtocol]] = None, +//| chip_select: Optional[Union[microcontroller.Pin, digitalio.DigitalInOutProtocol]] = None, +//| reset: Optional[Union[microcontroller.Pin, digitalio.DigitalInOutProtocol]] = None, //| baudrate: int = 24000000, //| polarity: int = 0, //| phase: int = 0, @@ -73,10 +73,6 @@ static mp_obj_t fourwire_fourwire_make_new(const mp_obj_type_t *type, size_t n_a mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *command = validate_obj_is_free_pin_or_none(args[ARG_command].u_obj, MP_QSTR_command); - const mcu_pin_obj_t *chip_select = validate_obj_is_free_pin_or_none(args[ARG_chip_select].u_obj, MP_QSTR_chip_select); - const mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj, MP_QSTR_reset); - mp_obj_t spi = mp_arg_validate_type(args[ARG_spi_bus].u_obj, &busio_spi_type, MP_QSTR_spi_bus); fourwire_fourwire_obj_t *self = &allocate_display_bus_or_raise()->fourwire_bus; @@ -86,7 +82,7 @@ static mp_obj_t fourwire_fourwire_make_new(const mp_obj_type_t *type, size_t n_a uint8_t phase = (uint8_t)mp_arg_validate_int_range(args[ARG_phase].u_int, 0, 1, MP_QSTR_phase); common_hal_fourwire_fourwire_construct(self, - MP_OBJ_TO_PTR(spi), command, chip_select, reset, args[ARG_baudrate].u_int, polarity, phase); + MP_OBJ_TO_PTR(spi), args[ARG_command].u_obj, args[ARG_chip_select].u_obj, args[ARG_reset].u_obj, args[ARG_baudrate].u_int, polarity, phase); return self; } diff --git a/shared-bindings/fourwire/FourWire.h b/shared-bindings/fourwire/FourWire.h index 515a466b4b98c..3e77c25434d64 100644 --- a/shared-bindings/fourwire/FourWire.h +++ b/shared-bindings/fourwire/FourWire.h @@ -16,8 +16,8 @@ extern const mp_obj_type_t fourwire_fourwire_type; void common_hal_fourwire_fourwire_construct(fourwire_fourwire_obj_t *self, - busio_spi_obj_t *spi, const mcu_pin_obj_t *command, - const mcu_pin_obj_t *chip_select, const mcu_pin_obj_t *reset, uint32_t baudrate, + busio_spi_obj_t *spi, mp_obj_t command, + mp_obj_t chip_select, mp_obj_t reset, uint32_t baudrate, uint8_t polarity, uint8_t phase); void common_hal_fourwire_fourwire_deinit(fourwire_fourwire_obj_t *self); diff --git a/shared-bindings/i2cioexpander/IOExpander.c b/shared-bindings/i2cioexpander/IOExpander.c new file mode 100644 index 0000000000000..f2257b4b63253 --- /dev/null +++ b/shared-bindings/i2cioexpander/IOExpander.c @@ -0,0 +1,247 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +#include "shared-bindings/i2cioexpander/IOExpander.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/util.h" +#include "shared/runtime/context_manager_helpers.h" + +//| class IOExpander: +//| """Control a generic I2C-based GPIO expander +//| +//| IOExpander provides a simple interface to I2C-based GPIO expanders that +//| use basic register reads and writes for control. The expander provides +//| individual pins through the `pins` attribute that implement the +//| DigitalInOutProtocol. +//| """ +//| +//| def __init__( +//| self, +//| i2c: busio.I2C, +//| address: int, +//| num_pins: int, +//| set_value_reg: Optional[int] = None, +//| get_value_reg: Optional[int] = None, +//| set_direction_reg: Optional[int] = None, +//| ) -> None: +//| """Initialize an I2C GPIO expander +//| +//| :param busio.I2C i2c: The I2C bus the expander is connected to +//| :param int address: The I2C device address +//| :param int num_pins: The number of GPIO pins (8 or 16) +//| :param int set_value_reg: Register address to write pin values (optional) +//| :param int get_value_reg: Register address to read pin values (optional) +//| :param int set_direction_reg: Register address to set pin directions (optional) +//| """ +//| ... + +static mp_obj_t i2cioexpander_ioexpander_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_i2c, ARG_address, ARG_num_pins, ARG_set_value_reg, ARG_get_value_reg, ARG_set_direction_reg }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_i2c, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_num_pins, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_set_value_reg, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_get_value_reg, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_set_direction_reg, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Validate I2C object + mp_obj_t i2c = mp_arg_validate_type(args[ARG_i2c].u_obj, &busio_i2c_type, MP_QSTR_i2c); + + // Validate address + int address = args[ARG_address].u_int; + if (address < 0 || address > 0x7F) { + mp_raise_ValueError(MP_ERROR_TEXT("address out of range")); + } + + // Validate num_pins + int num_pins = args[ARG_num_pins].u_int; + if (num_pins != 8 && num_pins != 16) { + mp_raise_ValueError(MP_ERROR_TEXT("num_pins must be 8 or 16")); + } + + i2cioexpander_ioexpander_obj_t *self = mp_obj_malloc(i2cioexpander_ioexpander_obj_t, &i2cioexpander_ioexpander_type); + + // Convert and validate register parameters + uint16_t set_value_reg = NO_REGISTER; + if (args[ARG_set_value_reg].u_obj != mp_const_none) { + mp_int_t reg = mp_obj_get_int(args[ARG_set_value_reg].u_obj); + mp_arg_validate_int_range(reg, 0, 255, MP_QSTR_set_value_reg); + set_value_reg = reg; + } + + uint16_t get_value_reg = NO_REGISTER; + if (args[ARG_get_value_reg].u_obj != mp_const_none) { + mp_int_t reg = mp_obj_get_int(args[ARG_get_value_reg].u_obj); + mp_arg_validate_int_range(reg, 0, 255, MP_QSTR_get_value_reg); + get_value_reg = reg; + } + + uint16_t set_direction_reg = NO_REGISTER; + if (args[ARG_set_direction_reg].u_obj != mp_const_none) { + mp_int_t reg = mp_obj_get_int(args[ARG_set_direction_reg].u_obj); + mp_arg_validate_int_range(reg, 0, 255, MP_QSTR_set_direction_reg); + set_direction_reg = reg; + } + + common_hal_i2cioexpander_ioexpander_construct( + self, + i2c, + address, + num_pins, + set_value_reg, + get_value_reg, + set_direction_reg); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialize the expander. No further operations are possible.""" +//| ... +static mp_obj_t i2cioexpander_ioexpander_deinit(mp_obj_t self_in) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_i2cioexpander_ioexpander_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_ioexpander_deinit_obj, i2cioexpander_ioexpander_deinit); + +//| def __enter__(self) -> IOExpander: +//| """No-op used by Context Managers.""" +//| ... +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +static mp_obj_t i2cioexpander_ioexpander___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_i2cioexpander_ioexpander_deinit(MP_OBJ_TO_PTR(args[0])); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cioexpander_ioexpander___exit___obj, 4, 4, i2cioexpander_ioexpander___exit__); + +//| @property +//| def input_value(self) -> int: +//| """Read the live value of all pins at once. Returns an integer where each +//| bit represents a pin's current state.""" +//| ... +static mp_obj_t i2cioexpander_ioexpander_obj_get_input_value(mp_obj_t self_in) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + size_t value; + if (!common_hal_i2cioexpander_ioexpander_get_input_value(self, &value)) { + mp_raise_OSError(MP_EIO); + } + return MP_OBJ_NEW_SMALL_INT(value); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_ioexpander_get_input_value_obj, i2cioexpander_ioexpander_obj_get_input_value); + +MP_PROPERTY_GETTER(i2cioexpander_ioexpander_input_value_obj, + (mp_obj_t)&i2cioexpander_ioexpander_get_input_value_obj); + +//| @property +//| def output_value(self) -> int: +//| """Get or set the cached output value. Reading returns the last value written, +//| not the live pin state. Writing updates the output pins.""" +//| ... +//| @output_value.setter +//| def output_value(self, val: int) -> None: ... +static mp_obj_t i2cioexpander_ioexpander_obj_get_output_value(mp_obj_t self_in) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + size_t value; + common_hal_i2cioexpander_ioexpander_get_output_value(self, &value); + return mp_obj_new_int(value); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_ioexpander_get_output_value_obj, i2cioexpander_ioexpander_obj_get_output_value); + +static mp_obj_t i2cioexpander_ioexpander_obj_set_output_value(mp_obj_t self_in, mp_obj_t value) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_errno_t result = common_hal_i2cioexpander_ioexpander_set_output_value(self, mp_obj_get_int(value)); + if (result != 0) { + mp_raise_OSError(result); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(i2cioexpander_ioexpander_set_output_value_obj, i2cioexpander_ioexpander_obj_set_output_value); + +MP_PROPERTY_GETSET(i2cioexpander_ioexpander_output_value_obj, + (mp_obj_t)&i2cioexpander_ioexpander_get_output_value_obj, + (mp_obj_t)&i2cioexpander_ioexpander_set_output_value_obj); + +//| @property +//| def output_mask(self) -> int: +//| """Get or set which pins are configured as outputs. Each bit in the mask +//| represents a pin: 1 for output, 0 for input.""" +//| ... +//| @output_mask.setter +//| def output_mask(self, val: int) -> None: ... +static mp_obj_t i2cioexpander_ioexpander_obj_get_output_mask(mp_obj_t self_in) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + size_t output_mask; + common_hal_i2cioexpander_ioexpander_get_output_mask(self, &output_mask); + return mp_obj_new_int(output_mask); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_ioexpander_get_output_mask_obj, i2cioexpander_ioexpander_obj_get_output_mask); + +static mp_obj_t i2cioexpander_ioexpander_obj_set_output_mask(mp_obj_t self_in, mp_obj_t value) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_errno_t result = common_hal_i2cioexpander_ioexpander_set_output_mask(self, mp_obj_get_int(value)); + if (result != 0) { + mp_raise_OSError(result); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(i2cioexpander_ioexpander_set_output_mask_obj, i2cioexpander_ioexpander_obj_set_output_mask); + +MP_PROPERTY_GETSET(i2cioexpander_ioexpander_output_mask_obj, + (mp_obj_t)&i2cioexpander_ioexpander_get_output_mask_obj, + (mp_obj_t)&i2cioexpander_ioexpander_set_output_mask_obj); + +//| @property +//| def pins(self) -> Tuple[IOPin, ...]: +//| """A tuple of `IOPin` objects that implement the DigitalInOutProtocol. +//| Each pin can be used like a digitalio.DigitalInOut object.""" +//| ... +static mp_obj_t i2cioexpander_ioexpander_obj_get_pins(mp_obj_t self_in) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_ioexpander_get_pins(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_ioexpander_get_pins_obj, i2cioexpander_ioexpander_obj_get_pins); + +MP_PROPERTY_GETTER(i2cioexpander_ioexpander_pins_obj, + (mp_obj_t)&i2cioexpander_ioexpander_get_pins_obj); + +static const mp_rom_map_elem_t i2cioexpander_ioexpander_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&i2cioexpander_ioexpander_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2cioexpander_ioexpander___exit___obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_input_value), MP_ROM_PTR(&i2cioexpander_ioexpander_input_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_output_value), MP_ROM_PTR(&i2cioexpander_ioexpander_output_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_output_mask), MP_ROM_PTR(&i2cioexpander_ioexpander_output_mask_obj) }, + { MP_ROM_QSTR(MP_QSTR_pins), MP_ROM_PTR(&i2cioexpander_ioexpander_pins_obj) }, +}; +static MP_DEFINE_CONST_DICT(i2cioexpander_ioexpander_locals_dict, i2cioexpander_ioexpander_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + i2cioexpander_ioexpander_type, + MP_QSTR_IOExpander, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, i2cioexpander_ioexpander_make_new, + locals_dict, &i2cioexpander_ioexpander_locals_dict + ); diff --git a/shared-bindings/i2cioexpander/IOExpander.h b/shared-bindings/i2cioexpander/IOExpander.h new file mode 100644 index 0000000000000..64e49b603648d --- /dev/null +++ b/shared-bindings/i2cioexpander/IOExpander.h @@ -0,0 +1,34 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "shared-module/i2cioexpander/IOExpander.h" + +extern const mp_obj_type_t i2cioexpander_ioexpander_type; + +void common_hal_i2cioexpander_ioexpander_construct( + i2cioexpander_ioexpander_obj_t *self, + mp_obj_t i2c, + uint8_t address, + uint8_t num_pins, + uint16_t set_value_reg, + uint16_t get_value_reg, + uint16_t set_direction_reg); + +void common_hal_i2cioexpander_ioexpander_deinit(i2cioexpander_ioexpander_obj_t *self); +bool common_hal_i2cioexpander_ioexpander_deinited(i2cioexpander_ioexpander_obj_t *self); + +mp_errno_t common_hal_i2cioexpander_ioexpander_get_input_value(i2cioexpander_ioexpander_obj_t *self, size_t *value); +// No error return because this returns a cached value. +void common_hal_i2cioexpander_ioexpander_get_output_value(i2cioexpander_ioexpander_obj_t *self, size_t *value); +mp_errno_t common_hal_i2cioexpander_ioexpander_set_output_value(i2cioexpander_ioexpander_obj_t *self, size_t value); + +void common_hal_i2cioexpander_ioexpander_get_output_mask(i2cioexpander_ioexpander_obj_t *self, size_t *mask); +mp_errno_t common_hal_i2cioexpander_ioexpander_set_output_mask(i2cioexpander_ioexpander_obj_t *self, size_t mask); + +mp_obj_t common_hal_i2cioexpander_ioexpander_get_pins(i2cioexpander_ioexpander_obj_t *self); diff --git a/shared-bindings/i2cioexpander/IOPin.c b/shared-bindings/i2cioexpander/IOPin.c new file mode 100644 index 0000000000000..e2957f9a220f9 --- /dev/null +++ b/shared-bindings/i2cioexpander/IOPin.c @@ -0,0 +1,326 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/i2cioexpander/IOPin.h" +#include "shared-module/i2cioexpander/IOPin.h" + +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" +#include "shared-bindings/digitalio/Direction.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/digitalio/Pull.h" +#include "shared-bindings/util.h" + +static void check_result(digitalinout_result_t result) { + switch (result) { + case DIGITALINOUT_OK: + return; + case DIGITALINOUT_PIN_BUSY: + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q in use"), MP_QSTR_Pin); + #if CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY + case DIGITALINOUT_INPUT_ONLY: + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_direction); + #endif + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL + case DIGITALINOUT_INVALID_PULL: + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_pull); + #endif + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE + case DIGITALINOUT_INVALID_DRIVE_MODE: + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_drive_mode); + #endif + } +} + +static inline void check_for_deinit(i2cioexpander_iopin_obj_t *self) { + if (common_hal_i2cioexpander_iopin_deinited(self)) { + raise_deinited_error(); + } +} +//| class IOPin: +//| """Control a single pin on an `IOExpander` in the same way as `DigitalInOut`. +//| +//| Not constructed directly. Get from `IOExpander.pins` instead. +//| """ +//| + +//| def switch_to_output( +//| self, value: bool = False, drive_mode: digitalio.DriveMode = digitalio.DriveMode.PUSH_PULL +//| ) -> None: +//| """Set the drive mode and value and then switch to writing out digital values. +//| +//| :param bool value: default value to set upon switching +//| :param digitalio.DriveMode drive_mode: drive mode for the output""" +//| ... +static mp_obj_t i2cioexpander_iopin_switch_to_output(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_value, ARG_drive_mode }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_value, MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_drive_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&digitalio_drive_mode_push_pull_obj)} }, + }; + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + digitalio_drive_mode_t drive_mode = DRIVE_MODE_PUSH_PULL; + if (args[ARG_drive_mode].u_rom_obj == MP_ROM_PTR(&digitalio_drive_mode_open_drain_obj)) { + drive_mode = DRIVE_MODE_OPEN_DRAIN; + } + check_result(common_hal_i2cioexpander_iopin_switch_to_output(self, args[ARG_value].u_bool, drive_mode)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(i2cioexpander_iopin_switch_to_output_obj, 1, i2cioexpander_iopin_switch_to_output); + +//| def switch_to_input(self, pull: Optional[digitalio.Pull] = None) -> None: +//| """Set the pull and then switch to read in digital values. +//| +//| :param digitalio.Pull pull: pull configuration for the input""" +//| ... +static mp_obj_t i2cioexpander_iopin_switch_to_input(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_pull }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + }; + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + check_result(common_hal_i2cioexpander_iopin_switch_to_input(self, validate_pull(args[ARG_pull].u_rom_obj, MP_QSTR_pull))); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(i2cioexpander_iopin_switch_to_input_obj, 1, i2cioexpander_iopin_switch_to_input); + +//| direction: digitalio.Direction +//| """The direction of the pin.""" +static mp_obj_t i2cioexpander_iopin_obj_get_direction(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + digitalio_direction_t direction = common_hal_i2cioexpander_iopin_get_direction(self); + if (direction == DIRECTION_INPUT) { + return MP_OBJ_FROM_PTR(&digitalio_direction_input_obj); + } + return MP_OBJ_FROM_PTR(&digitalio_direction_output_obj); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_iopin_get_direction_obj, i2cioexpander_iopin_obj_get_direction); + +static mp_obj_t i2cioexpander_iopin_obj_set_direction(mp_obj_t self_in, mp_obj_t value) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (value == MP_ROM_PTR(&digitalio_direction_input_obj)) { + check_result(common_hal_i2cioexpander_iopin_switch_to_input(self, PULL_NONE)); + } else if (value == MP_ROM_PTR(&digitalio_direction_output_obj)) { + check_result(common_hal_i2cioexpander_iopin_switch_to_output(self, false, DRIVE_MODE_PUSH_PULL)); + } else { + mp_arg_error_invalid(MP_QSTR_direction); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(i2cioexpander_iopin_set_direction_obj, i2cioexpander_iopin_obj_set_direction); + +MP_PROPERTY_GETSET(i2cioexpander_iopin_direction_obj, + (mp_obj_t)&i2cioexpander_iopin_get_direction_obj, + (mp_obj_t)&i2cioexpander_iopin_set_direction_obj); + +//| value: bool +//| """The digital logic level of the pin.""" +static mp_obj_t i2cioexpander_iopin_obj_get_value(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + bool value; + mp_errno_t res = common_hal_i2cioexpander_iopin_get_value(self, &value); + if (res != 0) { + mp_raise_OSError(-res); + } + return mp_obj_new_bool(value); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_iopin_get_value_obj, i2cioexpander_iopin_obj_get_value); + +static mp_obj_t i2cioexpander_iopin_obj_set_value(mp_obj_t self_in, mp_obj_t value) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_i2cioexpander_iopin_get_direction(self) == DIRECTION_INPUT) { + mp_raise_AttributeError(MP_ERROR_TEXT("Cannot set value when direction is input.")); + return mp_const_none; + } + mp_errno_t res = common_hal_i2cioexpander_iopin_set_value(self, mp_obj_is_true(value)); + if (res != 0) { + mp_raise_OSError(-res); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(i2cioexpander_iopin_set_value_obj, i2cioexpander_iopin_obj_set_value); + +MP_PROPERTY_GETSET(i2cioexpander_iopin_value_obj, + (mp_obj_t)&i2cioexpander_iopin_get_value_obj, + (mp_obj_t)&i2cioexpander_iopin_set_value_obj); + +//| drive_mode: digitalio.DriveMode +//| """The pin drive mode.""" +static mp_obj_t i2cioexpander_iopin_obj_get_drive_mode(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_i2cioexpander_iopin_get_direction(self) == DIRECTION_INPUT) { + mp_raise_AttributeError(MP_ERROR_TEXT("Drive mode not used when direction is input.")); + return mp_const_none; + } + digitalio_drive_mode_t drive_mode = common_hal_i2cioexpander_iopin_get_drive_mode(self); + if (drive_mode == DRIVE_MODE_PUSH_PULL) { + return MP_OBJ_FROM_PTR(&digitalio_drive_mode_push_pull_obj); + } + return MP_OBJ_FROM_PTR(&digitalio_drive_mode_open_drain_obj); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_iopin_get_drive_mode_obj, i2cioexpander_iopin_obj_get_drive_mode); + +static mp_obj_t i2cioexpander_iopin_obj_set_drive_mode(mp_obj_t self_in, mp_obj_t drive_mode) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_i2cioexpander_iopin_get_direction(self) == DIRECTION_INPUT) { + mp_raise_AttributeError(MP_ERROR_TEXT("Drive mode not used when direction is input.")); + return mp_const_none; + } + digitalio_drive_mode_t c_drive_mode = DRIVE_MODE_PUSH_PULL; + if (drive_mode == MP_ROM_PTR(&digitalio_drive_mode_open_drain_obj)) { + c_drive_mode = DRIVE_MODE_OPEN_DRAIN; + } + check_result(common_hal_i2cioexpander_iopin_set_drive_mode(self, c_drive_mode)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(i2cioexpander_iopin_set_drive_mode_obj, i2cioexpander_iopin_obj_set_drive_mode); + +MP_PROPERTY_GETSET(i2cioexpander_iopin_drive_mode_obj, + (mp_obj_t)&i2cioexpander_iopin_get_drive_mode_obj, + (mp_obj_t)&i2cioexpander_iopin_set_drive_mode_obj); + +//| pull: Optional[digitalio.Pull] +//| """The pin pull direction.""" +static mp_obj_t i2cioexpander_iopin_obj_get_pull(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_i2cioexpander_iopin_get_direction(self) == DIRECTION_OUTPUT) { + mp_raise_AttributeError(MP_ERROR_TEXT("Pull not used when direction is output.")); + return mp_const_none; + } + digitalio_pull_t pull = common_hal_i2cioexpander_iopin_get_pull(self); + if (pull == PULL_UP) { + return MP_OBJ_FROM_PTR(&digitalio_pull_up_obj); + } else if (pull == PULL_DOWN) { + return MP_OBJ_FROM_PTR(&digitalio_pull_down_obj); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_iopin_get_pull_obj, i2cioexpander_iopin_obj_get_pull); + +static mp_obj_t i2cioexpander_iopin_obj_set_pull(mp_obj_t self_in, mp_obj_t pull_obj) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_i2cioexpander_iopin_get_direction(self) == DIRECTION_OUTPUT) { + mp_raise_AttributeError(MP_ERROR_TEXT("Pull not used when direction is output.")); + return mp_const_none; + } + check_result(common_hal_i2cioexpander_iopin_set_pull(self, validate_pull(pull_obj, MP_QSTR_pull))); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(i2cioexpander_iopin_set_pull_obj, i2cioexpander_iopin_obj_set_pull); + +MP_PROPERTY_GETSET(i2cioexpander_iopin_pull_obj, + (mp_obj_t)&i2cioexpander_iopin_get_pull_obj, + (mp_obj_t)&i2cioexpander_iopin_set_pull_obj); + +// Protocol implementation for DigitalInOutProtocol +static void iopin_protocol_deinit(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_i2cioexpander_iopin_deinit(self); +} + +static bool iopin_protocol_deinited(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_deinited(self); +} + +static digitalinout_result_t iopin_protocol_switch_to_input(mp_obj_t self_in, digitalio_pull_t pull) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_switch_to_input(self, pull); +} + +static digitalinout_result_t iopin_protocol_switch_to_output(mp_obj_t self_in, bool value, digitalio_drive_mode_t drive_mode) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_switch_to_output(self, value, drive_mode); +} + +static digitalio_direction_t iopin_protocol_get_direction(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_get_direction(self); +} + +static mp_errno_t iopin_protocol_get_value(mp_obj_t self_in, bool *value) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_get_value(self, value); +} + +static mp_errno_t iopin_protocol_set_value(mp_obj_t self_in, bool value) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_set_value(self, value); +} + +static digitalio_drive_mode_t iopin_protocol_get_drive_mode(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_get_drive_mode(self); +} + +static digitalinout_result_t iopin_protocol_set_drive_mode(mp_obj_t self_in, digitalio_drive_mode_t drive_mode) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_set_drive_mode(self, drive_mode); +} + +static digitalio_pull_t iopin_protocol_get_pull(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_get_pull(self); +} + +static digitalinout_result_t iopin_protocol_set_pull(mp_obj_t self_in, digitalio_pull_t pull) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_set_pull(self, pull); +} + +static const digitalinout_p_t iopin_digitalinout_p = { + MP_PROTO_IMPLEMENT(MP_QSTR_DigitalInOut) + .deinit = iopin_protocol_deinit, + .deinited = iopin_protocol_deinited, + .switch_to_input = iopin_protocol_switch_to_input, + .switch_to_output = iopin_protocol_switch_to_output, + .get_direction = iopin_protocol_get_direction, + .get_value = iopin_protocol_get_value, + .set_value = iopin_protocol_set_value, + .get_drive_mode = iopin_protocol_get_drive_mode, + .set_drive_mode = iopin_protocol_set_drive_mode, + .get_pull = iopin_protocol_get_pull, + .set_pull = iopin_protocol_set_pull, +}; + +static const mp_rom_map_elem_t i2cioexpander_iopin_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_switch_to_input), MP_ROM_PTR(&i2cioexpander_iopin_switch_to_input_obj) }, + { MP_ROM_QSTR(MP_QSTR_switch_to_output), MP_ROM_PTR(&i2cioexpander_iopin_switch_to_output_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_direction), MP_ROM_PTR(&i2cioexpander_iopin_direction_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&i2cioexpander_iopin_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_drive_mode), MP_ROM_PTR(&i2cioexpander_iopin_drive_mode_obj) }, + { MP_ROM_QSTR(MP_QSTR_pull), MP_ROM_PTR(&i2cioexpander_iopin_pull_obj) }, +}; +static MP_DEFINE_CONST_DICT(i2cioexpander_iopin_locals_dict, i2cioexpander_iopin_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + i2cioexpander_iopin_type, + MP_QSTR_IOPin, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + protocol, &iopin_digitalinout_p, + locals_dict, &i2cioexpander_iopin_locals_dict + ); diff --git a/shared-bindings/i2cioexpander/IOPin.h b/shared-bindings/i2cioexpander/IOPin.h new file mode 100644 index 0000000000000..6a7d96130fa62 --- /dev/null +++ b/shared-bindings/i2cioexpander/IOPin.h @@ -0,0 +1,46 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "shared-module/i2cioexpander/IOPin.h" + +extern const mp_obj_type_t i2cioexpander_iopin_type; + +mp_errno_t i2cioexpander_iopin_construct( + i2cioexpander_iopin_obj_t *self, + i2cioexpander_ioexpander_obj_t *expander, + uint8_t pin_number); + +void common_hal_i2cioexpander_iopin_deinit(i2cioexpander_iopin_obj_t *self); +bool common_hal_i2cioexpander_iopin_deinited(i2cioexpander_iopin_obj_t *self); + +digitalinout_result_t common_hal_i2cioexpander_iopin_switch_to_input( + i2cioexpander_iopin_obj_t *self, + digitalio_pull_t pull); + +digitalinout_result_t common_hal_i2cioexpander_iopin_switch_to_output( + i2cioexpander_iopin_obj_t *self, + bool value, + digitalio_drive_mode_t drive_mode); + +digitalio_direction_t common_hal_i2cioexpander_iopin_get_direction(i2cioexpander_iopin_obj_t *self); + +mp_errno_t common_hal_i2cioexpander_iopin_set_value(i2cioexpander_iopin_obj_t *self, bool value); +mp_errno_t common_hal_i2cioexpander_iopin_get_value(i2cioexpander_iopin_obj_t *self, bool *value); + +digitalinout_result_t common_hal_i2cioexpander_iopin_set_drive_mode( + i2cioexpander_iopin_obj_t *self, + digitalio_drive_mode_t drive_mode); + +digitalio_drive_mode_t common_hal_i2cioexpander_iopin_get_drive_mode(i2cioexpander_iopin_obj_t *self); + +digitalinout_result_t common_hal_i2cioexpander_iopin_set_pull( + i2cioexpander_iopin_obj_t *self, + digitalio_pull_t pull); + +digitalio_pull_t common_hal_i2cioexpander_iopin_get_pull(i2cioexpander_iopin_obj_t *self); diff --git a/shared-bindings/i2cioexpander/__init__.c b/shared-bindings/i2cioexpander/__init__.c new file mode 100644 index 0000000000000..106c45c3768bf --- /dev/null +++ b/shared-bindings/i2cioexpander/__init__.c @@ -0,0 +1,49 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/i2cioexpander/__init__.h" +#include "shared-bindings/i2cioexpander/IOExpander.h" + +//| """Support for I2C-based GPIO expanders +//| +//| The `i2cioexpander` module contains classes to support I2C-based GPIO expanders +//| that can be controlled via simple register reads and writes. +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +//| Example:: +//| +//| import board +//| import busio +//| import i2cioexpander +//| +//| i2c = busio.I2C(board.SCL, board.SDA) +//| expander = i2cioexpander.IOExpander(i2c, 0x20, 8, 0x01, 0x00, 0x03) +//| pin0 = expander.pins[0] +//| pin0.switch_to_output(value=True) +//| """ + +static const mp_rom_map_elem_t i2cioexpander_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_i2cioexpander) }, + { MP_ROM_QSTR(MP_QSTR_IOExpander), MP_ROM_PTR(&i2cioexpander_ioexpander_type) }, +}; + +static MP_DEFINE_CONST_DICT(i2cioexpander_module_globals, i2cioexpander_module_globals_table); + +const mp_obj_module_t i2cioexpander_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&i2cioexpander_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_i2cioexpander, i2cioexpander_module); diff --git a/shared-bindings/i2cioexpander/__init__.h b/shared-bindings/i2cioexpander/__init__.h new file mode 100644 index 0000000000000..e0d0668686859 --- /dev/null +++ b/shared-bindings/i2cioexpander/__init__.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Nothing now. diff --git a/shared-bindings/sdcardio/SDCard.h b/shared-bindings/sdcardio/SDCard.h index 95998f5af5e90..ae364357707fe 100644 --- a/shared-bindings/sdcardio/SDCard.h +++ b/shared-bindings/sdcardio/SDCard.h @@ -7,6 +7,7 @@ #pragma once +#include "py/mperrno.h" #include "shared-module/sdcardio/SDCard.h" extern const mp_obj_type_t sdcardio_SDCard_type; @@ -17,9 +18,9 @@ bool common_hal_sdcardio_sdcard_deinited(sdcardio_sdcard_obj_t *self); void common_hal_sdcardio_sdcard_check_for_deinit(sdcardio_sdcard_obj_t *self); void common_hal_sdcardio_sdcard_mark_deinit(sdcardio_sdcard_obj_t *self); int common_hal_sdcardio_sdcard_get_blockcount(sdcardio_sdcard_obj_t *self); -int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf); -int common_hal_sdcardio_sdcard_sync(sdcardio_sdcard_obj_t *self); -int common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf); +mp_errno_t common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf); +mp_errno_t common_hal_sdcardio_sdcard_sync(sdcardio_sdcard_obj_t *self); +mp_errno_t common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf); // Used by native vfs blockdev. mp_uint_t sdcardio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t buflen); diff --git a/shared-bindings/sdioio/SDCard.h b/shared-bindings/sdioio/SDCard.h index dfeaf8fca8962..446ff3dfd7618 100644 --- a/shared-bindings/sdioio/SDCard.h +++ b/shared-bindings/sdioio/SDCard.h @@ -7,6 +7,7 @@ #pragma once #include "py/obj.h" +#include "py/mperrno.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/sdioio/SDCard.h" @@ -35,9 +36,14 @@ uint8_t common_hal_sdioio_sdcard_get_width(sdioio_sdcard_obj_t *self); // Return number of device blocks uint32_t common_hal_sdioio_sdcard_get_count(sdioio_sdcard_obj_t *self); -// Read or write blocks -int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo); -int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo); +// Read or write blocks - returns 0 on success or negative error code from mperrno.h +mp_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo); +mp_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo); + +// Used by native vfs blockdev. +mp_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t buflen); +mp_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t buflen); +bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, mp_int_t *out_value); // This is used by the supervisor to claim SDIO devices indefinitely. extern void common_hal_sdioio_sdcard_never_reset(sdioio_sdcard_obj_t *self); diff --git a/shared-bindings/socketpool/Socket.h b/shared-bindings/socketpool/Socket.h index a883ebd505463..295f86e737169 100644 --- a/shared-bindings/socketpool/Socket.h +++ b/shared-bindings/socketpool/Socket.h @@ -6,6 +6,7 @@ #pragma once +#include "py/mperrno.h" #include "common-hal/socketpool/Socket.h" extern const mp_obj_type_t socketpool_socket_type; diff --git a/shared-bindings/ssl/SSLSocket.c b/shared-bindings/ssl/SSLSocket.c index 92440f9ea30f7..4418a8e48d9c9 100644 --- a/shared-bindings/ssl/SSLSocket.c +++ b/shared-bindings/ssl/SSLSocket.c @@ -106,7 +106,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_connect_obj, ssl_sslsocket_connec //| def listen(self, backlog: int) -> None: //| """Set socket to listen for incoming connections //| -//| :param ~int backlog: length of backlog queue for waiting connetions""" +//| :param ~int backlog: length of backlog queue for waiting connections""" //| ... //| static mp_obj_t ssl_sslsocket_listen(mp_obj_t self_in, mp_obj_t backlog_in) { diff --git a/shared-module/bitbangio/I2C.c b/shared-module/bitbangio/I2C.c index 0089bdc1e1e1e..8e27298af7c0a 100644 --- a/shared-module/bitbangio/I2C.c +++ b/shared-module/bitbangio/I2C.c @@ -8,10 +8,15 @@ #include "py/mperrno.h" #include "py/obj.h" #include "py/runtime.h" +#include "py/gc.h" #include "common-hal/microcontroller/Pin.h" #include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" +#include "shared-bindings/util.h" +#include "supervisor/port.h" static void delay(bitbangio_i2c_obj_t *self) { // We need to use an accurate delay to get acceptable I2C @@ -19,61 +24,81 @@ static void delay(bitbangio_i2c_obj_t *self) { common_hal_mcu_delay_us(self->us_delay); } -static void scl_low(bitbangio_i2c_obj_t *self) { - common_hal_digitalio_digitalinout_set_value(&self->scl, false); +static bool scl_low(bitbangio_i2c_obj_t *self) { + return digitalinout_protocol_set_value(self->scl, false) == 0; } -static void scl_release(bitbangio_i2c_obj_t *self) { - common_hal_digitalio_digitalinout_set_value(&self->scl, true); +static bool scl_release(bitbangio_i2c_obj_t *self) { + if (digitalinout_protocol_set_value(self->scl, true) != 0) { + return false; + } uint32_t count = self->us_timeout; delay(self); // For clock stretching, wait for the SCL pin to be released, with timeout. - common_hal_digitalio_digitalinout_switch_to_input(&self->scl, PULL_UP); - for (; !common_hal_digitalio_digitalinout_get_value(&self->scl) && count; --count) { + digitalinout_protocol_switch_to_input(self->scl, PULL_UP); + bool value; + for (; count; --count) { + if (digitalinout_protocol_get_value(self->scl, &value) != 0) { + return false; + } + if (value) { + break; + } common_hal_mcu_delay_us(1); } - common_hal_digitalio_digitalinout_switch_to_output(&self->scl, true, DRIVE_MODE_OPEN_DRAIN); + digitalinout_protocol_switch_to_output(self->scl, true, DRIVE_MODE_OPEN_DRAIN); // raise exception on timeout if (count == 0) { mp_raise_msg_varg(&mp_type_TimeoutError, MP_ERROR_TEXT("%q too long"), MP_QSTR_timeout); } + return true; } -static void sda_low(bitbangio_i2c_obj_t *self) { - common_hal_digitalio_digitalinout_set_value(&self->sda, false); +static bool sda_low(bitbangio_i2c_obj_t *self) { + return digitalinout_protocol_set_value(self->sda, false) == 0; } -static void sda_release(bitbangio_i2c_obj_t *self) { - common_hal_digitalio_digitalinout_set_value(&self->sda, true); +static bool sda_release(bitbangio_i2c_obj_t *self) { + return digitalinout_protocol_set_value(self->sda, true) == 0; } -static bool sda_read(bitbangio_i2c_obj_t *self) { - common_hal_digitalio_digitalinout_switch_to_input(&self->sda, PULL_UP); - bool value = common_hal_digitalio_digitalinout_get_value(&self->sda); - common_hal_digitalio_digitalinout_switch_to_output(&self->sda, true, DRIVE_MODE_OPEN_DRAIN); - return value; +static bool sda_read(bitbangio_i2c_obj_t *self, bool *value) { + digitalinout_protocol_switch_to_input(self->sda, PULL_UP); + if (digitalinout_protocol_get_value(self->sda, value) != 0) { + return false; + } + digitalinout_protocol_switch_to_output(self->sda, true, DRIVE_MODE_OPEN_DRAIN); + return true; } -static void start(bitbangio_i2c_obj_t *self) { - sda_release(self); +static bool start(bitbangio_i2c_obj_t *self) { + if (!sda_release(self)) { + return false; + } delay(self); scl_release(self); sda_low(self); delay(self); + return true; } -static void stop(bitbangio_i2c_obj_t *self) { +static bool stop(bitbangio_i2c_obj_t *self) { delay(self); - sda_low(self); + if (!sda_low(self)) { + return false; + } delay(self); scl_release(self); sda_release(self); delay(self); + return true; } static int write_byte(bitbangio_i2c_obj_t *self, uint8_t val) { delay(self); - scl_low(self); + if (!scl_low(self)) { + return -1; + } for (int i = 7; i >= 0; i--) { if ((val >> i) & 1) { @@ -90,7 +115,10 @@ static int write_byte(bitbangio_i2c_obj_t *self, uint8_t val) { delay(self); scl_release(self); - int ret = sda_read(self); + bool ret; + if (!sda_read(self, &ret)) { + return -1; + } delay(self); scl_low(self); @@ -99,13 +127,17 @@ static int write_byte(bitbangio_i2c_obj_t *self, uint8_t val) { static bool read_byte(bitbangio_i2c_obj_t *self, uint8_t *val, bool ack) { delay(self); - scl_low(self); + if (!scl_low(self)) { + return false; + } delay(self); uint8_t data = 0; for (int i = 7; i >= 0; i--) { scl_release(self); - data = (data << 1) | sda_read(self); + bool bit; + sda_read(self, &bit); + data = (data << 1) | bit; scl_low(self); delay(self); } @@ -124,8 +156,8 @@ static bool read_byte(bitbangio_i2c_obj_t *self, uint8_t *val, bool ack) { } void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self, - const mcu_pin_obj_t *scl, - const mcu_pin_obj_t *sda, + mp_obj_t scl, + mp_obj_t sda, uint32_t frequency, uint32_t us_timeout) { @@ -134,32 +166,39 @@ void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self, if (self->us_delay == 0) { self->us_delay = 1; } - digitalinout_result_t result = common_hal_digitalio_digitalinout_construct(&self->scl, scl); - if (result != DIGITALINOUT_OK) { - return; - } - result = common_hal_digitalio_digitalinout_construct(&self->sda, sda); - if (result != DIGITALINOUT_OK) { - common_hal_digitalio_digitalinout_deinit(&self->scl); - return; - } - common_hal_digitalio_digitalinout_switch_to_output(&self->scl, true, DRIVE_MODE_OPEN_DRAIN); - common_hal_digitalio_digitalinout_switch_to_output(&self->sda, true, DRIVE_MODE_OPEN_DRAIN); - stop(self); + // Convert scl from Pin to DigitalInOutProtocol + self->scl = digitalinout_protocol_from_pin(scl, MP_QSTR_scl, false, false, &self->own_scl); + + // Convert sda from Pin to DigitalInOutProtocol + self->sda = digitalinout_protocol_from_pin(sda, MP_QSTR_sda, false, false, &self->own_sda); + + digitalinout_protocol_switch_to_output(self->scl, true, DRIVE_MODE_OPEN_DRAIN); + digitalinout_protocol_switch_to_output(self->sda, true, DRIVE_MODE_OPEN_DRAIN); + + if (!stop(self)) { + mp_raise_OSError(MP_EIO); + } } bool shared_module_bitbangio_i2c_deinited(bitbangio_i2c_obj_t *self) { // If one is deinited, both will be. - return common_hal_digitalio_digitalinout_deinited(&self->scl); + return digitalinout_protocol_deinited(self->scl); } void shared_module_bitbangio_i2c_deinit(bitbangio_i2c_obj_t *self) { if (shared_module_bitbangio_i2c_deinited(self)) { return; } - common_hal_digitalio_digitalinout_deinit(&self->scl); - common_hal_digitalio_digitalinout_deinit(&self->sda); + // Only deinit and free the pins if we own them + if (self->own_scl) { + digitalinout_protocol_deinit(self->scl); + circuitpy_free_obj(self->scl); + } + if (self->own_sda) { + digitalinout_protocol_deinit(self->sda); + circuitpy_free_obj(self->sda); + } } bool shared_module_bitbangio_i2c_try_lock(bitbangio_i2c_obj_t *self) { @@ -182,18 +221,28 @@ void shared_module_bitbangio_i2c_unlock(bitbangio_i2c_obj_t *self) { } bool shared_module_bitbangio_i2c_probe(bitbangio_i2c_obj_t *self, uint8_t addr) { - start(self); - bool ok = write_byte(self, addr << 1); + if (!start(self)) { + mp_raise_OSError(MP_EIO); + } + int result = write_byte(self, addr << 1); stop(self); - return ok; + if (result < 0) { + mp_raise_OSError(MP_EIO); + } + return result; } uint8_t shared_module_bitbangio_i2c_write(bitbangio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { // start the I2C transaction - start(self); + if (!start(self)) { + return MP_EIO; + } uint8_t status = 0; - if (!write_byte(self, addr << 1)) { + int result = write_byte(self, addr << 1); + if (result < 0) { + status = MP_EIO; + } else if (!result) { status = MP_ENODEV; } @@ -215,7 +264,9 @@ uint8_t shared_module_bitbangio_i2c_write(bitbangio_i2c_obj_t *self, uint16_t ad uint8_t shared_module_bitbangio_i2c_read(bitbangio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { // start the I2C transaction - start(self); + if (!start(self)) { + return MP_EIO; + } uint8_t status = 0; if (!write_byte(self, (addr << 1) | 1)) { status = MP_ENODEV; diff --git a/shared-module/bitbangio/I2C.h b/shared-module/bitbangio/I2C.h index 3908a3dd3740e..0cec9186e9b9d 100644 --- a/shared-module/bitbangio/I2C.h +++ b/shared-module/bitbangio/I2C.h @@ -12,9 +12,11 @@ typedef struct { mp_obj_base_t base; - digitalio_digitalinout_obj_t scl; - digitalio_digitalinout_obj_t sda; + mp_obj_t scl; + mp_obj_t sda; uint32_t us_delay; uint32_t us_timeout; volatile bool locked; + bool own_scl; + bool own_sda; } bitbangio_i2c_obj_t; diff --git a/shared-module/bitbangio/SPI.c b/shared-module/bitbangio/SPI.c index 56e978985edcc..b891d22c9aaaa 100644 --- a/shared-module/bitbangio/SPI.c +++ b/shared-module/bitbangio/SPI.c @@ -7,64 +7,63 @@ #include "py/mpconfig.h" #include "py/obj.h" #include "py/runtime.h" +#include "py/gc.h" #include "common-hal/microcontroller/Pin.h" #include "shared-bindings/bitbangio/SPI.h" #include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" #include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "supervisor/port.h" #define MAX_BAUDRATE (common_hal_mcu_get_clock_frequency() / 48) void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self, - const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, - const mcu_pin_obj_t *miso) { - digitalinout_result_t result = common_hal_digitalio_digitalinout_construct(&self->clock, clock); - if (result != DIGITALINOUT_OK) { - mp_raise_ValueError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_clock); - } - common_hal_digitalio_digitalinout_switch_to_output(&self->clock, self->polarity == 1, DRIVE_MODE_PUSH_PULL); + mp_obj_t clock, mp_obj_t mosi, mp_obj_t miso) { - if (mosi != NULL) { - result = common_hal_digitalio_digitalinout_construct(&self->mosi, mosi); - if (result != DIGITALINOUT_OK) { - common_hal_digitalio_digitalinout_deinit(&self->clock); - mp_raise_ValueError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_mosi); - } - self->has_mosi = true; - common_hal_digitalio_digitalinout_switch_to_output(&self->mosi, false, DRIVE_MODE_PUSH_PULL); - } + // Convert clock from Pin to DigitalInOutProtocol + self->clock = digitalinout_protocol_from_pin(clock, MP_QSTR_clock, false, false, &self->own_clock); + digitalinout_protocol_switch_to_output(self->clock, self->polarity == 1, DRIVE_MODE_PUSH_PULL); - if (miso != NULL) { - // Starts out as input by default, no need to change. - result = common_hal_digitalio_digitalinout_construct(&self->miso, miso); - if (result != DIGITALINOUT_OK) { - common_hal_digitalio_digitalinout_deinit(&self->clock); - if (mosi != NULL) { - common_hal_digitalio_digitalinout_deinit(&self->mosi); - } - mp_raise_ValueError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_miso); - } - self->has_miso = true; + // Convert mosi from Pin to DigitalInOutProtocol (optional) + self->mosi = digitalinout_protocol_from_pin(mosi, MP_QSTR_mosi, true, false, &self->own_mosi); + self->has_mosi = (self->mosi != mp_const_none); + if (self->has_mosi) { + digitalinout_protocol_switch_to_output(self->mosi, false, DRIVE_MODE_PUSH_PULL); } + + // Convert miso from Pin to DigitalInOutProtocol (optional) + self->miso = digitalinout_protocol_from_pin(miso, MP_QSTR_miso, true, false, &self->own_miso); + self->has_miso = (self->miso != mp_const_none); + // MISO starts out as input by default, no need to change + self->delay_half = 5; self->polarity = 0; self->phase = 0; } bool shared_module_bitbangio_spi_deinited(bitbangio_spi_obj_t *self) { - return common_hal_digitalio_digitalinout_deinited(&self->clock); + return digitalinout_protocol_deinited(self->clock); } void shared_module_bitbangio_spi_deinit(bitbangio_spi_obj_t *self) { if (shared_module_bitbangio_spi_deinited(self)) { return; } - common_hal_digitalio_digitalinout_deinit(&self->clock); - if (self->has_mosi) { - common_hal_digitalio_digitalinout_deinit(&self->mosi); + // Only deinit and free the pins if we own them + if (self->own_clock) { + digitalinout_protocol_deinit(self->clock); + circuitpy_free_obj(self->clock); + } + if (self->has_mosi && self->own_mosi) { + digitalinout_protocol_deinit(self->mosi); + circuitpy_free_obj(self->mosi); } - if (self->has_miso) { - common_hal_digitalio_digitalinout_deinit(&self->miso); + if (self->has_miso && self->own_miso) { + digitalinout_protocol_deinit(self->miso); + circuitpy_free_obj(self->miso); } } @@ -80,7 +79,7 @@ void shared_module_bitbangio_spi_configure(bitbangio_spi_obj_t *self, // If the polarity has changed, make sure we re-initialize the idle state // of the clock as well. self->polarity = polarity; - common_hal_digitalio_digitalinout_switch_to_output(&self->clock, polarity == 1, DRIVE_MODE_PUSH_PULL); + digitalinout_protocol_switch_to_output(self->clock, polarity == 1, DRIVE_MODE_PUSH_PULL); } self->phase = phase; } @@ -121,9 +120,15 @@ bool shared_module_bitbangio_spi_write(bitbangio_spi_obj_t *self, const uint8_t for (size_t i = 0; i < len; ++i) { uint8_t data_out = data[i]; for (int j = 0; j < 8; ++j, data_out <<= 1) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + if (i == 0 && j == 0) { + if (digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1) != 0) { + return false; + } + } else { + digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1); + } + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); } if (dest != NULL) { dest[i] = data_in; @@ -136,16 +141,22 @@ bool shared_module_bitbangio_spi_write(bitbangio_spi_obj_t *self, const uint8_t for (size_t i = 0; i < len; ++i) { uint8_t data_out = data[i]; for (int j = 0; j < 8; ++j, data_out <<= 1) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); + if (i == 0 && j == 0) { + if (!digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1)) { + return false; + } + } else { + digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1); + } if (self->phase == 0) { common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); } else { - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); common_hal_mcu_delay_us(delay_half); } } @@ -176,14 +187,18 @@ bool shared_module_bitbangio_spi_read(bitbangio_spi_obj_t *self, uint8_t *data, if (delay_half <= MICROPY_PY_MACHINE_SPI_MIN_DELAY) { // Clock out zeroes while we read. if (self->has_mosi) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, false); + if (digitalinout_protocol_set_value(self->mosi, false) != 0) { + return false; + } } for (size_t i = 0; i < len; ++i) { uint8_t data_in = 0; for (int j = 0; j < 8; ++j, data_out <<= 1) { - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); - data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); + bool bit; + digitalinout_protocol_get_value(self->miso, &bit); + data_in = (data_in << 1) | bit; + digitalinout_protocol_set_value(self->clock, self->polarity); } data[i] = data_in; } @@ -191,28 +206,32 @@ bool shared_module_bitbangio_spi_read(bitbangio_spi_obj_t *self, uint8_t *data, } #endif if (self->has_mosi) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, false); + if (!digitalinout_protocol_set_value(self->mosi, false)) { + return false; + } } for (size_t i = 0; i < len; ++i) { uint8_t data_out = write_data; uint8_t data_in = 0; for (int j = 0; j < 8; ++j, data_out <<= 1) { if (self->has_mosi) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); + digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1); } if (self->phase == 0) { common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); } else { - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); common_hal_mcu_delay_us(delay_half); } - data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); + bool bit; + digitalinout_protocol_get_value(self->miso, &bit); + data_in = (data_in << 1) | bit; if (self->phase == 0) { common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); } else { - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); common_hal_mcu_delay_us(delay_half); } } @@ -248,10 +267,18 @@ bool shared_module_bitbangio_spi_transfer(bitbangio_spi_obj_t *self, const uint8 uint8_t data_out = dout[i]; uint8_t data_in = 0; for (int j = 0; j < 8; ++j, data_out <<= 1) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); - data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + if (i == 0 && j == 0) { + if (digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1) != 0) { + return false; + } + } else { + digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1); + } + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); + bool bit; + digitalinout_protocol_get_value(self->miso, &bit); + data_in = (data_in << 1) | bit; + digitalinout_protocol_set_value(self->clock, self->polarity); } din[i] = data_in; @@ -267,20 +294,28 @@ bool shared_module_bitbangio_spi_transfer(bitbangio_spi_obj_t *self, const uint8 uint8_t data_out = dout[i]; uint8_t data_in = 0; for (int j = 0; j < 8; ++j, data_out <<= 1) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); + if (i == 0 && j == 0) { + if (!digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1)) { + return false; + } + } else { + digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1); + } if (self->phase == 0) { common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); } else { - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); common_hal_mcu_delay_us(delay_half); } - data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); + bool bit; + digitalinout_protocol_get_value(self->miso, &bit); + data_in = (data_in << 1) | bit; if (self->phase == 0) { common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); } else { - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); common_hal_mcu_delay_us(delay_half); } } diff --git a/shared-module/bitbangio/SPI.h b/shared-module/bitbangio/SPI.h index c19170af7c46f..5f3c109b7f685 100644 --- a/shared-module/bitbangio/SPI.h +++ b/shared-module/bitbangio/SPI.h @@ -12,13 +12,16 @@ typedef struct { mp_obj_base_t base; - digitalio_digitalinout_obj_t clock; - digitalio_digitalinout_obj_t mosi; - digitalio_digitalinout_obj_t miso; + mp_obj_t clock; + mp_obj_t mosi; + mp_obj_t miso; uint32_t delay_half; bool has_miso : 1; bool has_mosi : 1; uint8_t polarity : 1; uint8_t phase : 1; volatile bool locked : 1; + bool own_clock; + bool own_mosi; + bool own_miso; } bitbangio_spi_obj_t; diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index a9c0e9a6c80cf..6bfc0bbf0f1d9 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -156,6 +156,10 @@ void reset_board_buses(void) { } } #endif + #if CIRCUITPY_I2CIOEXPANDER + // Assume the native I2C bus is used for IO Expander pins. + display_using_i2c = true; + #endif if (i2c_obj_created[instance]) { // make sure I2C lock is not held over a soft reset common_hal_busio_i2c_unlock(&i2c_obj[instance]); diff --git a/shared-module/busdisplay/BusDisplay.c b/shared-module/busdisplay/BusDisplay.c index ac57f3bf3e019..a4652324c1e4f 100644 --- a/shared-module/busdisplay/BusDisplay.c +++ b/shared-module/busdisplay/BusDisplay.c @@ -80,7 +80,7 @@ void common_hal_busdisplay_busdisplay_construct(busdisplay_busdisplay_obj_t *sel memcpy(full_command + 1, data, data_size); self->bus.send(self->bus.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, full_command, data_size + 1); } else { - self->bus.send(self->bus.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, cmd, 1); + self->bus.send(self->bus.bus, DISPLAY_COMMAND, data_size > 0 ? CHIP_SELECT_TOGGLE_EVERY_BYTE : CHIP_SELECT_UNTOUCHED, cmd, 1); self->bus.send(self->bus.bus, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, data, data_size); } displayio_display_bus_end_transaction(&self->bus); diff --git a/shared-module/fourwire/FourWire.c b/shared-module/fourwire/FourWire.c index 0a168fa1563fc..0266401f9ce3a 100644 --- a/shared-module/fourwire/FourWire.c +++ b/shared-module/fourwire/FourWire.c @@ -11,13 +11,15 @@ #include "py/gc.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/time/__init__.h" +#include "supervisor/port.h" void common_hal_fourwire_fourwire_construct(fourwire_fourwire_obj_t *self, - busio_spi_obj_t *spi, const mcu_pin_obj_t *command, - const mcu_pin_obj_t *chip_select, const mcu_pin_obj_t *reset, uint32_t baudrate, + busio_spi_obj_t *spi, mp_obj_t command, + mp_obj_t chip_select, mp_obj_t reset, uint32_t baudrate, uint8_t polarity, uint8_t phase) { self->bus = spi; @@ -27,31 +29,24 @@ void common_hal_fourwire_fourwire_construct(fourwire_fourwire_obj_t *self, self->polarity = polarity; self->phase = phase; - - self->command.base.type = &mp_type_NoneType; - if (command != NULL) { - self->command.base.type = &digitalio_digitalinout_type; - common_hal_digitalio_digitalinout_construct(&self->command, command); - common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); + self->command = digitalinout_protocol_from_pin(command, MP_QSTR_command, true, false, &self->own_command); + if (self->command != mp_const_none) { + digitalinout_protocol_switch_to_output(self->command, true, DRIVE_MODE_PUSH_PULL); common_hal_never_reset_pin(command); } - self->reset.base.type = &mp_type_NoneType; - if (reset != NULL) { - self->reset.base.type = &digitalio_digitalinout_type; - common_hal_digitalio_digitalinout_construct(&self->reset, reset); - common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + + self->reset = digitalinout_protocol_from_pin(reset, MP_QSTR_reset, true, false, &self->own_reset); + if (self->reset != mp_const_none) { + digitalinout_protocol_switch_to_output(self->reset, true, DRIVE_MODE_PUSH_PULL); common_hal_never_reset_pin(reset); common_hal_fourwire_fourwire_reset(self); } - self->chip_select.base.type = &mp_type_NoneType; - if (chip_select != NULL) { - self->chip_select.base.type = &digitalio_digitalinout_type; - common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); - common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); + self->chip_select = digitalinout_protocol_from_pin(chip_select, MP_QSTR_chip_select, true, false, &self->own_chip_select); + if (self->chip_select != mp_const_none) { + digitalinout_protocol_switch_to_output(self->chip_select, true, DRIVE_MODE_PUSH_PULL); common_hal_never_reset_pin(chip_select); } - } void common_hal_fourwire_fourwire_deinit(fourwire_fourwire_obj_t *self) { @@ -59,19 +54,33 @@ void common_hal_fourwire_fourwire_deinit(fourwire_fourwire_obj_t *self) { common_hal_busio_spi_deinit(self->bus); } - common_hal_reset_pin(self->command.pin); - common_hal_reset_pin(self->chip_select.pin); - common_hal_reset_pin(self->reset.pin); + // Only deinit and free the pins if we own them + if (self->command != mp_const_none && self->own_command) { + digitalinout_protocol_deinit(self->command); + circuitpy_free_obj(self->command); + } + if (self->chip_select != mp_const_none && self->own_chip_select) { + digitalinout_protocol_deinit(self->chip_select); + circuitpy_free_obj(self->chip_select); + } + if (self->reset != mp_const_none && self->own_reset) { + digitalinout_protocol_deinit(self->reset); + circuitpy_free_obj(self->reset); + } } bool common_hal_fourwire_fourwire_reset(mp_obj_t obj) { fourwire_fourwire_obj_t *self = MP_OBJ_TO_PTR(obj); - if (self->reset.base.type == &mp_type_NoneType) { + if (self->reset == mp_const_none) { + return false; + } + if (digitalinout_protocol_set_value(self->reset, false) != 0) { return false; } - common_hal_digitalio_digitalinout_set_value(&self->reset, false); common_hal_mcu_delay_us(1000); - common_hal_digitalio_digitalinout_set_value(&self->reset, true); + if (digitalinout_protocol_set_value(self->reset, true) != 0) { + return false; + } common_hal_mcu_delay_us(1000); return true; } @@ -92,16 +101,23 @@ bool common_hal_fourwire_fourwire_begin_transaction(mp_obj_t obj) { } common_hal_busio_spi_configure(self->bus, self->frequency, self->polarity, self->phase, 8); - if (self->chip_select.base.type != &mp_type_NoneType) { - common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + if (self->chip_select != mp_const_none) { + // IO Expander CS can fail due to an I2C lock. + if (digitalinout_protocol_set_value(self->chip_select, false) != 0) { + common_hal_busio_spi_unlock(self->bus); + return false; + } } return true; } void common_hal_fourwire_fourwire_send(mp_obj_t obj, display_byte_type_t data_type, display_chip_select_behavior_t chip_select, const uint8_t *data, uint32_t data_length) { + if (data_length == 0) { + return; + } fourwire_fourwire_obj_t *self = MP_OBJ_TO_PTR(obj); - if (self->command.base.type == &mp_type_NoneType) { + if (self->command == mp_const_none) { // When the data/command pin is not specified, we simulate a 9-bit SPI mode, by // adding a data/command bit to every byte, and then splitting the resulting data back // into 8-bit chunks for transmission. If the length of the data being transmitted @@ -133,24 +149,24 @@ void common_hal_fourwire_fourwire_send(mp_obj_t obj, display_byte_type_t data_ty if (bits > 0) { buffer = buffer << (8 - bits); common_hal_busio_spi_write(self->bus, &buffer, 1); - if (self->chip_select.base.type != &mp_type_NoneType) { + if (self->chip_select != mp_const_none) { // toggle CS to discard superfluous bits - common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); + digitalinout_protocol_set_value(self->chip_select, true); common_hal_mcu_delay_us(1); - common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + digitalinout_protocol_set_value(self->chip_select, false); } } } else { - common_hal_digitalio_digitalinout_set_value(&self->command, data_type == DISPLAY_DATA); + digitalinout_protocol_set_value(self->command, data_type == DISPLAY_DATA); if (chip_select == CHIP_SELECT_TOGGLE_EVERY_BYTE) { // Toggle chip select after each command byte in case the display driver // IC latches commands based on it. for (size_t i = 0; i < data_length; i++) { common_hal_busio_spi_write(self->bus, &data[i], 1); - if (self->chip_select.base.type != &mp_type_NoneType) { - common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); + if (self->chip_select != mp_const_none) { + digitalinout_protocol_set_value(self->chip_select, true); common_hal_mcu_delay_us(1); - common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + digitalinout_protocol_set_value(self->chip_select, false); } } } else { @@ -161,8 +177,8 @@ void common_hal_fourwire_fourwire_send(mp_obj_t obj, display_byte_type_t data_ty void common_hal_fourwire_fourwire_end_transaction(mp_obj_t obj) { fourwire_fourwire_obj_t *self = MP_OBJ_TO_PTR(obj); - if (self->chip_select.base.type != &mp_type_NoneType) { - common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); + if (self->chip_select != mp_const_none) { + digitalinout_protocol_set_value(self->chip_select, true); } common_hal_busio_spi_unlock(self->bus); } diff --git a/shared-module/fourwire/FourWire.h b/shared-module/fourwire/FourWire.h index 629a426b3b035..c239a3dfde374 100644 --- a/shared-module/fourwire/FourWire.h +++ b/shared-module/fourwire/FourWire.h @@ -6,6 +6,8 @@ #pragma once +#include + #include "common-hal/busio/SPI.h" #include "common-hal/digitalio/DigitalInOut.h" #include "shared-module/displayio/Group.h" @@ -14,10 +16,13 @@ typedef struct { mp_obj_base_t base; busio_spi_obj_t *bus; busio_spi_obj_t inline_bus; - digitalio_digitalinout_obj_t command; - digitalio_digitalinout_obj_t chip_select; - digitalio_digitalinout_obj_t reset; + mp_obj_t command; + mp_obj_t chip_select; + mp_obj_t reset; uint32_t frequency; uint8_t polarity; uint8_t phase; + bool own_command; + bool own_chip_select; + bool own_reset; } fourwire_fourwire_obj_t; diff --git a/shared-module/i2cioexpander/IOExpander.c b/shared-module/i2cioexpander/IOExpander.c new file mode 100644 index 0000000000000..5146abc66e616 --- /dev/null +++ b/shared-module/i2cioexpander/IOExpander.c @@ -0,0 +1,196 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/i2cioexpander/IOExpander.h" +#include "shared-bindings/i2cioexpander/IOPin.h" + +#include + +#include "py/gc.h" +#include "py/runtime.h" +#include "shared-bindings/busio/I2C.h" +#include "supervisor/port.h" + +void common_hal_i2cioexpander_ioexpander_construct( + i2cioexpander_ioexpander_obj_t *self, + mp_obj_t i2c, + uint8_t address, + uint8_t num_pins, + uint16_t set_value_reg, + uint16_t get_value_reg, + uint16_t set_direction_reg) { + + // Store the I2C bus + self->i2c = (busio_i2c_obj_t *)i2c; + self->address = address; + self->num_pins = num_pins; + self->output_value = 0; + self->output_mask = 0; + + // Parse optional register addresses + self->has_set_value = (set_value_reg != NO_REGISTER); + if (self->has_set_value) { + self->set_value_reg = set_value_reg; + } + + self->has_get_value = (get_value_reg != NO_REGISTER); + if (self->has_get_value) { + self->get_value_reg = get_value_reg; + } + + self->has_set_direction = (set_direction_reg != NO_REGISTER); + if (self->has_set_direction) { + self->set_direction_reg = set_direction_reg; + } + + bool allocate_in_port_heap = !gc_alloc_possible() || !gc_ptr_on_heap(self); + + // Allocate tuple with space for pin objects in items[] + size_t tuple_size = offsetof(mp_obj_tuple_t, items) + sizeof(mp_obj_t) * num_pins; + mp_obj_tuple_t *pins_tuple = allocate_in_port_heap ? port_malloc(tuple_size, false) : m_malloc(tuple_size); + pins_tuple->base.type = &mp_type_tuple; + pins_tuple->len = num_pins; + + // Create IOPin objects for each pin + size_t pin_size = sizeof(i2cioexpander_iopin_obj_t); + for (uint8_t i = 0; i < num_pins; i++) { + i2cioexpander_iopin_obj_t *pin = allocate_in_port_heap ? port_malloc(pin_size, false) : m_malloc(pin_size); + pin->base.type = &i2cioexpander_iopin_type; + i2cioexpander_iopin_construct(pin, self, i); + pins_tuple->items[i] = MP_OBJ_FROM_PTR(pin); + } + + self->pins = pins_tuple; +} + +void common_hal_i2cioexpander_ioexpander_deinit(i2cioexpander_ioexpander_obj_t *self) { + if (gc_alloc_possible() && !gc_ptr_on_heap(self)) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Cannot deinitialize board IOExpander")); + } + for (uint8_t i = 0; i < self->num_pins; i++) { + circuitpy_free_obj(self->pins->items[i]); + } + circuitpy_free_obj(self->pins); + self->i2c = NULL; +} + +bool common_hal_i2cioexpander_ioexpander_deinited(i2cioexpander_ioexpander_obj_t *self) { + return self->i2c == NULL; +} + +mp_errno_t common_hal_i2cioexpander_ioexpander_get_input_value(i2cioexpander_ioexpander_obj_t *self, size_t *value) { + uint8_t buffer[2]; + uint8_t num_bytes = (self->num_pins > 8) ? 2 : 1; + + while (!common_hal_busio_i2c_try_lock(self->i2c)) { + RUN_BACKGROUND_TASKS; + } + + mp_errno_t result; + if (self->has_get_value) { + // Send register address then read + result = common_hal_busio_i2c_write_read( + self->i2c, self->address, &self->get_value_reg, 1, buffer, num_bytes); + } else { + // Read directly without register address + result = common_hal_busio_i2c_read(self->i2c, self->address, buffer, num_bytes); + } + common_hal_busio_i2c_unlock(self->i2c); + + if (result != 0) { + return result; + } + + if (num_bytes == 2) { + *value = buffer[0] | (buffer[1] << 8); + } else { + *value = buffer[0]; + } + return 0; +} + +void common_hal_i2cioexpander_ioexpander_get_output_value(i2cioexpander_ioexpander_obj_t *self, size_t *value) { + *value = self->output_value; +} + +mp_errno_t common_hal_i2cioexpander_ioexpander_set_output_value(i2cioexpander_ioexpander_obj_t *self, size_t value) { + uint8_t buffer[5]; + uint8_t num_bytes = 0; + + // Add register address if provided + if (self->has_set_value) { + buffer[num_bytes++] = self->set_value_reg; + } + + size_t current_value = self->output_value; + if (current_value == value) { + return 0; + } + size_t diff = current_value ^ value; + + // Add value byte(s) but only if a high bit is changed + buffer[num_bytes++] = value & 0xFF; + if (self->num_pins > 8 && (diff >> 8) != 0) { + buffer[num_bytes++] = (value >> 8) & 0xFF; + } + if (self->num_pins > 16 && (diff >> 16) != 0) { + buffer[num_bytes++] = (value >> 16) & 0xFF; + } + if (self->num_pins > 24 && (diff >> 24) != 0) { + buffer[num_bytes++] = (value >> 24) & 0xFF; + } + + if (!common_hal_busio_i2c_try_lock(self->i2c)) { + return -MP_EBUSY; + } + + mp_errno_t result = common_hal_busio_i2c_write(self->i2c, self->address, buffer, num_bytes); + common_hal_busio_i2c_unlock(self->i2c); + if (result == 0) { + self->output_value = value; + } + return result; +} + +void common_hal_i2cioexpander_ioexpander_get_output_mask(i2cioexpander_ioexpander_obj_t *self, size_t *mask) { + *mask = self->output_mask; +} + +mp_errno_t common_hal_i2cioexpander_ioexpander_set_output_mask(i2cioexpander_ioexpander_obj_t *self, size_t mask) { + self->output_mask = mask; + + // Only write to device if direction register is provided + if (!self->has_set_direction) { + return 0; + } + + uint8_t buffer[3]; + uint8_t num_bytes = 0; + + // Add register address + buffer[num_bytes++] = self->set_direction_reg; + + // Invert the mask so 0 indicates output. We taken 1 for output to match output enable. + size_t inverted_mask = ~mask; + + // Add mask byte(s) + buffer[num_bytes++] = inverted_mask & 0xFF; + if (self->num_pins > 8) { + buffer[num_bytes++] = (inverted_mask >> 8) & 0xFF; + } + + if (!common_hal_busio_i2c_try_lock(self->i2c)) { + return -MP_EBUSY; + } + + mp_errno_t result = common_hal_busio_i2c_write(self->i2c, self->address, buffer, num_bytes); + common_hal_busio_i2c_unlock(self->i2c); + return result; +} + +mp_obj_t common_hal_i2cioexpander_ioexpander_get_pins(i2cioexpander_ioexpander_obj_t *self) { + return MP_OBJ_FROM_PTR(self->pins); +} diff --git a/shared-module/i2cioexpander/IOExpander.h b/shared-module/i2cioexpander/IOExpander.h new file mode 100644 index 0000000000000..e225bfc75c778 --- /dev/null +++ b/shared-module/i2cioexpander/IOExpander.h @@ -0,0 +1,41 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "py/obj.h" +#include "py/objtuple.h" +#include "shared-bindings/busio/I2C.h" + +#define NO_REGISTER (0x100) + +typedef struct { + mp_obj_base_t base; + busio_i2c_obj_t *i2c; + uint8_t address; + uint8_t num_pins; + uint8_t set_value_reg; + uint8_t get_value_reg; + uint8_t set_direction_reg; + size_t output_value; + size_t output_mask; + bool has_set_value; + bool has_get_value; + bool has_set_direction; + mp_obj_tuple_t *pins; +} i2cioexpander_ioexpander_obj_t; + +void common_hal_i2cioexpander_ioexpander_construct( + i2cioexpander_ioexpander_obj_t *self, + mp_obj_t i2c, + uint8_t address, + uint8_t num_pins, + uint16_t set_value_reg, + uint16_t get_value_reg, + uint16_t set_direction_reg); diff --git a/shared-module/i2cioexpander/IOPin.c b/shared-module/i2cioexpander/IOPin.c new file mode 100644 index 0000000000000..9502d2814f3fb --- /dev/null +++ b/shared-module/i2cioexpander/IOPin.c @@ -0,0 +1,148 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/i2cioexpander/IOPin.h" +#include "shared-bindings/i2cioexpander/IOExpander.h" + +#include "py/runtime.h" + +mp_errno_t i2cioexpander_iopin_construct( + i2cioexpander_iopin_obj_t *self, + i2cioexpander_ioexpander_obj_t *expander, + uint8_t pin_number) { + + if (pin_number >= expander->num_pins) { + return MP_EINVAL; // Reusing this for "invalid pin" + } + + self->expander = expander; + self->pin_number = pin_number; + self->direction = DIRECTION_INPUT; + + return 0; +} + +void common_hal_i2cioexpander_iopin_deinit(i2cioexpander_iopin_obj_t *self) { + // Switch to input on deinit. + common_hal_i2cioexpander_iopin_switch_to_input(self, PULL_NONE); +} + +bool common_hal_i2cioexpander_iopin_deinited(i2cioexpander_iopin_obj_t *self) { + return self->expander == NULL || common_hal_i2cioexpander_ioexpander_deinited(self->expander); +} + +digitalinout_result_t common_hal_i2cioexpander_iopin_switch_to_input( + i2cioexpander_iopin_obj_t *self, + digitalio_pull_t pull) { + + if (pull != PULL_NONE) { + // IO expanders typically don't support pull resistors + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL + return DIGITALINOUT_INVALID_PULL; + #endif + } + + self->direction = DIRECTION_INPUT; + + // Clear the output mask bit for this pin + size_t new_mask = self->expander->output_mask & ~(1 << self->pin_number); + common_hal_i2cioexpander_ioexpander_set_output_mask(self->expander, new_mask); + + return DIGITALINOUT_OK; +} + +digitalinout_result_t common_hal_i2cioexpander_iopin_switch_to_output( + i2cioexpander_iopin_obj_t *self, + bool value, + digitalio_drive_mode_t drive_mode) { + + if (drive_mode != DRIVE_MODE_PUSH_PULL) { + // IO expanders typically only support push-pull + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE + return DIGITALINOUT_INVALID_DRIVE_MODE; + #endif + } + + self->direction = DIRECTION_OUTPUT; + + // Set the value first + size_t new_value = self->expander->output_value; + if (value) { + new_value |= (1 << self->pin_number); + } else { + new_value &= ~(1 << self->pin_number); + } + common_hal_i2cioexpander_ioexpander_set_output_value(self->expander, new_value); + + // Set the output mask bit for this pin + size_t new_mask = self->expander->output_mask | (1 << self->pin_number); + common_hal_i2cioexpander_ioexpander_set_output_mask(self->expander, new_mask); + + return DIGITALINOUT_OK; +} + +digitalio_direction_t common_hal_i2cioexpander_iopin_get_direction(i2cioexpander_iopin_obj_t *self) { + return self->direction; +} + +mp_errno_t common_hal_i2cioexpander_iopin_set_value(i2cioexpander_iopin_obj_t *self, bool value) { + size_t current_value; + common_hal_i2cioexpander_ioexpander_get_output_value(self->expander, ¤t_value); + size_t new_value; + if (value) { + new_value = current_value | (1 << self->pin_number); + } else { + new_value = current_value & ~(1 << self->pin_number); + } + if (new_value != current_value) { + return common_hal_i2cioexpander_ioexpander_set_output_value(self->expander, new_value); + } + return 0; +} + +mp_errno_t common_hal_i2cioexpander_iopin_get_value(i2cioexpander_iopin_obj_t *self, bool *value) { + size_t full_value; + mp_errno_t result = common_hal_i2cioexpander_ioexpander_get_input_value(self->expander, &full_value); + if (result != 0) { + return result; + } + *value = (full_value & (1 << self->pin_number)) != 0; + return 0; +} + +digitalinout_result_t common_hal_i2cioexpander_iopin_set_drive_mode( + i2cioexpander_iopin_obj_t *self, + digitalio_drive_mode_t drive_mode) { + + if (drive_mode != DRIVE_MODE_PUSH_PULL) { + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE + return DIGITALINOUT_INVALID_DRIVE_MODE; + #endif + } + + return DIGITALINOUT_OK; +} + +digitalio_drive_mode_t common_hal_i2cioexpander_iopin_get_drive_mode(i2cioexpander_iopin_obj_t *self) { + return DRIVE_MODE_PUSH_PULL; +} + +digitalinout_result_t common_hal_i2cioexpander_iopin_set_pull( + i2cioexpander_iopin_obj_t *self, + digitalio_pull_t pull) { + + if (pull != PULL_NONE) { + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL + return DIGITALINOUT_INVALID_PULL; + #endif + } + + return DIGITALINOUT_OK; +} + +digitalio_pull_t common_hal_i2cioexpander_iopin_get_pull(i2cioexpander_iopin_obj_t *self) { + return PULL_NONE; +} diff --git a/shared-module/i2cioexpander/IOPin.h b/shared-module/i2cioexpander/IOPin.h new file mode 100644 index 0000000000000..0c4da8a0213fc --- /dev/null +++ b/shared-module/i2cioexpander/IOPin.h @@ -0,0 +1,26 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "py/obj.h" +#include "shared-bindings/digitalio/Direction.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/digitalio/Pull.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-module/i2cioexpander/IOExpander.h" + +typedef struct { + mp_obj_base_t base; + i2cioexpander_ioexpander_obj_t *expander; + uint8_t pin_number; + digitalio_direction_t direction; +} i2cioexpander_iopin_obj_t; + +extern const mp_obj_type_t i2cioexpander_iopin_type; diff --git a/shared-module/i2cioexpander/__init__.c b/shared-module/i2cioexpander/__init__.c new file mode 100644 index 0000000000000..43e652db897e0 --- /dev/null +++ b/shared-module/i2cioexpander/__init__.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Nothing now. diff --git a/supervisor/port.h b/supervisor/port.h index 0bf8fd8d01350..192307a5f5714 100644 --- a/supervisor/port.h +++ b/supervisor/port.h @@ -115,3 +115,8 @@ bool port_boot_button_pressed(void); void *mp_obj_port_malloc_helper(size_t num_bytes, const mp_obj_type_t *type); mp_obj_t mp_obj_new_port_tuple(size_t n, const mp_obj_t *items); + +// Safely free an object that may have been allocated from either the GC heap or port heap. +// If the pointer is on the GC heap, it will be freed by the GC automatically. +// If the pointer is not on the GC heap, it will be freed with port_free. +void circuitpy_free_obj(mp_obj_t obj); diff --git a/supervisor/shared/port.c b/supervisor/shared/port.c index aabf003fb302d..f908e3f0bd877 100644 --- a/supervisor/shared/port.c +++ b/supervisor/shared/port.c @@ -9,6 +9,7 @@ #include #include "py/runtime.h" +#include "py/gc.h" #include "lib/tlsf/tlsf.h" @@ -56,6 +57,22 @@ MP_WEAK void port_free(void *ptr) { tlsf_free(heap, ptr); } +// Safely free an object that may have been allocated from either the GC heap or port heap. +// If the pointer is on the GC heap, it will be freed by the GC automatically, so we do nothing. +// If the pointer is not on the GC heap (i.e., allocated with port_malloc), we free it with port_free. +// This is safe to call during shutdown when GC may not be available. +void circuitpy_free_obj(mp_obj_t obj) { + if (obj == mp_const_none) { + return; + } + void *ptr = MP_OBJ_TO_PTR(obj); + if (gc_alloc_possible() && gc_ptr_on_heap(ptr)) { + gc_free(ptr); + } else { + port_free(ptr); + } +} + MP_WEAK void *port_realloc(void *ptr, size_t size, bool dma_capable) { return tlsf_realloc(heap, ptr, size); } diff --git a/supervisor/shared/status_leds.c b/supervisor/shared/status_leds.c index ffe8b46b20b7c..ca29fd79212cf 100644 --- a/supervisor/shared/status_leds.c +++ b/supervisor/shared/status_leds.c @@ -133,9 +133,9 @@ void status_led_init(void) { memset(status_apa102_color + 4, 0xff, APA102_BUFFER_LENGTH - 4); #if CIRCUITPY_BITBANG_APA102 shared_module_bitbangio_spi_construct(&status_apa102, - MICROPY_HW_APA102_SCK, - MICROPY_HW_APA102_MOSI, - NULL); + MP_OBJ_FROM_PTR(MICROPY_HW_APA102_SCK), + MP_OBJ_FROM_PTR(MICROPY_HW_APA102_MOSI), + mp_const_none); #else if (!common_hal_busio_spi_deinited(&status_apa102)) { common_hal_busio_spi_deinit(&status_apa102); diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c index eea11bd5fb4af..553fe8694c6ea 100644 --- a/supervisor/shared/web_workflow/web_workflow.c +++ b/supervisor/shared/web_workflow/web_workflow.c @@ -1085,6 +1085,10 @@ static void _reply_static(socketpool_socket_obj_t *socket, _request *request, co "Content-Encoding: gzip\r\n", "Content-Length: ", encoded_len, "\r\n", "Content-Type: ", content_type, "\r\n", + #if CIRCUITPY_DEBUG == 0 + "Cache-Control: max-age=31536000\r\n", // Cache for a year. + "Vary: Accept\r\n", + #endif "\r\n", NULL); web_workflow_send_raw(socket, true, response, response_len); } diff --git a/tools/safe_mode_finder.py b/tools/safe_mode_finder.py index fece85312788f..af3ff0d3c6d7b 100644 --- a/tools/safe_mode_finder.py +++ b/tools/safe_mode_finder.py @@ -86,8 +86,8 @@ print(e.has_dwarf_info()) d = e.get_dwarf_info() # print(dir(d)) - aranges = d.get_aranges() - cu_offset = aranges.cu_offset_at_addr(pc) + arranges = d.get_aranges() + cu_offset = arranges.cu_offset_at_addr(pc) if not cu_offset: cu_offset = 0 main_cu = d.get_CU_at(cu_offset)