diff --git a/.github/workflows/build-rapid-0.yaml b/.github/workflows/build-rapid-0.yaml new file mode 100644 index 000000000000..c36407914e7a --- /dev/null +++ b/.github/workflows/build-rapid-0.yaml @@ -0,0 +1,53 @@ +name: Build RAPID-0 Boards + +on: + push: + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + board: [rapid0_adcs, rapid0_cdh, rapid0_eps] + steps: + - name: Set up repository + uses: actions/checkout@v4 + with: + submodules: false + show-progress: false + fetch-depth: 1 + - name: Set up python + uses: actions/setup-python@v5 + with: + python-version: 3.x + - name: Set up ports + id: set-up-port + uses: ./.github/actions/deps/ports + with: + board: ${{ matrix.board }} + - name: Set up submodules + id: set-up-submodules + uses: ./.github/actions/deps/submodules + with: + action: cache + version: true + - name: Set up external + uses: ./.github/actions/deps/external + with: + action: cache + port: ${{ steps.set-up-port.outputs.port }} + - name: Set up mpy-cross + if: steps.set-up-submodules.outputs.frozen == 'True' + uses: ./.github/actions/mpy_cross + with: + cp-version: ${{ steps.set-up-submodules.outputs.version }} + download: false + - name: Build boards + run: make -j4 -C ports/atmel-samd BOARD=${{ matrix.board }} + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.board }} + path: ports/atmel-samd/build-${{ matrix.board }}/firmware.* + overwrite: true + diff --git a/build-rapid0-mac b/build-rapid0-mac new file mode 100755 index 000000000000..01fba1bdc1a8 --- /dev/null +++ b/build-rapid0-mac @@ -0,0 +1,18 @@ +if echo $PATH | grep "gcc-arm-none-eabi" >/dev/null; then + true +else + export PATH=/Volumes/Circuit_Python_Case_Sensitive_Disk/bruinspace-circuitpython/gcc-arm-none-eabi-10-2020-q4-major/bin:$PATH +fi + +cd ports/atmel-samd +make --debug -j8 BOARD=rapid0_adcs +make --debug -j8 BOARD=rapid0_cdh +make --debug -j8 BOARD=rapid0_eps +cd ../.. + +echo "Compilation complete! Press ^C to confirm and exit." + +while true; do + afplay /System/Library/Sounds/Ping.aiff + sleep 5s +done diff --git a/build-rapid0-ubuntu b/build-rapid0-ubuntu new file mode 100644 index 000000000000..b2fcec5053f6 --- /dev/null +++ b/build-rapid0-ubuntu @@ -0,0 +1,17 @@ +if echo $PATH | grep "gcc-arm-none-eabi" >/dev/null +then + true +else + export PATH=/mnt/d/Files/Documents/School/UCLA/Organizations/BruinSpace/Rapid-CDH/gcc-arm-none-eabi-10-2020-q4-major/bin:$PATH +fi +cd ports/atmel-samd +make --debug -j8 BOARD=rapid0_adcs +make --debug -j8 BOARD=rapid0_cdh +make --debug -j8 BOARD=rapid0_eps +cd ../.. +echo "Compilation complete! Press ^C to confirm and exit." +while true; +do + paplay /usr/share/sounds/freedesktop/stereo/complete.oga + sleep 5s +done \ No newline at end of file diff --git a/docs/porting.rst b/docs/porting.rst index f4ed2ab4cc86..9cb28b7e5d4a 100644 --- a/docs/porting.rst +++ b/docs/porting.rst @@ -72,6 +72,7 @@ as a natural "TODO" list. An example minimal build list is shown below: CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CTARGET = 0 + CIRCUITPY_SPITARGET = 0 # Requires SPI, PulseIO (stub ok): CIRCUITPY_DISPLAYIO = 0 diff --git a/ports/atmel-samd/boards/hallowing_m4_express/board.c b/ports/atmel-samd/boards/hallowing_m4_express/board.c index d8218d7151aa..82d8cea619b6 100644 --- a/ports/atmel-samd/boards/hallowing_m4_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m4_express/board.c @@ -50,7 +50,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_PA01, &pin_PA00, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_PA01, &pin_PA00, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h index 722a737786f4..3b9ca9666988 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h @@ -12,7 +12,7 @@ #define MICROPY_HW_NEOPIXEL (&pin_PB22) -#define BOARD_HAS_CRYSTAL 0 +#define BOARD_HAS_CRYSTAL 1 #define DEFAULT_I2C_BUS_SCL (&pin_PB03) #define DEFAULT_I2C_BUS_SDA (&pin_PB02) diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk index e44bc7fcb81d..4f01c141e484 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk @@ -11,7 +11,6 @@ EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C, W25Q16JVxQ" LONGINT_IMPL = MPZ CIRCUITPY__EVE = 1 -CIRCUITPY_CANIO = 0 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_JPEGIO = 0 CIRCUITPY_SYNTHIO = 0 diff --git a/ports/atmel-samd/boards/monster_m4sk/board.c b/ports/atmel-samd/boards/monster_m4sk/board.c index 2b015443ddee..34948b6a34b5 100644 --- a/ports/atmel-samd/boards/monster_m4sk/board.c +++ b/ports/atmel-samd/boards/monster_m4sk/board.c @@ -50,7 +50,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA12, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA12, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/atmel-samd/boards/openbook_m4/board.c b/ports/atmel-samd/boards/openbook_m4/board.c index 079544f42b99..d6911c7a07c3 100644 --- a/ports/atmel-samd/boards/openbook_m4/board.c +++ b/ports/atmel-samd/boards/openbook_m4/board.c @@ -59,7 +59,7 @@ uint8_t refresh_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/atmel-samd/boards/pewpew_lcd/board.c b/ports/atmel-samd/boards/pewpew_lcd/board.c index f7357d690882..3e1a1c1cf62c 100644 --- a/ports/atmel-samd/boards/pewpew_lcd/board.c +++ b/ports/atmel-samd/boards/pewpew_lcd/board.c @@ -70,7 +70,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_PA23, &pin_PA22, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_PA23, &pin_PA22, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/atmel-samd/boards/pewpew_m4/board.c b/ports/atmel-samd/boards/pewpew_m4/board.c index e55ef0899a0f..ba37a9ddcea8 100644 --- a/ports/atmel-samd/boards/pewpew_m4/board.c +++ b/ports/atmel-samd/boards/pewpew_m4/board.c @@ -99,7 +99,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA15, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA15, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/atmel-samd/boards/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c index b1063eb4767c..8314f354a296 100644 --- a/ports/atmel-samd/boards/pybadge/board.c +++ b/ports/atmel-samd/boards/pybadge/board.c @@ -70,7 +70,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/atmel-samd/boards/pygamer/board.c b/ports/atmel-samd/boards/pygamer/board.c index 57b6d58f7cf7..746298f578fe 100644 --- a/ports/atmel-samd/boards/pygamer/board.c +++ b/ports/atmel-samd/boards/pygamer/board.c @@ -72,7 +72,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/atmel-samd/boards/rapid0_adcs/board.c b/ports/atmel-samd/boards/rapid0_adcs/board.c new file mode 100644 index 000000000000..fb1ce4fb834f --- /dev/null +++ b/ports/atmel-samd/boards/rapid0_adcs/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/rapid0_adcs/mpconfigboard.h b/ports/atmel-samd/boards/rapid0_adcs/mpconfigboard.h new file mode 100644 index 000000000000..cfecca3164d5 --- /dev/null +++ b/ports/atmel-samd/boards/rapid0_adcs/mpconfigboard.h @@ -0,0 +1,45 @@ +#define MICROPY_HW_BOARD_NAME "RAPID-0 ADCS" +#define MICROPY_HW_MCU_NAME "samd51n20" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// This is for Rev F which is green + +// #define MICROPY_HW_LED_TX (&pin_PA27) +// #define MICROPY_HW_LED_RX (&pin_PB06) + +// #define MICROPY_HW_LED_STATUS (&pin_PA16) + +// #define MICROPY_HW_NEOPIXEL (&pin_PB22) + +#define BOARD_HAS_CRYSTAL 0 + +#define CAMERA_I2C_SCL (&pin_PB03) +#define CAMERA_I2C_SDA (&pin_PB02) + +#define CAMERA_SPI_SCK (&pin_PA05) +#define CAMERA_SPI_MISO (&pin_PA04) +#define CAMERA_SPI_MOSI (&pin_PA07) +#define CAMERA_SPI_CS (&pin_PA06) + +#define INTERSUBSYSTEM_SPI_SCK (&pin_PB17) +#define INTERSUBSYSTEM_SPI_MISO (&pin_PA21) +#define INTERSUBSYSTEM_SPI_MOSI (&pin_PB16) + +#define ADCS_SPI_CS (&pin_PA20) +#define EPS_SPI_CS (&pin_PB00) +#define PAYLOAD_SPI_CS (&pin_PB01) + +// #define DEFAULT_I2C_BUS_SCL (&pin_PB03) +// #define DEFAULT_I2C_BUS_SDA (&pin_PB02) + +// #define DEFAULT_SPI_BUS_SCK (&pin_PA13) +// #define DEFAULT_SPI_BUS_MOSI (&pin_PA12) +// #define DEFAULT_SPI_BUS_MISO (&pin_PA14) + +// #define DEFAULT_UART_BUS_RX (&pin_PA23) +// #define DEFAULT_UART_BUS_TX (&pin_PA22) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/rapid0_adcs/mpconfigboard.mk b/ports/atmel-samd/boards/rapid0_adcs/mpconfigboard.mk new file mode 100644 index 000000000000..a7b18c7f14b3 --- /dev/null +++ b/ports/atmel-samd/boards/rapid0_adcs/mpconfigboard.mk @@ -0,0 +1,27 @@ +USB_VID = 0x04D8 +USB_PID = 0xE5B3 +USB_PRODUCT = "RAPID-0" +USB_MANUFACTURER = "Bruin Spacecraft Group" + +CHIP_VARIANT = SAMD51N20A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICES = "GD25Q16C" +LONGINT_IMPL = MPZ + +CIRCUITPY__EVE = 1 +CIRCUITPY_CANIO = 0 +CIRCUITPY_FLOPPYIO = 0 +CIRCUITPY_JPEGIO = 0 +CIRCUITPY_SYNTHIO = 0 + +# We don't have room for the fonts for terminalio for certain languages, +# so turn off terminalio, and if it's off and displayio is on, +# force a clean build. +# Note that we cannot test $(CIRCUITPY_DISPLAYIO) directly with an +# ifeq, because it's not set yet. +ifneq (,$(filter $(TRANSLATION),ja ko ru)) +CIRCUITPY_TERMINALIO = 0 +RELEASE_NEEDS_CLEAN_BUILD = $(CIRCUITPY_DISPLAYIO) +endif diff --git a/ports/atmel-samd/boards/rapid0_adcs/pins.c b/ports/atmel-samd/boards/rapid0_adcs/pins.c new file mode 100644 index 000000000000..388b988a8f42 --- /dev/null +++ b/ports/atmel-samd/boards/rapid0_adcs/pins.c @@ -0,0 +1,66 @@ +#include "shared-bindings/board/__init__.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_OBJ_NEW_QSTR(MP_QSTR_CAMERA_I2C_SCL), MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAMERA_I2C_SDA), MP_ROM_PTR(&pin_PB02) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_CAMERA_SPI_SCK), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAMERA_SPI_MISO), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAMERA_SPI_MOSI), MP_ROM_PTR(&pin_PA07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAMERA_SPI_CS), MP_ROM_PTR(&pin_PA06) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_INTERSUBSYSTEM_SPI_SCK), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_INTERSUBSYSTEM_SPI_MISO), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_INTERSUBSYSTEM_SPI_MOSI), MP_ROM_PTR(&pin_PB16) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_ADCS_SPI_CS), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_EPS_SPI_CS), MP_ROM_PTR(&pin_PB00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PAYLOAD_SPI_CS), MP_ROM_PTR(&pin_PB01) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA06) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB09) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA23) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA23) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA22) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA22) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB17) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB16) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB13) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB14) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB15) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB12) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA21) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA20) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA19) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA17) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA16) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA16) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB02) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB03) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB22) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA13) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA14) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), MP_ROM_PTR(&pin_PB06) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), MP_ROM_PTR(&pin_PA27) }, + // { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + // { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + // { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/atmel-samd/boards/rapid0_cdh/board.c b/ports/atmel-samd/boards/rapid0_cdh/board.c new file mode 100644 index 000000000000..fb1ce4fb834f --- /dev/null +++ b/ports/atmel-samd/boards/rapid0_cdh/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/rapid0_cdh/mpconfigboard.h b/ports/atmel-samd/boards/rapid0_cdh/mpconfigboard.h new file mode 100644 index 000000000000..941074a8f08c --- /dev/null +++ b/ports/atmel-samd/boards/rapid0_cdh/mpconfigboard.h @@ -0,0 +1,45 @@ +#define MICROPY_HW_BOARD_NAME "RAPID-0 CDH" +#define MICROPY_HW_MCU_NAME "samd51j19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// This is for Rev F which is green + +// #define MICROPY_HW_LED_TX (&pin_PA27) +// #define MICROPY_HW_LED_RX (&pin_PB06) + +// #define MICROPY_HW_LED_STATUS (&pin_PA16) + +// #define MICROPY_HW_NEOPIXEL (&pin_PB22) + +#define BOARD_HAS_CRYSTAL 0 + +#define CAMERA_I2C_SCL (&pin_PB03) +#define CAMERA_I2C_SDA (&pin_PB02) + +#define CAMERA_SPI_SCK (&pin_PA05) +#define CAMERA_SPI_MISO (&pin_PA04) +#define CAMERA_SPI_MOSI (&pin_PA07) +#define CAMERA_SPI_CS (&pin_PA06) + +#define INTERSUBSYSTEM_SPI_SCK (&pin_PB17) +#define INTERSUBSYSTEM_SPI_MISO (&pin_PA21) +#define INTERSUBSYSTEM_SPI_MOSI (&pin_PB16) + +#define ADCS_SPI_CS (&pin_PA20) +#define EPS_SPI_CS (&pin_PB00) +#define PAYLOAD_SPI_CS (&pin_PB01) + +// #define DEFAULT_I2C_BUS_SCL (&pin_PB03) +// #define DEFAULT_I2C_BUS_SDA (&pin_PB02) + +// #define DEFAULT_SPI_BUS_SCK (&pin_PA13) +// #define DEFAULT_SPI_BUS_MOSI (&pin_PA12) +// #define DEFAULT_SPI_BUS_MISO (&pin_PA14) + +// #define DEFAULT_UART_BUS_RX (&pin_PA23) +// #define DEFAULT_UART_BUS_TX (&pin_PA22) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/rapid0_cdh/mpconfigboard.mk b/ports/atmel-samd/boards/rapid0_cdh/mpconfigboard.mk new file mode 100644 index 000000000000..2a5e00fb7f1d --- /dev/null +++ b/ports/atmel-samd/boards/rapid0_cdh/mpconfigboard.mk @@ -0,0 +1,27 @@ +USB_VID = 0x04D8 +USB_PID = 0xE5B3 +USB_PRODUCT = "RAPID-0" +USB_MANUFACTURER = "Bruin Spacecraft Group" + +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICES = "GD25Q16C" +LONGINT_IMPL = MPZ + +CIRCUITPY__EVE = 1 +CIRCUITPY_CANIO = 0 +CIRCUITPY_FLOPPYIO = 0 +CIRCUITPY_JPEGIO = 0 +CIRCUITPY_SYNTHIO = 0 + +# We don't have room for the fonts for terminalio for certain languages, +# so turn off terminalio, and if it's off and displayio is on, +# force a clean build. +# Note that we cannot test $(CIRCUITPY_DISPLAYIO) directly with an +# ifeq, because it's not set yet. +ifneq (,$(filter $(TRANSLATION),ja ko ru)) +CIRCUITPY_TERMINALIO = 0 +RELEASE_NEEDS_CLEAN_BUILD = $(CIRCUITPY_DISPLAYIO) +endif diff --git a/ports/atmel-samd/boards/rapid0_cdh/pins.c b/ports/atmel-samd/boards/rapid0_cdh/pins.c new file mode 100644 index 000000000000..388b988a8f42 --- /dev/null +++ b/ports/atmel-samd/boards/rapid0_cdh/pins.c @@ -0,0 +1,66 @@ +#include "shared-bindings/board/__init__.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_OBJ_NEW_QSTR(MP_QSTR_CAMERA_I2C_SCL), MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAMERA_I2C_SDA), MP_ROM_PTR(&pin_PB02) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_CAMERA_SPI_SCK), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAMERA_SPI_MISO), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAMERA_SPI_MOSI), MP_ROM_PTR(&pin_PA07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAMERA_SPI_CS), MP_ROM_PTR(&pin_PA06) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_INTERSUBSYSTEM_SPI_SCK), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_INTERSUBSYSTEM_SPI_MISO), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_INTERSUBSYSTEM_SPI_MOSI), MP_ROM_PTR(&pin_PB16) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_ADCS_SPI_CS), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_EPS_SPI_CS), MP_ROM_PTR(&pin_PB00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PAYLOAD_SPI_CS), MP_ROM_PTR(&pin_PB01) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA06) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB09) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA23) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA23) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA22) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA22) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB17) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB16) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB13) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB14) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB15) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB12) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA21) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA20) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA19) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA17) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA16) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA16) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB02) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB03) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB22) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA13) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA14) }, + + // { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), MP_ROM_PTR(&pin_PB06) }, + // { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), MP_ROM_PTR(&pin_PA27) }, + // { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + // { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + // { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/atmel-samd/boards/rapid0_eps/board.c b/ports/atmel-samd/boards/rapid0_eps/board.c new file mode 100644 index 000000000000..fb1ce4fb834f --- /dev/null +++ b/ports/atmel-samd/boards/rapid0_eps/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/rapid0_eps/mpconfigboard.h b/ports/atmel-samd/boards/rapid0_eps/mpconfigboard.h new file mode 100644 index 000000000000..63e75d0ba08d --- /dev/null +++ b/ports/atmel-samd/boards/rapid0_eps/mpconfigboard.h @@ -0,0 +1,29 @@ +#define MICROPY_HW_BOARD_NAME "RAPID-0 EPS" +#define MICROPY_HW_MCU_NAME "samd51j19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// This is for Rev F which is green + +#define MICROPY_HW_LED_TX (&pin_PA27) +#define MICROPY_HW_LED_RX (&pin_PB06) + +#define MICROPY_HW_LED_STATUS (&pin_PA16) + +#define MICROPY_HW_NEOPIXEL (&pin_PB22) + +#define BOARD_HAS_CRYSTAL 0 + +#define DEFAULT_I2C_BUS_SCL (&pin_PB03) +#define DEFAULT_I2C_BUS_SDA (&pin_PB02) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA13) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA12) +#define DEFAULT_SPI_BUS_MISO (&pin_PA14) + +#define DEFAULT_UART_BUS_RX (&pin_PA23) +#define DEFAULT_UART_BUS_TX (&pin_PA22) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/rapid0_eps/mpconfigboard.mk b/ports/atmel-samd/boards/rapid0_eps/mpconfigboard.mk new file mode 100644 index 000000000000..2a5e00fb7f1d --- /dev/null +++ b/ports/atmel-samd/boards/rapid0_eps/mpconfigboard.mk @@ -0,0 +1,27 @@ +USB_VID = 0x04D8 +USB_PID = 0xE5B3 +USB_PRODUCT = "RAPID-0" +USB_MANUFACTURER = "Bruin Spacecraft Group" + +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICES = "GD25Q16C" +LONGINT_IMPL = MPZ + +CIRCUITPY__EVE = 1 +CIRCUITPY_CANIO = 0 +CIRCUITPY_FLOPPYIO = 0 +CIRCUITPY_JPEGIO = 0 +CIRCUITPY_SYNTHIO = 0 + +# We don't have room for the fonts for terminalio for certain languages, +# so turn off terminalio, and if it's off and displayio is on, +# force a clean build. +# Note that we cannot test $(CIRCUITPY_DISPLAYIO) directly with an +# ifeq, because it's not set yet. +ifneq (,$(filter $(TRANSLATION),ja ko ru)) +CIRCUITPY_TERMINALIO = 0 +RELEASE_NEEDS_CLEAN_BUILD = $(CIRCUITPY_DISPLAYIO) +endif diff --git a/ports/atmel-samd/boards/rapid0_eps/pins.c b/ports/atmel-samd/boards/rapid0_eps/pins.c new file mode 100644 index 000000000000..f7e50f645388 --- /dev/null +++ b/ports/atmel-samd/boards/rapid0_eps/pins.c @@ -0,0 +1,50 @@ +#include "shared-bindings/board/__init__.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB09) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA17) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA16) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB03) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB22) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA14) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c b/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c index 077d6c2262c7..a4e563017a58 100644 --- a/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c +++ b/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c @@ -67,7 +67,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_PB20, &pin_PB19, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_PB20, &pin_PB19, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk index 17638a0ebd18..a364a2ee0120 100644 --- a/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk +++ b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk @@ -22,7 +22,6 @@ CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_KEYPAD = 0 -CIRCUITPY_I2CTARGET = 0 CIRCUITPY_TOUCHIO = 0 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_PS2IO = 0 diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index d80fc3dd79f8..7330442e6eb5 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -37,14 +37,12 @@ #include "hal/include/hal_gpio.h" #include "hal/include/hal_spi_m_sync.h" -#include "hal/include/hpl_spi_m_sync.h" #include "samd/dma.h" #include "samd/sercom.h" void common_hal_busio_spi_construct(busio_spi_obj_t *self, - const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, - const mcu_pin_obj_t *miso, const mcu_pin_obj_t *ss, bool half_duplex, bool slave_mode) { + const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { Sercom *sercom = NULL; uint8_t sercom_index; uint32_t clock_pinmux = 0; @@ -52,7 +50,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, bool miso_none = miso == NULL; uint32_t mosi_pinmux = 0; uint32_t miso_pinmux = 0; - uint32_t ss_pinmux = 0; uint8_t clock_pad = 0; uint8_t mosi_pad = 0; uint8_t miso_pad = 0; @@ -97,87 +94,36 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, if (!samd_peripherals_valid_spi_clock_pad(clock_pad)) { continue; } - if (slave_mode) { - // find miso_pad first, since it corresponds to dopo which takes limited values - for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { - if (!miso_none) { - if (sercom_index == miso->sercom[j].index) { - miso_pinmux = PINMUX(miso->number, (j == 0) ? MUX_C : MUX_D); - miso_pad = miso->sercom[j].pad; - dopo = samd_peripherals_get_spi_dopo(clock_pad, miso_pad); - if (dopo > 0x3) { - continue; // pad combination not possible - } - if (mosi_none) { - for (int m = 0; m < NUM_SERCOMS_PER_PIN; m++) { - if (sercom_index == ss->sercom[m].index) { - ss_pinmux = PINMUX(ss->number, (m == 0) ? MUX_C : MUX_D); - sercom = potential_sercom; - break; - } - } - if (sercom != NULL) { - break; - } - } - } else { - continue; + // find mosi_pad first, since it corresponds to dopo which takes limited values + for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { + if (!mosi_none) { + if (sercom_index == mosi->sercom[j].index) { + mosi_pinmux = PINMUX(mosi->number, (j == 0) ? MUX_C : MUX_D); + mosi_pad = mosi->sercom[j].pad; + dopo = samd_peripherals_get_spi_dopo(clock_pad, mosi_pad); + if (dopo > 0x3) { + continue; // pad combination not possible } - } - if (!mosi_none) { - for (int k = 0; k < NUM_SERCOMS_PER_PIN; k++) { - if (sercom_index == mosi->sercom[k].index) { - mosi_pinmux = PINMUX(mosi->number, (k == 0) ? MUX_C : MUX_D); - mosi_pad = mosi->sercom[k].pad; - for (int m = 0; m < NUM_SERCOMS_PER_PIN; m++) { - if (sercom_index == ss->sercom[m].index) { - ss_pinmux = PINMUX(ss->number, (m == 0) ? MUX_C : MUX_D); - sercom = potential_sercom; - break; - } - } - if (sercom != NULL) { - break; - } - } + if (miso_none) { + sercom = potential_sercom; + break; } - } - if (sercom != NULL) { - break; + } else { + continue; } } - } else { - // find mosi_pad first, since it corresponds to dopo which takes limited values - for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { - if (!mosi_none) { - if (sercom_index == mosi->sercom[j].index) { - mosi_pinmux = PINMUX(mosi->number, (j == 0) ? MUX_C : MUX_D); - mosi_pad = mosi->sercom[j].pad; - dopo = samd_peripherals_get_spi_dopo(clock_pad, mosi_pad); - if (dopo > 0x3) { - continue; // pad combination not possible - } - if (miso_none) { - sercom = potential_sercom; - break; - } - } else { - continue; + if (!miso_none) { + for (int k = 0; k < NUM_SERCOMS_PER_PIN; k++) { + if (sercom_index == miso->sercom[k].index) { + miso_pinmux = PINMUX(miso->number, (k == 0) ? MUX_C : MUX_D); + miso_pad = miso->sercom[k].pad; + sercom = potential_sercom; + break; } } - if (!miso_none) { - for (int k = 0; k < NUM_SERCOMS_PER_PIN; k++) { - if (sercom_index == miso->sercom[k].index) { - miso_pinmux = PINMUX(miso->number, (k == 0) ? MUX_C : MUX_D); - miso_pad = miso->sercom[k].pad; - sercom = potential_sercom; - break; - } - } - } - if (sercom != NULL) { - break; - } + } + if (sercom != NULL) { + break; } } if (sercom != NULL) { @@ -199,11 +145,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, // Pads must be set after spi_m_sync_init(), which uses default values from // the prototypical SERCOM. - hri_sercomspi_write_CTRLA_MODE_bf(sercom, slave_mode ? 2 : 3); - self->slave_mode = slave_mode; + hri_sercomspi_write_CTRLA_MODE_bf(sercom, 3); hri_sercomspi_write_CTRLA_DOPO_bf(sercom, dopo); - hri_sercomspi_write_CTRLA_DIPO_bf(sercom, slave_mode ? mosi_pad : miso_pad); - hri_sercomspi_write_CTRLB_PLOADEN_bit(sercom, slave_mode); + hri_sercomspi_write_CTRLA_DIPO_bf(sercom, miso_pad); // Always start at 250khz which is what SD cards need. They are sensitive to // SPI bus noise before they are put into SPI mode. @@ -214,7 +158,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, mp_raise_OSError(MP_EIO); } - gpio_set_pin_direction(clock->number, slave_mode ? GPIO_DIRECTION_IN : GPIO_DIRECTION_OUT); + gpio_set_pin_direction(clock->number, GPIO_DIRECTION_OUT); gpio_set_pin_pull_mode(clock->number, GPIO_PULL_OFF); gpio_set_pin_function(clock->number, clock_pinmux); claim_pin(clock); @@ -223,7 +167,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, if (mosi_none) { self->MOSI_pin = NO_PIN; } else { - gpio_set_pin_direction(mosi->number, slave_mode ? GPIO_DIRECTION_IN : GPIO_DIRECTION_OUT); + gpio_set_pin_direction(mosi->number, GPIO_DIRECTION_OUT); gpio_set_pin_pull_mode(mosi->number, GPIO_PULL_OFF); gpio_set_pin_function(mosi->number, mosi_pinmux); self->MOSI_pin = mosi->number; @@ -233,21 +177,13 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, if (miso_none) { self->MISO_pin = NO_PIN; } else { - gpio_set_pin_direction(miso->number, slave_mode ? GPIO_DIRECTION_OUT : GPIO_DIRECTION_IN); + gpio_set_pin_direction(miso->number, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(miso->number, GPIO_PULL_OFF); gpio_set_pin_function(miso->number, miso_pinmux); self->MISO_pin = miso->number; claim_pin(miso); } - if (slave_mode) { - gpio_set_pin_direction(ss->number, slave_mode ? GPIO_DIRECTION_OUT : GPIO_DIRECTION_IN); - gpio_set_pin_pull_mode(ss->number, GPIO_PULL_OFF); - gpio_set_pin_function(ss->number, ss_pinmux); - self->SS_pin = ss->number; - claim_pin(ss); - } - self->running_dma.failure = 1; // not started spi_m_sync_enable(&self->spi_desc); @@ -402,62 +338,6 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_ou return status >= 0; // Status is number of chars read or an error code < 0. } -void common_hal_busio_spi_transfer_async_start(busio_spi_obj_t *self, const uint8_t *data_out, uint8_t *data_in, size_t len) { - if (len == 0) { - return; - } - if (self->running_dma.failure != 1) { - mp_raise_RuntimeError(MP_ERROR_TEXT("Async SPI transfer in progress on this bus, keep awaiting.")); - } - Sercom* sercom = self->spi_desc.dev.prvt; - self->running_dma = shared_dma_transfer_start(sercom, data_out, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, data_in, len, 0); - - // There is an issue where if an unexpected SPI transfer is received before the user calls "end" for the in-progress, expected - // transfer, the SERCOM has an error and gets confused. This can be detected from INTFLAG.ERROR. I think the code in - // ports/atmel-samd/peripherals/samd/dma.c at line 277 (as of this commit; it's the part that reads s->SPI.INTFLAG.bit.RXC and - // s->SPI.DATA.reg) is supposed to fix this, but experimentation seems to show that it does not in fact fix anything. Anyways, if - // the ERROR bit is set, let's just reset the peripheral and then setup the transfer again -- that seems to work. - if (hri_sercomspi_get_INTFLAG_ERROR_bit(sercom)) { - shared_dma_transfer_close(self->running_dma); - - // disable the sercom - spi_m_sync_disable(&self->spi_desc); - hri_sercomspi_wait_for_sync(sercom, SERCOM_SPI_SYNCBUSY_MASK); - - // save configurations - hri_sercomspi_ctrla_reg_t ctrla_saved_val = hri_sercomspi_get_CTRLA_reg(sercom, -1); // -1 mask is all ones: save all bits - hri_sercomspi_ctrlb_reg_t ctrlb_saved_val = hri_sercomspi_get_CTRLB_reg(sercom, -1); // -1 mask is all ones: save all bits - hri_sercomspi_baud_reg_t baud_saved_val = hri_sercomspi_get_BAUD_reg(sercom, -1); // -1 mask is all ones: save all bits - // reset - hri_sercomspi_set_CTRLA_SWRST_bit(sercom); - hri_sercomspi_wait_for_sync(sercom, SERCOM_SPI_SYNCBUSY_MASK); - // re-write configurations - hri_sercomspi_write_CTRLA_reg(sercom, ctrla_saved_val); - hri_sercomspi_write_CTRLB_reg(sercom, ctrlb_saved_val); - hri_sercomspi_write_BAUD_reg (sercom, baud_saved_val); - hri_sercomspi_wait_for_sync(sercom, SERCOM_SPI_SYNCBUSY_MASK); - - // re-enable the sercom - spi_m_sync_enable(&self->spi_desc); - hri_sercomspi_wait_for_sync(sercom, SERCOM_SPI_SYNCBUSY_MASK); - - self->running_dma = shared_dma_transfer_start(sercom, data_out, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, data_in, len, 0); - } -} - -bool common_hal_busio_spi_transfer_async_check(busio_spi_obj_t *self) { - return self->running_dma.failure == 1 || shared_dma_transfer_finished(self->running_dma); -} - -int common_hal_busio_spi_transfer_async_end(busio_spi_obj_t *self) { - if (self->running_dma.failure == 1) { - return 0; - } - int res = shared_dma_transfer_close(self->running_dma); - self->running_dma.failure = 1; - return res; -} - uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t *self) { return samd_peripherals_spi_baud_reg_value_to_baudrate(hri_sercomspi_read_BAUD_reg(self->spi_desc.dev.prvt)); } diff --git a/ports/atmel-samd/common-hal/busio/SPI.h b/ports/atmel-samd/common-hal/busio/SPI.h index 95cc8d379f08..587d534cbe73 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.h +++ b/ports/atmel-samd/common-hal/busio/SPI.h @@ -40,8 +40,6 @@ typedef struct { uint8_t clock_pin; uint8_t MOSI_pin; uint8_t MISO_pin; - uint8_t SS_pin; - bool slave_mode; dma_descr_t running_dma; } busio_spi_obj_t; diff --git a/ports/atmel-samd/common-hal/spitarget/SPITarget.c b/ports/atmel-samd/common-hal/spitarget/SPITarget.c new file mode 100644 index 000000000000..0252436df7d0 --- /dev/null +++ b/ports/atmel-samd/common-hal/spitarget/SPITarget.c @@ -0,0 +1,235 @@ +#include "common-hal/spitarget/SPITarget.h" +#include "common-hal/busio/__init__.h" + +#include "shared-bindings/spitarget/SPITarget.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "hpl_sercom_config.h" +#include "peripheral_clk_config.h" + +#include "hal/include/hal_gpio.h" +#include "hal/include/hal_spi_m_sync.h" + +#include "hpl_sercom_config.h" +#include "samd/sercom.h" + +void common_hal_spitarget_spi_target_construct(spitarget_spi_target_obj_t *self, + const mcu_pin_obj_t *sck, const mcu_pin_obj_t *mosi, + const mcu_pin_obj_t *miso, const mcu_pin_obj_t *ss) { + Sercom *sercom = NULL; + uint8_t sercom_index; + uint32_t clock_pinmux = 0; + uint32_t mosi_pinmux = 0; + uint32_t miso_pinmux = 0; + uint32_t ss_pinmux = 0; + uint8_t clock_pad = 0; + uint8_t mosi_pad = 0; + uint8_t miso_pad = 0; + uint8_t dopo = 255; + + // Ensure the object starts in its deinit state. + self->clock_pin = NO_PIN; + + // Special case for SAMR21 boards. (feather_radiofruit_zigbee) + #if defined(PIN_PC19F_SERCOM4_PAD0) + if (miso == &pin_PC19) { + if (mosi == &pin_PB30 && sck == &pin_PC18) { + sercom = SERCOM4; + sercom_index = 4; + clock_pinmux = MUX_F; + mosi_pinmux = MUX_F; + miso_pinmux = MUX_F; + clock_pad = 3; + mosi_pad = 2; + miso_pad = 0; + dopo = samd_peripherals_get_spi_dopo(clock_pad, mosi_pad); + } + // Error, leave SERCOM unset to throw an exception later. + } else + #endif + { + for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { + sercom_index = sck->sercom[i].index; // 2 for SERCOM2, etc. + if (sercom_index >= SERCOM_INST_NUM) { + continue; + } + Sercom *potential_sercom = sercom_insts[sercom_index]; + if (potential_sercom->SPI.CTRLA.bit.ENABLE != 0) { + continue; + } + clock_pinmux = PINMUX(sck->number, (i == 0) ? MUX_C : MUX_D); + clock_pad = sck->sercom[i].pad; + if (!samd_peripherals_valid_spi_clock_pad(clock_pad)) { + continue; + } + // find miso_pad first, since it corresponds to dopo which takes limited values + for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { + if (sercom_index == miso->sercom[j].index) { + miso_pinmux = PINMUX(miso->number, (j == 0) ? MUX_C : MUX_D); + miso_pad = miso->sercom[j].pad; + dopo = samd_peripherals_get_spi_dopo(clock_pad, miso_pad); + if (dopo > 0x3) { + continue; // pad combination not possible + } + } else { + continue; + } + for (int k = 0; k < NUM_SERCOMS_PER_PIN; k++) { + if (sercom_index == mosi->sercom[k].index) { + mosi_pinmux = PINMUX(mosi->number, (k == 0) ? MUX_C : MUX_D); + mosi_pad = mosi->sercom[k].pad; + for (int m = 0; m < NUM_SERCOMS_PER_PIN; m++) { + if (sercom_index == ss->sercom[m].index) { + ss_pinmux = PINMUX(ss->number, (m == 0) ? MUX_C : MUX_D); + sercom = potential_sercom; + break; + } + } + if (sercom != NULL) { + break; + } + } + } + if (sercom != NULL) { + break; + } + } + if (sercom != NULL) { + break; + } + } + } + if (sercom == NULL) { + raise_ValueError_invalid_pins(); + } + + // Set up SPI clocks on SERCOM. + samd_peripherals_sercom_clock_init(sercom, sercom_index); + + if (spi_m_sync_init(&self->spi_desc, sercom) != ERR_NONE) { + mp_raise_OSError(MP_EIO); + } + + // Pads must be set after spi_m_sync_init(), which uses default values from + // the prototypical SERCOM. + + hri_sercomspi_write_CTRLA_MODE_bf(sercom, 2); + hri_sercomspi_write_CTRLA_DOPO_bf(sercom, dopo); + hri_sercomspi_write_CTRLA_DIPO_bf(sercom, mosi_pad); + hri_sercomspi_write_CTRLB_PLOADEN_bit(sercom, 1); + + // Always start at 250khz which is what SD cards need. They are sensitive to + // SPI bus noise before they are put into SPI mode. + uint8_t baud_value = samd_peripherals_spi_baudrate_to_baud_reg_value(250000); + if (spi_m_sync_set_baudrate(&self->spi_desc, baud_value) != ERR_NONE) { + // spi_m_sync_set_baudrate does not check for validity, just whether the device is + // busy or not + mp_raise_OSError(MP_EIO); + } + + gpio_set_pin_direction(sck->number, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(sck->number, GPIO_PULL_OFF); + gpio_set_pin_function(sck->number, clock_pinmux); + claim_pin(sck); + self->clock_pin = sck->number; + + gpio_set_pin_direction(mosi->number, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(mosi->number, GPIO_PULL_OFF); + gpio_set_pin_function(mosi->number, mosi_pinmux); + self->MOSI_pin = mosi->number; + claim_pin(mosi); + + gpio_set_pin_direction(miso->number, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(miso->number, GPIO_PULL_OFF); + gpio_set_pin_function(miso->number, miso_pinmux); + self->MISO_pin = miso->number; + claim_pin(miso); + + gpio_set_pin_direction(ss->number, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(ss->number, GPIO_PULL_OFF); + gpio_set_pin_function(ss->number, ss_pinmux); + self->SS_pin = ss->number; + claim_pin(ss); + + self->running_dma.failure = 1; // not started + + spi_m_sync_enable(&self->spi_desc); +} + +bool common_hal_spitarget_spi_target_deinited(spitarget_spi_target_obj_t *self) { + return self->clock_pin == NO_PIN; +} + +void common_hal_spitarget_spi_target_deinit(spitarget_spi_target_obj_t *self) { + if (common_hal_spitarget_spi_target_deinited(self)) { + return; + } + allow_reset_sercom(self->spi_desc.dev.prvt); + + spi_m_sync_disable(&self->spi_desc); + spi_m_sync_deinit(&self->spi_desc); + reset_pin_number(self->clock_pin); + reset_pin_number(self->MOSI_pin); + reset_pin_number(self->MISO_pin); + reset_pin_number(self->SS_pin); + self->clock_pin = NO_PIN; +} + +void common_hal_spitarget_spi_target_transfer_start(spitarget_spi_target_obj_t *self, + uint8_t *mosi_packet, const uint8_t *miso_packet, size_t len) { + if (len == 0) { + return; + } + if (self->running_dma.failure != 1) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Async SPI transfer in progress on this bus, keep awaiting.")); + } + Sercom* sercom = self->spi_desc.dev.prvt; + self->running_dma = shared_dma_transfer_start(sercom, miso_packet, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, mosi_packet, len, 0); + + // There is an issue where if an unexpected SPI transfer is received before the user calls "end" for the in-progress, expected + // transfer, the SERCOM has an error and gets confused. This can be detected from INTFLAG.ERROR. I think the code in + // ports/atmel-samd/peripherals/samd/dma.c at line 277 (as of this commit; it's the part that reads s->SPI.INTFLAG.bit.RXC and + // s->SPI.DATA.reg) is supposed to fix this, but experimentation seems to show that it does not in fact fix anything. Anyways, if + // the ERROR bit is set, let's just reset the peripheral and then setup the transfer again -- that seems to work. + if (hri_sercomspi_get_INTFLAG_ERROR_bit(sercom)) { + shared_dma_transfer_close(self->running_dma); + + // disable the sercom + spi_m_sync_disable(&self->spi_desc); + hri_sercomspi_wait_for_sync(sercom, SERCOM_SPI_SYNCBUSY_MASK); + + // save configurations + hri_sercomspi_ctrla_reg_t ctrla_saved_val = hri_sercomspi_get_CTRLA_reg(sercom, -1); // -1 mask is all ones: save all bits + hri_sercomspi_ctrlb_reg_t ctrlb_saved_val = hri_sercomspi_get_CTRLB_reg(sercom, -1); // -1 mask is all ones: save all bits + hri_sercomspi_baud_reg_t baud_saved_val = hri_sercomspi_get_BAUD_reg(sercom, -1); // -1 mask is all ones: save all bits + // reset + hri_sercomspi_set_CTRLA_SWRST_bit(sercom); + hri_sercomspi_wait_for_sync(sercom, SERCOM_SPI_SYNCBUSY_MASK); + // re-write configurations + hri_sercomspi_write_CTRLA_reg(sercom, ctrla_saved_val); + hri_sercomspi_write_CTRLB_reg(sercom, ctrlb_saved_val); + hri_sercomspi_write_BAUD_reg (sercom, baud_saved_val); + hri_sercomspi_wait_for_sync(sercom, SERCOM_SPI_SYNCBUSY_MASK); + + // re-enable the sercom + spi_m_sync_enable(&self->spi_desc); + hri_sercomspi_wait_for_sync(sercom, SERCOM_SPI_SYNCBUSY_MASK); + + self->running_dma = shared_dma_transfer_start(sercom, miso_packet, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, mosi_packet, len, 0); + } +} + +bool common_hal_spitarget_spi_target_transfer_is_finished(spitarget_spi_target_obj_t *self) { + return self->running_dma.failure == 1 || shared_dma_transfer_finished(self->running_dma); +} + +int common_hal_spitarget_spi_target_transfer_close(spitarget_spi_target_obj_t *self) { + if (self->running_dma.failure == 1) { + return 0; + } + int res = shared_dma_transfer_close(self->running_dma); + self->running_dma.failure = 1; + return res; +} diff --git a/ports/atmel-samd/common-hal/spitarget/SPITarget.h b/ports/atmel-samd/common-hal/spitarget/SPITarget.h new file mode 100644 index 000000000000..8b8b4b98549b --- /dev/null +++ b/ports/atmel-samd/common-hal/spitarget/SPITarget.h @@ -0,0 +1,21 @@ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_TARGET_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_TARGET_H + +#include "common-hal/microcontroller/Pin.h" +#include "hal/include/hal_spi_m_sync.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + + struct spi_m_sync_descriptor spi_desc; + + uint8_t clock_pin; + uint8_t MOSI_pin; + uint8_t MISO_pin; + uint8_t SS_pin; + + dma_descr_t running_dma; +} spitarget_spi_target_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_TARGET_H diff --git a/ports/atmel-samd/common-hal/spitarget/__init__.c b/ports/atmel-samd/common-hal/spitarget/__init__.c new file mode 100644 index 000000000000..c0ce8cef9a16 --- /dev/null +++ b/ports/atmel-samd/common-hal/spitarget/__init__.c @@ -0,0 +1 @@ +// No spitarget module functions. diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index 1e18fee5f813..d8028b5f327b 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -46,6 +46,7 @@ CIRCUITPY_OS_GETENV ?= 0 CIRCUITPY_PIXELMAP ?= 0 CIRCUITPY_RE ?= 0 CIRCUITPY_SDCARDIO ?= 0 +CIRCUITPY_SPITARGET ?= 0 CIRCUITPY_SYNTHIO ?= 0 CIRCUITPY_TOUCHIO_USE_NATIVE ?= 1 CIRCUITPY_TRACEBACK ?= 0 @@ -105,6 +106,7 @@ CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_FULL_BUILD) CIRCUITPY_PS2IO ?= 1 CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_FRAMEBUFFERIO) CIRCUITPY_SAMD ?= 1 +CIRCUITPY_SPITARGET ?= 1 CIRCUITPY_SYNTHIO_MAX_CHANNELS = 12 CIRCUITPY_ULAB_OPTIMIZE_SIZE ?= 1 CIRCUITPY_WATCHDOG ?= 1 diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals index 87483f3281fe..fd82c8b829b8 160000 --- a/ports/atmel-samd/peripherals +++ b/ports/atmel-samd/peripherals @@ -1 +1 @@ -Subproject commit 87483f3281fe6a05c9e66ae62615205f74675c49 +Subproject commit fd82c8b829b8d72eb0e45de16ac9db43a77ac764 diff --git a/ports/broadcom/common-hal/busio/SPI.c b/ports/broadcom/common-hal/busio/SPI.c index 62a1bb5ce091..238c550615e5 100644 --- a/ports/broadcom/common-hal/busio/SPI.c +++ b/ports/broadcom/common-hal/busio/SPI.c @@ -76,8 +76,7 @@ void reset_spi(void) { } void common_hal_busio_spi_construct(busio_spi_obj_t *self, - const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, - const mcu_pin_obj_t *miso, const mcu_pin_obj_t *ss, bool half_duplex, bool slave_mode) { + const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { size_t instance_index = NUM_SPI; BP_Function_Enum clock_alt = 0; BP_Function_Enum mosi_alt = 0; @@ -86,9 +85,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, if (half_duplex) { mp_raise_NotImplementedError(MP_ERROR_TEXT("Half duplex SPI is not implemented")); } - if (slave_mode) { - mp_raise_NotImplementedError(MP_ERROR_TEXT("Slave mode SPI is not implemented")); - } // BCM_VERSION != 2711 have 3 SPI but as listed in peripherals/gen/pins.c two are on // index 0, once one index 0 SPI is found the other will throw an invalid_pins error. diff --git a/ports/cxd56/common-hal/busio/SPI.c b/ports/cxd56/common-hal/busio/SPI.c index 9a8212fc347b..5131028665c0 100644 --- a/ports/cxd56/common-hal/busio/SPI.c +++ b/ports/cxd56/common-hal/busio/SPI.c @@ -36,15 +36,12 @@ #include "shared-bindings/microcontroller/Pin.h" void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, - const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, const mcu_pin_obj_t *ss, bool half_duplex, bool slave_mode) { + const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { int port = -1; if (half_duplex) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_half_duplex); } - if (slave_mode) { - mp_raise_NotImplementedError(MP_ERROR_TEXT("Slave mode SPI is not implemented")); - } if (clock->number == PIN_SPI4_SCK && (mosi == NULL || mosi->number == PIN_SPI4_MOSI) && diff --git a/ports/espressif/boards/adafruit_funhouse/board.c b/ports/espressif/boards/adafruit_funhouse/board.c index 761a478daaea..a19ceda83773 100644 --- a/ports/espressif/boards/adafruit_funhouse/board.c +++ b/ports/espressif/boards/adafruit_funhouse/board.c @@ -52,7 +52,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO36, &pin_GPIO35, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO36, &pin_GPIO35, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; 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 3d21b3f8bda3..841c241b31c3 100644 --- a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c +++ b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c @@ -116,7 +116,7 @@ const uint8_t refresh_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO36, &pin_GPIO35, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO36, &pin_GPIO35, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/espressif/boards/espressif_esp32s3_box/board.c b/ports/espressif/boards/espressif_esp32s3_box/board.c index a3f3de39ea1d..3ab932c83ae0 100644 --- a/ports/espressif/boards/espressif_esp32s3_box/board.c +++ b/ports/espressif/boards/espressif_esp32s3_box/board.c @@ -45,7 +45,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO7, &pin_GPIO6, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO7, &pin_GPIO6, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/espressif/boards/espressif_esp32s3_box_lite/board.c b/ports/espressif/boards/espressif_esp32s3_box_lite/board.c index 818f290c08da..fe9cc993e803 100644 --- a/ports/espressif/boards/espressif_esp32s3_box_lite/board.c +++ b/ports/espressif/boards/espressif_esp32s3_box_lite/board.c @@ -46,7 +46,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO7, &pin_GPIO6, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO7, &pin_GPIO6, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; 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 25bf86c43534..3dd272b622ad 100644 --- a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c +++ b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c @@ -73,7 +73,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO6, &pin_GPIO7, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO6, &pin_GPIO7, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/espressif/boards/hardkernel_odroid_go/board.c b/ports/espressif/boards/hardkernel_odroid_go/board.c index 4c3d4fa4bb0f..141a891d5739 100644 --- a/ports/espressif/boards/hardkernel_odroid_go/board.c +++ b/ports/espressif/boards/hardkernel_odroid_go/board.c @@ -65,7 +65,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO23, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO23, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/espressif/boards/hiibot_iots2/board.c b/ports/espressif/boards/hiibot_iots2/board.c index cc453f16b52c..fbad7dc605ee 100644 --- a/ports/espressif/boards/hiibot_iots2/board.c +++ b/ports/espressif/boards/hiibot_iots2/board.c @@ -73,9 +73,7 @@ static void display_init(void) { &pin_GPIO34, // CLK &pin_GPIO33, // MOSI NULL, // MISO not connected - NULL, // SS not connected - false, // Not half-duplex - false // operate SPI bus as master + false // Not half-duplex ); common_hal_busio_spi_never_reset(spi); diff --git a/ports/espressif/boards/lilygo_tembed_esp32s3/board.c b/ports/espressif/boards/lilygo_tembed_esp32s3/board.c index d77508380bfa..8039f618f0c2 100644 --- a/ports/espressif/boards/lilygo_tembed_esp32s3/board.c +++ b/ports/espressif/boards/lilygo_tembed_esp32s3/board.c @@ -45,7 +45,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO12, &pin_GPIO11, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO12, &pin_GPIO11, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; 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 d9de096982e5..4abcc75a1c61 100644 --- a/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c +++ b/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c @@ -73,9 +73,7 @@ static void display_init(void) { &pin_GPIO36, // CLK &pin_GPIO35, // MOSI NULL, // MISO not connected - NULL, // SS not connected - false, // Not half-duplex - false // operate SPI bus as master + false // Not half-duplex ); common_hal_busio_spi_never_reset(spi); 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 0ccff151d36a..adee839ccaaf 100644 --- a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c @@ -53,9 +53,7 @@ static void display_init(void) { &pin_GPIO18, // CLK &pin_GPIO19, // MOSI NULL, // MISO not connected - NULL, // SS not connected - false, // Not half-duplex - false // operate SPI bus as master + false // Not half-duplex ); common_hal_busio_spi_never_reset(spi); diff --git a/ports/espressif/boards/lilygo_twatch_2020_v3/board.c b/ports/espressif/boards/lilygo_twatch_2020_v3/board.c index 25bd47d130f9..495209365268 100644 --- a/ports/espressif/boards/lilygo_twatch_2020_v3/board.c +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/board.c @@ -56,9 +56,7 @@ static void display_init(void) { &pin_GPIO18, // CLK &pin_GPIO19, // MOSI NULL, // MISO not connected - NULL, // SS not connected - false, // Not half-duplex - false // operate SPI bus as master + false // Not half-duplex ); common_hal_busio_spi_never_reset(spi); diff --git a/ports/espressif/boards/m5stack_atoms3/board.c b/ports/espressif/boards/m5stack_atoms3/board.c index aff7d3d30a8a..1b46c9510756 100644 --- a/ports/espressif/boards/m5stack_atoms3/board.c +++ b/ports/espressif/boards/m5stack_atoms3/board.c @@ -53,7 +53,7 @@ void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; // busio_spi_obj_t *spi = common_hal_board_create_spi(0); busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO17, &pin_GPIO21, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO17, &pin_GPIO21, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/espressif/boards/m5stack_stick_c/board.c b/ports/espressif/boards/m5stack_stick_c/board.c index 3ab7c5f03e97..4d33b21c583b 100644 --- a/ports/espressif/boards/m5stack_stick_c/board.c +++ b/ports/espressif/boards/m5stack_stick_c/board.c @@ -167,7 +167,7 @@ static bool pmic_init(busio_i2c_obj_t *i2c) { static bool display_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO13, &pin_GPIO15, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO13, &pin_GPIO15, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/espressif/boards/m5stack_stick_c_plus/board.c b/ports/espressif/boards/m5stack_stick_c_plus/board.c index 610262dbe01d..6d58e3a0a427 100644 --- a/ports/espressif/boards/m5stack_stick_c_plus/board.c +++ b/ports/espressif/boards/m5stack_stick_c_plus/board.c @@ -167,7 +167,7 @@ static bool pmic_init(busio_i2c_obj_t *i2c) { static bool display_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO13, &pin_GPIO15, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO13, &pin_GPIO15, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/espressif/boards/morpheans_morphesp-240/board.c b/ports/espressif/boards/morpheans_morphesp-240/board.c index 73d7b279ba4d..97ee6207b34d 100644 --- a/ports/espressif/boards/morpheans_morphesp-240/board.c +++ b/ports/espressif/boards/morpheans_morphesp-240/board.c @@ -149,9 +149,7 @@ void board_init(void) { &pin_GPIO12, // CLK &pin_GPIO11, // MOSI NULL, // MISO not connected - NULL, // SS not connected - false, // Not half-duplex - false // operate SPI bus as master + false // Not half-duplex ); common_hal_busio_spi_never_reset(spi); 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 6e2ef5c17dce..c5b8e340f07a 100644 --- a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c +++ b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c @@ -72,9 +72,7 @@ static void display_init(void) { &pin_GPIO10, // CLK &pin_GPIO11, // MOSI NULL, // MISO not connected - NULL, // SS not connected - false, // Not half-duplex - false // operate SPI bus as master + false // Not half-duplex ); common_hal_busio_spi_never_reset(spi); diff --git a/ports/espressif/common-hal/busio/SPI.c b/ports/espressif/common-hal/busio/SPI.c index e3a214b8cb70..ffe8d41c7998 100644 --- a/ports/espressif/common-hal/busio/SPI.c +++ b/ports/espressif/common-hal/busio/SPI.c @@ -76,8 +76,7 @@ static void set_spi_config(busio_spi_obj_t *self, } void common_hal_busio_spi_construct(busio_spi_obj_t *self, - const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, - const mcu_pin_obj_t *miso, const mcu_pin_obj_t *ss, bool half_duplex, bool slave_mode) { + const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { const spi_bus_config_t bus_config = { .mosi_io_num = mosi != NULL ? mosi->number : -1, @@ -90,9 +89,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, if (half_duplex) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_half_duplex); } - if (slave_mode) { - mp_raise_NotImplementedError(MP_ERROR_TEXT("Slave mode SPI is not implemented")); - } for (spi_host_device_t host_id = SPI2_HOST; host_id < SOC_SPI_PERIPH_NUM; host_id++) { if (spi_bus_is_free(host_id)) { diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.c b/ports/mimxrt10xx/common-hal/busio/SPI.c index ead30396231c..0fba94b40b51 100644 --- a/ports/mimxrt10xx/common-hal/busio/SPI.c +++ b/ports/mimxrt10xx/common-hal/busio/SPI.c @@ -90,8 +90,7 @@ void spi_reset(void) { } void common_hal_busio_spi_construct(busio_spi_obj_t *self, - const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, - const mcu_pin_obj_t *miso, const mcu_pin_obj_t *ss, bool half_duplex, bool slave_mode) { + const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { const uint32_t sck_count = MP_ARRAY_SIZE(mcu_spi_sck_list); const uint32_t miso_count = MP_ARRAY_SIZE(mcu_spi_sdi_list); @@ -101,9 +100,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, if (half_duplex) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_half_duplex); } - if (slave_mode) { - mp_raise_NotImplementedError(MP_ERROR_TEXT("Slave mode SPI is not implemented")); - } for (uint i = 0; i < sck_count; i++) { if (mcu_spi_sck_list[i].pin != clock) { diff --git a/ports/nrf/boards/clue_nrf52840_express/board.c b/ports/nrf/boards/clue_nrf52840_express/board.c index f013f646ad01..4478e0f3ba29 100644 --- a/ports/nrf/boards/clue_nrf52840_express/board.c +++ b/ports/nrf/boards/clue_nrf52840_express/board.c @@ -49,7 +49,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_P0_14, &pin_P0_15, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_P0_14, &pin_P0_15, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/nrf/boards/espruino_banglejs2/board.c b/ports/nrf/boards/espruino_banglejs2/board.c index f3213d1508aa..dc741744c853 100644 --- a/ports/nrf/boards/espruino_banglejs2/board.c +++ b/ports/nrf/boards/espruino_banglejs2/board.c @@ -52,7 +52,7 @@ void board_init(void) { fb->base.type = &sharpdisplay_framebuffer_type; busio_spi_obj_t *spi = &fb->inline_bus; - common_hal_busio_spi_construct(spi, &pin_P0_26, &pin_P0_27, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_P0_26, &pin_P0_27, NULL, false); common_hal_busio_spi_never_reset(spi); common_hal_sharpdisplay_framebuffer_construct(fb, spi, &pin_P0_05, 500000, 176, 176, true); diff --git a/ports/nrf/boards/hiibot_bluefi/board.c b/ports/nrf/boards/hiibot_bluefi/board.c index 400f60164681..d07b31673339 100644 --- a/ports/nrf/boards/hiibot_bluefi/board.c +++ b/ports/nrf/boards/hiibot_bluefi/board.c @@ -49,7 +49,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_P0_07, &pin_P1_08, NULL, NULL, false, false); // SCK, MOSI, MISO, not half-duplex + common_hal_busio_spi_construct(spi, &pin_P0_07, &pin_P1_08, NULL, false); // SCK, MOSI, MISO, not half-duplex common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/nrf/boards/makerdiary_nrf52840_m2_devkit/board.c b/ports/nrf/boards/makerdiary_nrf52840_m2_devkit/board.c index bd94cd8cf99e..a22d96e95980 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_m2_devkit/board.c +++ b/ports/nrf/boards/makerdiary_nrf52840_m2_devkit/board.c @@ -50,7 +50,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_P0_11, &pin_P0_12, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_P0_11, &pin_P0_12, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/nrf/boards/ohs2020_badge/board.c b/ports/nrf/boards/ohs2020_badge/board.c index 3c69db91504d..7b48e1985dd7 100644 --- a/ports/nrf/boards/ohs2020_badge/board.c +++ b/ports/nrf/boards/ohs2020_badge/board.c @@ -49,7 +49,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_P0_11, &pin_P0_12, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_P0_11, &pin_P0_12, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c index 5dbda51f7277..48fae8adc3eb 100644 --- a/ports/nrf/common-hal/busio/SPI.c +++ b/ports/nrf/common-hal/busio/SPI.c @@ -143,14 +143,11 @@ static nrf_spim_frequency_t baudrate_to_spim_frequency(const uint32_t baudrate) return 0; } -void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, const mcu_pin_obj_t *ss, bool half_duplex, bool slave_mode) { +void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { if (half_duplex) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_half_duplex); } - if (slave_mode) { - mp_raise_NotImplementedError(MP_ERROR_TEXT("Slave mode SPI is not implemented")); - } // Find a free instance, with most desirable (highest freq and not shared) allocated first. self->spim_peripheral = NULL; diff --git a/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c b/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c index 1b55f3744f09..0006b80260a9 100644 --- a/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c @@ -61,7 +61,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO26, &pin_GPIO27, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO26, &pin_GPIO27, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/raspberrypi/boards/hack_club_sprig/board.c b/ports/raspberrypi/boards/hack_club_sprig/board.c index 0d3c56dab951..e101e26d3dce 100644 --- a/ports/raspberrypi/boards/hack_club_sprig/board.c +++ b/ports/raspberrypi/boards/hack_club_sprig/board.c @@ -80,7 +80,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO19, &pin_GPIO16, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO19, &pin_GPIO16, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/raspberrypi/boards/lilygo_t_display_rp2040/board.c b/ports/raspberrypi/boards/lilygo_t_display_rp2040/board.c index aee49e4baaa6..69320824ff0b 100644 --- a/ports/raspberrypi/boards/lilygo_t_display_rp2040/board.c +++ b/ports/raspberrypi/boards/lilygo_t_display_rp2040/board.c @@ -74,9 +74,7 @@ static void display_init(void) { &pin_GPIO2, // CLK &pin_GPIO3, // MOSI NULL, // MISO not connected - NULL, // SS not connected - false, // Not half-duplex - false // operate SPI bus as master + false // Not half-duplex ); common_hal_busio_spi_never_reset(spi); diff --git a/ports/raspberrypi/boards/pajenicko_picopad/board.c b/ports/raspberrypi/boards/pajenicko_picopad/board.c index c361363068a4..c02c65d160e3 100644 --- a/ports/raspberrypi/boards/pajenicko_picopad/board.c +++ b/ports/raspberrypi/boards/pajenicko_picopad/board.c @@ -66,7 +66,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO19, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO19, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/raspberrypi/boards/pimoroni_badger2040/board.c b/ports/raspberrypi/boards/pimoroni_badger2040/board.c index 1b2263bece82..b602f8cb65ac 100644 --- a/ports/raspberrypi/boards/pimoroni_badger2040/board.c +++ b/ports/raspberrypi/boards/pimoroni_badger2040/board.c @@ -276,7 +276,7 @@ void board_init(void) { // Set up the SPI object used to control the display fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO19, &pin_GPIO16, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO19, &pin_GPIO16, false); common_hal_busio_spi_never_reset(spi); // Set up the DisplayIO pin object diff --git a/ports/raspberrypi/boards/pimoroni_picosystem/board.c b/ports/raspberrypi/boards/pimoroni_picosystem/board.c index d733988f24f5..5ee79715930c 100644 --- a/ports/raspberrypi/boards/pimoroni_picosystem/board.c +++ b/ports/raspberrypi/boards/pimoroni_picosystem/board.c @@ -66,7 +66,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO6, &pin_GPIO7, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO6, &pin_GPIO7, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; diff --git a/ports/raspberrypi/boards/ugame22/board.c b/ports/raspberrypi/boards/ugame22/board.c index 8718c15c4ffc..48a26f9da04d 100644 --- a/ports/raspberrypi/boards/ugame22/board.c +++ b/ports/raspberrypi/boards/ugame22/board.c @@ -66,7 +66,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO2, &pin_GPIO3, NULL, NULL, false, false); + common_hal_busio_spi_construct(spi, &pin_GPIO2, &pin_GPIO3, NULL, false); common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; 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 65c8cd856eaa..31750619da45 100644 --- a/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/board.c +++ b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/board.c @@ -70,9 +70,7 @@ static void display_init(void) { &pin_GPIO10, // CLK &pin_GPIO11, // MOSI NULL, // MISO not connected - NULL, // SS not connected - false, // Not half-duplex - false // operate SPI bus as master + false // Not half-duplex ); common_hal_busio_spi_never_reset(spi); diff --git a/ports/raspberrypi/common-hal/busio/SPI.c b/ports/raspberrypi/common-hal/busio/SPI.c index 819f2d847bc9..f9060ec6414f 100644 --- a/ports/raspberrypi/common-hal/busio/SPI.c +++ b/ports/raspberrypi/common-hal/busio/SPI.c @@ -53,16 +53,12 @@ void reset_spi(void) { } void common_hal_busio_spi_construct(busio_spi_obj_t *self, - const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, - const mcu_pin_obj_t *miso, const mcu_pin_obj_t *ss, bool half_duplex, bool slave_mode) { + const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { size_t instance_index = NO_INSTANCE; if (half_duplex) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_half_duplex); } - if (slave_mode) { - mp_raise_NotImplementedError(MP_ERROR_TEXT("Slave mode SPI is not implemented")); - } if (clock->number % 4 == 2) { instance_index = (clock->number / 8) % 2; diff --git a/ports/silabs/common-hal/busio/SPI.c b/ports/silabs/common-hal/busio/SPI.c index b89edb714300..ff41b8905477 100644 --- a/ports/silabs/common-hal/busio/SPI.c +++ b/ports/silabs/common-hal/busio/SPI.c @@ -53,17 +53,13 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *sck, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, - const mcu_pin_obj_t *ss, - bool half_duplex, bool slave_mode) { + bool half_duplex) { Ecode_t sc = ECODE_OK; if (half_duplex) { mp_raise_NotImplementedError( MP_ERROR_TEXT("Half duplex SPI is not implemented")); } - if (slave_mode) { - mp_raise_NotImplementedError(MP_ERROR_TEXT("Slave mode SPI is not implemented")); - } if ((sck != NULL) && (mosi != NULL) && (miso != NULL)) { if (sck->function_list[FN_EUSART1_SCLK] == 1 diff --git a/ports/stm/common-hal/busio/SPI.c b/ports/stm/common-hal/busio/SPI.c index b0b401c077b3..b6f0f0996c13 100644 --- a/ports/stm/common-hal/busio/SPI.c +++ b/ports/stm/common-hal/busio/SPI.c @@ -166,11 +166,7 @@ STATIC int check_pins(busio_spi_obj_t *self, } void common_hal_busio_spi_construct(busio_spi_obj_t *self, - const mcu_pin_obj_t *sck, const mcu_pin_obj_t *mosi, - const mcu_pin_obj_t *miso, const mcu_pin_obj_t *ss, bool half_duplex, bool slave_mode) { - if (slave_mode) { - mp_raise_NotImplementedError(MP_ERROR_TEXT("Slave mode SPI is not implemented")); - } + const mcu_pin_obj_t *sck, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { int periph_index = check_pins(self, sck, mosi, miso); SPI_TypeDef *SPIx = mcu_spi_banks[periph_index - 1]; diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 62acd69ae1a5..bb8f8099e23a 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -351,6 +351,9 @@ endif ifeq ($(CIRCUITPY_SOCKETPOOL),1) SRC_PATTERNS += socketpool/% endif +ifeq ($(CIRCUITPY_SPITARGET),1) +SRC_PATTERNS += spitarget/% +endif ifeq ($(CIRCUITPY_SSL),1) SRC_PATTERNS += ssl/% endif @@ -516,6 +519,8 @@ SRC_COMMON_HAL_ALL = \ socketpool/__init__.c \ socketpool/SocketPool.c \ socketpool/Socket.c \ + spitarget/SPITarget.c \ + spitarget/__init__.c \ supervisor/Runtime.c \ supervisor/__init__.c \ usb_host/__init__.c \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index fc9fdcbd31af..d3774258fbed 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -476,6 +476,9 @@ CFLAGS += -DCIRCUITPY_SKIP_SAFE_MODE_WAIT=$(CIRCUITPY_SKIP_SAFE_MODE_WAIT) CIRCUITPY_SOCKETPOOL ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_SOCKETPOOL=$(CIRCUITPY_SOCKETPOOL) +CIRCUITPY_SPITARGET ?= 0 +CFLAGS += -DCIRCUITPY_SPITARGET=$(CIRCUITPY_SPITARGET) + CIRCUITPY_SSL ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_SSL=$(CIRCUITPY_SSL) diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index f9036af3e659..8b264bbdbc4f 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -73,9 +73,7 @@ //| clock: microcontroller.Pin, //| MOSI: Optional[microcontroller.Pin] = None, //| MISO: Optional[microcontroller.Pin] = None, -//| SS: Optional[microcontroller.Pin] = None, -//| half_duplex: bool = False, -//| slave_mode: bool = False, +//| half_duplex: bool = False //| ) -> None: //| """Construct an SPI object on the given pins. //| @@ -98,10 +96,8 @@ //| :param ~microcontroller.Pin MOSI: the Main Out Selected In pin. //| :param ~microcontroller.Pin MISO: the Main In Selected Out pin. //| :param bool half_duplex: True when MOSI is used for bidirectional data. False when SPI is full-duplex or simplex. -//| :param-bool slave_mode: True when the chip is operating as a slave. False when the chip is operating as a master. //| //| **Limitations:** ``half_duplex`` is available only on STM; other chips do not have the hardware support. -//| **Limitations:** ``slave_mode`` is available only on SAMD51; other chips do not have the firmware support. //| """ //| ... @@ -110,14 +106,12 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_BUSIO_SPI busio_spi_obj_t *self = mp_obj_malloc(busio_spi_obj_t, &busio_spi_type); - enum { ARG_clock, ARG_MOSI, ARG_MISO, ARG_SS, ARG_half_duplex, ARG_slave_mode }; + enum { ARG_clock, ARG_MOSI, ARG_MISO, ARG_half_duplex }; static const mp_arg_t allowed_args[] = { { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_MOSI, MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_MISO, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_SS, MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_half_duplex, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, - { MP_QSTR_slave_mode, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, }; 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); @@ -125,19 +119,12 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, siz 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); - const mcu_pin_obj_t *ss = validate_obj_is_free_pin_or_none(args[ARG_SS].u_obj, MP_QSTR_ss); if (!miso && !mosi) { mp_raise_ValueError(MP_ERROR_TEXT("Must provide MISO or MOSI pin")); } - if (args[ARG_slave_mode].u_bool && !ss) { - mp_raise_ValueError(MP_ERROR_TEXT("Must provide SS pin to operate in slave mode")); - } - if (!args[ARG_slave_mode].u_bool && ss) { - mp_raise_ValueError(MP_ERROR_TEXT("Hardware SS pin only supported for slave mode")); - } - common_hal_busio_spi_construct(self, clock, mosi, miso, ss, args[ARG_half_duplex].u_bool, args[ARG_slave_mode].u_bool); + common_hal_busio_spi_construct(self, clock, mosi, miso, args[ARG_half_duplex].u_bool); return MP_OBJ_FROM_PTR(self); #else raise_ValueError_invalid_pins(); @@ -482,145 +469,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_get_frequency_obj, busio_spi_obj_get_frequen MP_PROPERTY_GETTER(busio_spi_frequency_obj, (mp_obj_t)&busio_spi_get_frequency_obj); -#if CIRCUITPY_SAMD - -//| import sys -//| def async_transfer_start( -//| self, -//| out_buffer: ReadableBuffer, -//| in_buffer: WriteableBuffer, -//| *, -//| out_start: int = 0, -//| out_end: int = sys.maxsize, -//| in_start: int = 0, -//| in_end: int = sys.maxsize -//| ) -> None: -//| """Write out the data in ``out_buffer`` while simultaneously reading data into ``in_buffer``. -//| The SPI object must be locked. Note: this method returns immediately, and the data will not -//| actually be transferred until some time has passed. Use `async_transfer_finished` and -//| `async_transfer_end` to check on the status of the transfer and close out its resources. -//| -//| If ``out_start`` or ``out_end`` is provided, then the buffer will be sliced -//| as if ``out_buffer[out_start:out_end]`` were passed, but without copying the data. -//| The number of bytes written will be the length of ``out_buffer[out_start:out_end]``. -//| -//| If ``in_start`` or ``in_end`` is provided, then the input buffer will be sliced -//| as if ``in_buffer[in_start:in_end]`` were passed, -//| The number of bytes read will be the length of ``out_buffer[in_start:in_end]``. -//| -//| The lengths of the slices defined by ``out_buffer[out_start:out_end]`` -//| and ``in_buffer[in_start:in_end]`` must be equal. -//| If buffer slice lengths are both 0, nothing happens. -//| -//| Note: This method is currently only available on atmel-samd` ports of CircuitPython. -//| -//| :param ReadableBuffer out_buffer: write out bytes from this buffer -//| :param WriteableBuffer in_buffer: read bytes into this buffer -//| :param int out_start: beginning of ``out_buffer`` slice -//| :param int out_end: end of ``out_buffer`` slice; if not specified, use ``len(out_buffer)`` -//| :param int in_start: beginning of ``in_buffer`` slice -//| :param int in_end: end of ``in_buffer slice``; if not specified, use ``len(in_buffer)`` -//| """ -//| ... - -STATIC mp_obj_t busio_spi_start_async_transfer(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_out_buffer, ARG_in_buffer, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_out_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_in_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_out_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_out_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, - { MP_QSTR_in_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, - }; - busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - check_for_deinit(self); - check_lock(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); - - mp_buffer_info_t buf_out_info; - mp_get_buffer_raise(args[ARG_out_buffer].u_obj, &buf_out_info, MP_BUFFER_READ); - int out_stride_in_bytes = mp_binary_get_size('@', buf_out_info.typecode, NULL); - int32_t out_start = args[ARG_out_start].u_int; - size_t out_length = buf_out_info.len / out_stride_in_bytes; - normalize_buffer_bounds(&out_start, args[ARG_out_end].u_int, &out_length); - - mp_buffer_info_t buf_in_info; - mp_get_buffer_raise(args[ARG_in_buffer].u_obj, &buf_in_info, MP_BUFFER_WRITE); - int in_stride_in_bytes = mp_binary_get_size('@', buf_in_info.typecode, NULL); - int32_t in_start = args[ARG_in_start].u_int; - size_t in_length = buf_in_info.len / in_stride_in_bytes; - normalize_buffer_bounds(&in_start, args[ARG_in_end].u_int, &in_length); - - // Treat start and length in terms of bytes from now on. - out_start *= out_stride_in_bytes; - out_length *= out_stride_in_bytes; - in_start *= in_stride_in_bytes; - in_length *= in_stride_in_bytes; - - if (out_length != in_length) { - mp_raise_ValueError(MP_ERROR_TEXT("buffer slices must be of equal length")); - } - - common_hal_busio_spi_transfer_async_start(self, - ((uint8_t *)buf_out_info.buf) + out_start, - ((uint8_t *)buf_in_info.buf) + in_start, - out_length); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_start_transfer_obj, 1, busio_spi_start_async_transfer); - -//| import sys -//| def async_transfer_finished( -//| self -//| ) -> None: -//| """Check whether or not the last async transfer started on this SPI object has finished. If -//| no transfer was started, this method behaves as though the most recent transfer has finished -//| and returns `True`. Otherwise, it returns `False`. -//| -//| Note: This method is currently only available on atmel-samd` ports of CircuitPython. -//| """ -//| ... -STATIC mp_obj_t busio_spi_obj_check_async_transfer(mp_obj_t self_in) { - busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return common_hal_busio_spi_transfer_async_check(self) ? mp_const_true : mp_const_false; -} -MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_check_transfer_obj, busio_spi_obj_check_async_transfer); - -//| import sys -//| def async_transfer_end( -//| self -//| ) -> None: -//| """Return the status code with which the last async transfer on this SPI object completed. This -//| method MUST be called for all transfers, regardless of user interest in status code. The resources -//| for the transfer will be left open until this method is called. Once this method is called, the -//| peripheral resets and is ready for another transfer. The return code of this method also resets to -//| its pre-transfer state: repeated calls to this method may produce different codes. -//| -//| Return code 0: No transfer has occured, either because `start_async_transfer` was never called, or because -//| it was called with zero-length buffers. -//| Return code -1: The transfer failed because no DMA channels are available. -//| Return code -2: The transfer executed, but the DMA controller indicates that either some data is -//| untransferred, that a software issue prevented the data transfer from completing, or that some other error -//| has occured within the DMA controller. -//| Return code -3: An unaligned buffer was passed to the QSPI peripheral, which prevents the DMA controller from -//| appropriately chunking the transfer. -//| Return code n>0: A transfer of `n` bytes in each direction has succeeded. -//| -//| Note: This method is currently only available on atmel-samd` ports of CircuitPython. -//| """ -//| ... -STATIC mp_obj_t busio_spi_obj_end_async_transfer(mp_obj_t self_in) { - busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_busio_spi_transfer_async_end(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_end_transfer_obj, busio_spi_obj_end_async_transfer); - -#endif // CIRCUITPY_SAMD - #endif // CIRCUITPY_BUSIO_SPI @@ -639,13 +487,6 @@ STATIC const mp_rom_map_elem_t busio_spi_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&busio_spi_write_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&busio_spi_frequency_obj) } - #if CIRCUITPY_SAMD - , - { MP_ROM_QSTR(MP_QSTR_async_transfer_start), MP_ROM_PTR(&busio_spi_start_transfer_obj) }, - { MP_ROM_QSTR(MP_QSTR_async_transfer_finished), MP_ROM_PTR(&busio_spi_check_transfer_obj) }, - { MP_ROM_QSTR(MP_QSTR_async_transfer_end), MP_ROM_PTR(&busio_spi_end_transfer_obj) } - #endif // CIRCUITPY_SAMD - #endif // CIRCUITPY_BUSIO_SPI }; STATIC MP_DEFINE_CONST_DICT(busio_spi_locals_dict, busio_spi_locals_dict_table); diff --git a/shared-bindings/busio/SPI.h b/shared-bindings/busio/SPI.h index c56ed5dd463b..2665ecc7e597 100644 --- a/shared-bindings/busio/SPI.h +++ b/shared-bindings/busio/SPI.h @@ -37,8 +37,7 @@ extern const mp_obj_type_t busio_spi_type; // Construct an underlying SPI object. extern void common_hal_busio_spi_construct(busio_spi_obj_t *self, - const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, - const mcu_pin_obj_t *miso, const mcu_pin_obj_t *ss, bool half_duplex, bool slave_mode); + const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex); extern void common_hal_busio_spi_deinit(busio_spi_obj_t *self); extern bool common_hal_busio_spi_deinited(busio_spi_obj_t *self); @@ -58,19 +57,6 @@ extern bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size // Reads and write len bytes simultaneously. extern bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_out, uint8_t *data_in, size_t len); -#if CIRCUITPY_SAMD - -// Initiates a transfer that reads and write len bytes simultaneously -extern void common_hal_busio_spi_transfer_async_start(busio_spi_obj_t *self, const uint8_t *data_out, uint8_t *data_in, size_t len); - -// Reads the state of the in-progress transfer -extern bool common_hal_busio_spi_transfer_async_check(busio_spi_obj_t *self); - -// Cleans up the completed transfer and returns any error code produced by the transfer -extern int common_hal_busio_spi_transfer_async_end(busio_spi_obj_t *self); - -#endif // CIRCUITPY_SAMD - // Return actual SPI bus frequency. uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t *self); diff --git a/shared-bindings/spitarget/SPITarget.c b/shared-bindings/spitarget/SPITarget.c new file mode 100644 index 000000000000..e9de54f2b4e4 --- /dev/null +++ b/shared-bindings/spitarget/SPITarget.c @@ -0,0 +1,208 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/spitarget/SPITarget.h" +#include "shared-bindings/time/__init__.h" +#include "shared-bindings/util.h" + +#include "shared/runtime/buffer_helper.h" +#include "shared/runtime/context_manager_helpers.h" +#include "shared/runtime/interrupt_char.h" + +#include "py/mperrno.h" +#include "py/mphal.h" +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +//| class SPITarget: +//| """Serial Peripheral Interface protocol target""" +//| +//| def __init__( +//| self, +//| sck: microcontroller.Pin, +//| mosi: microcontroller.Pin, +//| miso: microcontroller.Pin, +//| ss: microcontroller.Pin +//| ) -> None: +//| """I2C is a two-wire protocol for communicating between devices. +//| This implements the secondary (aka target or peripheral) side. +//| +//| :param ~microcontroller.Pin sck: The SPI clock pin +//| :param ~microcontroller.Pin mosi: The pin transferring data from the main to the secondary +//| :param ~microcontroller.Pin miso: The pin transferring data from the secondary to the main +//| :param ~microcontroller.Pin ss: The secondary selection pin""" +//| ... +STATIC mp_obj_t spitarget_spi_target_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + spitarget_spi_target_obj_t *self = mp_obj_malloc(spitarget_spi_target_obj_t, &spitarget_spi_target_type); + enum { ARG_sck, ARG_mosi, ARG_miso, ARG_ss }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sck, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_mosi, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_miso, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_ss, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + 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 *sck = validate_obj_is_free_pin(args[ARG_sck].u_obj, MP_QSTR_sck); + const mcu_pin_obj_t *mosi = validate_obj_is_free_pin(args[ARG_mosi].u_obj, MP_QSTR_mosi); + const mcu_pin_obj_t *miso = validate_obj_is_free_pin(args[ARG_miso].u_obj, MP_QSTR_miso); + const mcu_pin_obj_t *ss = validate_obj_is_free_pin(args[ARG_ss].u_obj, MP_QSTR_ss); + + common_hal_spitarget_spi_target_construct(self, sck, mosi, miso, ss); + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Releases control of the underlying hardware so other classes can use it.""" +//| ... +STATIC mp_obj_t spitarget_spi_target_obj_deinit(mp_obj_t self_in) { + mp_check_self(mp_obj_is_type(self_in, &spitarget_spi_target_type)); + spitarget_spi_target_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_spitarget_spi_target_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(spitarget_spi_target_deinit_obj, spitarget_spi_target_obj_deinit); + +//| def __enter__(self) -> SPITarget: +//| """No-op used in Context Managers.""" +//| ... +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware on context exit. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +STATIC mp_obj_t spitarget_spi_target_obj___exit__(size_t n_args, const mp_obj_t *args) { + mp_check_self(mp_obj_is_type(args[0], &spitarget_spi_target_target_type)); + spitarget_spi_target_obj_t *self = MP_OBJ_TO_PTR(args[0]); + common_hal_spitarget_spi_target_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(spitarget_spi_target___exit___obj, 4, 4, spitarget_spi_target_obj___exit__); + +//| def load_packet(self, mosi_packet: bytearray, miso_packet: bytearray) -> None: +//| """Queue data for the next SPI transfer from the main device. +//| If a packet has already been queued for this SPI bus but has not yet been transferred, an error will be raised. +//| +//| :param bytearray miso_packet: Packet data to be sent from secondary to main on next request.""" +//| +STATIC mp_obj_t spitarget_spi_target_load_packet(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_check_self(mp_obj_is_type(pos_args[0], &spitarget_spi_target_type)); + spitarget_spi_target_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + if (common_hal_spitarget_spi_target_deinited(self)) { + raise_deinited_error(); + } + enum { ARG_mosi_packet, ARG_miso_packet }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_mosi_packet, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_miso_packet, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + 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); + + mp_buffer_info_t mosi_bufinfo; + mp_get_buffer_raise(args[ARG_mosi_packet].u_obj, &mosi_bufinfo, MP_BUFFER_WRITE); + + mp_buffer_info_t miso_bufinfo; + mp_get_buffer_raise(args[ARG_miso_packet].u_obj, &miso_bufinfo, MP_BUFFER_READ); + + if (miso_bufinfo.len != mosi_bufinfo.len) { + mp_raise_ValueError(MP_ERROR_TEXT("Packet buffers for an SPI transfer must have the same length.")); + } + + common_hal_spitarget_spi_target_transfer_start(self, ((uint8_t *)mosi_bufinfo.buf), ((uint8_t *)miso_bufinfo.buf), mosi_bufinfo.len); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(spitarget_spi_target_load_packet_obj, 1, spitarget_spi_target_load_packet); + +//| def try_transfer(self, *, timeout: float = -1) -> bool: +//| """Wait for an SPI transfer from the main device. +//| +//| :param float timeout: Timeout in seconds. Zero means wait forever, a negative value means check once +//| :return: True if the transfer is complete, or False if no response received before the timeout +//| :rtype: ~bool""" +//| +STATIC mp_obj_t spitarget_spi_target_try_transfer(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_check_self(mp_obj_is_type(pos_args[0], &spitarget_spi_target_type)); + spitarget_spi_target_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + if (common_hal_spitarget_spi_target_deinited(self)) { + raise_deinited_error(); + } + enum { ARG_timeout }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} }, + }; + 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); + + #if MICROPY_PY_BUILTINS_FLOAT + float f = mp_obj_get_float(args[ARG_timeout].u_obj) * 1000; + int timeout_ms = (int)f; + #else + int timeout_ms = mp_obj_get_int(args[ARG_timeout].u_obj) * 1000; + #endif + + bool forever = false; + uint64_t timeout_end = 0; + if (timeout_ms == 0) { + forever = true; + } else if (timeout_ms > 0) { + timeout_end = common_hal_time_monotonic_ms() + timeout_ms; + } + + do { + if (common_hal_spitarget_spi_target_transfer_is_finished(self)) { + common_hal_spitarget_spi_target_transfer_close(self); // implicitly discards error indicator code + return mp_const_true; + } + mp_hal_delay_us(10); + } while (forever || common_hal_time_monotonic_ms() < timeout_end); + + return mp_const_false; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(spitarget_spi_target_try_transfer_obj, 1, spitarget_spi_target_try_transfer); + +STATIC const mp_rom_map_elem_t spitarget_spi_target_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&spitarget_spi_target_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&spitarget_spi_target___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_load_packet), MP_ROM_PTR(&spitarget_spi_target_load_packet_obj) }, + { MP_ROM_QSTR(MP_QSTR_try_transfer), MP_ROM_PTR(&spitarget_spi_target_try_transfer_obj) }, + +}; + +STATIC MP_DEFINE_CONST_DICT(spitarget_spi_target_locals_dict, spitarget_spi_target_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + spitarget_spi_target_type, + MP_QSTR_SPITarget, + MP_TYPE_FLAG_NONE, + make_new, spitarget_spi_target_make_new, + locals_dict, &spitarget_spi_target_locals_dict + ); diff --git a/shared-bindings/spitarget/SPITarget.h b/shared-bindings/spitarget/SPITarget.h new file mode 100644 index 000000000000..bbfb0f9942eb --- /dev/null +++ b/shared-bindings/spitarget/SPITarget.h @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_TARGET_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_TARGET_H + +#include "py/obj.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/spitarget/SPITarget.h" + +extern const mp_obj_type_t spitarget_spi_target_type; + +extern void common_hal_spitarget_spi_target_construct(spitarget_spi_target_obj_t *self, + const mcu_pin_obj_t *sck, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, const mcu_pin_obj_t *ss); +extern void common_hal_spitarget_spi_target_deinit(spitarget_spi_target_obj_t *self); +extern bool common_hal_spitarget_spi_target_deinited(spitarget_spi_target_obj_t *self); + +extern void common_hal_spitarget_spi_target_transfer_start(spitarget_spi_target_obj_t *self, + uint8_t *mosi_packet, const uint8_t *miso_packet, size_t len); +extern bool common_hal_spitarget_spi_target_transfer_is_finished(spitarget_spi_target_obj_t *self); +extern int common_hal_spitarget_spi_target_transfer_close(spitarget_spi_target_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_TARGET_H diff --git a/shared-bindings/spitarget/__init__.c b/shared-bindings/spitarget/__init__.c new file mode 100644 index 000000000000..f92e1b29271f --- /dev/null +++ b/shared-bindings/spitarget/__init__.c @@ -0,0 +1,40 @@ +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/spitarget/SPITarget.h" + +#include "py/runtime.h" + +//| """Serial Peripheral Interface protocol target +//| +//| The `spitarget` module contains classes to support an SPI target. +//| +//| Example emulating a target :: +//| +//| import board +//| from spitarget import SPITarget +//| +//| TODO +//| +//| This example sets up an SPI device that can be accessed from Linux like this:: +//| +//| $ TODO command +//| TODO result +//| $ TODO command + +STATIC const mp_rom_map_elem_t spitarget_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_spitarget) }, + { MP_ROM_QSTR(MP_QSTR_SPITarget), MP_ROM_PTR(&spitarget_spi_target_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(spitarget_module_globals, spitarget_module_globals_table); + +const mp_obj_module_t spitarget_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&spitarget_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_spitarget, spitarget_module); diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index af56ec1a998d..08a9761ed5f7 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -130,7 +130,7 @@ mp_obj_t common_hal_board_create_spi(const mp_int_t instance) { assert_pin_free(spi_pin[instance].mosi); assert_pin_free(spi_pin[instance].miso); - common_hal_busio_spi_construct(self, spi_pin[instance].clock, spi_pin[instance].mosi, spi_pin[instance].miso, NULL, false, false); + common_hal_busio_spi_construct(self, spi_pin[instance].clock, spi_pin[instance].mosi, spi_pin[instance].miso, false); spi_obj_created[instance] = true; return &spi_obj[instance]; diff --git a/supervisor/shared/external_flash/spi_flash.c b/supervisor/shared/external_flash/spi_flash.c index 3911fb880166..abff3437134d 100644 --- a/supervisor/shared/external_flash/spi_flash.c +++ b/supervisor/shared/external_flash/spi_flash.c @@ -149,7 +149,7 @@ void spi_flash_init(void) { common_hal_digitalio_digitalinout_never_reset(&cs_pin); supervisor_flash_spi_bus.base.type = &busio_spi_type; - common_hal_busio_spi_construct(&supervisor_flash_spi_bus, SPI_FLASH_SCK_PIN, SPI_FLASH_MOSI_PIN, SPI_FLASH_MISO_PIN, NULL, false, false); + common_hal_busio_spi_construct(&supervisor_flash_spi_bus, SPI_FLASH_SCK_PIN, SPI_FLASH_MOSI_PIN, SPI_FLASH_MISO_PIN, false); common_hal_busio_spi_never_reset(&supervisor_flash_spi_bus); common_hal_busio_spi_configure(&supervisor_flash_spi_bus, SPI_FLASH_MAX_BAUDRATE, 0, 0, 8); diff --git a/supervisor/shared/status_leds.c b/supervisor/shared/status_leds.c index c66747ad0df1..414b35dd4164 100644 --- a/supervisor/shared/status_leds.c +++ b/supervisor/shared/status_leds.c @@ -164,8 +164,6 @@ void status_led_init() { MICROPY_HW_APA102_SCK, MICROPY_HW_APA102_MOSI, NULL, - NULL, - false, false); #endif #if CIRCUITPY_BITBANG_APA102