summaryrefslogtreecommitdiff
path: root/ports
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2020-02-20 22:27:16 -0500
committerDan Halbert <halbert@halwitz.org>2020-02-20 22:27:16 -0500
commit23d6a3dc1fe2ece41642f602343650fce5be83c7 (patch)
tree801979949b826c0a2c439563f0efe692831a25d1 /ports
parent1caf6bd8d3924b2f7861cd8b0af0d16a608bb736 (diff)
parent675930083de102ab73af6f6a586614793e467f5f (diff)
merge from upstream
Diffstat (limited to 'ports')
-rw-r--r--ports/atmel-samd/audio_dma.c4
-rw-r--r--ports/atmel-samd/boards/capablerobot_usbhub/board.c7
-rw-r--r--ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk4
-rw-r--r--ports/atmel-samd/boards/capablerobot_usbhub/pins.c5
-rwxr-xr-xports/atmel-samd/boards/circuitbrains_basic_m0/board.c40
-rwxr-xr-xports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.h35
-rwxr-xr-xports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk16
-rwxr-xr-xports/atmel-samd/boards/circuitbrains_basic_m0/pins.c35
-rwxr-xr-xports/atmel-samd/boards/circuitbrains_deluxe_m4/board.c40
-rwxr-xr-xports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.h32
-rwxr-xr-xports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.mk16
-rwxr-xr-xports/atmel-samd/boards/circuitbrains_deluxe_m4/pins.c55
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express/board.c12
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h4
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_crickit/board.c12
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h4
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_displayio/board.c12
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h4
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/feather_m4_express/pins.c23
-rw-r--r--ports/atmel-samd/boards/hallowing_m4_express/board.c2
-rw-r--r--ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/monster_m4sk/board.c2
-rw-r--r--ports/atmel-samd/boards/ndgarage_ndbit6/board.c39
-rw-r--r--ports/atmel-samd/boards/ndgarage_ndbit6/mpconfigboard.h32
-rw-r--r--ports/atmel-samd/boards/ndgarage_ndbit6/mpconfigboard.mk15
-rw-r--r--ports/atmel-samd/boards/ndgarage_ndbit6/pins.c39
-rw-r--r--ports/atmel-samd/boards/openbook_m4/board.c107
-rw-r--r--ports/atmel-samd/boards/openbook_m4/mpconfigboard.h28
-rw-r--r--ports/atmel-samd/boards/openbook_m4/mpconfigboard.mk14
-rw-r--r--ports/atmel-samd/boards/openbook_m4/pins.c71
-rw-r--r--ports/atmel-samd/boards/pewpew_m4/board.c2
-rw-r--r--ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk3
-rw-r--r--ports/atmel-samd/boards/pybadge/board.c8
-rw-r--r--ports/atmel-samd/boards/pybadge/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/pybadge_airlift/board.c4
-rw-r--r--ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/pycubed/board.c61
-rw-r--r--ports/atmel-samd/boards/pycubed/mpconfigboard.h34
-rw-r--r--ports/atmel-samd/boards/pycubed/mpconfigboard.mk24
-rw-r--r--ports/atmel-samd/boards/pycubed/pins.c55
-rw-r--r--ports/atmel-samd/boards/pygamer/board.c8
-rw-r--r--ports/atmel-samd/boards/pygamer/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/pygamer_advance/board.c4
-rw-r--r--ports/atmel-samd/boards/pygamer_advance/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/sam32/mpconfigboard.h13
-rw-r--r--ports/atmel-samd/boards/sam32/mpconfigboard.mk7
-rw-r--r--ports/atmel-samd/boards/sam32/pins.c33
-rw-r--r--ports/atmel-samd/boards/seeeduino_xiao/board.c39
-rw-r--r--ports/atmel-samd/boards/seeeduino_xiao/mpconfigboard.h20
-rw-r--r--ports/atmel-samd/boards/seeeduino_xiao/mpconfigboard.mk13
-rw-r--r--ports/atmel-samd/boards/seeeduino_xiao/pins.c54
-rw-r--r--ports/atmel-samd/common-hal/audioio/AudioOut.c23
-rw-r--r--ports/atmel-samd/common-hal/busio/I2C.c3
-rw-r--r--ports/atmel-samd/common-hal/busio/UART.c15
-rw-r--r--ports/atmel-samd/common-hal/nvm/ByteArray.c4
-rw-r--r--ports/atmel-samd/common-hal/time/__init__.c11
-rw-r--r--ports/atmel-samd/mpconfigport.h30
m---------ports/atmel-samd/peripherals0
-rw-r--r--ports/atmel-samd/supervisor/port.c11
-rw-r--r--ports/cxd56/Makefile12
-rw-r--r--ports/cxd56/common-hal/busio/UART.c12
-rw-r--r--ports/cxd56/common-hal/time/__init__.c8
-rw-r--r--ports/cxd56/mkspk/.gitignore3
-rw-r--r--ports/cxd56/mkspk/Makefile51
-rw-r--r--ports/cxd56/mkspk/clefia.c517
-rw-r--r--ports/cxd56/mkspk/clefia.h65
-rw-r--r--ports/cxd56/mkspk/mkspk.c383
-rw-r--r--ports/cxd56/mkspk/mkspk.h83
-rw-r--r--ports/cxd56/supervisor/port.c8
-rw-r--r--ports/mimxrt10xx/Makefile48
-rw-r--r--ports/mimxrt10xx/background.c6
-rw-r--r--ports/mimxrt10xx/boards/feather_m7_1011/board.c39
-rw-r--r--ports/mimxrt10xx/boards/feather_m7_1011/flash_config.c122
-rw-r--r--ports/mimxrt10xx/boards/feather_m7_1011/mpconfigboard.h20
-rw-r--r--ports/mimxrt10xx/boards/feather_m7_1011/mpconfigboard.mk8
-rw-r--r--ports/mimxrt10xx/boards/feather_m7_1011/pins.c43
-rw-r--r--ports/mimxrt10xx/boards/feather_mimxrt1011/board.c16
-rw-r--r--ports/mimxrt10xx/boards/feather_mimxrt1011/flash_config.c122
-rw-r--r--ports/mimxrt10xx/boards/feather_mimxrt1011/mpconfigboard.h11
-rw-r--r--ports/mimxrt10xx/boards/feather_mimxrt1011/mpconfigboard.mk15
-rw-r--r--ports/mimxrt10xx/boards/feather_mimxrt1062/board.c16
-rw-r--r--ports/mimxrt10xx/boards/feather_mimxrt1062/flash_config.c122
-rw-r--r--ports/mimxrt10xx/boards/feather_mimxrt1062/mpconfigboard.h8
-rw-r--r--ports/mimxrt10xx/boards/feather_mimxrt1062/mpconfigboard.mk15
-rw-r--r--ports/mimxrt10xx/boards/imxrt1010_evk/board.c16
-rw-r--r--ports/mimxrt10xx/boards/imxrt1010_evk/flash_config.c121
-rw-r--r--ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.h17
-rw-r--r--ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.mk16
-rw-r--r--ports/mimxrt10xx/boards/imxrt1010_evk/pins.c30
-rw-r--r--ports/mimxrt10xx/boards/imxrt1020_evk/board.c39
-rw-r--r--ports/mimxrt10xx/boards/imxrt1020_evk/flash_config.c126
-rw-r--r--ports/mimxrt10xx/boards/imxrt1020_evk/mpconfigboard.h14
-rw-r--r--ports/mimxrt10xx/boards/imxrt1020_evk/mpconfigboard.mk8
-rw-r--r--ports/mimxrt10xx/boards/imxrt1020_evk/pins.c84
-rw-r--r--ports/mimxrt10xx/boards/imxrt1060_evk/board.c39
-rw-r--r--ports/mimxrt10xx/boards/imxrt1060_evk/flash_config.c122
-rw-r--r--ports/mimxrt10xx/boards/imxrt1060_evk/mpconfigboard.h14
-rw-r--r--ports/mimxrt10xx/boards/imxrt1060_evk/mpconfigboard.mk8
-rw-r--r--ports/mimxrt10xx/boards/imxrt1060_evk/pins.c128
-rw-r--r--ports/mimxrt10xx/boards/mimxrt1011-bootloader-external-flash.ld106
-rw-r--r--ports/mimxrt10xx/boards/mimxrt1011-external-flash.ld123
-rw-r--r--ports/mimxrt10xx/boards/mimxrt1062-bootloader-external-flash.ld106
-rw-r--r--ports/mimxrt10xx/boards/teensy40/board.c39
-rw-r--r--ports/mimxrt10xx/boards/teensy40/board.ld1
-rw-r--r--ports/mimxrt10xx/boards/teensy40/flash_config.c126
-rw-r--r--ports/mimxrt10xx/boards/teensy40/mpconfigboard.h18
-rw-r--r--ports/mimxrt10xx/boards/teensy40/mpconfigboard.mk8
-rw-r--r--ports/mimxrt10xx/boards/teensy40/pins.c87
-rw-r--r--ports/mimxrt10xx/common-hal/busio/I2C.c2
-rw-r--r--ports/mimxrt10xx/common-hal/busio/UART.c87
-rw-r--r--ports/mimxrt10xx/common-hal/displayio/ParallelBus.c68
-rw-r--r--ports/mimxrt10xx/common-hal/displayio/ParallelBus.h36
-rw-r--r--ports/mimxrt10xx/common-hal/microcontroller/Pin.c4
-rw-r--r--ports/mimxrt10xx/common-hal/microcontroller/Processor.c11
-rw-r--r--ports/mimxrt10xx/common-hal/microcontroller/__init__.c6
-rw-r--r--ports/mimxrt10xx/common-hal/time/__init__.c12
-rw-r--r--ports/mimxrt10xx/linking/chip_family/MIMXRT1011.ld2
-rw-r--r--ports/mimxrt10xx/linking/chip_family/MIMXRT1021.ld2
-rw-r--r--ports/mimxrt10xx/linking/chip_family/MIMXRT1062.ld2
-rw-r--r--ports/mimxrt10xx/linking/common.ld154
-rw-r--r--ports/mimxrt10xx/linking/flash/AT25SF128A.ld1
-rw-r--r--ports/mimxrt10xx/linking/flash/IS25LP064A.ld1
-rw-r--r--ports/mimxrt10xx/linking/flash/IS25WP064A.ld1
-rw-r--r--ports/mimxrt10xx/linking/flash/W25Q16JV.ld1
-rw-r--r--ports/mimxrt10xx/linking/flash/W25Q32JV.ld1
-rw-r--r--ports/mimxrt10xx/linking/flash/W25Q64JV.ld1
-rw-r--r--ports/mimxrt10xx/mpconfigport.h12
-rw-r--r--ports/mimxrt10xx/mpconfigport.mk16
-rw-r--r--ports/mimxrt10xx/mphalport.c2
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/clocks.c31
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.c20
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h2
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/pins.c4
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/clocks.c341
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c258
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h45
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/pins.c128
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/pins.h129
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/clocks.c28
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.c42
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h2
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/periph.h2
-rw-r--r--ports/mimxrt10xx/peripherals/mimxrt10xx/pins.h2
-rw-r--r--ports/mimxrt10xx/reset.c2
-rw-r--r--ports/mimxrt10xx/reset.h2
m---------ports/mimxrt10xx/sdk0
-rw-r--r--ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c13
-rw-r--r--ports/mimxrt10xx/supervisor/internal_flash.c10
-rw-r--r--ports/mimxrt10xx/supervisor/port.c255
-rw-r--r--ports/mimxrt10xx/supervisor/usb.c4
-rwxr-xr-xports/nrf/Makefile29
-rw-r--r--ports/nrf/background.c2
-rw-r--r--ports/nrf/bluetooth/ble_drv.c3
-rw-r--r--ports/nrf/bluetooth/ble_drv.h2
-rw-r--r--ports/nrf/boards/aramcon_badge_2019/board.c40
-rw-r--r--ports/nrf/boards/aramcon_badge_2019/mpconfigboard.h31
-rw-r--r--ports/nrf/boards/aramcon_badge_2019/mpconfigboard.mk14
-rw-r--r--ports/nrf/boards/aramcon_badge_2019/pins.c34
-rw-r--r--ports/nrf/boards/circuitplayground_bluefruit/board.c3
-rw-r--r--ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h4
-rw-r--r--ports/nrf/boards/clue_nrf52840_express/board.c8
-rw-r--r--ports/nrf/boards/clue_nrf52840_express/mpconfigboard.h3
-rw-r--r--ports/nrf/boards/clue_nrf52840_express/pins.c16
-rw-r--r--ports/nrf/boards/common.template.ld15
-rw-r--r--ports/nrf/boards/feather_bluefruit_sense/board.c38
-rw-r--r--ports/nrf/boards/feather_bluefruit_sense/mpconfigboard.h70
-rw-r--r--ports/nrf/boards/feather_bluefruit_sense/mpconfigboard.mk10
-rw-r--r--ports/nrf/boards/feather_bluefruit_sense/pins.c58
-rw-r--r--ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk2
-rw-r--r--ports/nrf/boards/ohs2020_badge/board.c99
-rw-r--r--ports/nrf/boards/ohs2020_badge/mpconfigboard.h57
-rw-r--r--ports/nrf/boards/ohs2020_badge/mpconfigboard.mk10
-rw-r--r--ports/nrf/boards/ohs2020_badge/pins.c29
-rw-r--r--ports/nrf/boards/particle_argon/mpconfigboard.mk4
-rw-r--r--ports/nrf/boards/particle_boron/mpconfigboard.mk4
-rw-r--r--ports/nrf/boards/particle_xenon/mpconfigboard.mk4
-rw-r--r--ports/nrf/common-hal/_bleio/Adapter.c41
-rw-r--r--ports/nrf/common-hal/_bleio/Adapter.h2
-rw-r--r--ports/nrf/common-hal/_bleio/Characteristic.c1
-rw-r--r--ports/nrf/common-hal/_bleio/Connection.c84
-rw-r--r--ports/nrf/common-hal/_bleio/Connection.h12
-rw-r--r--ports/nrf/common-hal/_bleio/__init__.c9
-rw-r--r--ports/nrf/common-hal/_bleio/__init__.h6
-rw-r--r--ports/nrf/common-hal/_bleio/bonding.c310
-rw-r--r--ports/nrf/common-hal/_bleio/bonding.h85
-rw-r--r--ports/nrf/common-hal/busio/I2C.c16
-rw-r--r--ports/nrf/common-hal/busio/SPI.c169
-rw-r--r--ports/nrf/common-hal/busio/SPI.h4
-rw-r--r--ports/nrf/common-hal/busio/UART.c15
-rw-r--r--ports/nrf/common-hal/microcontroller/__init__.c30
-rw-r--r--ports/nrf/common-hal/neopixel_write/__init__.c18
-rw-r--r--ports/nrf/common-hal/nvm/ByteArray.c14
-rw-r--r--ports/nrf/common-hal/os/__init__.c20
-rw-r--r--ports/nrf/common-hal/time/__init__.c8
-rw-r--r--ports/nrf/ld_defines.c3
-rw-r--r--ports/nrf/mpconfigport.h41
-rw-r--r--ports/nrf/nrfx_config.h18
-rw-r--r--ports/nrf/peripherals/nrf/nrf52840/power.c18
-rw-r--r--ports/nrf/peripherals/nrf/nvm.c49
-rw-r--r--ports/nrf/peripherals/nrf/nvm.h5
-rw-r--r--ports/nrf/supervisor/port.c11
-rwxr-xr-xports/stm32f4/Makefile50
-rw-r--r--ports/stm32f4/boards/STM32F401xd_fs.ld107
-rw-r--r--ports/stm32f4/boards/STM32F401xe_boot.ld106
-rw-r--r--ports/stm32f4/boards/STM32F401xe_fs.ld107
-rw-r--r--ports/stm32f4/boards/STM32F405_boot.ld107
-rw-r--r--ports/stm32f4/boards/STM32F405_default.ld107
-rw-r--r--ports/stm32f4/boards/STM32F405_fs.ld (renamed from ports/stm32f4/boards/STM32F405.ld)0
-rw-r--r--ports/stm32f4/boards/STM32F407_fs.ld108
-rw-r--r--ports/stm32f4/boards/espruino_pico/README.md15
-rw-r--r--ports/stm32f4/boards/espruino_pico/board.c39
-rw-r--r--ports/stm32f4/boards/espruino_pico/mpconfigboard.h39
-rw-r--r--ports/stm32f4/boards/espruino_pico/mpconfigboard.mk16
-rw-r--r--ports/stm32f4/boards/espruino_pico/pins.c33
-rw-r--r--ports/stm32f4/boards/espruino_pico/stm32f4xx_hal_conf.h440
-rw-r--r--ports/stm32f4/boards/espruino_wifi/README.MD15
-rw-r--r--ports/stm32f4/boards/espruino_wifi/board.c38
-rw-r--r--ports/stm32f4/boards/espruino_wifi/mpconfigboard.h36
-rw-r--r--ports/stm32f4/boards/espruino_wifi/mpconfigboard.mk16
-rw-r--r--ports/stm32f4/boards/espruino_wifi/pins.c39
-rw-r--r--ports/stm32f4/boards/espruino_wifi/stm32f4xx_hal_conf.h439
-rw-r--r--ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h7
-rw-r--r--ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.mk9
-rw-r--r--ports/stm32f4/boards/meowbit_v121/board.c121
-rw-r--r--ports/stm32f4/boards/meowbit_v121/mpconfigboard.h47
-rw-r--r--ports/stm32f4/boards/meowbit_v121/mpconfigboard.mk24
-rw-r--r--ports/stm32f4/boards/meowbit_v121/pins.c68
-rw-r--r--ports/stm32f4/boards/meowbit_v121/stm32f4xx_hal_conf.h440
-rw-r--r--ports/stm32f4/boards/openocd_stm32f4.cfg44
-rw-r--r--ports/stm32f4/boards/pyb_nano_v2/mpconfigboard.h6
-rw-r--r--ports/stm32f4/boards/pyb_nano_v2/mpconfigboard.mk3
-rw-r--r--ports/stm32f4/boards/pyboard_v11/mpconfigboard.h1
-rw-r--r--ports/stm32f4/boards/pyboard_v11/mpconfigboard.mk5
-rw-r--r--ports/stm32f4/boards/startup_stm32f401xe.s448
-rw-r--r--ports/stm32f4/boards/startup_stm32f407xx.s516
-rw-r--r--ports/stm32f4/boards/stm32f411ce_blackpill/mpconfigboard.h8
-rw-r--r--ports/stm32f4/boards/stm32f411ce_blackpill/mpconfigboard.mk3
-rw-r--r--ports/stm32f4/boards/stm32f411ce_blackpill/pins.c1
-rw-r--r--ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h2
-rw-r--r--ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.mk3
-rw-r--r--ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h2
-rw-r--r--ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk3
-rw-r--r--ports/stm32f4/boards/stm32f4_discovery/board.c38
-rw-r--r--ports/stm32f4/boards/stm32f4_discovery/mpconfigboard.h35
-rw-r--r--ports/stm32f4/boards/stm32f4_discovery/mpconfigboard.mk18
-rw-r--r--ports/stm32f4/boards/stm32f4_discovery/pins.c107
-rw-r--r--ports/stm32f4/boards/stm32f4_discovery/stm32f4xx_hal_conf.h439
-rw-r--r--ports/stm32f4/common-hal/busio/I2C.c202
-rw-r--r--ports/stm32f4/common-hal/busio/SPI.c308
-rw-r--r--ports/stm32f4/common-hal/busio/UART.c75
-rw-r--r--ports/stm32f4/common-hal/microcontroller/Pin.c1
-rw-r--r--ports/stm32f4/common-hal/microcontroller/Processor.c80
-rw-r--r--ports/stm32f4/common-hal/microcontroller/__init__.c2
-rw-r--r--ports/stm32f4/common-hal/pulseio/PWMOut.c203
-rw-r--r--ports/stm32f4/common-hal/time/__init__.c8
-rw-r--r--ports/stm32f4/mpconfigport.h11
-rw-r--r--ports/stm32f4/mpconfigport.mk4
-rw-r--r--ports/stm32f4/mphalport.c21
-rw-r--r--ports/stm32f4/mphalport.h28
-rw-r--r--ports/stm32f4/peripherals/stm32f4/periph.h12
-rw-r--r--ports/stm32f4/peripherals/stm32f4/pins.h11
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f401xe/clocks.c62
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f401xe/gpio.c51
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f401xe/periph.c173
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f401xe/periph.h57
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f401xe/pins.c123
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f401xe/pins.h121
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f405xx/clocks.c3
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f407xx/clocks.c64
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f407xx/gpio.c56
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f407xx/periph.c194
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f407xx/periph.h57
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f407xx/pins.c161
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f407xx/pins.h158
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c4
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f412zx/clocks.c3
-rw-r--r--ports/stm32f4/supervisor/internal_flash.h10
-rw-r--r--ports/stm32f4/supervisor/port.c9
-rw-r--r--ports/stm32f4/supervisor/usb.c4
-rw-r--r--ports/stm32f4/system_stm32f4xx.c35
282 files changed, 12932 insertions, 1304 deletions
diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c
index 0478cc9bf..352af8980 100644
--- a/ports/atmel-samd/audio_dma.c
+++ b/ports/atmel-samd/audio_dma.c
@@ -203,13 +203,13 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t* dma,
if (output_signed != samples_signed) {
output_spacing = 1;
max_buffer_length /= dma->spacing;
- dma->first_buffer = (uint8_t*) m_malloc(max_buffer_length, false);
+ dma->first_buffer = (uint8_t*) m_realloc(dma->first_buffer, max_buffer_length);
if (dma->first_buffer == NULL) {
return AUDIO_DMA_MEMORY_ERROR;
}
dma->first_buffer_free = true;
if (!single_buffer) {
- dma->second_buffer = (uint8_t*) m_malloc(max_buffer_length, false);
+ dma->second_buffer = (uint8_t*) m_realloc(dma->second_buffer, max_buffer_length);
if (dma->second_buffer == NULL) {
return AUDIO_DMA_MEMORY_ERROR;
}
diff --git a/ports/atmel-samd/boards/capablerobot_usbhub/board.c b/ports/atmel-samd/boards/capablerobot_usbhub/board.c
index 9a19e02d1..46385f094 100644
--- a/ports/atmel-samd/boards/capablerobot_usbhub/board.c
+++ b/ports/atmel-samd/boards/capablerobot_usbhub/board.c
@@ -30,13 +30,6 @@
#include "common-hal/microcontroller/Pin.h"
void board_init(void) {
- // Don't reset:
- // - USB Host Enable Pin
- // - reset pin of the USB Hub
- //
- // If either are reset, USB devices will disconnect when the MCU restarts
- never_reset_pin_number(PIN_PA07);
- never_reset_pin_number(PIN_PB08);
}
bool board_requests_safe_mode(void) {
diff --git a/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk b/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk
index 0ff6f58ea..62399b1cd 100644
--- a/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk
@@ -7,8 +7,8 @@ CHIP_VARIANT = SAMD51G19A
CHIP_FAMILY = samd51
QSPI_FLASH_FILESYSTEM = 1
-EXTERNAL_FLASH_DEVICE_COUNT = 1
-EXTERNAL_FLASH_DEVICES = GD25Q16C
+EXTERNAL_FLASH_DEVICE_COUNT = 2
+EXTERNAL_FLASH_DEVICES = "GD25Q16C, W25Q16JV_IQ"
LONGINT_IMPL = MPZ
# No I2S on SAMD51G
diff --git a/ports/atmel-samd/boards/capablerobot_usbhub/pins.c b/ports/atmel-samd/boards/capablerobot_usbhub/pins.c
index 1fde60940..b1966930c 100644
--- a/ports/atmel-samd/boards/capablerobot_usbhub/pins.c
+++ b/ports/atmel-samd/boards/capablerobot_usbhub/pins.c
@@ -17,8 +17,9 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA16) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA17) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_USBHEN), MP_ROM_PTR(&pin_PA07) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_USBRST), MP_ROM_PTR(&pin_PB08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_USBHOSTEN), MP_ROM_PTR(&pin_PA07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_USBRESET), MP_ROM_PTR(&pin_PB08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_USBBCEN), MP_ROM_PTR(&pin_PB22) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) },
diff --git a/ports/atmel-samd/boards/circuitbrains_basic_m0/board.c b/ports/atmel-samd/boards/circuitbrains_basic_m0/board.c
new file mode 100755
index 000000000..efafd152d
--- /dev/null
+++ b/ports/atmel-samd/boards/circuitbrains_basic_m0/board.c
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Original work copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Modified work copyright (c) 2019 Kevin Neubauer for Null Byte Labs LLC
+ *
+ * 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 "boards/board.h"
+#include "mpconfigboard.h"
+#include "hal/include/hal_gpio.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.h b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.h
new file mode 100755
index 000000000..592160b84
--- /dev/null
+++ b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.h
@@ -0,0 +1,35 @@
+#define MICROPY_HW_BOARD_NAME "CircuitBrains Basic"
+#define MICROPY_HW_MCU_NAME "samd21e18"
+
+#define CIRCUITPY_MCU_FAMILY samd21
+
+#define MICROPY_HW_LED_STATUS (&pin_PA14)
+
+// On-board flash
+#define SPI_FLASH_MOSI_PIN &pin_PA16
+#define SPI_FLASH_MISO_PIN &pin_PA18
+#define SPI_FLASH_SCK_PIN &pin_PA17
+#define SPI_FLASH_CS_PIN &pin_PA19
+
+// These are pins not to reset.
+#define MICROPY_PORT_A (0)
+#define MICROPY_PORT_B (0)
+#define MICROPY_PORT_C (0)
+
+#define SPI_FLASH_BAUDRATE (8000000)
+
+#define CALIBRATE_CRYSTALLESS 1
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA05)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA04)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PA11)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PA10)
+#define DEFAULT_SPI_BUS_MISO (&pin_PA09)
+
+#define DEFAULT_UART_BUS_RX (&pin_PA07)
+#define DEFAULT_UART_BUS_TX (&pin_PA06)
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1 \ No newline at end of file
diff --git a/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk
new file mode 100755
index 000000000..3587f1a33
--- /dev/null
+++ b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk
@@ -0,0 +1,16 @@
+USB_VID = 0x04D8
+USB_PID = 0xEC63
+USB_PRODUCT = "CircuitBrains Basic"
+USB_MANUFACTURER = "Kevin Neubauer"
+
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
+SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "W25Q32JV_IQ"
+LONGINT_IMPL = MPZ
+
+CIRCUITPY_BITBANGIO = 0
+CIRCUITPY_FREQUENCYIO = 0
+CIRCUITPY_I2CSLAVE = 0
diff --git a/ports/atmel-samd/boards/circuitbrains_basic_m0/pins.c b/ports/atmel-samd/boards/circuitbrains_basic_m0/pins.c
new file mode 100755
index 000000000..5acad5e98
--- /dev/null
+++ b/ports/atmel-samd/boards/circuitbrains_basic_m0/pins.c
@@ -0,0 +1,35 @@
+#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_global_dict_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA08) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA28) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA27) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA23) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA22) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_STATUS_LED),MP_ROM_PTR(&pin_PA14) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PA04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PA05) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA09) },
+
+ { 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_global_dict_table);
diff --git a/ports/atmel-samd/boards/circuitbrains_deluxe_m4/board.c b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/board.c
new file mode 100755
index 000000000..efafd152d
--- /dev/null
+++ b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/board.c
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Original work copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Modified work copyright (c) 2019 Kevin Neubauer for Null Byte Labs LLC
+ *
+ * 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 "boards/board.h"
+#include "mpconfigboard.h"
+#include "hal/include/hal_gpio.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.h b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.h
new file mode 100755
index 000000000..687e97a5a
--- /dev/null
+++ b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.h
@@ -0,0 +1,32 @@
+#define MICROPY_HW_BOARD_NAME "CircuitBrains Deluxe"
+#define MICROPY_HW_MCU_NAME "samd51j19"
+
+#define CIRCUITPY_MCU_FAMILY samd51
+
+#define MICROPY_HW_LED_STATUS (&pin_PB13)
+
+// These are pins not to reset.
+// QSPI Data pins
+#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11)
+// QSPI CS, QSPI SCK
+#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11)
+#define MICROPY_PORT_C (0)
+#define MICROPY_PORT_D (0)
+
+#define AUTORESET_DELAY_MS 500
+
+#define BOARD_HAS_CRYSTAL 1
+
+#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/circuitbrains_deluxe_m4/mpconfigboard.mk b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.mk
new file mode 100755
index 000000000..7a9e5a780
--- /dev/null
+++ b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.mk
@@ -0,0 +1,16 @@
+USB_VID = 0x04D8
+USB_PID = 0xEC64
+USB_PRODUCT = "CircuitBrains Deluxe"
+USB_MANUFACTURER = "Kevin Neubauer"
+
+CHIP_VARIANT = SAMD51J19A
+CHIP_FAMILY = samd51
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 2
+EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, S25FL064L"
+LONGINT_IMPL = MPZ
+
+CIRCUITPY_NETWORK = 1
+MICROPY_PY_WIZNET5K = 5500
+CIRCUITPY_PS2IO = 1
diff --git a/ports/atmel-samd/boards/circuitbrains_deluxe_m4/pins.c b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/pins.c
new file mode 100755
index 000000000..45fcd0464
--- /dev/null
+++ b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/pins.c
@@ -0,0 +1,55 @@
+#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_global_dict_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB09) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PA04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PA06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_PB00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_PB01) },
+
+ { 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_PA21) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA20) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB17) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB16) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA19) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA18) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA17) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA16) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PB15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PB14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB13) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_STATUS_LED),MP_ROM_PTR(&pin_PB13) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PB31) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PA27) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PB23) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_PB22) },
+
+ { 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_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_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_global_dict_table);
diff --git a/ports/atmel-samd/boards/circuitplayground_express/board.c b/ports/atmel-samd/boards/circuitplayground_express/board.c
index 578963642..85c37ee62 100644
--- a/ports/atmel-samd/boards/circuitplayground_express/board.c
+++ b/ports/atmel-samd/boards/circuitplayground_express/board.c
@@ -28,9 +28,8 @@
#include "boards/board.h"
#include "common-hal/microcontroller/Pin.h"
+#include "supervisor/shared/board.h"
#include "hal/include/hal_gpio.h"
-#include "shared-bindings/digitalio/DigitalInOut.h"
-#include "shared-bindings/neopixel_write/__init__.h"
void board_init(void)
{
@@ -54,12 +53,5 @@ bool board_requests_safe_mode(void) {
}
void reset_board(void) {
- uint8_t empty[30];
- memset(empty, 0, 30);
- digitalio_digitalinout_obj_t neopixel_pin;
- common_hal_digitalio_digitalinout_construct(&neopixel_pin, &pin_PB23);
- common_hal_digitalio_digitalinout_switch_to_output(&neopixel_pin, false,
- DRIVE_MODE_PUSH_PULL);
- common_hal_neopixel_write(&neopixel_pin, empty, 30);
- common_hal_digitalio_digitalinout_deinit(&neopixel_pin);
+ board_reset_user_neopixels();
}
diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h
index 6eb49b02c..0c5e5b762 100644
--- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h
@@ -28,7 +28,9 @@
#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up"
// Increase stack size slightly due to CPX library import nesting
-#define CIRCUITPY_DEFAULT_STACK_SIZE (4504)
+#define CIRCUITPY_DEFAULT_STACK_SIZE (4760) //divisible by 8
+
+#define USER_NEOPIXELS_PIN (&pin_PB23)
#define DEFAULT_I2C_BUS_SCL (&pin_PB03)
#define DEFAULT_I2C_BUS_SDA (&pin_PB02)
diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c b/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c
index 578963642..21217caac 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c
+++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c
@@ -29,8 +29,7 @@
#include "boards/board.h"
#include "common-hal/microcontroller/Pin.h"
#include "hal/include/hal_gpio.h"
-#include "shared-bindings/digitalio/DigitalInOut.h"
-#include "shared-bindings/neopixel_write/__init__.h"
+#include "supervisor/shared/board.h"
void board_init(void)
{
@@ -54,12 +53,5 @@ bool board_requests_safe_mode(void) {
}
void reset_board(void) {
- uint8_t empty[30];
- memset(empty, 0, 30);
- digitalio_digitalinout_obj_t neopixel_pin;
- common_hal_digitalio_digitalinout_construct(&neopixel_pin, &pin_PB23);
- common_hal_digitalio_digitalinout_switch_to_output(&neopixel_pin, false,
- DRIVE_MODE_PUSH_PULL);
- common_hal_neopixel_write(&neopixel_pin, empty, 30);
- common_hal_digitalio_digitalinout_deinit(&neopixel_pin);
+ board_reset_user_neopixels();
}
diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h
index e64997c0e..312fd2626 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h
+++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h
@@ -24,11 +24,13 @@
#define CALIBRATE_CRYSTALLESS 1
+#define USER_NEOPIXELS_PIN (&pin_PB23)
+
// Explanation of how a user got into safe mode.
#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up"
// Increase stack size slightly due to CPX library import nesting
-#define CIRCUITPY_DEFAULT_STACK_SIZE (4504)
+#define CIRCUITPY_DEFAULT_STACK_SIZE (4760) // divisible by 8
#define DEFAULT_I2C_BUS_SCL (&pin_PB03)
#define DEFAULT_I2C_BUS_SDA (&pin_PB02)
diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
index 04b4b7792..1516c149b 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
@@ -14,9 +14,9 @@ EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
LONGINT_IMPL = NONE
CIRCUITPY_DISPLAYIO = 0
CIRCUITPY_FREQUENCYIO = 0
-CIRCUITPY_GAMEPAD = 0
CIRCUITPY_I2CSLAVE = 0
CIRCUITPY_PIXELBUF = 0
+CIRCUITPY_RTC = 0
SUPEROPT_GC = 0
CFLAGS_INLINE_LIMIT = 55
diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/board.c b/ports/atmel-samd/boards/circuitplayground_express_displayio/board.c
index 578963642..21217caac 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_displayio/board.c
+++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/board.c
@@ -29,8 +29,7 @@
#include "boards/board.h"
#include "common-hal/microcontroller/Pin.h"
#include "hal/include/hal_gpio.h"
-#include "shared-bindings/digitalio/DigitalInOut.h"
-#include "shared-bindings/neopixel_write/__init__.h"
+#include "supervisor/shared/board.h"
void board_init(void)
{
@@ -54,12 +53,5 @@ bool board_requests_safe_mode(void) {
}
void reset_board(void) {
- uint8_t empty[30];
- memset(empty, 0, 30);
- digitalio_digitalinout_obj_t neopixel_pin;
- common_hal_digitalio_digitalinout_construct(&neopixel_pin, &pin_PB23);
- common_hal_digitalio_digitalinout_switch_to_output(&neopixel_pin, false,
- DRIVE_MODE_PUSH_PULL);
- common_hal_neopixel_write(&neopixel_pin, empty, 30);
- common_hal_digitalio_digitalinout_deinit(&neopixel_pin);
+ board_reset_user_neopixels();
}
diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h
index c9a7ce040..4796e90a5 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h
+++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h
@@ -28,7 +28,9 @@
#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up"
// Increase stack size slightly due to CPX library import nesting.
-#define CIRCUITPY_DEFAULT_STACK_SIZE (4504) // divisible by 8
+#define CIRCUITPY_DEFAULT_STACK_SIZE (4760) // divisible by 8
+
+#define USER_NEOPIXELS_PIN (&pin_PB23)
#define DEFAULT_I2C_BUS_SCL (&pin_PB03)
#define DEFAULT_I2C_BUS_SDA (&pin_PB02)
diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk
index b5a7c2424..d65dc993f 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk
@@ -16,7 +16,6 @@ CIRCUITPY_BITBANGIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CSLAVE = 0
CIRCUITPY_PIXELBUF = 0
-CIRCUITPY_GAMEPAD = 0
CIRCUITPY_RTC = 0
SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/feather_m4_express/pins.c b/ports/atmel-samd/boards/feather_m4_express/pins.c
index d9496ecfc..61bd8abad 100644
--- a/ports/atmel-samd/boards/feather_m4_express/pins.c
+++ b/ports/atmel-samd/boards/feather_m4_express/pins.c
@@ -2,18 +2,38 @@
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PA02) },
+
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PA05) },
+
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PB08) },
+
{ MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PB09) },
+
{ MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_PA04) },
+
{ MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_PA06) },
+
{ MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_PA17) },
+
{ MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) },
+ { MP_ROM_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_PB23) },
+
{ MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) },
+ { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_PB22) },
+
{ MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB17) },
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17) },
+
{ MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB16) },
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16) },
+
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) },
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) },
{ MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14) },
@@ -24,9 +44,12 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21) },
{ MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22) },
{ MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) },
+
{ MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB03) },
+
{ MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PB01) },
{ MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB01) },
+
{ 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) },
diff --git a/ports/atmel-samd/boards/hallowing_m4_express/board.c b/ports/atmel-samd/boards/hallowing_m4_express/board.c
index 6bb2a591f..5d1ef6d9b 100644
--- a/ports/atmel-samd/boards/hallowing_m4_express/board.c
+++ b/ports/atmel-samd/boards/hallowing_m4_express/board.c
@@ -49,7 +49,7 @@ uint8_t display_init_sequence[] = {
void board_init(void) {
busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
- common_hal_busio_spi_construct(spi, &pin_PA01, &pin_PA00, NULL);
+ common_hal_busio_spi_construct(spi, &pin_PA01, &pin_PA00, mp_const_none);
common_hal_busio_spi_never_reset(spi);
displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk
index 62e6b7c72..c2603002c 100644
--- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk
@@ -10,3 +10,5 @@ QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 3
EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C"
LONGINT_IMPL = MPZ
+
+CIRCUITPY__EVE = 1
diff --git a/ports/atmel-samd/boards/monster_m4sk/board.c b/ports/atmel-samd/boards/monster_m4sk/board.c
index 2377f4a9d..40141ca15 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) {
busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
- common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA12, NULL);
+ common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA12, mp_const_none);
common_hal_busio_spi_never_reset(spi);
displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
diff --git a/ports/atmel-samd/boards/ndgarage_ndbit6/board.c b/ports/atmel-samd/boards/ndgarage_ndbit6/board.c
new file mode 100644
index 000000000..0f60736a2
--- /dev/null
+++ b/ports/atmel-samd/boards/ndgarage_ndbit6/board.c
@@ -0,0 +1,39 @@
+/*
+ * 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 "boards/board.h"
+#include "mpconfigboard.h"
+#include "hal/include/hal_gpio.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/ndgarage_ndbit6/mpconfigboard.h b/ports/atmel-samd/boards/ndgarage_ndbit6/mpconfigboard.h
new file mode 100644
index 000000000..869f207a1
--- /dev/null
+++ b/ports/atmel-samd/boards/ndgarage_ndbit6/mpconfigboard.h
@@ -0,0 +1,32 @@
+#define MICROPY_HW_BOARD_NAME "ndGarage[n°]Bit6:FeatherSnow"
+#define MICROPY_HW_MCU_NAME "samd21e18"
+
+#define MICROPY_HW_LED_STATUS (&pin_PA23)
+
+#define SPI_FLASH_MOSI_PIN &pin_PA16
+#define SPI_FLASH_MISO_PIN &pin_PA18
+#define SPI_FLASH_SCK_PIN &pin_PA17
+#define SPI_FLASH_CS_PIN &pin_PA15
+
+#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25)
+#define MICROPY_PORT_B (0)
+#define MICROPY_PORT_C (0)
+
+#define CIRCUITPY_INTERNAL_NVM_SIZE 256
+
+#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA09)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA08)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PA05)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PA04)
+#define DEFAULT_SPI_BUS_MISO (&pin_PA06)
+
+#define DEFAULT_UART_BUS_RX (&pin_PA09)
+#define DEFAULT_UART_BUS_TX (&pin_PA08)
+
+// USB is always used.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
+
diff --git a/ports/atmel-samd/boards/ndgarage_ndbit6/mpconfigboard.mk b/ports/atmel-samd/boards/ndgarage_ndbit6/mpconfigboard.mk
new file mode 100644
index 000000000..b73f0951e
--- /dev/null
+++ b/ports/atmel-samd/boards/ndgarage_ndbit6/mpconfigboard.mk
@@ -0,0 +1,15 @@
+LD_FILE = boards/samd21x18-bootloader.ld
+USB_VID = 0x239A
+USB_PID = 0x8066
+USB_PRODUCT = "Bit6"
+USB_MANUFACTURER = "ndGarage"
+
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = NONE
+CIRCUITPY_SMALL_BUILD = 1
+
+SUPEROPT_GC = 0
+
diff --git a/ports/atmel-samd/boards/ndgarage_ndbit6/pins.c b/ports/atmel-samd/boards/ndgarage_ndbit6/pins.c
new file mode 100644
index 000000000..6d1fc53b6
--- /dev/null
+++ b/ports/atmel-samd/boards/ndgarage_ndbit6/pins.c
@@ -0,0 +1,39 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA28) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA15) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PA14) },
+ { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PA27) },
+ { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_PA02) },
+
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA05) },
+
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA09) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) },
+
+ { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_PA23) },
+
+ { 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_global_dict_table);
diff --git a/ports/atmel-samd/boards/openbook_m4/board.c b/ports/atmel-samd/boards/openbook_m4/board.c
new file mode 100644
index 000000000..85a588879
--- /dev/null
+++ b/ports/atmel-samd/boards/openbook_m4/board.c
@@ -0,0 +1,107 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Joey Castillo
+ *
+ * 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 "boards/board.h"
+#include "mpconfigboard.h"
+#include "hal/include/hal_gpio.h"
+#include "shared-bindings/busio/SPI.h"
+#include "shared-bindings/displayio/FourWire.h"
+#include "shared-bindings/time/__init__.h"
+#include "shared-module/displayio/__init__.h"
+#include "shared-module/displayio/mipi_constants.h"
+#include "tick.h"
+
+displayio_fourwire_obj_t board_display_obj;
+
+#define DELAY 0x80
+#define HEIGHT 400
+#define WIDTH 300
+
+uint8_t start_sequence[] = {
+ 0x01, 0x04, 0x03, 0x00, 0x2b, 0x2b, // power setting
+ 0x06, 0x03, 0x17, 0x17, 0x17, // booster soft start
+ 0x04, 0x80, 0xc8, // power on and wait 200 ms
+ 0x00, 0x01, 0x0f, // panel setting
+ 0x61, 0x04, (HEIGHT >> 8) & 0xFF, HEIGHT & 0xFF, (WIDTH >> 8) & 0xFF, WIDTH & 0xFF // Resolution
+};
+
+uint8_t stop_sequence[] = {
+ 0x50, 0x01, 0xf7, // CDI setting
+ 0x02, 0x80, 0xf0 // Power off
+};
+
+void board_init(void) {
+ busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
+ common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, mp_const_none);
+ common_hal_busio_spi_never_reset(spi);
+
+ displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
+ bus->base.type = &displayio_fourwire_type;
+ common_hal_displayio_fourwire_construct(bus,
+ spi,
+ &pin_PB05, // EPD_DC Command or data
+ &pin_PB07, // EPD_CS Chip select
+ &pin_PA00, // EPD_RST Reset
+ 1000000);
+
+ displayio_epaperdisplay_obj_t* display = &displays[0].epaper_display;
+ display->base.type = &displayio_epaperdisplay_type;
+ common_hal_displayio_epaperdisplay_construct(display,
+ bus,
+ start_sequence,
+ sizeof(start_sequence),
+ stop_sequence,
+ sizeof(stop_sequence),
+ 400, // width
+ 300, // height
+ 400, // RAM width
+ 300, // RAM height
+ 0, // colstart
+ 0, // rowstart
+ 0, // rotation
+ NO_COMMAND, // set_column_window_command
+ NO_COMMAND, // set_row_window_command
+ NO_COMMAND, // set_current_column_command
+ NO_COMMAND, // set_current_row_command
+ 0x13, // write_black_ram_command
+ false, // black_bits_inverted
+ NO_COMMAND, // write_color_ram_command (can add this for grayscale eventually)
+ false, // color_bits_inverted
+ 0x000000, // highlight_color
+ 0x12, // refresh_display_command
+ 40, // refresh_time
+ &pin_PA01, // busy_pin
+ false, // busy_state
+ 5, // seconds_per_frame
+ false); // chip_select (don't always toggle chip select)
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/openbook_m4/mpconfigboard.h b/ports/atmel-samd/boards/openbook_m4/mpconfigboard.h
new file mode 100644
index 000000000..6d75c086e
--- /dev/null
+++ b/ports/atmel-samd/boards/openbook_m4/mpconfigboard.h
@@ -0,0 +1,28 @@
+#define MICROPY_HW_BOARD_NAME "The Open Book Feather"
+#define MICROPY_HW_MCU_NAME "samd51j19"
+
+#define CIRCUITPY_MCU_FAMILY samd51
+
+#define MICROPY_HW_LED_STATUS (&pin_PA23)
+
+// These are pins not to reset.
+// QSPI Data pins
+#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11)
+// DotStar pins, QSPI CS, and QSPI SCK
+#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11)
+#define MICROPY_PORT_C (0)
+#define MICROPY_PORT_D (0)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA13)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA12)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PA17)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PB23)
+#define DEFAULT_SPI_BUS_MISO (&pin_PB22)
+
+#define DEFAULT_UART_BUS_RX (&pin_PB17)
+#define DEFAULT_UART_BUS_TX (&pin_PB16)
+
+// 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/openbook_m4/mpconfigboard.mk b/ports/atmel-samd/boards/openbook_m4/mpconfigboard.mk
new file mode 100644
index 000000000..e5fa0cd84
--- /dev/null
+++ b/ports/atmel-samd/boards/openbook_m4/mpconfigboard.mk
@@ -0,0 +1,14 @@
+USB_VID = 0x239A
+USB_PID = 0x807E
+USB_PRODUCT = "The Open Book Feather"
+USB_MANUFACTURER = "Oddly Specific Objects"
+
+CHIP_VARIANT = SAMD51J19A
+CHIP_FAMILY = samd51
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = GD25Q16C
+LONGINT_IMPL = MPZ
+
+CIRCUITPY_GAMEPADSHIFT = 1
diff --git a/ports/atmel-samd/boards/openbook_m4/pins.c b/ports/atmel-samd/boards/openbook_m4/pins.c
new file mode 100644
index 000000000..3fbb67860
--- /dev/null
+++ b/ports/atmel-samd/boards/openbook_m4/pins.c
@@ -0,0 +1,71 @@
+#include "shared-bindings/board/__init__.h"
+
+#include "boards/board.h"
+#include "shared-module/displayio/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, // A0 = audio right channel
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, // A1 = audio left channel
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB01) }, // A6 = VBAT Monitor
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB04) }, // A7 = Raw mic input
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB03) }, // A8 = Bottom STEMMA Port
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PB02) }, // A9 = Top STEMMA Port
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA07) }, // A10 = Amplified mic input
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_PB00) }, // A11 = VBUS Monitor
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB17) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB16) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA16) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA18) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA19) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA20) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D48), MP_ROM_PTR(&pin_PB31) },
+
+ // UART
+ { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16) },
+
+ // I2C
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) },
+
+ // SPI
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) },
+
+ // e-paper SPI and control pins
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCK1), MP_ROM_PTR(&pin_PB13) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI1), MP_ROM_PTR(&pin_PB15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ECS), MP_ROM_PTR(&pin_PB07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_EDC), MP_ROM_PTR(&pin_PB05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ERST), MP_ROM_PTR(&pin_PA00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_EBSY), MP_ROM_PTR(&pin_PA01) },
+
+ // Special named pins
+ { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_LOCK_BUTTON), MP_ROM_PTR(&pin_PA27) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_LATCH), MP_ROM_PTR(&pin_PB12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_OUT), MP_ROM_PTR(&pin_PB30) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_CLOCK), MP_ROM_PTR(&pin_PB14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SDCS), MP_ROM_PTR(&pin_PA14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MIC_SHUTDOWN), MP_ROM_PTR(&pin_PB31) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_BCS), MP_ROM_PTR(&pin_PB06) }, // BCS = Babel Chip Select, the second flash chip
+
+ { 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_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].epaper_display)}
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/pewpew_m4/board.c b/ports/atmel-samd/boards/pewpew_m4/board.c
index 5f5a01e48..1872d1876 100644
--- a/ports/atmel-samd/boards/pewpew_m4/board.c
+++ b/ports/atmel-samd/boards/pewpew_m4/board.c
@@ -97,7 +97,7 @@ uint8_t display_init_sequence[] = {
void board_init(void) {
busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
- common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA15, NULL);
+ common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA15, mp_const_none);
common_hal_busio_spi_never_reset(spi);
displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
diff --git a/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk
index 1d1891e8e..51b4fc993 100644
--- a/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk
@@ -10,6 +10,9 @@ INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
+# TODO: Turn off analogio for now for space reasons, but restore it
+# when frozen module gets smaller.
+CIRCUITPY_ANALOGIO = 0
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_FREQUENCYIO = 0
diff --git a/ports/atmel-samd/boards/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c
index 37f7991d1..28e1aec13 100644
--- a/ports/atmel-samd/boards/pybadge/board.c
+++ b/ports/atmel-samd/boards/pybadge/board.c
@@ -31,6 +31,7 @@
#include "shared-bindings/displayio/FourWire.h"
#include "shared-module/displayio/__init__.h"
#include "shared-module/displayio/mipi_constants.h"
+#include "supervisor/shared/board.h"
#include "tick.h"
displayio_fourwire_obj_t board_display_obj;
@@ -51,7 +52,7 @@ uint8_t display_init_sequence[] = {
0xc4, 2, 0x8a, 0xee,
0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V
0x2a, 0, // _INVOFF
- 0x36, 1, 0x00, // _MADCTL top to bottom refresh in vsync aligned order.
+ 0x36, 1, 0b10100000, // _MADCTL for rotation 0
// 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie,
// fix on VTL
0x3a, 1, 0x05, // COLMOD - 16bit color
@@ -71,7 +72,7 @@ uint8_t display_init_sequence[] = {
void board_init(void) {
busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
- common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL);
+ common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, mp_const_none);
common_hal_busio_spi_never_reset(spi);
displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
@@ -91,7 +92,7 @@ void board_init(void) {
128, // Height (after rotation)
0, // column start
0, // row start
- 270, // rotation
+ 0, // rotation
16, // Color depth
false, // grayscale
false, // pixels in byte share row. only used for depth < 8
@@ -118,4 +119,5 @@ bool board_requests_safe_mode(void) {
}
void reset_board(void) {
+ board_reset_user_neopixels();
}
diff --git a/ports/atmel-samd/boards/pybadge/mpconfigboard.h b/ports/atmel-samd/boards/pybadge/mpconfigboard.h
index 435185322..74a13eb1c 100644
--- a/ports/atmel-samd/boards/pybadge/mpconfigboard.h
+++ b/ports/atmel-samd/boards/pybadge/mpconfigboard.h
@@ -14,6 +14,8 @@
#define MICROPY_PORT_C (0)
#define MICROPY_PORT_D (0)
+#define USER_NEOPIXELS_PIN (&pin_PA15)
+
#define DEFAULT_I2C_BUS_SCL (&pin_PA13)
#define DEFAULT_I2C_BUS_SDA (&pin_PA12)
diff --git a/ports/atmel-samd/boards/pybadge_airlift/board.c b/ports/atmel-samd/boards/pybadge_airlift/board.c
index 7622de6f0..fbb4441f0 100644
--- a/ports/atmel-samd/boards/pybadge_airlift/board.c
+++ b/ports/atmel-samd/boards/pybadge_airlift/board.c
@@ -31,6 +31,7 @@
#include "shared-bindings/displayio/FourWire.h"
#include "shared-module/displayio/__init__.h"
#include "shared-module/displayio/mipi_constants.h"
+#include "supervisor/shared/board.h"
#include "tick.h"
displayio_fourwire_obj_t board_display_obj;
@@ -49,7 +50,7 @@ uint8_t display_init_sequence[] = {
void board_init(void) {
busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
- common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL);
+ common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, mp_const_none);
common_hal_busio_spi_never_reset(spi);
displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
@@ -96,4 +97,5 @@ bool board_requests_safe_mode(void) {
}
void reset_board(void) {
+ board_reset_user_neopixels();
}
diff --git a/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.h b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.h
index 229cfa335..c6ab4ed8e 100644
--- a/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.h
+++ b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.h
@@ -14,6 +14,8 @@
#define MICROPY_PORT_C (0)
#define MICROPY_PORT_D (0)
+#define USER_NEOPIXELS_PIN (&pin_PA15)
+
#define DEFAULT_I2C_BUS_SCL (&pin_PA13)
#define DEFAULT_I2C_BUS_SDA (&pin_PA12)
diff --git a/ports/atmel-samd/boards/pycubed/board.c b/ports/atmel-samd/boards/pycubed/board.c
new file mode 100644
index 000000000..31b081209
--- /dev/null
+++ b/ports/atmel-samd/boards/pycubed/board.c
@@ -0,0 +1,61 @@
+/*
+ * 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 <string.h>
+
+#include "boards/board.h"
+#include "py/mpconfig.h"
+#include "shared-bindings/nvm/ByteArray.h"
+#include "common-hal/microcontroller/Pin.h"
+#include "hal/include/hal_gpio.h"
+#include "shared-bindings/pulseio/PWMOut.h"
+
+nvm_bytearray_obj_t bootcnt = {
+ .base = {
+ .type = &nvm_bytearray_type
+ },
+ .len = ( uint32_t) 8192,
+ .start_address = (uint8_t*) (0x00080000 - 8192)
+ };
+
+
+void board_init(void) {
+ pulseio_pwmout_obj_t pwm;
+ common_hal_pulseio_pwmout_construct(&pwm, &pin_PA23, 4096, 2, false);
+ common_hal_pulseio_pwmout_never_reset(&pwm);
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+ uint8_t value_out = 0;
+ common_hal_nvm_bytearray_get_bytes(&bootcnt,0,1,&value_out);
+ ++value_out;
+ common_hal_nvm_bytearray_set_bytes(&bootcnt,0,&value_out,1);
+} \ No newline at end of file
diff --git a/ports/atmel-samd/boards/pycubed/mpconfigboard.h b/ports/atmel-samd/boards/pycubed/mpconfigboard.h
new file mode 100644
index 000000000..49a98e8d4
--- /dev/null
+++ b/ports/atmel-samd/boards/pycubed/mpconfigboard.h
@@ -0,0 +1,34 @@
+
+#define MICROPY_HW_BOARD_NAME "PyCubedv04"
+#define MICROPY_HW_MCU_NAME "samd51j19"
+#define CIRCUITPY_MCU_FAMILY samd51
+
+#define MICROPY_HW_NEOPIXEL (&pin_PA21)
+
+#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11)
+#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11)
+#define MICROPY_PORT_C (0)
+#define MICROPY_PORT_D (0)
+
+#define AUTORESET_DELAY_MS 500
+
+#define CIRCUITPY_INTERNAL_NVM_SIZE 8192
+
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define EXTERNAL_FLASH_QSPI_DUAL
+
+#define BOARD_HAS_CRYSTAL 1
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PB13)
+#define DEFAULT_I2C_BUS_SDA (&pin_PB12)
+
+#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_TX (&pin_PB02)
+#define DEFAULT_UART_BUS_RX (&pin_PB03)
+
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
diff --git a/ports/atmel-samd/boards/pycubed/mpconfigboard.mk b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk
new file mode 100644
index 000000000..adbb4aedb
--- /dev/null
+++ b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk
@@ -0,0 +1,24 @@
+LD_FILE = boards/samd51x19-bootloader-external-flash.ld
+USB_VID = 0x04D8
+USB_PID = 0xEC44
+USB_PRODUCT = "PyCubed"
+USB_MANUFACTURER = "maholli"
+
+CHIP_VARIANT = SAMD51J19A
+CHIP_FAMILY = samd51
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = W25Q80DV
+LONGINT_IMPL = MPZ
+
+# Not needed.
+CIRCUITPY_AUDIOBUSIO = 0
+CIRCUITPY_DISPLAYIO = 0
+CIRCUITPY_GAMEPAD = 0
+CIRCUITPY_PS2IO = 0
+
+FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
+FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
+FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register
+FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD \ No newline at end of file
diff --git a/ports/atmel-samd/boards/pycubed/pins.c b/ports/atmel-samd/boards/pycubed/pins.c
new file mode 100644
index 000000000..4c97f58a8
--- /dev/null
+++ b/ports/atmel-samd/boards/pycubed/pins.c
@@ -0,0 +1,55 @@
+#include "shared-bindings/board/__init__.h"
+#include "boards/board.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA13) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA14) },
+ { MP_ROM_QSTR(MP_QSTR_xSDCS), MP_ROM_PTR(&pin_PA27) },
+
+ { MP_ROM_QSTR(MP_QSTR_RELAY_A), MP_ROM_PTR(&pin_PB15) },
+ { MP_ROM_QSTR(MP_QSTR_BURN1), MP_ROM_PTR(&pin_PB31) },
+ { MP_ROM_QSTR(MP_QSTR_BURN2), MP_ROM_PTR(&pin_PA15) },
+
+ { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_L1PROG), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_AIN4), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_AIN5), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_CHRG), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_DAC0), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_PA17), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_PA18), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_PA19), MP_ROM_PTR(&pin_PA19) },
+ { MP_ROM_QSTR(MP_QSTR_PA20), MP_ROM_PTR(&pin_PA20) },
+ { MP_ROM_QSTR(MP_QSTR_PA22), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_PB16), MP_ROM_PTR(&pin_PB16) },
+ { MP_ROM_QSTR(MP_QSTR_PB17), MP_ROM_PTR(&pin_PB17) },
+ { MP_ROM_QSTR(MP_QSTR_PB22), MP_ROM_PTR(&pin_PB22) },
+ { MP_ROM_QSTR(MP_QSTR_PB23), MP_ROM_PTR(&pin_PB23) },
+
+ { MP_ROM_QSTR(MP_QSTR_RF1_RST), MP_ROM_PTR(&pin_PB00) },
+ { MP_ROM_QSTR(MP_QSTR_RF1_CS), MP_ROM_PTR(&pin_PB30) },
+ { MP_ROM_QSTR(MP_QSTR_RF1_IO0), MP_ROM_PTR(&pin_PB05) },
+ { MP_ROM_QSTR(MP_QSTR_RF1_IO4), MP_ROM_PTR(&pin_PB04) },
+
+ { MP_ROM_QSTR(MP_QSTR_RF2_RST), MP_ROM_PTR(&pin_PB14) },
+ { MP_ROM_QSTR(MP_QSTR_RF2_CS), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_RF2_IO1), MP_ROM_PTR(&pin_PB06) },
+ { MP_ROM_QSTR(MP_QSTR_RF2_BSY), MP_ROM_PTR(&pin_PB07) },
+
+ { MP_ROM_QSTR(MP_QSTR_EN_GPS), MP_ROM_PTR(&pin_PB01) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB03) },
+
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB12) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB13) },
+
+ { MP_ROM_QSTR(MP_QSTR_WDT_WDI), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA21) },
+
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+ { 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_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); \ No newline at end of file
diff --git a/ports/atmel-samd/boards/pygamer/board.c b/ports/atmel-samd/boards/pygamer/board.c
index b33ae4fb0..c052614db 100644
--- a/ports/atmel-samd/boards/pygamer/board.c
+++ b/ports/atmel-samd/boards/pygamer/board.c
@@ -31,6 +31,7 @@
#include "shared-bindings/displayio/FourWire.h"
#include "shared-module/displayio/__init__.h"
#include "shared-module/displayio/mipi_constants.h"
+#include "supervisor/shared/board.h"
#include "tick.h"
displayio_fourwire_obj_t board_display_obj;
@@ -51,7 +52,7 @@ uint8_t display_init_sequence[] = {
0xc4, 2, 0x8a, 0xee,
0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V
0x2a, 0, // _INVOFF
- 0x36, 1, 0x00, // _MADCTL top to bottom refresh in vsync aligned order.
+ 0x36, 1, 0b10100000, // _MADCTL for rotation 0
// 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie,
// fix on VTL
0x3a, 1, 0x05, // COLMOD - 16bit color
@@ -71,7 +72,7 @@ uint8_t display_init_sequence[] = {
void board_init(void) {
busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
- common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL);
+ common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, mp_const_none);
common_hal_busio_spi_never_reset(spi);
displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
@@ -91,7 +92,7 @@ void board_init(void) {
128, // Height
0, // column start
0, // row start
- 270, // rotation
+ 0, // rotation
16, // Color depth
false, // Grayscale
false, // pixels in a byte share a row. Only valid for depths < 8
@@ -118,4 +119,5 @@ bool board_requests_safe_mode(void) {
}
void reset_board(void) {
+ board_reset_user_neopixels();
}
diff --git a/ports/atmel-samd/boards/pygamer/mpconfigboard.h b/ports/atmel-samd/boards/pygamer/mpconfigboard.h
index 102c25956..21f75d272 100644
--- a/ports/atmel-samd/boards/pygamer/mpconfigboard.h
+++ b/ports/atmel-samd/boards/pygamer/mpconfigboard.h
@@ -13,6 +13,8 @@
#define MICROPY_PORT_C (0)
#define MICROPY_PORT_D (0)
+#define USER_NEOPIXELS_PIN (&pin_PA15)
+
#define DEFAULT_I2C_BUS_SCL (&pin_PA13)
#define DEFAULT_I2C_BUS_SDA (&pin_PA12)
diff --git a/ports/atmel-samd/boards/pygamer_advance/board.c b/ports/atmel-samd/boards/pygamer_advance/board.c
index 8eb501243..a138c7e50 100644
--- a/ports/atmel-samd/boards/pygamer_advance/board.c
+++ b/ports/atmel-samd/boards/pygamer_advance/board.c
@@ -31,6 +31,7 @@
#include "shared-bindings/displayio/FourWire.h"
#include "shared-module/displayio/__init__.h"
#include "shared-module/displayio/mipi_constants.h"
+#include "supervisor/shared/board.h"
#include "tick.h"
displayio_fourwire_obj_t board_display_obj;
@@ -49,7 +50,7 @@ uint8_t display_init_sequence[] = {
void board_init(void) {
busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
- common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB12, NULL);
+ common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB12, mp_const_none);
common_hal_busio_spi_never_reset(spi);
displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
@@ -96,4 +97,5 @@ bool board_requests_safe_mode(void) {
}
void reset_board(void) {
+ board_reset_user_neopixels();
}
diff --git a/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.h b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.h
index fbe946b72..7c631d1c3 100644
--- a/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.h
+++ b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.h
@@ -13,6 +13,8 @@
#define MICROPY_PORT_C (0)
#define MICROPY_PORT_D (0)
+#define USER_NEOPIXELS_PIN (&pin_PA15)
+
#define DEFAULT_I2C_BUS_SCL (&pin_PA13)
#define DEFAULT_I2C_BUS_SDA (&pin_PA12)
diff --git a/ports/atmel-samd/boards/sam32/mpconfigboard.h b/ports/atmel-samd/boards/sam32/mpconfigboard.h
index bd9f5e398..364d380d1 100644
--- a/ports/atmel-samd/boards/sam32/mpconfigboard.h
+++ b/ports/atmel-samd/boards/sam32/mpconfigboard.h
@@ -1,23 +1,22 @@
-
-#define MICROPY_HW_BOARD_NAME "SAM32v2a"
+#define MICROPY_HW_BOARD_NAME "SAM32v26"
#define MICROPY_HW_MCU_NAME "samd51j20"
#define CIRCUITPY_MCU_FAMILY samd51
#define MICROPY_HW_LED_STATUS (&pin_PA27)
-#define MICROPY_HW_NEOPIXEL (&pin_PA15)
+#define MICROPY_HW_NEOPIXEL (&pin_PA15)
#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25)
#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
-#define MICROPY_PORT_D (0)
+#define MICROPY_PORT_D (0)
-// No microcontroller.nvm
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
+#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE (128*1024)
#define BOARD_HAS_CRYSTAL 1
-#define DEFAULT_I2C_BUS_SCL (&pin_PA04)
-#define DEFAULT_I2C_BUS_SDA (&pin_PA07)
+#define DEFAULT_I2C_BUS_SCL (&pin_PA09)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA08)
#define DEFAULT_SPI_BUS_SCK (&pin_PB13)
#define DEFAULT_SPI_BUS_MOSI (&pin_PB12)
diff --git a/ports/atmel-samd/boards/sam32/mpconfigboard.mk b/ports/atmel-samd/boards/sam32/mpconfigboard.mk
index 0d6be6437..118744935 100644
--- a/ports/atmel-samd/boards/sam32/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/sam32/mpconfigboard.mk
@@ -8,3 +8,10 @@ CHIP_FAMILY = samd51
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = MPZ
+
+# No I2S on SAMD51
+CIRCUITPY_AUDIOBUSIO = 0
+CIRCUITPY_USTACK = 1
+
+FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
+FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel \ No newline at end of file
diff --git a/ports/atmel-samd/boards/sam32/pins.c b/ports/atmel-samd/boards/sam32/pins.c
index f32057d75..f0a5b2b62 100644
--- a/ports/atmel-samd/boards/sam32/pins.c
+++ b/ports/atmel-samd/boards/sam32/pins.c
@@ -1,10 +1,8 @@
#include "shared-bindings/board/__init__.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PB08) },
- { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB09) },
- { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA08) },
- { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_PB09) },
{ MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB04) },
{ MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB05) },
{ MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB06) },
@@ -13,15 +11,14 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB13) },
{ MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB12) },
{ MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB14) },
- { MP_ROM_QSTR(MP_QSTR_xSDCS),MP_ROM_PTR(&pin_PB15) },
+ { MP_ROM_QSTR(MP_QSTR_xSDCS),MP_ROM_PTR(&pin_PA04) },
{ MP_ROM_QSTR(MP_QSTR_DAC0), MP_ROM_PTR(&pin_PA02) },
{ MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PA07) },
{ MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_PA10) },
{ MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_PA11) },
- { MP_ROM_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_PA12) },
- { MP_ROM_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_PA13) },
{ MP_ROM_QSTR(MP_QSTR_D31), MP_ROM_PTR(&pin_PA14) },
{ MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_PA16) },
{ MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_PA17) },
@@ -35,12 +32,24 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_D50), MP_ROM_PTR(&pin_PB23) },
{ MP_ROM_QSTR(MP_QSTR_D59), MP_ROM_PTR(&pin_PB30) },
{ MP_ROM_QSTR(MP_QSTR_D60), MP_ROM_PTR(&pin_PB31) },
- { MP_ROM_QSTR(MP_QSTR_D64), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_D61), MP_ROM_PTR(&pin_PB00) },
+
+ { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_PB01) },
+ { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_PB03) },
+
+ { MP_ROM_QSTR(MP_QSTR_TCK), MP_ROM_PTR(&pin_PB01) },
+ { MP_ROM_QSTR(MP_QSTR_TDI), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_TMS), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_ESP_CS),MP_ROM_PTR(&pin_PB15) },
+
+ { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PA12) },
+ { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PA13) },
+ { MP_ROM_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_PB16) },
+ { MP_ROM_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_PB17) },
- { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16) },
- { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17) },
- { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA07) },
- { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) },
{ MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_PTR(&pin_PB11) },
{ MP_ROM_QSTR(MP_QSTR_DTR), MP_ROM_PTR(&pin_PB10) },
diff --git a/ports/atmel-samd/boards/seeeduino_xiao/board.c b/ports/atmel-samd/boards/seeeduino_xiao/board.c
new file mode 100644
index 000000000..0f60736a2
--- /dev/null
+++ b/ports/atmel-samd/boards/seeeduino_xiao/board.c
@@ -0,0 +1,39 @@
+/*
+ * 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 "boards/board.h"
+#include "mpconfigboard.h"
+#include "hal/include/hal_gpio.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/seeeduino_xiao/mpconfigboard.h b/ports/atmel-samd/boards/seeeduino_xiao/mpconfigboard.h
new file mode 100644
index 000000000..4bd10ca41
--- /dev/null
+++ b/ports/atmel-samd/boards/seeeduino_xiao/mpconfigboard.h
@@ -0,0 +1,20 @@
+#define MICROPY_HW_BOARD_NAME "Seeeduino XIAO"
+#define MICROPY_HW_MCU_NAME "samd21g18"
+
+#define MICROPY_PORT_A (0)
+#define MICROPY_PORT_B (0)
+#define MICROPY_PORT_C (0)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA09) // was PA23
+#define DEFAULT_I2C_BUS_SDA (&pin_PA08) // was PA22
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PA07) // was PA17
+#define DEFAULT_SPI_BUS_MOSI (&pin_PA06) // was PA16
+#define DEFAULT_SPI_BUS_MISO (&pin_PA05) // was PA19
+
+#define DEFAULT_UART_BUS_RX (&pin_PB09) // was PA11
+#define DEFAULT_UART_BUS_TX (&pin_PB08) // was PA10
+
+// 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/seeeduino_xiao/mpconfigboard.mk b/ports/atmel-samd/boards/seeeduino_xiao/mpconfigboard.mk
new file mode 100644
index 000000000..2741454ce
--- /dev/null
+++ b/ports/atmel-samd/boards/seeeduino_xiao/mpconfigboard.mk
@@ -0,0 +1,13 @@
+USB_VID = 0x2886
+USB_PID = 0x002f
+USB_PRODUCT = "Seeeduino XIAO"
+USB_MANUFACTURER = "Seeed"
+
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = NONE
+CIRCUITPY_SMALL_BUILD = 1
+
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/seeeduino_xiao/pins.c b/ports/atmel-samd/boards/seeeduino_xiao/pins.c
new file mode 100644
index 000000000..8b9690253
--- /dev/null
+++ b/ports/atmel-samd/boards/seeeduino_xiao/pins.c
@@ -0,0 +1,54 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+
+ // Analog pins
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA06) },
+
+ // Digital pins
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) },
+
+ // UART pins
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB09) },
+
+ // SPI pins
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA05) },
+
+ // I2C pins
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) },
+
+ // LED pins
+ { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA17) }, // status
+ { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_PA17) },
+
+ // Comm objects
+ { 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_global_dict_table);
diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c
index 36ab52006..b75c2b335 100644
--- a/ports/atmel-samd/common-hal/audioio/AudioOut.c
+++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c
@@ -397,15 +397,22 @@ void common_hal_audioio_audioout_play(audioio_audioout_obj_t* self,
if (self->right_channel == &pin_PA02) {
right_channel_reg = (uint32_t) &DAC->DATABUF[0].reg;
}
- result = audio_dma_setup_playback(&self->left_dma, sample, loop, true, 0,
- false /* output unsigned */,
- left_channel_reg,
- left_channel_trigger);
- if (right_channel_reg != 0 && result == AUDIO_DMA_OK) {
- result = audio_dma_setup_playback(&self->right_dma, sample, loop, true, 1,
+ if(right_channel_reg == left_channel_reg + 2 && audiosample_bits_per_sample(sample) == 16) {
+ result = audio_dma_setup_playback(&self->left_dma, sample, loop, false, 0,
false /* output unsigned */,
- right_channel_reg,
- right_channel_trigger);
+ left_channel_reg,
+ left_channel_trigger);
+ } else {
+ result = audio_dma_setup_playback(&self->left_dma, sample, loop, true, 0,
+ false /* output unsigned */,
+ left_channel_reg,
+ left_channel_trigger);
+ if (right_channel_reg != 0 && result == AUDIO_DMA_OK) {
+ result = audio_dma_setup_playback(&self->right_dma, sample, loop, true, 1,
+ false /* output unsigned */,
+ right_channel_reg,
+ right_channel_trigger);
+ }
}
#endif
if (result != AUDIO_DMA_OK) {
diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c
index b0e5714a7..ffe74a274 100644
--- a/ports/atmel-samd/common-hal/busio/I2C.c
+++ b/ports/atmel-samd/common-hal/busio/I2C.c
@@ -76,6 +76,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
mp_raise_ValueError(translate("Invalid pins"));
}
+#if CIRCUITPY_REQUIRE_I2C_PULLUPS
// Test that the pins are in a high state. (Hopefully indicating they are pulled up.)
gpio_set_pin_function(sda->number, GPIO_PIN_FUNCTION_OFF);
gpio_set_pin_function(scl->number, GPIO_PIN_FUNCTION_OFF);
@@ -98,6 +99,8 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
reset_pin_number(scl->number);
mp_raise_RuntimeError(translate("SDA or SCL needs a pull up"));
}
+#endif
+
gpio_set_pin_function(sda->number, sda_pinmux);
gpio_set_pin_function(scl->number, scl_pinmux);
diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c
index 4ad47a58d..fb9968605 100644
--- a/ports/atmel-samd/common-hal/busio/UART.c
+++ b/ports/atmel-samd/common-hal/busio/UART.c
@@ -52,9 +52,12 @@ static void usart_async_rxc_callback(const struct usart_async_descriptor *const
}
void common_hal_busio_uart_construct(busio_uart_obj_t *self,
- const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
- uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
- uint16_t receiver_buffer_size) {
+ const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx,
+ const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
+ const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
+ uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
+ mp_float_t timeout, uint16_t receiver_buffer_size) {
+
Sercom* sercom = NULL;
uint8_t sercom_index = 255; // Unset index
uint32_t rx_pinmux = 0;
@@ -62,6 +65,10 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
uint32_t tx_pinmux = 0;
uint8_t tx_pad = 255; // Unset pad
+ if ((rts != mp_const_none) || (cts != mp_const_none) || (rs485_dir != mp_const_none) || (rs485_invert)) {
+ mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device"));
+ }
+
if (bits > 8) {
mp_raise_NotImplementedError(translate("bytes > 8 bits not supported"));
}
@@ -150,7 +157,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
self->buffer = (uint8_t *) gc_alloc(self->buffer_length * sizeof(uint8_t), false, true);
if (self->buffer == NULL) {
common_hal_busio_uart_deinit(self);
- mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer"));
+ mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), self->buffer_length * sizeof(uint8_t));
}
} else {
self->buffer_length = 0;
diff --git a/ports/atmel-samd/common-hal/nvm/ByteArray.c b/ports/atmel-samd/common-hal/nvm/ByteArray.c
index 12a127f53..ac896a9d5 100644
--- a/ports/atmel-samd/common-hal/nvm/ByteArray.c
+++ b/ports/atmel-samd/common-hal/nvm/ByteArray.c
@@ -43,9 +43,9 @@ bool common_hal_nvm_bytearray_set_bytes(nvm_bytearray_obj_t *self,
// whenever we need it instead of storing it long term.
struct flash_descriptor desc;
desc.dev.hw = NVMCTRL;
- flash_write(&desc, (uint32_t) self->start_address + start_index, values, len);
+ bool status = flash_write(&desc, (uint32_t) self->start_address + start_index, values, len) == ERR_NONE;
assert_heap_ok();
- return true;
+ return status;
}
// NVM memory is memory mapped so reading it is easy.
diff --git a/ports/atmel-samd/common-hal/time/__init__.c b/ports/atmel-samd/common-hal/time/__init__.c
index 2d82b3d1a..652e455fc 100644
--- a/ports/atmel-samd/common-hal/time/__init__.c
+++ b/ports/atmel-samd/common-hal/time/__init__.c
@@ -29,11 +29,20 @@
#include "shared-bindings/time/__init__.h"
#include "supervisor/shared/tick.h"
+#include "tick.h"
-inline uint64_t common_hal_time_monotonic() {
+inline uint64_t common_hal_time_monotonic(void) {
return supervisor_ticks_ms64();
}
+uint64_t common_hal_time_monotonic_ns(void) {
+ uint64_t ms;
+ uint32_t us_until_ms;
+ current_tick(&ms, &us_until_ms);
+ // us counts down.
+ return 1000 * (ms * 1000 + (1000 - us_until_ms));
+}
+
void common_hal_time_delay_ms(uint32_t delay) {
mp_hal_delay_ms(delay);
}
diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h
index 28a844ffc..04ad98c22 100644
--- a/ports/atmel-samd/mpconfigport.h
+++ b/ports/atmel-samd/mpconfigport.h
@@ -109,6 +109,9 @@
#define CIRCUITPY_DEFAULT_STACK_SIZE 4096
#endif
+// Smallest unit of flash that can be erased.
+#define FLASH_ERASE_SIZE NVMCTRL_ROW_SIZE
+
#endif // SAMD21
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -123,6 +126,9 @@
#define CIRCUITPY_DEFAULT_STACK_SIZE (24*1024)
#endif
+// Smallest unit of flash that can be erased.
+#define FLASH_ERASE_SIZE NVMCTRL_BLOCK_SIZE
+
// If CIRCUITPY is internal, use half of flash for it.
#if INTERNAL_FLASH_FILESYSTEM
#ifndef CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE
@@ -187,25 +193,25 @@
#error BOOTLOADER_START_ADDR must be on a flash page boundary.
#endif
-#if CIRCUITPY_INTERNAL_NVM_START_ADDR % FLASH_PAGE_SIZE != 0
-#error CIRCUITPY_INTERNAL_NVM_START_ADDR must be on a flash page boundary.
+#if CIRCUITPY_INTERNAL_NVM_START_ADDR % FLASH_ERASE_SIZE != 0
+#error CIRCUITPY_INTERNAL_NVM_START_ADDR must be on a flash erase (row or block) boundary.
#endif
-#if CIRCUITPY_INTERNAL_NVM_SIZE % FLASH_PAGE_SIZE != 0
-#error CIRCUITPY_INTERNAL_NVM_SIZE must be a multiple of FLASH_PAGE_SIZE.
+#if CIRCUITPY_INTERNAL_NVM_SIZE % FLASH_ERASE_SIZE != 0
+#error CIRCUITPY_INTERNAL_NVM_SIZE must be a multiple of FLASH_ERASE_SIZE.
#endif
-#if CIRCUITPY_INTERNAL_CONFIG_START_ADDR % FLASH_PAGE_SIZE != 0
-#error CIRCUITPY_INTERNAL_CONFIG_SIZE must be on a flash page boundary.
+#if CIRCUITPY_INTERNAL_CONFIG_START_ADDR % FLASH_ERASE_SIZE != 0
+#error CIRCUITPY_INTERNAL_CONFIG_SIZE must be on a flash erase (row or block) boundary.
#endif
-#if CIRCUITPY_INTERNAL_CONFIG_SIZE % FLASH_PAGE_SIZE != 0
-#error CIRCUITPY_INTERNAL_CONFIG_SIZE must be a multiple of FLASH_PAGE_SIZE.
+#if CIRCUITPY_INTERNAL_CONFIG_SIZE % FLASH_ERASE_SIZE != 0
+#error CIRCUITPY_INTERNAL_CONFIG_SIZE must be a multiple of FLASH_ERASE_SIZE.
#endif
-#if CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR % FLASH_PAGE_SIZE != 0
-#error CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE must be on a flash page boundary.
+#if CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR % FLASH_ERASE_SIZE != 0
+#error CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE must be on a flash erase (row or block) boundary.
#endif
-#if CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE % FLASH_PAGE_SIZE != 0
-#error CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE must be a multiple of FLASH_PAGE_SIZE.
+#if CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE % FLASH_ERASE_SIZE != 0
+#error CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE must be a multiple of FLASH_ERASE_SIZE.
#endif
#if CIRCUITPY_FIRMWARE_SIZE < 0
diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals
-Subproject 4c0deecf889da0074c1dbc9a5e2d24cb7c7a31c
+Subproject b89811f22a24ac350079ceaf0cdf0e62aa03f4f
diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c
index 5662b159b..01ca797ca 100644
--- a/ports/atmel-samd/supervisor/port.c
+++ b/ports/atmel-samd/supervisor/port.c
@@ -232,9 +232,6 @@ safe_mode_t port_init(void) {
// Reset everything into a known state before board_init.
reset_port();
- // Init the board last so everything else is ready
- board_init();
-
#ifdef SAMD21
if (PM->RCAUSE.bit.BOD33 == 1 || PM->RCAUSE.bit.BOD12 == 1) {
return BROWNOUT;
@@ -331,6 +328,14 @@ uint32_t *port_stack_get_top(void) {
return &_estack;
}
+uint32_t *port_heap_get_bottom(void) {
+ return port_stack_get_limit();
+}
+
+uint32_t *port_heap_get_top(void) {
+ return port_stack_get_top();
+}
+
// Place the word to save 8k from the end of RAM so we and the bootloader don't clobber it.
#ifdef SAMD21
uint32_t* safe_word = (uint32_t*) (HMCRAMC0_ADDR + HMCRAMC0_SIZE - 0x2000);
diff --git a/ports/cxd56/Makefile b/ports/cxd56/Makefile
index d65c2e266..a0782c4e9 100644
--- a/ports/cxd56/Makefile
+++ b/ports/cxd56/Makefile
@@ -67,13 +67,13 @@ PLATFORM := $(firstword $(subst _, ,$(shell uname -s 2>/dev/null)))
ifeq ($(PLATFORM),Darwin)
# macOS
- MKSPK = $(SPRESENSE_SDK)/sdk/tools/macos/mkspk
+ MKSPK = mkspk/mkspk
else ifeq ($(PLATFORM),Linux)
# Linux
- MKSPK = $(SPRESENSE_SDK)/sdk/tools/linux/mkspk
+ MKSPK = mkspk/mkspk
else
# Cygwin/MSYS2
- MKSPK = $(SPRESENSE_SDK)/sdk/tools/windows/mkspk.exe
+ MKSPK = mkspk/mkspk.exe
endif
SERIAL ?= /dev/ttyUSB0
@@ -131,6 +131,7 @@ LDFLAGS = \
-o $(BUILD)/firmware.elf \
--start-group \
-u spresense_main \
+ -u board_timerhook \
$(BUILD)/libmpy.a \
$(SPRESENSE_SDK)/sdk/libs/libapps.a \
$(SPRESENSE_SDK)/sdk/libs/libsdk.a \
@@ -200,7 +201,10 @@ $(BUILD)/firmware.elf: $(BUILD)/libmpy.a
$(ECHO) "LD $@"
$(Q)$(LD) $(LDFLAGS)
-$(BUILD)/firmware.spk: $(BUILD)/firmware.elf
+$(MKSPK):
+ $(MAKE) -C mkspk
+
+$(BUILD)/firmware.spk: $(BUILD)/firmware.elf $(MKSPK)
$(ECHO) "Creating $@"
$(MKSPK) -c 2 $(BUILD)/firmware.elf nuttx $(BUILD)/firmware.spk
diff --git a/ports/cxd56/common-hal/busio/UART.c b/ports/cxd56/common-hal/busio/UART.c
index 40ae3b761..3ed980952 100644
--- a/ports/cxd56/common-hal/busio/UART.c
+++ b/ports/cxd56/common-hal/busio/UART.c
@@ -53,11 +53,17 @@ STATIC busio_uart_dev_t busio_uart_dev[] = {
};
void common_hal_busio_uart_construct(busio_uart_obj_t *self,
- const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, uint32_t baudrate,
- uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
- uint16_t receiver_buffer_size) {
+ const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx,
+ const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
+ const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
+ uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
+ mp_float_t timeout, uint16_t receiver_buffer_size) {
struct termios tio;
+ if ((rts != mp_const_none) || (cts != mp_const_none) || (rs485_dir != mp_const_none) || (rs485_invert)) {
+ mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device"));
+ }
+
if (bits != 8) {
mp_raise_ValueError(translate("Could not initialize UART"));
}
diff --git a/ports/cxd56/common-hal/time/__init__.c b/ports/cxd56/common-hal/time/__init__.c
index 6f5eedd41..31c63cbb2 100644
--- a/ports/cxd56/common-hal/time/__init__.c
+++ b/ports/cxd56/common-hal/time/__init__.c
@@ -24,6 +24,8 @@
* THE SOFTWARE.
*/
+#include <sys/time.h>
+
#include "py/mphal.h"
#include "supervisor/shared/tick.h"
@@ -32,6 +34,12 @@ uint64_t common_hal_time_monotonic(void) {
return supervisor_ticks_ms64();
}
+uint64_t common_hal_time_monotonic_ns(void) {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return 1000 * ((uint64_t) tv.tv_sec * 1000000 + (uint64_t) tv.tv_usec);
+}
+
void common_hal_time_delay_ms(uint32_t delay) {
mp_hal_delay_ms(delay);
}
diff --git a/ports/cxd56/mkspk/.gitignore b/ports/cxd56/mkspk/.gitignore
new file mode 100644
index 000000000..e9a6ab18f
--- /dev/null
+++ b/ports/cxd56/mkspk/.gitignore
@@ -0,0 +1,3 @@
+/mkspk
+/mkspk.exe
+
diff --git a/ports/cxd56/mkspk/Makefile b/ports/cxd56/mkspk/Makefile
new file mode 100644
index 000000000..d91d17a3c
--- /dev/null
+++ b/ports/cxd56/mkspk/Makefile
@@ -0,0 +1,51 @@
+############################################################################
+# tools/mkspk/Makefile
+#
+# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+all: mkspk
+default: mkspk
+.PHONY: clean
+
+# Add CFLAGS=-g on the make command line to build debug versions
+
+CFLAGS = -O2 -Wall -I.
+
+# mkspk - Convert nuttx.hex image to nuttx.spk image
+
+mkspk:
+ @gcc $(CFLAGS) -o mkspk mkspk.c clefia.c
+
+clean:
+ @rm -f *.o *.a *.dSYM *~ .*.swp
+ @rm -f mkspk mkspk.exe
diff --git a/ports/cxd56/mkspk/clefia.c b/ports/cxd56/mkspk/clefia.c
new file mode 100644
index 000000000..02a175505
--- /dev/null
+++ b/ports/cxd56/mkspk/clefia.c
@@ -0,0 +1,517 @@
+/****************************************************************************
+ * tools/cxd56/clefia.c
+ *
+ * Copyright (C) 2007, 2008 Sony Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <assert.h>
+
+#include "clefia.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define clefiamul4(_x) (clefiamul2(clefiamul2((_x))))
+#define clefiamul6(_x) (clefiamul2((_x)) ^ clefiamul4((_x)))
+#define clefiamul8(_x) (clefiamul2(clefiamul4((_x))))
+#define clefiamula(_x) (clefiamul2((_x)) ^ clefiamul8((_x)))
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* S0 (8-bit S-box based on four 4-bit S-boxes) */
+
+static const unsigned char clefia_s0[256] =
+{
+ 0x57u, 0x49u, 0xd1u, 0xc6u, 0x2fu, 0x33u, 0x74u, 0xfbu,
+ 0x95u, 0x6du, 0x82u, 0xeau, 0x0eu, 0xb0u, 0xa8u, 0x1cu,
+ 0x28u, 0xd0u, 0x4bu, 0x92u, 0x5cu, 0xeeu, 0x85u, 0xb1u,
+ 0xc4u, 0x0au, 0x76u, 0x3du, 0x63u, 0xf9u, 0x17u, 0xafu,
+ 0xbfu, 0xa1u, 0x19u, 0x65u, 0xf7u, 0x7au, 0x32u, 0x20u,
+ 0x06u, 0xceu, 0xe4u, 0x83u, 0x9du, 0x5bu, 0x4cu, 0xd8u,
+ 0x42u, 0x5du, 0x2eu, 0xe8u, 0xd4u, 0x9bu, 0x0fu, 0x13u,
+ 0x3cu, 0x89u, 0x67u, 0xc0u, 0x71u, 0xaau, 0xb6u, 0xf5u,
+ 0xa4u, 0xbeu, 0xfdu, 0x8cu, 0x12u, 0x00u, 0x97u, 0xdau,
+ 0x78u, 0xe1u, 0xcfu, 0x6bu, 0x39u, 0x43u, 0x55u, 0x26u,
+ 0x30u, 0x98u, 0xccu, 0xddu, 0xebu, 0x54u, 0xb3u, 0x8fu,
+ 0x4eu, 0x16u, 0xfau, 0x22u, 0xa5u, 0x77u, 0x09u, 0x61u,
+ 0xd6u, 0x2au, 0x53u, 0x37u, 0x45u, 0xc1u, 0x6cu, 0xaeu,
+ 0xefu, 0x70u, 0x08u, 0x99u, 0x8bu, 0x1du, 0xf2u, 0xb4u,
+ 0xe9u, 0xc7u, 0x9fu, 0x4au, 0x31u, 0x25u, 0xfeu, 0x7cu,
+ 0xd3u, 0xa2u, 0xbdu, 0x56u, 0x14u, 0x88u, 0x60u, 0x0bu,
+ 0xcdu, 0xe2u, 0x34u, 0x50u, 0x9eu, 0xdcu, 0x11u, 0x05u,
+ 0x2bu, 0xb7u, 0xa9u, 0x48u, 0xffu, 0x66u, 0x8au, 0x73u,
+ 0x03u, 0x75u, 0x86u, 0xf1u, 0x6au, 0xa7u, 0x40u, 0xc2u,
+ 0xb9u, 0x2cu, 0xdbu, 0x1fu, 0x58u, 0x94u, 0x3eu, 0xedu,
+ 0xfcu, 0x1bu, 0xa0u, 0x04u, 0xb8u, 0x8du, 0xe6u, 0x59u,
+ 0x62u, 0x93u, 0x35u, 0x7eu, 0xcau, 0x21u, 0xdfu, 0x47u,
+ 0x15u, 0xf3u, 0xbau, 0x7fu, 0xa6u, 0x69u, 0xc8u, 0x4du,
+ 0x87u, 0x3bu, 0x9cu, 0x01u, 0xe0u, 0xdeu, 0x24u, 0x52u,
+ 0x7bu, 0x0cu, 0x68u, 0x1eu, 0x80u, 0xb2u, 0x5au, 0xe7u,
+ 0xadu, 0xd5u, 0x23u, 0xf4u, 0x46u, 0x3fu, 0x91u, 0xc9u,
+ 0x6eu, 0x84u, 0x72u, 0xbbu, 0x0du, 0x18u, 0xd9u, 0x96u,
+ 0xf0u, 0x5fu, 0x41u, 0xacu, 0x27u, 0xc5u, 0xe3u, 0x3au,
+ 0x81u, 0x6fu, 0x07u, 0xa3u, 0x79u, 0xf6u, 0x2du, 0x38u,
+ 0x1au, 0x44u, 0x5eu, 0xb5u, 0xd2u, 0xecu, 0xcbu, 0x90u,
+ 0x9au, 0x36u, 0xe5u, 0x29u, 0xc3u, 0x4fu, 0xabu, 0x64u,
+ 0x51u, 0xf8u, 0x10u, 0xd7u, 0xbcu, 0x02u, 0x7du, 0x8eu
+};
+
+/* S1 (8-bit S-box based on inverse function) */
+
+static const unsigned char clefia_s1[256] =
+{
+ 0x6cu, 0xdau, 0xc3u, 0xe9u, 0x4eu, 0x9du, 0x0au, 0x3du,
+ 0xb8u, 0x36u, 0xb4u, 0x38u, 0x13u, 0x34u, 0x0cu, 0xd9u,
+ 0xbfu, 0x74u, 0x94u, 0x8fu, 0xb7u, 0x9cu, 0xe5u, 0xdcu,
+ 0x9eu, 0x07u, 0x49u, 0x4fu, 0x98u, 0x2cu, 0xb0u, 0x93u,
+ 0x12u, 0xebu, 0xcdu, 0xb3u, 0x92u, 0xe7u, 0x41u, 0x60u,
+ 0xe3u, 0x21u, 0x27u, 0x3bu, 0xe6u, 0x19u, 0xd2u, 0x0eu,
+ 0x91u, 0x11u, 0xc7u, 0x3fu, 0x2au, 0x8eu, 0xa1u, 0xbcu,
+ 0x2bu, 0xc8u, 0xc5u, 0x0fu, 0x5bu, 0xf3u, 0x87u, 0x8bu,
+ 0xfbu, 0xf5u, 0xdeu, 0x20u, 0xc6u, 0xa7u, 0x84u, 0xceu,
+ 0xd8u, 0x65u, 0x51u, 0xc9u, 0xa4u, 0xefu, 0x43u, 0x53u,
+ 0x25u, 0x5du, 0x9bu, 0x31u, 0xe8u, 0x3eu, 0x0du, 0xd7u,
+ 0x80u, 0xffu, 0x69u, 0x8au, 0xbau, 0x0bu, 0x73u, 0x5cu,
+ 0x6eu, 0x54u, 0x15u, 0x62u, 0xf6u, 0x35u, 0x30u, 0x52u,
+ 0xa3u, 0x16u, 0xd3u, 0x28u, 0x32u, 0xfau, 0xaau, 0x5eu,
+ 0xcfu, 0xeau, 0xedu, 0x78u, 0x33u, 0x58u, 0x09u, 0x7bu,
+ 0x63u, 0xc0u, 0xc1u, 0x46u, 0x1eu, 0xdfu, 0xa9u, 0x99u,
+ 0x55u, 0x04u, 0xc4u, 0x86u, 0x39u, 0x77u, 0x82u, 0xecu,
+ 0x40u, 0x18u, 0x90u, 0x97u, 0x59u, 0xddu, 0x83u, 0x1fu,
+ 0x9au, 0x37u, 0x06u, 0x24u, 0x64u, 0x7cu, 0xa5u, 0x56u,
+ 0x48u, 0x08u, 0x85u, 0xd0u, 0x61u, 0x26u, 0xcau, 0x6fu,
+ 0x7eu, 0x6au, 0xb6u, 0x71u, 0xa0u, 0x70u, 0x05u, 0xd1u,
+ 0x45u, 0x8cu, 0x23u, 0x1cu, 0xf0u, 0xeeu, 0x89u, 0xadu,
+ 0x7au, 0x4bu, 0xc2u, 0x2fu, 0xdbu, 0x5au, 0x4du, 0x76u,
+ 0x67u, 0x17u, 0x2du, 0xf4u, 0xcbu, 0xb1u, 0x4au, 0xa8u,
+ 0xb5u, 0x22u, 0x47u, 0x3au, 0xd5u, 0x10u, 0x4cu, 0x72u,
+ 0xccu, 0x00u, 0xf9u, 0xe0u, 0xfdu, 0xe2u, 0xfeu, 0xaeu,
+ 0xf8u, 0x5fu, 0xabu, 0xf1u, 0x1bu, 0x42u, 0x81u, 0xd6u,
+ 0xbeu, 0x44u, 0x29u, 0xa6u, 0x57u, 0xb9u, 0xafu, 0xf2u,
+ 0xd4u, 0x75u, 0x66u, 0xbbu, 0x68u, 0x9fu, 0x50u, 0x02u,
+ 0x01u, 0x3cu, 0x7fu, 0x8du, 0x1au, 0x88u, 0xbdu, 0xacu,
+ 0xf7u, 0xe4u, 0x79u, 0x96u, 0xa2u, 0xfcu, 0x6du, 0xb2u,
+ 0x6bu, 0x03u, 0xe1u, 0x2eu, 0x7du, 0x14u, 0x95u, 0x1du
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void bytecpy(unsigned char *dst, const unsigned char *src, int bytelen)
+{
+ while (bytelen-- > 0)
+ {
+ *dst++ = *src++;
+ }
+}
+
+static unsigned char clefiamul2(unsigned char x)
+{
+ /* multiplication over GF(2^8) (p(x) = '11d') */
+
+ if (x & 0x80u)
+ {
+ x ^= 0x0eu;
+ }
+
+ return ((x << 1) | (x >> 7));
+}
+
+static void clefiaf0xor(unsigned char *dst, const unsigned char *src,
+ const unsigned char *rk)
+{
+ unsigned char x[4];
+ unsigned char y[4];
+ unsigned char z[4];
+
+ /* F0 */
+
+ /* Key addition */
+
+ bytexor(x, src, rk, 4);
+
+ /* Substitution layer */
+
+ z[0] = clefia_s0[x[0]];
+ z[1] = clefia_s1[x[1]];
+ z[2] = clefia_s0[x[2]];
+ z[3] = clefia_s1[x[3]];
+
+ /* Diffusion layer (M0) */
+
+ y[0] = z[0] ^ clefiamul2(z[1]) ^ clefiamul4(z[2]) ^ clefiamul6(z[3]);
+ y[1] = clefiamul2(z[0]) ^ z[1] ^ clefiamul6(z[2]) ^ clefiamul4(z[3]);
+ y[2] = clefiamul4(z[0]) ^ clefiamul6(z[1]) ^ z[2] ^ clefiamul2(z[3]);
+ y[3] = clefiamul6(z[0]) ^ clefiamul4(z[1]) ^ clefiamul2(z[2]) ^ z[3];
+
+ /* Xoring after F0 */
+
+ bytecpy(dst + 0, src + 0, 4);
+ bytexor(dst + 4, src + 4, y, 4);
+}
+
+static void clefiaf1xor(unsigned char *dst, const unsigned char *src,
+ const unsigned char *rk)
+{
+ unsigned char x[4];
+ unsigned char y[4];
+ unsigned char z[4];
+
+ /* F1 */
+
+ /* Key addition */
+
+ bytexor(x, src, rk, 4);
+
+ /* Substitution layer */
+
+ z[0] = clefia_s1[x[0]];
+ z[1] = clefia_s0[x[1]];
+ z[2] = clefia_s1[x[2]];
+ z[3] = clefia_s0[x[3]];
+
+ /* Diffusion layer (M1) */
+
+ y[0] = z[0] ^ clefiamul8(z[1]) ^ clefiamul2(z[2]) ^ clefiamula(z[3]);
+ y[1] = clefiamul8(z[0]) ^ z[1] ^ clefiamula(z[2]) ^ clefiamul2(z[3]);
+ y[2] = clefiamul2(z[0]) ^ clefiamula(z[1]) ^ z[2] ^ clefiamul8(z[3]);
+ y[3] = clefiamula(z[0]) ^ clefiamul2(z[1]) ^ clefiamul8(z[2]) ^ z[3];
+
+ /* Xoring after F1 */
+
+ bytecpy(dst + 0, src + 0, 4);
+ bytexor(dst + 4, src + 4, y, 4);
+}
+
+static void clefiagfn4(unsigned char *y, const unsigned char *x,
+ const unsigned char *rk, int r)
+{
+ unsigned char fin[16];
+ unsigned char fout[16];
+
+ bytecpy(fin, x, 16);
+ while (r-- > 0)
+ {
+ clefiaf0xor(fout + 0, fin + 0, rk + 0);
+ clefiaf1xor(fout + 8, fin + 8, rk + 4);
+ rk += 8;
+ if (r)
+ {
+ /* swapping for encryption */
+
+ bytecpy(fin + 0, fout + 4, 12);
+ bytecpy(fin + 12, fout + 0, 4);
+ }
+ }
+
+ bytecpy(y, fout, 16);
+}
+
+#if 0 /* Not used */
+static void clefiagfn8(unsigned char *y, const unsigned char *x,
+ const unsigned char *rk, int r)
+{
+ unsigned char fin[32];
+ unsigned char fout[32];
+
+ bytecpy(fin, x, 32);
+ while (r-- > 0)
+ {
+ clefiaf0xor(fout + 0, fin + 0, rk + 0);
+ clefiaf1xor(fout + 8, fin + 8, rk + 4);
+ clefiaf0xor(fout + 16, fin + 16, rk + 8);
+ clefiaf1xor(fout + 24, fin + 24, rk + 12);
+ rk += 16;
+ if (r)
+ {
+ /* swapping for encryption */
+
+ bytecpy(fin + 0, fout + 4, 28);
+ bytecpy(fin + 28, fout + 0, 4);
+ }
+ }
+
+ bytecpy(y, fout, 32);
+}
+#endif
+
+#if 0 /* Not used */
+static void clefiagfn4inv(unsigned char *y, const unsigned char *x,
+ const unsigned char *rk, int r)
+{
+ unsigned char fin[16];
+ unsigned char fout[16];
+
+ rk += (r - 1) * 8;
+ bytecpy(fin, x, 16);
+ while (r-- > 0)
+ {
+ clefiaf0xor(fout + 0, fin + 0, rk + 0);
+ clefiaf1xor(fout + 8, fin + 8, rk + 4);
+ rk -= 8;
+ if (r)
+ {
+ /* swapping for decryption */
+
+ bytecpy(fin + 0, fout + 12, 4);
+ bytecpy(fin + 4, fout + 0, 12);
+ }
+ }
+
+ bytecpy(y, fout, 16);
+}
+#endif
+
+static void clefiadoubleswap(unsigned char *lk)
+{
+ unsigned char t[16];
+
+ t[0] = (lk[0] << 7) | (lk[1] >> 1);
+ t[1] = (lk[1] << 7) | (lk[2] >> 1);
+ t[2] = (lk[2] << 7) | (lk[3] >> 1);
+ t[3] = (lk[3] << 7) | (lk[4] >> 1);
+ t[4] = (lk[4] << 7) | (lk[5] >> 1);
+ t[5] = (lk[5] << 7) | (lk[6] >> 1);
+ t[6] = (lk[6] << 7) | (lk[7] >> 1);
+ t[7] = (lk[7] << 7) | (lk[15] & 0x7fu);
+
+ t[8] = (lk[8] >> 7) | (lk[0] & 0xfeu);
+ t[9] = (lk[9] >> 7) | (lk[8] << 1);
+ t[10] = (lk[10] >> 7) | (lk[9] << 1);
+ t[11] = (lk[11] >> 7) | (lk[10] << 1);
+ t[12] = (lk[12] >> 7) | (lk[11] << 1);
+ t[13] = (lk[13] >> 7) | (lk[12] << 1);
+ t[14] = (lk[14] >> 7) | (lk[13] << 1);
+ t[15] = (lk[15] >> 7) | (lk[14] << 1);
+
+ bytecpy(lk, t, 16);
+}
+
+static void clefiaconset(unsigned char *con, const unsigned char *iv, int lk)
+{
+ unsigned char t[2];
+ unsigned char tmp;
+
+ bytecpy(t, iv, 2);
+ while (lk-- > 0)
+ {
+ con[0] = t[0] ^ 0xb7u; /* P_16 = 0xb7e1 (natural logarithm) */
+ con[1] = t[1] ^ 0xe1u;
+ con[2] = ~((t[0] << 1) | (t[1] >> 7));
+ con[3] = ~((t[1] << 1) | (t[0] >> 7));
+ con[4] = ~t[0] ^ 0x24u; /* Q_16 = 0x243f (circle ratio) */
+ con[5] = ~t[1] ^ 0x3fu;
+ con[6] = t[1];
+ con[7] = t[0];
+ con += 8;
+
+ /* updating T */
+
+ if (t[1] & 0x01u)
+ {
+ t[0] ^= 0xa8u;
+ t[1] ^= 0x30u;
+ }
+
+ tmp = t[0] << 7;
+ t[0] = (t[0] >> 1) | (t[1] << 7);
+ t[1] = (t[1] >> 1) | tmp;
+ }
+}
+
+static void left_shift_one(uint8_t * in, uint8_t * out)
+{
+ int i;
+ int overflow;
+
+ overflow = 0;
+ for (i = 15; i >= 0; i--)
+ {
+ out[i] = in[i] << 1;
+ out[i] |= overflow;
+ overflow = (in[i] >> 7) & 1;
+ }
+}
+
+static void gen_subkey(struct cipher *c)
+{
+ uint8_t L[16];
+
+ memset(L, 0, 16);
+ clefiaencrypt(L, L, c->rk, c->round);
+
+ left_shift_one(L, c->k1);
+ if (L[0] & 0x80)
+ {
+ c->k1[15] = c->k1[15] ^ 0x87;
+ }
+
+ left_shift_one(c->k1, c->k2);
+ if (c->k1[0] & 0x80)
+ {
+ c->k2[15] = c->k2[15] ^ 0x87;
+ }
+
+ memset(L, 0, 16);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+struct cipher *cipher_init(uint8_t * key, uint8_t * iv)
+{
+ struct cipher *c;
+
+ c = (struct cipher *)malloc(sizeof(*c));
+ if (!c)
+ {
+ return NULL;
+ }
+
+ c->round = clefiakeyset(c->rk, key);
+
+ gen_subkey(c);
+ memset(c->vector, 0, 16);
+
+ return c;
+}
+
+void cipher_deinit(struct cipher *c)
+{
+ memset(c, 0, sizeof(*c));
+ free(c);
+}
+
+int cipher_calc_cmac(struct cipher *c, void *data, int size, void *cmac)
+{
+ uint8_t m[16];
+ uint8_t *p;
+
+ if (size & 0xf)
+ {
+ return -1;
+ }
+
+ p = (uint8_t *) data;
+ while (size)
+ {
+ bytexor(m, c->vector, p, 16);
+ clefiaencrypt(c->vector, m, c->rk, c->round);
+ size -= 16;
+ p += 16;
+ }
+
+ bytexor(cmac, m, c->k1, 16);
+ clefiaencrypt(cmac, cmac, c->rk, c->round);
+ memset(m, 0, 16);
+
+ return 0;
+}
+
+void bytexor(unsigned char *dst, const unsigned char *a,
+ const unsigned char *b, int bytelen)
+{
+ while (bytelen-- > 0)
+ {
+ *dst++ = *a++ ^ *b++;
+ }
+}
+
+int clefiakeyset(unsigned char *rk, const unsigned char *skey)
+{
+ const unsigned char iv[2] =
+ {
+ 0x42u, 0x8au /* cubic root of 2 */
+ };
+
+ unsigned char lk[16];
+ unsigned char con128[4 * 60];
+ int i;
+
+ /* generating CONi^(128) (0 <= i < 60, lk = 30) */
+
+ clefiaconset(con128, iv, 30);
+
+ /* GFN_{4,12} (generating L from K) */
+
+ clefiagfn4(lk, skey, con128, 12);
+
+ bytecpy(rk, skey, 8); /* initial whitening key (WK0, WK1) */
+ rk += 8;
+ for (i = 0; i < 9; i++)
+ {
+ /* round key (RKi (0 <= i < 36)) */
+
+ bytexor(rk, lk, con128 + i * 16 + (4 * 24), 16);
+ if (i % 2)
+ {
+ bytexor(rk, rk, skey, 16); /* Xoring K */
+ }
+
+ clefiadoubleswap(lk); /* Updating L (DoubleSwap function) */
+ rk += 16;
+ }
+
+ bytecpy(rk, skey + 8, 8); /* final whitening key (WK2, WK3) */
+
+ return 18;
+}
+
+void clefiaencrypt(unsigned char *ct, const unsigned char *pt,
+ const unsigned char *rk, const int r)
+{
+ unsigned char rin[16];
+ unsigned char rout[16];
+
+ bytecpy(rin, pt, 16);
+
+ bytexor(rin + 4, rin + 4, rk + 0, 4); /* initial key whitening */
+ bytexor(rin + 12, rin + 12, rk + 4, 4);
+ rk += 8;
+
+ clefiagfn4(rout, rin, rk, r); /* GFN_{4,r} */
+
+ bytecpy(ct, rout, 16);
+ bytexor(ct + 4, ct + 4, rk + r * 8 + 0, 4); /* final key whitening */
+ bytexor(ct + 12, ct + 12, rk + r * 8 + 4, 4);
+}
diff --git a/ports/cxd56/mkspk/clefia.h b/ports/cxd56/mkspk/clefia.h
new file mode 100644
index 000000000..a0e02587d
--- /dev/null
+++ b/ports/cxd56/mkspk/clefia.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+ * tools/cxd56/clefia.h
+ *
+ * Copyright (C) 2007, 2008 Sony Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef _TOOLS_CXD56_CLEFIA_H_
+#define _TOOLS_CXD56_CLEFIA_H_
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct cipher
+ {
+ int mode;
+ int dir;
+ uint8_t rk[8 * 26 + 16];
+ uint8_t vector[16];
+ int round;
+ uint8_t k1[16];
+ uint8_t k2[16];
+ };
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+struct cipher *cipher_init(uint8_t * key, uint8_t * iv);
+void cipher_deinit(struct cipher *c);
+int cipher_calc_cmac(struct cipher *c, void *data, int size, void *cmac);
+void bytexor(unsigned char *dst, const unsigned char *a,
+ const unsigned char *b, int bytelen);
+int clefiakeyset(unsigned char *rk, const unsigned char *skey);
+void clefiaencrypt(unsigned char *ct, const unsigned char *pt,
+ const unsigned char *rk, const int r);
+
+#endif
diff --git a/ports/cxd56/mkspk/mkspk.c b/ports/cxd56/mkspk/mkspk.c
new file mode 100644
index 000000000..c447ad7da
--- /dev/null
+++ b/ports/cxd56/mkspk/mkspk.c
@@ -0,0 +1,383 @@
+/****************************************************************************
+ * tools/cxd56/mkspk.c
+ *
+ * Copyright (C) 2007, 2008 Sony Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <assert.h>
+
+#include "mkspk.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct args
+{
+ int core;
+ char *elffile;
+ char *savename;
+ char *outputfile;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static uint8_t vmk[16] =
+ "\x27\xc0\xaf\x1b\x5d\xcb\xc6\xc5\x58\x22\x1c\xdd\xaf\xf3\x20\x21";
+
+static struct args g_options =
+{
+ 0
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static struct args *parse_args(int argc, char **argv)
+{
+ int opt;
+ int show_help;
+ struct args *args = &g_options;
+ char *endp;
+
+ show_help = 0;
+
+ if (argc < 2)
+ {
+ show_help = 1;
+ }
+
+ memset(args, 0, sizeof(*args));
+ args->core = -1;
+
+ while ((opt = getopt(argc, argv, "h:c:")) != -1)
+ {
+ switch (opt)
+ {
+ case 'c':
+ args->core = strtol(optarg, &endp, 0);
+ if (*endp)
+ {
+ fprintf(stderr, "Invalid core number \"%s\"\n", optarg);
+ show_help = 1;
+ }
+ break;
+
+ case 'h':
+ default:
+ show_help = 1;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ args->elffile = argv[0];
+ args->savename = argv[1];
+ argc -= 2;
+ argv += 2;
+
+ if (argc > 0)
+ {
+ args->outputfile = strdup(argv[0]);
+ }
+ else
+ {
+ show_help = 1;
+ }
+
+ /* Sanity checks for options */
+
+ if (show_help == 1)
+ {
+ fprintf(stderr,
+ "mkspk [-c <number>] <filename> <save name> [<output file>]\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (args->core < 0)
+ {
+ fprintf(stderr, "Core number is not set. Please use -c option.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (strlen(args->savename) > 63)
+ {
+ fprintf(stderr, "savename too long.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ return args;
+}
+
+static struct elf_file *load_elf(const char *filename)
+{
+ size_t fsize;
+ int pos;
+ char *buf;
+ FILE *fp;
+ struct elf_file *ef;
+ Elf32_Shdr *sh;
+ uint16_t i;
+ int ret;
+
+ fp = fopen(filename, "rb");
+ if (!fp)
+ {
+ return NULL;
+ }
+
+ ef = (struct elf_file *)malloc(sizeof(*ef));
+ if (!ef)
+ {
+ return NULL;
+ }
+
+ pos = fseek(fp, 0, SEEK_END);
+ fsize = (size_t) ftell(fp);
+ fseek(fp, pos, SEEK_SET);
+
+ buf = (char *)malloc(fsize);
+ if (!buf)
+ {
+ return NULL;
+ }
+
+ ret = fread(buf, fsize, 1, fp);
+ fclose(fp);
+ if (ret != 1)
+ {
+ return NULL;
+ }
+
+ ef->data = buf;
+
+ ef->ehdr = (Elf32_Ehdr *) buf;
+
+ Elf32_Ehdr *h = (Elf32_Ehdr *) buf;
+
+ if (!(h->e_ident[EI_MAG0] == 0x7f &&
+ h->e_ident[EI_MAG1] == 'E' &&
+ h->e_ident[EI_MAG2] == 'L' && h->e_ident[EI_MAG3] == 'F'))
+ {
+ free(ef);
+ free(buf);
+ return NULL;
+ }
+
+ ef->phdr = (Elf32_Phdr *) (buf + ef->ehdr->e_phoff);
+ ef->shdr = (Elf32_Shdr *) (buf + ef->ehdr->e_shoff);
+ ef->shstring = buf + ef->shdr[ef->ehdr->e_shstrndx].sh_offset;
+
+ for (i = 0, sh = ef->shdr; i < ef->ehdr->e_shnum; i++, sh++)
+ {
+ if (sh->sh_type == SHT_SYMTAB)
+ {
+ ef->symtab = (Elf32_Sym *) (buf + sh->sh_offset);
+ ef->nsyms = sh->sh_size / sh->sh_entsize;
+ continue;
+ }
+
+ if (sh->sh_type == SHT_STRTAB)
+ {
+ if (!strcmp(".strtab", ef->shstring + sh->sh_name))
+ {
+ ef->string = buf + sh->sh_offset;
+ }
+ }
+ }
+
+ return ef;
+}
+
+static void *create_image(struct elf_file *elf, int core, char *savename,
+ int *image_size)
+{
+ char *img;
+ struct spk_header *header;
+ struct spk_prog_info *pi;
+ Elf32_Phdr *ph;
+ Elf32_Sym *sym;
+ char *name;
+ int snlen;
+ int nphs, psize, imgsize;
+ int i;
+ int j;
+ uint32_t offset;
+ uint32_t sp;
+
+ snlen = alignup(strlen(savename) + 1, 16);
+
+ nphs = 0;
+ psize = 0;
+ for (i = 0, ph = elf->phdr; i < elf->ehdr->e_phnum; i++, ph++)
+ {
+ if (ph->p_type != PT_LOAD || ph->p_filesz == 0)
+ {
+ continue;
+ }
+
+ nphs++;
+ psize += alignup(ph->p_filesz, 16);
+ }
+
+ imgsize = sizeof(*header) + snlen + (nphs * 16) + psize;
+
+ img = (char *)malloc(imgsize + 32);
+ if (!img)
+ {
+ return NULL;
+ }
+
+ *image_size = imgsize;
+ sym = elf->symtab;
+ name = elf->string;
+ sp = 0;
+
+ for (j = 0; j < elf->nsyms; j++, sym++)
+ {
+ if (!strcmp("__stack", name + sym->st_name))
+ {
+ sp = sym->st_value;
+ }
+ }
+
+ memset(img, 0, imgsize);
+
+ header = (struct spk_header *)img;
+ header->magic[0] = 0xef;
+ header->magic[1] = 'M';
+ header->magic[2] = 'O';
+ header->magic[3] = 'D';
+ header->cpu = core;
+
+ header->entry = elf->ehdr->e_entry;
+ header->stack = sp;
+ header->core = core;
+
+ header->binaries = nphs;
+ header->phoffs = sizeof(*header) + snlen;
+ header->mode = 0777;
+
+ strncpy(img + sizeof(*header), savename, 63);
+
+ ph = elf->phdr;
+ pi = (struct spk_prog_info *)(img + header->phoffs);
+ offset = ((char *)pi - img) + (nphs * sizeof(*pi));
+ for (i = 0; i < elf->ehdr->e_phnum; i++, ph++)
+ {
+ if (ph->p_type != PT_LOAD || ph->p_filesz == 0)
+ continue;
+ pi->load_address = ph->p_paddr;
+ pi->offset = offset;
+ pi->size = alignup(ph->p_filesz, 16); /* need 16 bytes align for
+ * decryption */
+ pi->memsize = ph->p_memsz;
+
+ memcpy(img + pi->offset, elf->data + ph->p_offset, ph->p_filesz);
+
+ offset += alignup(ph->p_filesz, 16);
+ pi++;
+ }
+
+ return img;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, char **argv)
+{
+ struct args *args;
+ struct elf_file *elf;
+ struct cipher *c;
+ uint8_t *spkimage;
+ int size = 0;
+ FILE *fp;
+ char footer[16];
+
+ args = parse_args(argc, argv);
+
+ elf = load_elf(args->elffile);
+ if (!elf)
+ {
+ fprintf(stderr, "Loading ELF %s failure.\n", args->elffile);
+ exit(EXIT_FAILURE);
+ }
+
+ spkimage = create_image(elf, args->core, args->savename, &size);
+ free(elf);
+
+ c = cipher_init(vmk, NULL);
+ cipher_calc_cmac(c, spkimage, size, (uint8_t *) spkimage + size);
+ cipher_deinit(c);
+
+ size += 16; /* Extend CMAC size */
+
+ snprintf(footer, 16, "MKSPK_BN_HOOTER");
+ footer[15] = '\0';
+
+ fp = fopen(args->outputfile, "wb");
+ if (!fp)
+ {
+ fprintf(stderr, "Output file open error.\n");
+ free(spkimage);
+ exit(EXIT_FAILURE);
+ }
+
+ fwrite(spkimage, size, 1, fp);
+ fwrite(footer, 16, 1, fp);
+
+ fclose(fp);
+
+ printf("File %s is successfully created.\n", args->outputfile);
+ free(args->outputfile);
+
+ memset(spkimage, 0, size);
+ free(spkimage);
+
+ exit(EXIT_SUCCESS);
+}
diff --git a/ports/cxd56/mkspk/mkspk.h b/ports/cxd56/mkspk/mkspk.h
new file mode 100644
index 000000000..5a67bb3dd
--- /dev/null
+++ b/ports/cxd56/mkspk/mkspk.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * tools/cxd56/mkspk.h
+ *
+ * Copyright (C) 2007, 2008 Sony Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "clefia.h"
+#include "elf.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define alignup(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
+#define swap(a, b) { (a) ^= (b); (b) ^= (a); (a) ^= (b); }
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct spk_header
+ {
+ uint8_t magic[4];
+ uint8_t cpu;
+ uint8_t reserved[11];
+ uint32_t entry;
+ uint32_t stack;
+ uint16_t core;
+ uint16_t binaries;
+ uint16_t phoffs;
+ uint16_t mode;
+ };
+
+struct spk_prog_info
+ {
+ uint32_t load_address;
+ uint32_t offset;
+ uint32_t size;
+ uint32_t memsize;
+ };
+
+struct elf_file
+ {
+ Elf32_Ehdr *ehdr;
+ Elf32_Phdr *phdr;
+ Elf32_Shdr *shdr;
+ Elf32_Sym *symtab;
+ int nsyms;
+ char *shstring;
+ char *string;
+ char *data;
+ };
diff --git a/ports/cxd56/supervisor/port.c b/ports/cxd56/supervisor/port.c
index f06133468..5d2957f35 100644
--- a/ports/cxd56/supervisor/port.c
+++ b/ports/cxd56/supervisor/port.c
@@ -85,6 +85,14 @@ uint32_t *port_stack_get_top(void) {
return rtcb->adj_stack_ptr;
}
+uint32_t *port_heap_get_bottom(void) {
+ return port_stack_get_limit();
+}
+
+uint32_t *port_heap_get_top(void) {
+ return port_stack_get_top();
+}
+
extern uint32_t _ebss;
// Place the word to save just after our BSS section that gets blanked.
diff --git a/ports/mimxrt10xx/Makefile b/ports/mimxrt10xx/Makefile
index 68ddea565..80d1da1aa 100644
--- a/ports/mimxrt10xx/Makefile
+++ b/ports/mimxrt10xx/Makefile
@@ -71,6 +71,7 @@ INC += \
-Isdk/CMSIS/Include \
-Isdk/devices/$(CHIP_FAMILY) \
-Isdk/devices/$(CHIP_FAMILY)/drivers \
+ -Isdk/devices/$(CHIP_FAMILY)/xip \
# NDEBUG disables assert() statements. This reduces code size pretty dramatically, per tannewt.
@@ -83,24 +84,10 @@ CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_
ifeq ($(DEBUG), 1)
CFLAGS += -ggdb
# You may want to disable -flto if it interferes with debugging.
- #CFLAGS += -flto -flto-partition=none
+ # CFLAGS += -flto -flto-partition=none
# You may want to enable these flags to make setting breakpoints easier.
CFLAGS += -fno-inline -fno-ipa-sra
else
- # -finline-limit can shrink the image size.
- # -finline-limit=80 or so is similar to not having it on.
- # There is no simple default value, though.
-
- # Do a default shrink for small builds.
- ifndef CFLAGS_INLINE_LIMIT
- ifeq ($(CIRCUITPY_SMALL_BUILD),1)
- CFLAGS_INLINE_LIMIT = 50
- endif
- endif
-
- ifdef CFLAGS_INLINE_LIMIT
- CFLAGS += -finline-limit=$(CFLAGS_INLINE_LIMIT)
- endif
#CFLAGS += -flto -flto-partition=none
endif
@@ -114,14 +101,15 @@ CFLAGS += \
-mfpu=fpv5-sp-d16 \
-DCPU_$(CHIP_VARIANT) \
-DDEBUG \
- -DXIP_EXTERNAL_FLASH=1 \
- -DXIP_BOOT_HEADER_ENABLE=1 \
- -D__START=main \
+ -DIMXRT10XX \
-Os -g3 -Wno-unused-parameter \
- -ffunction-sections -fdata-sections -fstack-usage \
- -D__STARTUP_CLEAR_BSS
+ -ffunction-sections -fdata-sections -fstack-usage
-LDFLAGS = $(CFLAGS) -nostartfiles -fshort-enums -Wl,-nostdlib -Wl,-T,$(LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs
+LD_FILES = $(wildcard boards/$(BOARD)/*.ld) $(addprefix linking/, flash/$(FLASH).ld chip_family/$(CHIP_FAMILY).ld common.ld)
+
+LD_SCRIPT_FLAG := -Wl,-T,
+
+LDFLAGS = $(CFLAGS) -nostartfiles -fshort-enums -Wl,-nostdlib $(addprefix $(LD_SCRIPT_FLAG), $(LD_FILES)) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs
LIBS := -lgcc -lc -lnosys -lm
# Use toolchain libm if we're not using our own.
@@ -154,6 +142,7 @@ SRC_SDK := $(addprefix sdk/devices/$(CHIP_FAMILY)/, $(SRC_SDK))
SRC_C = \
background.c \
boards/$(BOARD)/board.c \
+ boards/$(BOARD)/flash_config.c \
boards/$(BOARD)/pins.c \
fatfs_port.c \
lib/mp-readline/readline.c \
@@ -231,19 +220,24 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)
-all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2
+all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2 $(BUILD)/firmware.hex
-$(BUILD)/firmware.elf: $(LD_FILE) $(OBJ)
+$(BUILD)/firmware.elf: $(OBJ) $(LD_FILES)
$(STEPECHO) "LINK $@"
- $(Q)$(CC) -o $@ $(LDFLAGS) $(filter-out $<,$^) -Wl,--start-group $(LIBS) -Wl,--end-group
+ $(Q)$(CC) -o $@ $(LDFLAGS) $(filter-out %.ld, $^) -Wl,--start-group $(LIBS) -Wl,--end-group
$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
$(STEPECHO) "Create $@"
- $(Q)$(OBJCOPY) -O binary -j .interrupts -j .text -j .ARM.exidx -j .data $^ $@
+ $(Q)$(OBJCOPY) -O binary -j .flash_config -j .ivt -j .text -j .ARM.exidx -j .data -j .itcm -j .dtcm_data $^ $@
-$(BUILD)/firmware.uf2: $(BUILD)/firmware.bin
+$(BUILD)/firmware.uf2: $(BUILD)/firmware.elf
$(STEPECHO) "Create $@"
- $(Q)$(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -b $(BOOTLOADER_SIZE) -f MIMXRT10XX -c -o $@ $^
+ $(Q)$(OBJCOPY) -O binary -j .text -j .ARM.exidx -j .data -j .itcm -j .dtcm_data $^ $@-binpart
+ $(Q)$(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -b $(BOOTLOADER_SIZE) -f MIMXRT10XX -c -o $@ $@-binpart
+ $(Q)rm $@-binpart
+
+$(BUILD)/firmware.hex: $(BUILD)/firmware.elf
+ $(Q)$(OBJCOPY) -O ihex -j .flash_config -j .ivt -j .text -j .ARM.exidx -j .data -j .itcm -j .dtcm_data $< $@
include $(TOP)/py/mkrules.mk
diff --git a/ports/mimxrt10xx/background.c b/ports/mimxrt10xx/background.c
index 8c7333cf8..71dd79521 100644
--- a/ports/mimxrt10xx/background.c
+++ b/ports/mimxrt10xx/background.c
@@ -34,11 +34,11 @@
#include "py/runtime.h"
#include "shared-module/network/__init__.h"
+#include "supervisor/linker.h"
#include "supervisor/shared/stack.h"
-// TODO
#ifdef CIRCUITPY_DISPLAYIO
-//#include "shared-module/displayio/__init__.h"
+#include "shared-module/displayio/__init__.h"
#endif
volatile uint64_t last_finished_tick = 0;
@@ -51,7 +51,7 @@ void background_tasks_reset(void) {
running_background_tasks = false;
}
-void run_background_tasks(void) {
+void PLACE_IN_ITCM(run_background_tasks)(void) {
// Don't call ourselves recursively.
if (running_background_tasks) {
return;
diff --git a/ports/mimxrt10xx/boards/feather_m7_1011/board.c b/ports/mimxrt10xx/boards/feather_m7_1011/board.c
new file mode 100644
index 000000000..52dd498b3
--- /dev/null
+++ b/ports/mimxrt10xx/boards/feather_m7_1011/board.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Artur Pacholec
+ *
+ * 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 "boards/board.h"
+#include "mpconfigboard.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/mimxrt10xx/boards/feather_m7_1011/flash_config.c b/ports/mimxrt10xx/boards/feather_m7_1011/flash_config.c
new file mode 100644
index 000000000..b74c0b151
--- /dev/null
+++ b/ports/mimxrt10xx/boards/feather_m7_1011/flash_config.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_flexspi_nor_boot.h"
+#include "fsl_flexspi_nor_config.h"
+
+
+__attribute__((section(".boot_hdr.ivt")))
+/*************************************
+ * IVT Data
+ *************************************/
+const ivt image_vector_table = {
+ IVT_HEADER, /* IVT Header */
+ IMAGE_ENTRY_ADDRESS, /* Image Entry Function */
+ IVT_RSVD, /* Reserved = 0 */
+ (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */
+ (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */
+ (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */
+ (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */
+ IVT_RSVD /* Reserved = 0 */
+};
+
+__attribute__((section(".boot_hdr.boot_data")))
+/*************************************
+ * Boot Data
+ *************************************/
+const BOOT_DATA_T boot_data = {
+ FLASH_BASE, /* boot start location */
+ FLASH_SIZE, /* size */
+ PLUGIN_FLAG, /* Plugin flag*/
+ 0xFFFFFFFF /* empty - extra data word */
+};
+
+__attribute__((section(".boot_hdr.conf")))
+// Values copied from https://github.com/PaulStoffregen/cores/blob/ddb23fa5d97dac763bc06e11b9b41f026bd51f0a/teensy4/bootdata.c#L39
+const flexspi_nor_config_t qspiflash_config = {
+ .memConfig =
+ {
+ .tag = FLEXSPI_CFG_BLK_TAG,
+ .version = FLEXSPI_CFG_BLK_VERSION,
+ .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
+ .csHoldTime = 1u,
+ .csSetupTime = 2u,
+ // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock
+ .deviceType = kFlexSpiDeviceType_SerialNOR,
+ .sflashPadType = kSerialFlash_4Pads,
+ .serialClkFreq = kFlexSpiSerialClk_60MHz, // 03
+ .sflashA1Size = FLASH_SIZE,
+ .lookupTable =
+ {
+ // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1)
+ // (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) |
+ // FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
+ // Read LUTs
+ FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
+ FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
+ 0,
+ 0,
+
+ 0x24040405,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000406,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x08180420,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x081804D8,
+ 0,
+ 0,
+ 0,
+
+ 0x08180402,
+ 0x00002004,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000460,
+ },
+ },
+ .pageSize = 256u,
+ .sectorSize = 4u * 1024u,
+ .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz,
+ .blockSize = 0x00010000,
+ .isUniformBlockSize = false,
+};
diff --git a/ports/mimxrt10xx/boards/feather_m7_1011/mpconfigboard.h b/ports/mimxrt10xx/boards/feather_m7_1011/mpconfigboard.h
new file mode 100644
index 000000000..e96ec13dd
--- /dev/null
+++ b/ports/mimxrt10xx/boards/feather_m7_1011/mpconfigboard.h
@@ -0,0 +1,20 @@
+#define MICROPY_HW_BOARD_NAME "Feather MIMXRT1011"
+#define MICROPY_HW_MCU_NAME "IMXRT1011DAE5A"
+
+#define MICROPY_HW_NEOPIXEL (&pin_GPIO_00)
+
+// If you change this, then make sure to update the linker scripts as well to
+// make sure you don't overwrite code
+#define CIRCUITPY_INTERNAL_NVM_SIZE 0
+
+#define BOARD_FLASH_SIZE (4 * 1024 * 1024)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_GPIO_12)
+#define DEFAULT_I2C_BUS_SDA (&pin_GPIO_11)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_GPIO_AD_06)
+#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO_AD_04)
+#define DEFAULT_SPI_BUS_MISO (&pin_GPIO_AD_03)
+
+#define DEFAULT_UART_BUS_RX (&pin_GPIO_AD_01)
+#define DEFAULT_UART_BUS_TX (&pin_GPIO_AD_02)
diff --git a/ports/mimxrt10xx/boards/feather_m7_1011/mpconfigboard.mk b/ports/mimxrt10xx/boards/feather_m7_1011/mpconfigboard.mk
new file mode 100644
index 000000000..670b48b60
--- /dev/null
+++ b/ports/mimxrt10xx/boards/feather_m7_1011/mpconfigboard.mk
@@ -0,0 +1,8 @@
+USB_VID = 0x239A
+USB_PID = 0x8092
+USB_PRODUCT = "Feather M7 1011"
+USB_MANUFACTURER = "Adafruit"
+
+CHIP_VARIANT = MIMXRT1011DAE5A
+CHIP_FAMILY = MIMXRT1011
+FLASH = W25Q32JV
diff --git a/ports/mimxrt10xx/boards/feather_m7_1011/pins.c b/ports/mimxrt10xx/boards/feather_m7_1011/pins.c
new file mode 100644
index 000000000..09e321761
--- /dev/null
+++ b/ports/mimxrt10xx/boards/feather_m7_1011/pins.c
@@ -0,0 +1,43 @@
+#include "shared-bindings/board/__init__.h"
+
+#include "boards/board.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ // Analog
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO_AD_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO_AD_10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO_AD_09) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO_AD_08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO_AD_07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO_AD_05) },
+
+ // Digital
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO_10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO_09) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO_08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO_07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO_05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO_04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO_AD_00) },
+
+ // SPI
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO_AD_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO_AD_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO_AD_04) },
+
+ // UART
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO_AD_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO_AD_01) },
+
+ // I2C
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO_12) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO_00) },
+
+ { 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_global_dict_table);
diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1011/board.c b/ports/mimxrt10xx/boards/feather_mimxrt1011/board.c
index 8e73df4ad..52dd498b3 100644
--- a/ports/mimxrt10xx/boards/feather_mimxrt1011/board.c
+++ b/ports/mimxrt10xx/boards/feather_mimxrt1011/board.c
@@ -27,24 +27,8 @@
#include "boards/board.h"
#include "mpconfigboard.h"
-#include "fsl_iomuxc.h"
void board_init(void) {
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_06_FLEXSPI_A_SS0_B, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_07_FLEXSPI_A_DATA1,1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_08_FLEXSPI_A_DATA2, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_09_FLEXSPI_A_DATA0, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_10_FLEXSPI_A_SCLK, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_11_FLEXSPI_A_DATA3, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_12_FLEXSPI_A_DQS, 1U);
-
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_06_FLEXSPI_A_SS0_B,0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_07_FLEXSPI_A_DATA1, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_08_FLEXSPI_A_DATA2, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_09_FLEXSPI_A_DATA0, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_10_FLEXSPI_A_SCLK, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_11_FLEXSPI_A_DATA3, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_12_FLEXSPI_A_DQS, 0x10E1U);
}
bool board_requests_safe_mode(void) {
diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1011/flash_config.c b/ports/mimxrt10xx/boards/feather_mimxrt1011/flash_config.c
new file mode 100644
index 000000000..b74c0b151
--- /dev/null
+++ b/ports/mimxrt10xx/boards/feather_mimxrt1011/flash_config.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_flexspi_nor_boot.h"
+#include "fsl_flexspi_nor_config.h"
+
+
+__attribute__((section(".boot_hdr.ivt")))
+/*************************************
+ * IVT Data
+ *************************************/
+const ivt image_vector_table = {
+ IVT_HEADER, /* IVT Header */
+ IMAGE_ENTRY_ADDRESS, /* Image Entry Function */
+ IVT_RSVD, /* Reserved = 0 */
+ (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */
+ (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */
+ (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */
+ (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */
+ IVT_RSVD /* Reserved = 0 */
+};
+
+__attribute__((section(".boot_hdr.boot_data")))
+/*************************************
+ * Boot Data
+ *************************************/
+const BOOT_DATA_T boot_data = {
+ FLASH_BASE, /* boot start location */
+ FLASH_SIZE, /* size */
+ PLUGIN_FLAG, /* Plugin flag*/
+ 0xFFFFFFFF /* empty - extra data word */
+};
+
+__attribute__((section(".boot_hdr.conf")))
+// Values copied from https://github.com/PaulStoffregen/cores/blob/ddb23fa5d97dac763bc06e11b9b41f026bd51f0a/teensy4/bootdata.c#L39
+const flexspi_nor_config_t qspiflash_config = {
+ .memConfig =
+ {
+ .tag = FLEXSPI_CFG_BLK_TAG,
+ .version = FLEXSPI_CFG_BLK_VERSION,
+ .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
+ .csHoldTime = 1u,
+ .csSetupTime = 2u,
+ // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock
+ .deviceType = kFlexSpiDeviceType_SerialNOR,
+ .sflashPadType = kSerialFlash_4Pads,
+ .serialClkFreq = kFlexSpiSerialClk_60MHz, // 03
+ .sflashA1Size = FLASH_SIZE,
+ .lookupTable =
+ {
+ // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1)
+ // (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) |
+ // FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
+ // Read LUTs
+ FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
+ FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
+ 0,
+ 0,
+
+ 0x24040405,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000406,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x08180420,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x081804D8,
+ 0,
+ 0,
+ 0,
+
+ 0x08180402,
+ 0x00002004,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000460,
+ },
+ },
+ .pageSize = 256u,
+ .sectorSize = 4u * 1024u,
+ .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz,
+ .blockSize = 0x00010000,
+ .isUniformBlockSize = false,
+};
diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1011/mpconfigboard.h b/ports/mimxrt10xx/boards/feather_mimxrt1011/mpconfigboard.h
index 98d1f478b..a715a2c56 100644
--- a/ports/mimxrt10xx/boards/feather_mimxrt1011/mpconfigboard.h
+++ b/ports/mimxrt10xx/boards/feather_mimxrt1011/mpconfigboard.h
@@ -1,19 +1,8 @@
#define MICROPY_HW_BOARD_NAME "Feather MIMXRT1011"
#define MICROPY_HW_MCU_NAME "IMXRT1011DAE5A"
-//TODO
-//#define MICROPY_HW_LED_STATUS (&pin_PA27)
-
#define MICROPY_HW_NEOPIXEL (&pin_GPIO_SD_05)
-// These are pins not to reset.
-// QSPI Data pins
-//#define MICROPY_PORT_A ( PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 )
-// QSPI CS, and QSPI SCK
-//#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 | PORT_PB22 )
-//#define MICROPY_PORT_C ( 0 )
-//#define MICROPY_PORT_D ( 0 )
-
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1011/mpconfigboard.mk b/ports/mimxrt10xx/boards/feather_mimxrt1011/mpconfigboard.mk
index 6efd3f329..08164b140 100644
--- a/ports/mimxrt10xx/boards/feather_mimxrt1011/mpconfigboard.mk
+++ b/ports/mimxrt10xx/boards/feather_mimxrt1011/mpconfigboard.mk
@@ -1,21 +1,8 @@
-LD_FILE = boards/mimxrt1011-bootloader-external-flash.ld
USB_VID = 0x239A
USB_PID = 0x8074
USB_PRODUCT = "Feather MIMXRT1011"
USB_MANUFACTURER = "arturo182"
-USB_DEVICES = "CDC,MSC,HID"
CHIP_VARIANT = MIMXRT1011DAE5A
CHIP_FAMILY = MIMXRT1011
-
-INTERNAL_FLASH_FILESYSTEM = 1
-
-CIRCUITPY_DISPLAYIO = 0
-CIRCUITPY_AUDIOIO = 0
-CIRCUITPY_AUDIOBUSIO = 0
-CIRCUITPY_FREQUENCYIO = 0
-CIRCUITPY_I2CSLAVE = 0
-CIRCUITPY_NVM = 0
-CIRCUITPY_ROTARYIO = 0
-
-LONGINT_IMPL = MPZ
+FLASH = W25Q64JV
diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1062/board.c b/ports/mimxrt10xx/boards/feather_mimxrt1062/board.c
index 979dd82ce..52dd498b3 100644
--- a/ports/mimxrt10xx/boards/feather_mimxrt1062/board.c
+++ b/ports/mimxrt10xx/boards/feather_mimxrt1062/board.c
@@ -27,24 +27,8 @@
#include "boards/board.h"
#include "mpconfigboard.h"
-#include "fsl_iomuxc.h"
void board_init(void) {
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK,1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 1U);
-
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B,0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 0x10E1U);
}
bool board_requests_safe_mode(void) {
diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1062/flash_config.c b/ports/mimxrt10xx/boards/feather_mimxrt1062/flash_config.c
new file mode 100644
index 000000000..b74c0b151
--- /dev/null
+++ b/ports/mimxrt10xx/boards/feather_mimxrt1062/flash_config.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_flexspi_nor_boot.h"
+#include "fsl_flexspi_nor_config.h"
+
+
+__attribute__((section(".boot_hdr.ivt")))
+/*************************************
+ * IVT Data
+ *************************************/
+const ivt image_vector_table = {
+ IVT_HEADER, /* IVT Header */
+ IMAGE_ENTRY_ADDRESS, /* Image Entry Function */
+ IVT_RSVD, /* Reserved = 0 */
+ (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */
+ (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */
+ (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */
+ (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */
+ IVT_RSVD /* Reserved = 0 */
+};
+
+__attribute__((section(".boot_hdr.boot_data")))
+/*************************************
+ * Boot Data
+ *************************************/
+const BOOT_DATA_T boot_data = {
+ FLASH_BASE, /* boot start location */
+ FLASH_SIZE, /* size */
+ PLUGIN_FLAG, /* Plugin flag*/
+ 0xFFFFFFFF /* empty - extra data word */
+};
+
+__attribute__((section(".boot_hdr.conf")))
+// Values copied from https://github.com/PaulStoffregen/cores/blob/ddb23fa5d97dac763bc06e11b9b41f026bd51f0a/teensy4/bootdata.c#L39
+const flexspi_nor_config_t qspiflash_config = {
+ .memConfig =
+ {
+ .tag = FLEXSPI_CFG_BLK_TAG,
+ .version = FLEXSPI_CFG_BLK_VERSION,
+ .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
+ .csHoldTime = 1u,
+ .csSetupTime = 2u,
+ // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock
+ .deviceType = kFlexSpiDeviceType_SerialNOR,
+ .sflashPadType = kSerialFlash_4Pads,
+ .serialClkFreq = kFlexSpiSerialClk_60MHz, // 03
+ .sflashA1Size = FLASH_SIZE,
+ .lookupTable =
+ {
+ // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1)
+ // (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) |
+ // FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
+ // Read LUTs
+ FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
+ FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
+ 0,
+ 0,
+
+ 0x24040405,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000406,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x08180420,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x081804D8,
+ 0,
+ 0,
+ 0,
+
+ 0x08180402,
+ 0x00002004,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000460,
+ },
+ },
+ .pageSize = 256u,
+ .sectorSize = 4u * 1024u,
+ .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz,
+ .blockSize = 0x00010000,
+ .isUniformBlockSize = false,
+};
diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1062/mpconfigboard.h b/ports/mimxrt10xx/boards/feather_mimxrt1062/mpconfigboard.h
index b91209c82..4c3953187 100644
--- a/ports/mimxrt10xx/boards/feather_mimxrt1062/mpconfigboard.h
+++ b/ports/mimxrt10xx/boards/feather_mimxrt1062/mpconfigboard.h
@@ -6,14 +6,6 @@
//#define MICROPY_HW_NEOPIXEL (&pin_PB22)
-// These are pins not to reset.
-// QSPI Data pins
-//#define MICROPY_PORT_A ( PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 )
-// QSPI CS, and QSPI SCK
-//#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 | PORT_PB22 )
-//#define MICROPY_PORT_C ( 0 )
-//#define MICROPY_PORT_D ( 0 )
-
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1062/mpconfigboard.mk b/ports/mimxrt10xx/boards/feather_mimxrt1062/mpconfigboard.mk
index b2e356e55..1c8646991 100644
--- a/ports/mimxrt10xx/boards/feather_mimxrt1062/mpconfigboard.mk
+++ b/ports/mimxrt10xx/boards/feather_mimxrt1062/mpconfigboard.mk
@@ -1,21 +1,8 @@
-LD_FILE = boards/mimxrt1062-bootloader-external-flash.ld
USB_VID = 0x239A
USB_PID = 0x8076
USB_PRODUCT = "Feather MIMXRT1062"
USB_MANUFACTURER = "arturo182"
-USB_DEVICES = "CDC,MSC,HID"
CHIP_VARIANT = MIMXRT1062DVJ6A
CHIP_FAMILY = MIMXRT1062
-
-INTERNAL_FLASH_FILESYSTEM = 1
-
-CIRCUITPY_DISPLAYIO = 0
-CIRCUITPY_AUDIOIO = 0
-CIRCUITPY_AUDIOBUSIO = 0
-CIRCUITPY_FREQUENCYIO = 0
-CIRCUITPY_I2CSLAVE = 0
-CIRCUITPY_NVM = 0
-CIRCUITPY_ROTARYIO = 0
-
-LONGINT_IMPL = MPZ
+FLASH = W25Q64JV
diff --git a/ports/mimxrt10xx/boards/imxrt1010_evk/board.c b/ports/mimxrt10xx/boards/imxrt1010_evk/board.c
index 8e73df4ad..52dd498b3 100644
--- a/ports/mimxrt10xx/boards/imxrt1010_evk/board.c
+++ b/ports/mimxrt10xx/boards/imxrt1010_evk/board.c
@@ -27,24 +27,8 @@
#include "boards/board.h"
#include "mpconfigboard.h"
-#include "fsl_iomuxc.h"
void board_init(void) {
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_06_FLEXSPI_A_SS0_B, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_07_FLEXSPI_A_DATA1,1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_08_FLEXSPI_A_DATA2, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_09_FLEXSPI_A_DATA0, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_10_FLEXSPI_A_SCLK, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_11_FLEXSPI_A_DATA3, 1U);
- IOMUXC_SetPinMux(IOMUXC_GPIO_SD_12_FLEXSPI_A_DQS, 1U);
-
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_06_FLEXSPI_A_SS0_B,0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_07_FLEXSPI_A_DATA1, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_08_FLEXSPI_A_DATA2, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_09_FLEXSPI_A_DATA0, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_10_FLEXSPI_A_SCLK, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_11_FLEXSPI_A_DATA3, 0x10E1U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_12_FLEXSPI_A_DQS, 0x10E1U);
}
bool board_requests_safe_mode(void) {
diff --git a/ports/mimxrt10xx/boards/imxrt1010_evk/flash_config.c b/ports/mimxrt10xx/boards/imxrt1010_evk/flash_config.c
new file mode 100644
index 000000000..7e8fb75b2
--- /dev/null
+++ b/ports/mimxrt10xx/boards/imxrt1010_evk/flash_config.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_flexspi_nor_boot.h"
+#include "fsl_flexspi_nor_config.h"
+
+__attribute__((section(".boot_hdr.ivt")))
+/*************************************
+ * IVT Data
+ *************************************/
+const ivt image_vector_table = {
+ IVT_HEADER, /* IVT Header */
+ IMAGE_ENTRY_ADDRESS, /* Image Entry Function */
+ IVT_RSVD, /* Reserved = 0 */
+ (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */
+ (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */
+ (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */
+ (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */
+ IVT_RSVD /* Reserved = 0 */
+};
+
+__attribute__((section(".boot_hdr.boot_data")))
+/*************************************
+ * Boot Data
+ *************************************/
+const BOOT_DATA_T boot_data = {
+ FLASH_BASE, /* boot start location */
+ FLASH_SIZE, /* size */
+ PLUGIN_FLAG, /* Plugin flag*/
+ 0xFFFFFFFF /* empty - extra data word */
+};
+
+__attribute__((section(".boot_hdr.conf")))
+// Values copied from https://github.com/PaulStoffregen/cores/blob/ddb23fa5d97dac763bc06e11b9b41f026bd51f0a/teensy4/bootdata.c#L39
+const flexspi_nor_config_t qspiflash_config = {
+ .memConfig =
+ {
+ .tag = FLEXSPI_CFG_BLK_TAG,
+ .version = FLEXSPI_CFG_BLK_VERSION,
+ .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
+ .csHoldTime = 1u,
+ .csSetupTime = 2u,
+ // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock
+ .deviceType = kFlexSpiDeviceType_SerialNOR,
+ .sflashPadType = kSerialFlash_4Pads,
+ .serialClkFreq = kFlexSpiSerialClk_60MHz, // 03
+ .sflashA1Size = FLASH_SIZE,
+ .lookupTable =
+ {
+ // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1)
+ // (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) |
+ // FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
+ // Read LUTs
+ FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
+ FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
+ 0,
+ 0,
+
+ 0x24040405,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000406,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x08180420,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x081804D8,
+ 0,
+ 0,
+ 0,
+
+ 0x08180402,
+ 0x00002004,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000460,
+ },
+ },
+ .pageSize = 256u,
+ .sectorSize = 4u * 1024u,
+ .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz,
+ .blockSize = 0x00010000,
+ .isUniformBlockSize = false,
+};
diff --git a/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.h b/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.h
index 12cb5e8a8..128e33111 100644
--- a/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.h
+++ b/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.h
@@ -1,19 +1,6 @@
#define MICROPY_HW_BOARD_NAME "IMXRT1010-EVK"
#define MICROPY_HW_MCU_NAME "IMXRT1011DAE5A"
-//TODO
-//#define MICROPY_HW_LED_STATUS (&pin_PA27)
-
-//#define MICROPY_HW_NEOPIXEL (&pin_PB22)
-
-// These are pins not to reset.
-// QSPI Data pins
-//#define MICROPY_PORT_A ( PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 )
-// QSPI CS, and QSPI SCK
-//#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 | PORT_PB22 )
-//#define MICROPY_PORT_C ( 0 )
-//#define MICROPY_PORT_D ( 0 )
-
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
@@ -23,9 +10,5 @@
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO_02)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO_01)
-#define DEFAULT_SPI_BUS_SCK (&pin_GPIO_AD_06)
-#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO_AD_04)
-#define DEFAULT_SPI_BUS_MISO (&pin_GPIO_AD_03)
-
#define DEFAULT_UART_BUS_RX (&pin_GPIO_09)
#define DEFAULT_UART_BUS_TX (&pin_GPIO_10)
diff --git a/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.mk b/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.mk
index 4401647c4..81eb63597 100644
--- a/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.mk
+++ b/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.mk
@@ -1,22 +1,8 @@
-LD_FILE = boards/mimxrt1011-bootloader-external-flash.ld
USB_VID = 0x239A
USB_PID = 0x8078
USB_PRODUCT = "IMXRT1010-EVK"
USB_MANUFACTURER = "NXP"
-USB_DEVICES = "CDC,MSC,HID"
CHIP_VARIANT = MIMXRT1011DAE5A
CHIP_FAMILY = MIMXRT1011
-
-INTERNAL_FLASH_FILESYSTEM = 1
-
-CIRCUITPY_DISPLAYIO = 0
-CIRCUITPY_AUDIOIO = 0
-CIRCUITPY_AUDIOBUSIO = 0
-CIRCUITPY_FREQUENCYIO = 0
-CIRCUITPY_I2CSLAVE = 0
-CIRCUITPY_NEOPIXEL_WRITE = 0
-CIRCUITPY_NVM = 0
-CIRCUITPY_ROTARYIO = 0
-
-LONGINT_IMPL = MPZ
+FLASH = AT25SF128A
diff --git a/ports/mimxrt10xx/boards/imxrt1010_evk/pins.c b/ports/mimxrt10xx/boards/imxrt1010_evk/pins.c
index cfc876369..a5a598760 100644
--- a/ports/mimxrt10xx/boards/imxrt1010_evk/pins.c
+++ b/ports/mimxrt10xx/boards/imxrt1010_evk/pins.c
@@ -4,21 +4,25 @@
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO_09) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO_09) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO_10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO_10) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO_AD_05) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO_AD_06) },
- //{ MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO_08) }, // Connected to audio codec
- //{ MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO_01) }, // Connected to audio codec
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO_08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO_01) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO_AD_01) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO_AD_02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO_SD_02) },
- //{ MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO_03) }, // Connected to audio codec
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO_03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO_AD_05) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO_AD_04) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO_AD_03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO_AD_06) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO_01) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO_02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO_AD_07) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO_AD_09) },
@@ -27,8 +31,24 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO_AD_01) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO_AD_02) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_USR_LED), MP_ROM_PTR(&pin_GPIO_11) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_USR_SW), MP_ROM_PTR(&pin_GPIO_SD_05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_USER_LED), MP_ROM_PTR(&pin_GPIO_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO_SD_05) },
+
+ // Audio Interface
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_INT), MP_ROM_PTR(&pin_GPIO_00) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_SYNC), MP_ROM_PTR(&pin_GPIO_07) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_BCLK), MP_ROM_PTR(&pin_GPIO_06) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_RXD), MP_ROM_PTR(&pin_GPIO_03) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_TXD), MP_ROM_PTR(&pin_GPIO_04) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_MCLK), MP_ROM_PTR(&pin_GPIO_08) },
+
+ // SPDIF
+ { MP_ROM_QSTR(MP_QSTR_SPDIF_IN), MP_ROM_PTR(&pin_GPIO_10) },
+ { MP_ROM_QSTR(MP_QSTR_SPDIF_OUT), MP_ROM_PTR(&pin_GPIO_11) },
+
+ // Freelink UART
+ { MP_ROM_QSTR(MP_QSTR_FREELINK_TX), MP_ROM_PTR(&pin_GPIO_10) },
+ { MP_ROM_QSTR(MP_QSTR_FREELINK_RX), MP_ROM_PTR(&pin_GPIO_09) },
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
diff --git a/ports/mimxrt10xx/boards/imxrt1020_evk/board.c b/ports/mimxrt10xx/boards/imxrt1020_evk/board.c
new file mode 100644
index 000000000..52dd498b3
--- /dev/null
+++ b/ports/mimxrt10xx/boards/imxrt1020_evk/board.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Artur Pacholec
+ *
+ * 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 "boards/board.h"
+#include "mpconfigboard.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/mimxrt10xx/boards/imxrt1020_evk/flash_config.c b/ports/mimxrt10xx/boards/imxrt1020_evk/flash_config.c
new file mode 100644
index 000000000..80a57f17b
--- /dev/null
+++ b/ports/mimxrt10xx/boards/imxrt1020_evk/flash_config.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_flexspi_nor_boot.h"
+#include "fsl_flexspi_nor_config.h"
+
+
+__attribute__((section(".boot_hdr.ivt")))
+/*************************************
+ * IVT Data
+ *************************************/
+const ivt image_vector_table = {
+ IVT_HEADER, /* IVT Header */
+ IMAGE_ENTRY_ADDRESS, /* Image Entry Function */
+ IVT_RSVD, /* Reserved = 0 */
+ (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */
+ (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */
+ (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */
+ (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */
+ IVT_RSVD /* Reserved = 0 */
+};
+
+__attribute__((section(".boot_hdr.boot_data")))
+/*************************************
+ * Boot Data
+ *************************************/
+const BOOT_DATA_T boot_data = {
+ FLASH_BASE, /* boot start location */
+ FLASH_SIZE, /* size */
+ PLUGIN_FLAG, /* Plugin flag*/
+ 0xFFFFFFFF /* empty - extra data word */
+};
+
+__attribute__((section(".boot_hdr.conf")))
+// Values copied from https://github.com/PaulStoffregen/cores/blob/ddb23fa5d97dac763bc06e11b9b41f026bd51f0a/teensy4/bootdata.c#L39
+const flexspi_nor_config_t qspiflash_config = {
+ .memConfig =
+ {
+ .tag = FLEXSPI_CFG_BLK_TAG,
+ .version = FLEXSPI_CFG_BLK_VERSION,
+#ifdef BOARD_USING_SECONDARY_QSPI_PINMUX
+ .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromInternally,
+#else
+ .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
+#endif
+ .csHoldTime = 1u,
+ .csSetupTime = 2u,
+ // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock
+ .deviceType = kFlexSpiDeviceType_SerialNOR,
+ .sflashPadType = kSerialFlash_4Pads,
+ .serialClkFreq = kFlexSpiSerialClk_60MHz, // 03
+ .sflashA1Size = FLASH_SIZE,
+ .lookupTable =
+ {
+ // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1)
+ // (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) |
+ // FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
+ // Read LUTs
+ FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
+ FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
+ 0,
+ 0,
+
+ 0x24040405,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000406,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x08180420,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x081804D8,
+ 0,
+ 0,
+ 0,
+
+ 0x08180402,
+ 0x00002004,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000460,
+ },
+ },
+ .pageSize = 256u,
+ .sectorSize = 4u * 1024u,
+ .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz,
+ .blockSize = 0x00010000,
+ .isUniformBlockSize = false,
+};
diff --git a/ports/mimxrt10xx/boards/imxrt1020_evk/mpconfigboard.h b/ports/mimxrt10xx/boards/imxrt1020_evk/mpconfigboard.h
new file mode 100644
index 000000000..a40df100e
--- /dev/null
+++ b/ports/mimxrt10xx/boards/imxrt1020_evk/mpconfigboard.h
@@ -0,0 +1,14 @@
+#define MICROPY_HW_BOARD_NAME "iMX RT 1020 EVK"
+#define MICROPY_HW_MCU_NAME "IMXRT1021DAG5A"
+
+// If you change this, then make sure to update the linker scripts as well to
+// make sure you don't overwrite code
+#define CIRCUITPY_INTERNAL_NVM_SIZE 0
+
+#define BOARD_FLASH_SIZE (8 * 1024 * 1024)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_GPIO_SD_B1_03)
+#define DEFAULT_I2C_BUS_SDA (&pin_GPIO_SD_B1_02)
+
+#define DEFAULT_UART_BUS_RX (&pin_GPIO_AD_B1_09)
+#define DEFAULT_UART_BUS_TX (&pin_GPIO_AD_B1_08)
diff --git a/ports/mimxrt10xx/boards/imxrt1020_evk/mpconfigboard.mk b/ports/mimxrt10xx/boards/imxrt1020_evk/mpconfigboard.mk
new file mode 100644
index 000000000..7147fdf48
--- /dev/null
+++ b/ports/mimxrt10xx/boards/imxrt1020_evk/mpconfigboard.mk
@@ -0,0 +1,8 @@
+USB_VID = 0x239A
+USB_PID = 0x8082
+USB_PRODUCT = "iMX RT 1020 EVK"
+USB_MANUFACTURER = "NXP"
+
+CHIP_VARIANT = MIMXRT1021DAG5A
+CHIP_FAMILY = MIMXRT1021
+FLASH = IS25LP064A
diff --git a/ports/mimxrt10xx/boards/imxrt1020_evk/pins.c b/ports/mimxrt10xx/boards/imxrt1020_evk/pins.c
new file mode 100644
index 000000000..ef8115a64
--- /dev/null
+++ b/ports/mimxrt10xx/boards/imxrt1020_evk/pins.c
@@ -0,0 +1,84 @@
+#include "shared-bindings/board/__init__.h"
+
+#include "boards/board.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO_AD_B1_09) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO_AD_B1_09) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO_AD_B1_08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO_AD_B1_08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO_AD_B0_09) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO_AD_B0_07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO_AD_B0_05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO_AD_B0_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO_AD_B0_14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO_AD_B1_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO_AD_B1_07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO_AD_B0_15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO_AD_B0_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO_AD_B0_12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO_AD_B0_13) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO_AD_B0_10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO_SD_B1_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO_SD_B1_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO_SD_B1_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO_SD_B1_02) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO_AD_B1_10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO_AD_B1_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO_AD_B1_12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO_AD_B1_13) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO_AD_B1_15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO_AD_B1_14) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_USER_LED), MP_ROM_PTR(&pin_GPIO_AD_B0_05) },
+
+ // SD Card
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO_SD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_SW), MP_ROM_PTR(&pin_GPIO_SD_B0_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_GPIO_SD_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_D0), MP_ROM_PTR(&pin_GPIO_SD_B0_04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_D1), MP_ROM_PTR(&pin_GPIO_SD_B0_05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_D2), MP_ROM_PTR(&pin_GPIO_SD_B0_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_D3), MP_ROM_PTR(&pin_GPIO_SD_B0_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_PWREN), MP_ROM_PTR(&pin_GPIO_SD_B1_04) },
+
+ // // Audio Interface
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_INT), MP_ROM_PTR(&pin_GPIO_AD_B1_04) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_SYNC), MP_ROM_PTR(&pin_GPIO_AD_B1_02) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_BCLK), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_RXD), MP_ROM_PTR(&pin_GPIO_AD_B1_05) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_TXD), MP_ROM_PTR(&pin_GPIO_AD_B1_03) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_MCLK), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
+
+ // // Ethernet
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_MDIO), MP_ROM_PTR(&pin_GPIO_EMC_40) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_MDC), MP_ROM_PTR(&pin_GPIO_EMC_41) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_RXD0), MP_ROM_PTR(&pin_GPIO_AD_B0_10) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_RXD1), MP_ROM_PTR(&pin_GPIO_AD_B0_09) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_CRS_DV), MP_ROM_PTR(&pin_GPIO_AD_B0_11) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_TXD0), MP_ROM_PTR(&pin_GPIO_AD_B0_14) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_TXD1), MP_ROM_PTR(&pin_GPIO_AD_B0_15) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_TXEN), MP_ROM_PTR(&pin_GPIO_AD_B0_13) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_INT), MP_ROM_PTR(&pin_GPIO_AD_B1_06) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_RST), MP_ROM_PTR(&pin_GPIO_AD_B0_04) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_CLK), MP_ROM_PTR(&pin_GPIO_AD_B0_08) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_RXER), MP_ROM_PTR(&pin_GPIO_AD_B0_12) },
+
+ // // Freelink UART
+ { MP_ROM_QSTR(MP_QSTR_FREELINK_TX), MP_ROM_PTR(&pin_GPIO_AD_B0_06) },
+ { MP_ROM_QSTR(MP_QSTR_FREELINK_RX), MP_ROM_PTR(&pin_GPIO_AD_B0_07) },
+
+ // CAN
+ { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_GPIO_SD_B1_00) },
+ { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_GPIO_SD_B1_01) },
+ { MP_ROM_QSTR(MP_QSTR_CAN_STBY), MP_ROM_PTR(&pin_GPIO_AD_B1_13) },
+
+ //
+ { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_SDA), MP_ROM_PTR(&pin_GPIO_SD_B1_03) },
+ { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_SCL), MP_ROM_PTR(&pin_GPIO_SD_B1_02) },
+
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/mimxrt10xx/boards/imxrt1060_evk/board.c b/ports/mimxrt10xx/boards/imxrt1060_evk/board.c
new file mode 100644
index 000000000..52dd498b3
--- /dev/null
+++ b/ports/mimxrt10xx/boards/imxrt1060_evk/board.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Artur Pacholec
+ *
+ * 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 "boards/board.h"
+#include "mpconfigboard.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/mimxrt10xx/boards/imxrt1060_evk/flash_config.c b/ports/mimxrt10xx/boards/imxrt1060_evk/flash_config.c
new file mode 100644
index 000000000..7e046d494
--- /dev/null
+++ b/ports/mimxrt10xx/boards/imxrt1060_evk/flash_config.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_flexspi_nor_boot.h"
+#include "fsl_flexspi_nor_config.h"
+
+__attribute__((section(".boot_hdr.ivt")))
+
+/*************************************
+ * IVT Data
+ *************************************/
+const ivt image_vector_table = {
+ IVT_HEADER, /* IVT Header */
+ IMAGE_ENTRY_ADDRESS, /* Image Entry Function */
+ IVT_RSVD, /* Reserved = 0 */
+ (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */
+ (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */
+ (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */
+ (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */
+ IVT_RSVD /* Reserved = 0 */
+};
+
+__attribute__((section(".boot_hdr.boot_data")))
+/*************************************
+ * Boot Data
+ *************************************/
+const BOOT_DATA_T boot_data = {
+ FLASH_BASE, /* boot start location */
+ FLASH_SIZE, /* size */
+ PLUGIN_FLAG, /* Plugin flag*/
+ 0xFFFFFFFF /* empty - extra data word */
+};
+
+__attribute__((section(".boot_hdr.conf")))
+// Values copied from https://github.com/PaulStoffregen/cores/blob/ddb23fa5d97dac763bc06e11b9b41f026bd51f0a/teensy4/bootdata.c#L39
+const flexspi_nor_config_t qspiflash_config = {
+ .memConfig =
+ {
+ .tag = FLEXSPI_CFG_BLK_TAG,
+ .version = FLEXSPI_CFG_BLK_VERSION,
+ .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
+ .csHoldTime = 1u,
+ .csSetupTime = 2u,
+ // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock
+ .deviceType = kFlexSpiDeviceType_SerialNOR,
+ .sflashPadType = kSerialFlash_4Pads,
+ .serialClkFreq = kFlexSpiSerialClk_60MHz, // 03
+ .sflashA1Size = FLASH_SIZE,
+ .lookupTable =
+ {
+ // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1)
+ // (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) |
+ // FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
+ // Read LUTs
+ FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
+ FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
+ 0,
+ 0,
+
+ 0x24040405,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000406,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x08180420,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x081804D8,
+ 0,
+ 0,
+ 0,
+
+ 0x08180402,
+ 0x00002004,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000460,
+ },
+ },
+ .pageSize = 256u,
+ .sectorSize = 4u * 1024u,
+ .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz,
+ .blockSize = 0x00010000,
+ .isUniformBlockSize = false,
+};
diff --git a/ports/mimxrt10xx/boards/imxrt1060_evk/mpconfigboard.h b/ports/mimxrt10xx/boards/imxrt1060_evk/mpconfigboard.h
new file mode 100644
index 000000000..8eccd8aee
--- /dev/null
+++ b/ports/mimxrt10xx/boards/imxrt1060_evk/mpconfigboard.h
@@ -0,0 +1,14 @@
+#define MICROPY_HW_BOARD_NAME "iMX RT 1060 EVK"
+#define MICROPY_HW_MCU_NAME "IMXRT1062DVJ6A"
+
+// If you change this, then make sure to update the linker scripts as well to
+// make sure you don't overwrite code
+#define CIRCUITPY_INTERNAL_NVM_SIZE 0
+
+#define BOARD_FLASH_SIZE (8 * 1024 * 1024)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_GPIO_AD_B1_00)
+#define DEFAULT_I2C_BUS_SDA (&pin_GPIO_AD_B1_01)
+
+#define DEFAULT_UART_BUS_RX (&pin_GPIO_AD_B1_07)
+#define DEFAULT_UART_BUS_TX (&pin_GPIO_AD_B1_06)
diff --git a/ports/mimxrt10xx/boards/imxrt1060_evk/mpconfigboard.mk b/ports/mimxrt10xx/boards/imxrt1060_evk/mpconfigboard.mk
new file mode 100644
index 000000000..e82d8ee74
--- /dev/null
+++ b/ports/mimxrt10xx/boards/imxrt1060_evk/mpconfigboard.mk
@@ -0,0 +1,8 @@
+USB_VID = 0x239A
+USB_PID = 0x8084
+USB_PRODUCT = "iMX RT 1060 EVK"
+USB_MANUFACTURER = "NXP"
+
+CHIP_VARIANT = MIMXRT1062DVJ6A
+CHIP_FAMILY = MIMXRT1062
+FLASH = IS25WP064A
diff --git a/ports/mimxrt10xx/boards/imxrt1060_evk/pins.c b/ports/mimxrt10xx/boards/imxrt1060_evk/pins.c
new file mode 100644
index 000000000..2d268952d
--- /dev/null
+++ b/ports/mimxrt10xx/boards/imxrt1060_evk/pins.c
@@ -0,0 +1,128 @@
+#include "shared-bindings/board/__init__.h"
+
+#include "boards/board.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO_AD_B1_07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO_AD_B1_07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO_AD_B1_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO_AD_B1_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO_AD_B0_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO_AD_B1_08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO_AD_B0_09) }, // Connected to audio codec
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO_AD_B0_10) }, // Connected to audio codec
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO_AD_B1_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO_AD_B1_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO_AD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO_AD_B0_02) }, // Connected to audio codec
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO_SD_B0_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO_SD_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO_SD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO_SD_B0_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
+
+ // i2c sensor is on I2C1_SCL/SDA
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO_AD_B1_10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO_AD_B1_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO_AD_B1_04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO_AD_B1_05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_USER_LED), MP_ROM_PTR(&pin_GPIO_AD_B0_09) },
+
+ // Camera Sensor Interface
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CSI_VSYNC), MP_ROM_PTR(&pin_GPIO_AD_B1_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CSI_PWDN), MP_ROM_PTR(&pin_GPIO_AD_B1_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CSI_HSYNC), MP_ROM_PTR(&pin_GPIO_AD_B1_07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CSI_D9), MP_ROM_PTR(&pin_GPIO_AD_B1_08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CSI_MCLK), MP_ROM_PTR(&pin_GPIO_AD_B1_05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CSI_D8), MP_ROM_PTR(&pin_GPIO_AD_B1_09) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CSI_D7), MP_ROM_PTR(&pin_GPIO_AD_B1_10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CSI_PIXCLK), MP_ROM_PTR(&pin_GPIO_AD_B1_04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CSI_D6), MP_ROM_PTR(&pin_GPIO_AD_B1_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CSI_D2), MP_ROM_PTR(&pin_GPIO_AD_B1_15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CSI_D5), MP_ROM_PTR(&pin_GPIO_AD_B1_12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CSI_D3), MP_ROM_PTR(&pin_GPIO_AD_B1_14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CSI_D4), MP_ROM_PTR(&pin_GPIO_AD_B1_13) },
+
+ // SD Card
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO_SD_B0_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_SW), MP_ROM_PTR(&pin_GPIO_B1_12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_GPIO_SD_B0_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_D0), MP_ROM_PTR(&pin_GPIO_SD_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_D1), MP_ROM_PTR(&pin_GPIO_SD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_D2), MP_ROM_PTR(&pin_GPIO_SD_B0_04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_D3), MP_ROM_PTR(&pin_GPIO_SD_B0_05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_PWREN), MP_ROM_PTR(&pin_GPIO_AD_B1_03) },
+
+ // LCD Interface
+ { MP_ROM_QSTR(MP_QSTR_LCD_BACKLIGHT), MP_ROM_PTR(&pin_GPIO_B1_15) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO_AD_B0_02) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_ENABLE), MP_ROM_PTR(&pin_GPIO_B0_01) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_VSYNC), MP_ROM_PTR(&pin_GPIO_B0_03) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_HSYNC), MP_ROM_PTR(&pin_GPIO_B0_02) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO_B0_00) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D0), MP_ROM_PTR(&pin_GPIO_B0_04) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D1), MP_ROM_PTR(&pin_GPIO_B0_05) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D2), MP_ROM_PTR(&pin_GPIO_B0_06) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D3), MP_ROM_PTR(&pin_GPIO_B0_07) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D4), MP_ROM_PTR(&pin_GPIO_B0_08) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D5), MP_ROM_PTR(&pin_GPIO_B0_09) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D6), MP_ROM_PTR(&pin_GPIO_B0_10) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D7), MP_ROM_PTR(&pin_GPIO_B0_11) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D8), MP_ROM_PTR(&pin_GPIO_B0_12) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D9), MP_ROM_PTR(&pin_GPIO_B0_13) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D10), MP_ROM_PTR(&pin_GPIO_B0_14) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D11), MP_ROM_PTR(&pin_GPIO_B0_15) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D12), MP_ROM_PTR(&pin_GPIO_B1_00) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D13), MP_ROM_PTR(&pin_GPIO_B1_01) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D14), MP_ROM_PTR(&pin_GPIO_B1_02) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D15), MP_ROM_PTR(&pin_GPIO_B1_03) },
+
+ // Touch Interface
+ { MP_ROM_QSTR(MP_QSTR_LCD_TOUCH_INT), MP_ROM_PTR(&pin_GPIO_AD_B0_11) },
+
+ // Audio Interface
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_INT), MP_ROM_PTR(&pin_GPIO_AD_B1_08) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_SYNC), MP_ROM_PTR(&pin_GPIO_AD_B1_15) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_BCLK), MP_ROM_PTR(&pin_GPIO_AD_B1_14) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_RXD), MP_ROM_PTR(&pin_GPIO_AD_B1_12) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_TXD), MP_ROM_PTR(&pin_GPIO_AD_B1_13) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_MCLK), MP_ROM_PTR(&pin_GPIO_AD_B1_09) },
+
+ // SPDIF
+ { MP_ROM_QSTR(MP_QSTR_SPDIF_IN), MP_ROM_PTR(&pin_GPIO_AD_B1_03) },
+ { MP_ROM_QSTR(MP_QSTR_SPDIF_OUT), MP_ROM_PTR(&pin_GPIO_AD_B1_02) },
+
+ // Ethernet
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_MDIO), MP_ROM_PTR(&pin_GPIO_EMC_41) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_MDC), MP_ROM_PTR(&pin_GPIO_EMC_40) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_RXD0), MP_ROM_PTR(&pin_GPIO_B1_04) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_RXD1), MP_ROM_PTR(&pin_GPIO_B1_05) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_CRS_DV), MP_ROM_PTR(&pin_GPIO_B1_06) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_TXD0), MP_ROM_PTR(&pin_GPIO_B1_07) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_TXD1), MP_ROM_PTR(&pin_GPIO_B1_08) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_TXEN), MP_ROM_PTR(&pin_GPIO_B1_09) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_INT), MP_ROM_PTR(&pin_GPIO_AD_B0_10) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_RST), MP_ROM_PTR(&pin_GPIO_AD_B0_09) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_CLK), MP_ROM_PTR(&pin_GPIO_B1_10) },
+ { MP_ROM_QSTR(MP_QSTR_ETHERNET_RXER), MP_ROM_PTR(&pin_GPIO_B1_11) },
+
+ // Freelink UART
+ { MP_ROM_QSTR(MP_QSTR_FREELINK_TX), MP_ROM_PTR(&pin_GPIO_AD_B0_12) },
+ { MP_ROM_QSTR(MP_QSTR_FREELINK_RX), MP_ROM_PTR(&pin_GPIO_AD_B0_13) },
+
+ // CAN
+ { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_GPIO_AD_B0_14) },
+ { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_GPIO_AD_B0_15) },
+ { MP_ROM_QSTR(MP_QSTR_CAN_STBY), MP_ROM_PTR(&pin_GPIO_AD_B0_05) },
+
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/mimxrt10xx/boards/mimxrt1011-bootloader-external-flash.ld b/ports/mimxrt10xx/boards/mimxrt1011-bootloader-external-flash.ld
deleted file mode 100644
index d36ee1239..000000000
--- a/ports/mimxrt10xx/boards/mimxrt1011-bootloader-external-flash.ld
+++ /dev/null
@@ -1,106 +0,0 @@
-ENTRY(Reset_Handler)
-
-_minimum_stack_size = 64K;
-_minimum_heap_size = 0;
-
-MEMORY
-{
- FLASH (rx) : ORIGIN = 0x60000000, LENGTH = 8M
- FLASH_BOOTLOADER (rx) : ORIGIN = 0x60000000, LENGTH = 48K
- FLASH_ISR (rx) : ORIGIN = 0x6000C000, LENGTH = 1K
- FLASH_TEXT (rx) : ORIGIN = 0x6000C400, LENGTH = 975K
- FLASH_FATFS (r) : ORIGIN = 0x60100000, LENGTH = 7M
- RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 32K
- OCRAM (rwx) : ORIGIN = 0x20200000, LENGTH = 64K
-}
-
-_estack = ORIGIN(OCRAM) + LENGTH(OCRAM);
-_bootloader_dbl_tap = ORIGIN(RAM) + LENGTH(RAM) - 4;
-
-__fatfs_flash_start_addr = ORIGIN(FLASH_FATFS);
-__fatfs_flash_length = LENGTH(FLASH_FATFS);
-
-__RAM_VECTOR_TABLE_SIZE_BYTES = 0;
-
-SECTIONS
-{
- .interrupts :
- {
- __VECTOR_TABLE = .;
- __VECTOR_RAM = .;
-
- . = ALIGN(4);
- KEEP(*(.isr_vector)) /* Startup code */
- . = ALIGN(4);
- } > FLASH_ISR
-
- .text :
- {
- . = ALIGN(4);
- *(EXCLUDE_FILE(
- *flexspi_nor_flash_ops.o
- *fsl_flexspi.o
- ) .text*) /* .text* sections (code) */
- *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
- . = ALIGN(4);
- } > FLASH_TEXT
-
- .ARM.exidx :
- {
- *(.ARM.exidx*)
- *(.gnu.linkonce.armexidx.*)
- _etext = .; /* define a global symbol at end of code */
- __etext = .; /* define a global symbol at end of code */
- } > FLASH_TEXT
-
- /* used by the startup to initialize data */
- _sidata = .;
-
- .data : AT (_sidata)
- {
- . = ALIGN(4);
- __data_start__ = .; /* create a global symbol at data start */
-
- *(.data*) /* .data* sections */
- *flexspi_nor_flash_ops.o(.text*)
- *fsl_flexspi.o(.text*)
- . = ALIGN(4);
-
- __data_end__ = .; /* define a global symbol at data end */
- } > RAM
-
- /* Uninitialized data section */
- .bss :
- {
- . = ALIGN(4);
- __bss_start__ = .;
-
- *(.bss*)
- *(COMMON)
-
- . = ALIGN(4);
- __bss_end__ = .;
- PROVIDE(end = .);
- } > RAM
-
- .heap :
- {
- . = ALIGN(8);
- _heap_start = .; /* define a global symbol at heap start */
-
- . += _minimum_heap_size;
-
- __HeapLimit = .;
- } > OCRAM
-
- .stack :
- {
- . = ALIGN(8);
- . += _minimum_stack_size;
- } > OCRAM
-
- .ARM.attributes 0 : { *(.ARM.attributes) }
-}
-
-ASSERT(__data_end__ <= ORIGIN(FLASH_TEXT) + LENGTH(FLASH_TEXT), "region FLASH_TEXT overflowed with text and data")
-ASSERT(_estack - _minimum_stack_size >= __HeapLimit, "region OCRAM overflowed with stack and heap")
diff --git a/ports/mimxrt10xx/boards/mimxrt1011-external-flash.ld b/ports/mimxrt10xx/boards/mimxrt1011-external-flash.ld
deleted file mode 100644
index f1b0d8554..000000000
--- a/ports/mimxrt10xx/boards/mimxrt1011-external-flash.ld
+++ /dev/null
@@ -1,123 +0,0 @@
-ENTRY(Reset_Handler)
-
-_minimum_stack_size = 64K;
-_minimum_heap_size = 0;
-
-MEMORY
-{
- FLASH (rx) : ORIGIN = 0x60000000, LENGTH = 8M
- FLASH_CONFIG (rx) : ORIGIN = 0x60000400, LENGTH = 3K
- FLASH_IVT (rx) : ORIGIN = 0x60001000, LENGTH = 4K
- FLASH_ISR (rx) : ORIGIN = 0x60002000, LENGTH = 1K
- FLASH_TEXT (rx) : ORIGIN = 0x60002400, LENGTH = 1015K
- FLASH_FATFS (r) : ORIGIN = 0x60100000, LENGTH = 7M
- RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 32K
- OCRAM (rwx) : ORIGIN = 0x20200000, LENGTH = 64K
-}
-
-_estack = ORIGIN(OCRAM) + LENGTH(OCRAM);
-_bootloader_dbl_tap = 0;
-
-__fatfs_flash_start_addr = ORIGIN(FLASH_FATFS);
-__fatfs_flash_length = LENGTH(FLASH_FATFS);
-
-__RAM_VECTOR_TABLE_SIZE_BYTES = 0;
-
-SECTIONS
-{
- .flash_config :
- {
- . = ALIGN(4);
- KEEP(* (.boot_hdr.conf))
- . = ALIGN(4);
- } > FLASH_CONFIG
-
- .ivt :
- {
- . = ALIGN(4);
- KEEP(* (.boot_hdr.ivt))
- KEEP(* (.boot_hdr.boot_data))
- KEEP(* (.boot_hdr.dcd_data))
- . = ALIGN(4);
- } > FLASH_IVT
-
- .interrupts :
- {
- __VECTOR_TABLE = .;
- __VECTOR_RAM = .;
-
- . = ALIGN(4);
- KEEP(*(.isr_vector)) /* Startup code */
- . = ALIGN(4);
- } > FLASH_ISR
-
- .text :
- {
- . = ALIGN(4);
- *(EXCLUDE_FILE(
- *flexspi_nor_flash_ops.o
- *fsl_flexspi.o
- ) .text*) /* .text* sections (code) */
- *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
- . = ALIGN(4);
- } > FLASH_TEXT
-
- .ARM.exidx :
- {
- *(.ARM.exidx*)
- *(.gnu.linkonce.armexidx.*)
- _etext = .; /* define a global symbol at end of code */
- __etext = .; /* define a global symbol at end of code */
- } > FLASH_TEXT
-
- /* used by the startup to initialize data */
- _sidata = .;
-
- .data : AT (_sidata)
- {
- . = ALIGN(4);
- __data_start__ = .; /* create a global symbol at data start */
-
- *(.data*) /* .data* sections */
- *flexspi_nor_flash_ops.o(.text*)
- *fsl_flexspi.o(.text*)
- . = ALIGN(4);
-
- __data_end__ = .; /* define a global symbol at data end */
- } > RAM
-
- /* Uninitialized data section */
- .bss :
- {
- . = ALIGN(4);
- __bss_start__ = .;
-
- *(.bss*)
- *(COMMON)
-
- . = ALIGN(4);
- __bss_end__ = .;
- PROVIDE(end = .);
- } > RAM
-
- .heap :
- {
- . = ALIGN(8);
- _heap_start = .; /* define a global symbol at heap start */
-
- . += _minimum_heap_size;
-
- __HeapLimit = .;
- } > OCRAM
-
- .stack :
- {
- . = ALIGN(8);
- . += _minimum_stack_size;
- } > OCRAM
-
- .ARM.attributes 0 : { *(.ARM.attributes) }
-}
-
-ASSERT(__data_end__ <= ORIGIN(FLASH_TEXT) + LENGTH(FLASH_TEXT), "region FLASH_TEXT overflowed with text and data")
-ASSERT(_estack - _minimum_stack_size >= __HeapLimit, "region OCRAM overflowed with stack and heap")
diff --git a/ports/mimxrt10xx/boards/mimxrt1062-bootloader-external-flash.ld b/ports/mimxrt10xx/boards/mimxrt1062-bootloader-external-flash.ld
deleted file mode 100644
index 16442607f..000000000
--- a/ports/mimxrt10xx/boards/mimxrt1062-bootloader-external-flash.ld
+++ /dev/null
@@ -1,106 +0,0 @@
-ENTRY(Reset_Handler)
-
-_minimum_stack_size = 64K;
-_minimum_heap_size = 0;
-
-MEMORY
-{
- FLASH (rx) : ORIGIN = 0x60000000, LENGTH = 8M
- FLASH_BOOTLOADER (rx) : ORIGIN = 0x60000000, LENGTH = 48K
- FLASH_ISR (rx) : ORIGIN = 0x6000C000, LENGTH = 1K
- FLASH_TEXT (rx) : ORIGIN = 0x6000C400, LENGTH = 975K
- FLASH_FATFS (r) : ORIGIN = 0x60100000, LENGTH = 7M
- RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 128K
- OCRAM (rwx) : ORIGIN = 0x20200000, LENGTH = 768K
-}
-
-_estack = ORIGIN(OCRAM) + LENGTH(OCRAM);
-_bootloader_dbl_tap = ORIGIN(RAM) + LENGTH(RAM) - 4;
-
-__fatfs_flash_start_addr = ORIGIN(FLASH_FATFS);
-__fatfs_flash_length = LENGTH(FLASH_FATFS);
-
-__RAM_VECTOR_TABLE_SIZE_BYTES = 0;
-
-SECTIONS
-{
- .interrupts :
- {
- __VECTOR_TABLE = .;
- __VECTOR_RAM = .;
-
- . = ALIGN(4);
- KEEP(*(.isr_vector)) /* Startup code */
- . = ALIGN(4);
- } > FLASH_ISR
-
- .text :
- {
- . = ALIGN(4);
- *(EXCLUDE_FILE(
- *flexspi_nor_flash_ops.o
- *fsl_flexspi.o
- ) .text*) /* .text* sections (code) */
- *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
- . = ALIGN(4);
- } > FLASH_TEXT
-
- .ARM.exidx :
- {
- *(.ARM.exidx*)
- *(.gnu.linkonce.armexidx.*)
- _etext = .; /* define a global symbol at end of code */
- __etext = .; /* define a global symbol at end of code */
- } > FLASH_TEXT
-
- /* used by the startup to initialize data */
- _sidata = .;
-
- .data : AT (_sidata)
- {
- . = ALIGN(4);
- __data_start__ = .; /* create a global symbol at data start */
-
- *(.data*) /* .data* sections */
- *flexspi_nor_flash_ops.o(.text*)
- *fsl_flexspi.o(.text*)
- . = ALIGN(4);
-
- __data_end__ = .; /* define a global symbol at data end */
- } > RAM
-
- /* Uninitialized data section */
- .bss :
- {
- . = ALIGN(4);
- __bss_start__ = .;
-
- *(.bss*)
- *(COMMON)
-
- . = ALIGN(4);
- __bss_end__ = .;
- PROVIDE(end = .);
- } > RAM
-
- .heap :
- {
- . = ALIGN(8);
- _heap_start = .; /* define a global symbol at heap start */
-
- . += _minimum_heap_size;
-
- __HeapLimit = .;
- } > OCRAM
-
- .stack :
- {
- . = ALIGN(8);
- . += _minimum_stack_size;
- } > OCRAM
-
- .ARM.attributes 0 : { *(.ARM.attributes) }
-}
-
-ASSERT(__data_end__ <= ORIGIN(FLASH_TEXT) + LENGTH(FLASH_TEXT), "region FLASH_TEXT overflowed with text and data")
-ASSERT(_estack - _minimum_stack_size >= __HeapLimit, "region OCRAM overflowed with stack and heap")
diff --git a/ports/mimxrt10xx/boards/teensy40/board.c b/ports/mimxrt10xx/boards/teensy40/board.c
new file mode 100644
index 000000000..52dd498b3
--- /dev/null
+++ b/ports/mimxrt10xx/boards/teensy40/board.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Artur Pacholec
+ *
+ * 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 "boards/board.h"
+#include "mpconfigboard.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/mimxrt10xx/boards/teensy40/board.ld b/ports/mimxrt10xx/boards/teensy40/board.ld
new file mode 100644
index 000000000..8f19810a3
--- /dev/null
+++ b/ports/mimxrt10xx/boards/teensy40/board.ld
@@ -0,0 +1 @@
+_ld_reserved_flash_size = 4K;
diff --git a/ports/mimxrt10xx/boards/teensy40/flash_config.c b/ports/mimxrt10xx/boards/teensy40/flash_config.c
new file mode 100644
index 000000000..426deb884
--- /dev/null
+++ b/ports/mimxrt10xx/boards/teensy40/flash_config.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_flexspi_nor_boot.h"
+#include "fsl_flexspi_nor_config.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.xip_device"
+#endif
+
+__attribute__((section(".boot_hdr.ivt")))
+/*************************************
+ * IVT Data
+ *************************************/
+const ivt image_vector_table = {
+ IVT_HEADER, /* IVT Header */
+ IMAGE_ENTRY_ADDRESS, /* Image Entry Function */
+ IVT_RSVD, /* Reserved = 0 */
+ (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */
+ (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */
+ (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */
+ (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */
+ IVT_RSVD /* Reserved = 0 */
+};
+
+__attribute__((section(".boot_hdr.boot_data")))
+/*************************************
+ * Boot Data
+ *************************************/
+const BOOT_DATA_T boot_data = {
+ FLASH_BASE, /* boot start location */
+ FLASH_SIZE, /* size */
+ PLUGIN_FLAG, /* Plugin flag*/
+ 0xFFFFFFFF /* empty - extra data word */
+};
+
+__attribute__((section(".boot_hdr.conf")))
+// Values copied from https://github.com/PaulStoffregen/cores/blob/ddb23fa5d97dac763bc06e11b9b41f026bd51f0a/teensy4/bootdata.c#L39
+const flexspi_nor_config_t qspiflash_config = {
+ .memConfig =
+ {
+ .tag = FLEXSPI_CFG_BLK_TAG,
+ .version = FLEXSPI_CFG_BLK_VERSION,
+ .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
+ .csHoldTime = 1u,
+ .csSetupTime = 2u,
+ // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock
+ .deviceType = kFlexSpiDeviceType_SerialNOR,
+ .sflashPadType = kSerialFlash_4Pads,
+ .serialClkFreq = kFlexSpiSerialClk_60MHz, // 03
+ .sflashA1Size = FLASH_SIZE,
+ .lookupTable =
+ {
+ // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1)
+ // (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) |
+ // FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
+ // Read LUTs
+ FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
+ FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
+ 0,
+ 0,
+
+ 0x24040405,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000406,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x08180420,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x081804D8,
+ 0,
+ 0,
+ 0,
+
+ 0x08180402,
+ 0x00002004,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000460,
+ },
+ },
+ .pageSize = 256u,
+ .sectorSize = 4u * 1024u,
+ .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz,
+ .blockSize = 0x00010000,
+ .isUniformBlockSize = false,
+};
diff --git a/ports/mimxrt10xx/boards/teensy40/mpconfigboard.h b/ports/mimxrt10xx/boards/teensy40/mpconfigboard.h
new file mode 100644
index 000000000..718d9b967
--- /dev/null
+++ b/ports/mimxrt10xx/boards/teensy40/mpconfigboard.h
@@ -0,0 +1,18 @@
+#define MICROPY_HW_BOARD_NAME "Teensy 4.0"
+#define MICROPY_HW_MCU_NAME "IMXRT1062DVJ6A"
+
+// If you change this, then make sure to update the linker scripts as well to
+// make sure you don't overwrite code
+#define CIRCUITPY_INTERNAL_NVM_SIZE 0
+
+#define BOARD_FLASH_SIZE (2 * 1024 * 1024)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_GPIO_AD_B1_00)
+#define DEFAULT_I2C_BUS_SDA (&pin_GPIO_AD_B1_01)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_GPIO_B0_03)
+#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO_B0_02)
+#define DEFAULT_SPI_BUS_MISO (&pin_GPIO_B0_01)
+
+#define DEFAULT_UART_BUS_RX (&pin_GPIO_AD_B0_03)
+#define DEFAULT_UART_BUS_TX (&pin_GPIO_AD_B0_02)
diff --git a/ports/mimxrt10xx/boards/teensy40/mpconfigboard.mk b/ports/mimxrt10xx/boards/teensy40/mpconfigboard.mk
new file mode 100644
index 000000000..7900d327a
--- /dev/null
+++ b/ports/mimxrt10xx/boards/teensy40/mpconfigboard.mk
@@ -0,0 +1,8 @@
+USB_VID = 0x239A
+USB_PID = 0x8086
+USB_PRODUCT = "Teensy 4.0"
+USB_MANUFACTURER = "PJRC"
+
+CHIP_VARIANT = MIMXRT1062DVJ6A
+CHIP_FAMILY = MIMXRT1062
+FLASH = W25Q16JV
diff --git a/ports/mimxrt10xx/boards/teensy40/pins.c b/ports/mimxrt10xx/boards/teensy40/pins.c
new file mode 100644
index 000000000..9066ce0d2
--- /dev/null
+++ b/ports/mimxrt10xx/boards/teensy40/pins.c
@@ -0,0 +1,87 @@
+#include "shared-bindings/board/__init__.h"
+
+#include "boards/board.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ // With USB on left. Bottom edge.
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO_AD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO_AD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_GPIO_AD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO_AD_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO_AD_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_GPIO_AD_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO_EMC_04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO_EMC_05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO_EMC_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO_EMC_08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO_B0_10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO_B1_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO_B1_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO_B0_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO_B0_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO_B0_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO_B0_01) },
+
+ // Top edge
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO_AD_B1_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO_AD_B1_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO_AD_B1_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO_AD_B1_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO_AD_B1_07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO_AD_B1_07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO_AD_B1_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO_AD_B1_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SDA0), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCL0), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO_AD_B1_10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO_AD_B1_10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO_AD_B1_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO_AD_B1_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO_AD_B1_08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO_AD_B1_08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO_AD_B1_09) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO_AD_B1_09) },
+
+ // Back side
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_GPIO_AD_B0_12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_GPIO_AD_B0_12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO_AD_B0_13) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_GPIO_AD_B0_13) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO_AD_B1_14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO_AD_B1_14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO_AD_B1_15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A13), MP_ROM_PTR(&pin_GPIO_AD_B1_15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_GPIO_EMC_32) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_GPIO_EMC_31) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_GPIO_EMC_37) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D31), MP_ROM_PTR(&pin_GPIO_EMC_36) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO_B0_12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO_EMC_07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_GPIO_SD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_DAT1), MP_ROM_PTR(&pin_GPIO_SD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO_SD_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_DAT0), MP_ROM_PTR(&pin_GPIO_SD_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO_SD_B0_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO_SD_B0_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO_SD_B0_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CMD), MP_ROM_PTR(&pin_GPIO_SD_B0_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO_SD_B0_04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_DAT3), MP_ROM_PTR(&pin_GPIO_SD_B0_04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO_SD_B0_05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_DAT2), MP_ROM_PTR(&pin_GPIO_SD_B0_05) },
+
+ { 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_global_dict_table);
diff --git a/ports/mimxrt10xx/common-hal/busio/I2C.c b/ports/mimxrt10xx/common-hal/busio/I2C.c
index 3c555df45..2de996f9a 100644
--- a/ports/mimxrt10xx/common-hal/busio/I2C.c
+++ b/ports/mimxrt10xx/common-hal/busio/I2C.c
@@ -98,11 +98,13 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
LPI2C_MasterInit(self->i2c, &config, I2C_CLOCK_FREQ);
+#if CIRCUITPY_REQUIRE_I2C_PULLUPS
// if (!gpio_get_pin_level(sda->number) || !gpio_get_pin_level(scl->number)) {
// reset_pin_number(sda->number);
// reset_pin_number(scl->number);
// mp_raise_RuntimeError(translate("SDA or SCL needs a pull up"));
// }
+#endif
claim_pin(self->sda_pin->pin);
claim_pin(self->scl_pin->pin);
diff --git a/ports/mimxrt10xx/common-hal/busio/UART.c b/ports/mimxrt10xx/common-hal/busio/UART.c
index a4819798b..4fd7afecb 100644
--- a/ports/mimxrt10xx/common-hal/busio/UART.c
+++ b/ports/mimxrt10xx/common-hal/busio/UART.c
@@ -53,8 +53,8 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) {
IOMUXC_SetPinConfig(0, 0, 0, 0,
periph->pin->cfg_reg,
IOMUXC_SW_PAD_CTL_PAD_HYS(0)
- | IOMUXC_SW_PAD_CTL_PAD_PUS(0)
- | IOMUXC_SW_PAD_CTL_PAD_PUE(0)
+ | IOMUXC_SW_PAD_CTL_PAD_PUS(1)
+ | IOMUXC_SW_PAD_CTL_PAD_PUE(1)
| IOMUXC_SW_PAD_CTL_PAD_PKE(1)
| IOMUXC_SW_PAD_CTL_PAD_ODE(0)
| IOMUXC_SW_PAD_CTL_PAD_SPEED(1)
@@ -72,9 +72,11 @@ void LPUART_UserCallback(LPUART_Type *base, lpuart_handle_t *handle, status_t st
}
void common_hal_busio_uart_construct(busio_uart_obj_t *self,
- const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
- uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
- uint16_t receiver_buffer_size) {
+ const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx,
+ const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
+ const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
+ uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
+ mp_float_t timeout, uint16_t receiver_buffer_size) {
// TODO: Allow none rx or tx
@@ -111,12 +113,60 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
if(self->rx_pin == NULL || self->tx_pin == NULL) {
mp_raise_RuntimeError(translate("Invalid UART pin selection"));
- } else {
- self->uart = mcu_uart_banks[self->tx_pin->bank_idx - 1];
}
+ // Filter for sane settings for RS485
+ if (rs485_dir != mp_const_none) {
+ if ((rts != mp_const_none) || (cts != mp_const_none)) {
+ mp_raise_ValueError(translate("Cannot specify RTS or CTS in RS485 mode"));
+ }
+ // For IMXRT the RTS pin is used for RS485 direction
+ rts = rs485_dir;
+ }
+ else {
+ if (rs485_invert) {
+ mp_raise_ValueError(translate("RS485 inversion specified when not in RS485 mode"));
+ }
+ }
+
+ // Now check for RTS/CTS (or overloaded RS485 direction) pin(s)
+ const uint32_t rts_count = sizeof(mcu_uart_rts_list) / sizeof(mcu_periph_obj_t);
+ const uint32_t cts_count = sizeof(mcu_uart_cts_list) / sizeof(mcu_periph_obj_t);
+
+ if (rts != mp_const_none) {
+ for (uint32_t i=0; i < rts_count; ++i) {
+ if (mcu_uart_rts_list[i].bank_idx == self->rx_pin->bank_idx) {
+ if (mcu_uart_rts_list[i].pin == rts) {
+ self->rts_pin = &mcu_uart_rts_list[i];
+ break;
+ }
+ }
+ }
+ if (self->rts_pin == NULL)
+ mp_raise_ValueError(translate("Selected RTS pin not valid"));
+ }
+
+ if (cts != mp_const_none) {
+ for (uint32_t i=0; i < cts_count; ++i) {
+ if (mcu_uart_cts_list[i].bank_idx == self->rx_pin->bank_idx) {
+ if (mcu_uart_cts_list[i].pin == cts) {
+ self->cts_pin = &mcu_uart_cts_list[i];
+ break;
+ }
+ }
+ }
+ if (self->cts_pin == NULL)
+ mp_raise_ValueError(translate("Selected CTS pin not valid"));
+ }
+
+ self->uart = mcu_uart_banks[self->tx_pin->bank_idx - 1];
+
config_periph_pin(self->rx_pin);
config_periph_pin(self->tx_pin);
+ if (self->rts_pin)
+ config_periph_pin(self->rts_pin);
+ if (self->cts_pin)
+ config_periph_pin(self->cts_pin);
lpuart_config_t config = { 0 };
LPUART_GetDefaultConfig(&config);
@@ -125,10 +175,27 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
config.baudRate_Bps = self->baudrate;
config.enableTx = self->tx_pin != NULL;
config.enableRx = self->rx_pin != NULL;
+ config.enableRxRTS = self->rts_pin != NULL;
+ config.enableTxCTS = self->cts_pin != NULL;
+ if (self->rts_pin != NULL)
+ claim_pin(self->rts_pin->pin);
+ if (self->cts_pin != NULL)
+ claim_pin(self->cts_pin->pin);
LPUART_Init(self->uart, &config, UART_CLOCK_FREQ);
- claim_pin(self->tx_pin->pin);
+ // Before we init, setup RS485 direction pin
+ // ..unfortunately this isn't done by the driver library
+ uint32_t modir = (self->uart->MODIR) & ~(LPUART_MODIR_TXRTSPOL_MASK | LPUART_MODIR_TXRTSE_MASK);
+ if (rs485_dir != mp_const_none) {
+ modir |= LPUART_MODIR_TXRTSE_MASK;
+ if (rs485_invert)
+ modir |= LPUART_MODIR_TXRTSPOL_MASK;
+ }
+ self->uart->MODIR = modir;
+
+ if (self->tx_pin != NULL)
+ claim_pin(self->tx_pin->pin);
if (self->rx_pin != NULL) {
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
@@ -203,7 +270,9 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
LPUART_TransferAbortReceive(self->uart, &self->handle);
}
- return len - self->handle.rxDataSize;
+ // The only place we can reliably tell how many bytes have been received is from the current
+ // wp in the handle (because the abort nukes rxDataSize, and reading it before abort is a race.)
+ return self->handle.rxData-data;
}
// Write characters.
diff --git a/ports/mimxrt10xx/common-hal/displayio/ParallelBus.c b/ports/mimxrt10xx/common-hal/displayio/ParallelBus.c
new file mode 100644
index 000000000..87fc511af
--- /dev/null
+++ b/ports/mimxrt10xx/common-hal/displayio/ParallelBus.c
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Artur Pacholec
+ *
+ * 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/displayio/ParallelBus.h"
+
+#include <stdint.h>
+
+#include "common-hal/microcontroller/Pin.h"
+#include "py/runtime.h"
+#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/microcontroller/__init__.h"
+
+#include "tick.h"
+
+void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self,
+ const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select,
+ const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) {
+
+ mp_raise_NotImplementedError(translate("ParallelBus not yet supported"));
+}
+
+void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self) {
+
+}
+
+bool common_hal_displayio_parallelbus_reset(mp_obj_t obj) {
+ return false;
+}
+
+bool common_hal_displayio_parallelbus_bus_free(mp_obj_t obj) {
+ return false;
+}
+
+bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) {
+
+ return false;
+}
+
+void common_hal_displayio_parallelbus_send(mp_obj_t obj, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length) {
+
+}
+
+void common_hal_displayio_parallelbus_end_transaction(mp_obj_t obj) {
+
+}
diff --git a/ports/mimxrt10xx/common-hal/displayio/ParallelBus.h b/ports/mimxrt10xx/common-hal/displayio/ParallelBus.h
new file mode 100644
index 000000000..845e44df0
--- /dev/null
+++ b/ports/mimxrt10xx/common-hal/displayio/ParallelBus.h
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Artur Pacholec
+ *
+ * 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_MIMXRT10XX_COMMON_HAL_DISPLAYIO_PARALLELBUS_H
+#define MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_DISPLAYIO_PARALLELBUS_H
+
+#include "common-hal/digitalio/DigitalInOut.h"
+
+typedef struct {
+ mp_obj_base_t base;
+} displayio_parallelbus_obj_t;
+
+#endif // MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_DISPLAYIO_PARALLELBUS_H
diff --git a/ports/mimxrt10xx/common-hal/microcontroller/Pin.c b/ports/mimxrt10xx/common-hal/microcontroller/Pin.c
index 04dd99739..21e61d29d 100644
--- a/ports/mimxrt10xx/common-hal/microcontroller/Pin.c
+++ b/ports/mimxrt10xx/common-hal/microcontroller/Pin.c
@@ -224,3 +224,7 @@ bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) {
void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
// reset_pin_number(pin->number);
}
+
+void common_hal_never_reset_pin(const mcu_pin_obj_t* pin) {
+// never_reset_pin_number(pin->port, pin->number);
+}
diff --git a/ports/mimxrt10xx/common-hal/microcontroller/Processor.c b/ports/mimxrt10xx/common-hal/microcontroller/Processor.c
index 23493f766..0c8131ef4 100644
--- a/ports/mimxrt10xx/common-hal/microcontroller/Processor.c
+++ b/ports/mimxrt10xx/common-hal/microcontroller/Processor.c
@@ -58,8 +58,13 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
OCOTP_Init(OCOTP, CLOCK_GetFreq(kCLOCK_IpgClk));
// Reads shadow registers 0x01 - 0x04 (Configuration and Manufacturing Info)
- for (int i = 0; i < 4; ++i)
- ((uint32_t*) raw_id)[i] = OCOTP_ReadFuseShadowRegister(OCOTP, i + 1);
-
+ // into 8 bit wide destination, avoiding punning.
+ for (int i = 0; i < 4; ++i) {
+ uint32_t wr = OCOTP_ReadFuseShadowRegister(OCOTP, i + 1);
+ for (int j = 0; j < 4; j++) {
+ raw_id[i*4+j] = wr & 0xff;
+ wr >>= 8;
+ }
+ }
OCOTP_Deinit(OCOTP);
}
diff --git a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c
index 68de3a890..a9f4c740f 100644
--- a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c
+++ b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c
@@ -72,10 +72,10 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
}
// Pretend to be the first of the two reset presses needed to enter the
// bootloader. That way one reset will end in the bootloader.
- _bootloader_dbl_tap = DBL_TAP_MAGIC;
+ SNVS->LPGPR[0] = DBL_TAP_MAGIC;
} else {
// Set up the default.
- _bootloader_dbl_tap = DBL_TAP_MAGIC_QUICK_BOOT;
+ SNVS->LPGPR[0] = DBL_TAP_MAGIC_QUICK_BOOT;
}
if (runmode == RUNMODE_SAFE_MODE) {
safe_mode_on_next_reset(PROGRAMMATIC_SAFE_MODE);
@@ -229,6 +229,7 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_GPIO_AD_B1_13), MP_ROM_PTR(&pin_GPIO_AD_B1_13) },
{ MP_ROM_QSTR(MP_QSTR_GPIO_AD_B1_14), MP_ROM_PTR(&pin_GPIO_AD_B1_14) },
{ MP_ROM_QSTR(MP_QSTR_GPIO_AD_B1_15), MP_ROM_PTR(&pin_GPIO_AD_B1_15) },
+ #ifdef MIMXRT1062_SERIES
{ MP_ROM_QSTR(MP_QSTR_GPIO_B0_00), MP_ROM_PTR(&pin_GPIO_B0_00) },
{ MP_ROM_QSTR(MP_QSTR_GPIO_B0_01), MP_ROM_PTR(&pin_GPIO_B0_01) },
{ MP_ROM_QSTR(MP_QSTR_GPIO_B0_02), MP_ROM_PTR(&pin_GPIO_B0_02) },
@@ -261,6 +262,7 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_GPIO_B1_13), MP_ROM_PTR(&pin_GPIO_B1_13) },
{ MP_ROM_QSTR(MP_QSTR_GPIO_B1_14), MP_ROM_PTR(&pin_GPIO_B1_14) },
{ MP_ROM_QSTR(MP_QSTR_GPIO_B1_15), MP_ROM_PTR(&pin_GPIO_B1_15) },
+ #endif
{ MP_ROM_QSTR(MP_QSTR_GPIO_SD_B0_00), MP_ROM_PTR(&pin_GPIO_SD_B0_00) },
{ MP_ROM_QSTR(MP_QSTR_GPIO_SD_B0_01), MP_ROM_PTR(&pin_GPIO_SD_B0_01) },
{ MP_ROM_QSTR(MP_QSTR_GPIO_SD_B0_02), MP_ROM_PTR(&pin_GPIO_SD_B0_02) },
diff --git a/ports/mimxrt10xx/common-hal/time/__init__.c b/ports/mimxrt10xx/common-hal/time/__init__.c
index 2d82b3d1a..524e31d1a 100644
--- a/ports/mimxrt10xx/common-hal/time/__init__.c
+++ b/ports/mimxrt10xx/common-hal/time/__init__.c
@@ -30,10 +30,20 @@
#include "supervisor/shared/tick.h"
-inline uint64_t common_hal_time_monotonic() {
+#include "tick.h"
+
+inline uint64_t common_hal_time_monotonic(void) {
return supervisor_ticks_ms64();
}
+uint64_t common_hal_time_monotonic_ns(void) {
+ uint64_t ms;
+ uint32_t us_until_ms;
+ current_tick(&ms, &us_until_ms);
+ // us counts down.
+ return 1000 * (ms * 1000 + (1000 - us_until_ms));
+}
+
void common_hal_time_delay_ms(uint32_t delay) {
mp_hal_delay_ms(delay);
}
diff --git a/ports/mimxrt10xx/linking/chip_family/MIMXRT1011.ld b/ports/mimxrt10xx/linking/chip_family/MIMXRT1011.ld
new file mode 100644
index 000000000..0d0beebaa
--- /dev/null
+++ b/ports/mimxrt10xx/linking/chip_family/MIMXRT1011.ld
@@ -0,0 +1,2 @@
+ram_size = 128K;
+flash_config_location = 0x60000400;
diff --git a/ports/mimxrt10xx/linking/chip_family/MIMXRT1021.ld b/ports/mimxrt10xx/linking/chip_family/MIMXRT1021.ld
new file mode 100644
index 000000000..21f2ea872
--- /dev/null
+++ b/ports/mimxrt10xx/linking/chip_family/MIMXRT1021.ld
@@ -0,0 +1,2 @@
+ram_size = 256K;
+flash_config_location = 0x60000000;
diff --git a/ports/mimxrt10xx/linking/chip_family/MIMXRT1062.ld b/ports/mimxrt10xx/linking/chip_family/MIMXRT1062.ld
new file mode 100644
index 000000000..e07c5c2c3
--- /dev/null
+++ b/ports/mimxrt10xx/linking/chip_family/MIMXRT1062.ld
@@ -0,0 +1,2 @@
+ram_size = 1M;
+flash_config_location = 0x60000000;
diff --git a/ports/mimxrt10xx/linking/common.ld b/ports/mimxrt10xx/linking/common.ld
new file mode 100644
index 000000000..10568bfb8
--- /dev/null
+++ b/ports/mimxrt10xx/linking/common.ld
@@ -0,0 +1,154 @@
+/* Template for iMX RT 10xx linking. This is the last of four linker scripts passed in.
+
+The first three provide variables for this one.
+
+Boards can setup reserved flash with _ld_reserved_flash_size in board.ld. */
+
+ENTRY(Reset_Handler)
+
+code_size = 1M;
+_ld_default_stack_size = 20K;
+
+/* Default reserved flash to nothing. */
+_ld_reserved_flash_size = DEFINED(_ld_reserved_flash_size) ? _ld_reserved_flash_size : 0K ;
+
+MEMORY
+{
+ /* These next two sections are included in place of a bootloader. If a UF2 is used to load, it
+ will ignore these two sections because it lives there. */
+ /* This is the first block and is read so that the bootrom knows the optimal way to interface with the flash chip. */
+ FLASH_CONFIG (rx) : ORIGIN = flash_config_location, LENGTH = 512
+ /* This can't move because the bootrom looks at this address. */
+ FLASH_IVT (rx) : ORIGIN = 0x60001000, LENGTH = 4K
+ /* Place the ISRs 48k in to leave room for the bootloader when it is available. */
+ FLASH_TEXT (rx) : ORIGIN = 0x6000C000, LENGTH = code_size - 48K
+ FLASH_FATFS (r) : ORIGIN = 0x60100000, LENGTH = _ld_flash_size - code_size - _ld_reserved_flash_size
+ /* Teensy uses the last bit of flash for recovery. */
+ RESERVED_FLASH : ORIGIN = 0x60100000 + _ld_flash_size - _ld_reserved_flash_size, LENGTH = _ld_reserved_flash_size
+ OCRAM (rwx) : ORIGIN = 0x20200000, LENGTH = ram_size - 64K
+ DTCM (x) : ORIGIN = 0x20000000, LENGTH = 32K
+ ITCM (x) : ORIGIN = 0x00000000, LENGTH = 32K
+}
+
+__data_start__ = 0;
+__data_end__ = 0;
+_start = 0;
+
+SECTIONS
+{
+ .flash_config :
+ {
+ . = ALIGN(4);
+ KEEP(* (.boot_hdr.conf))
+ . = ALIGN(4);
+ } > FLASH_CONFIG
+
+ .ivt :
+ {
+ . = ALIGN(4);
+ KEEP(* (.boot_hdr.ivt))
+ KEEP(* (.boot_hdr.boot_data))
+ KEEP(* (.boot_hdr.dcd_data))
+ . = ALIGN(4);
+ } > FLASH_IVT
+ image_vector_table = LOADADDR(.ivt);
+
+ .text :
+ {
+ . = ALIGN(4);
+ __VECTOR_TABLE = .;
+ __VECTOR_RAM = .;
+ _ld_isr_table = .;
+
+ KEEP(*(.isr_vector)) /* Startup code */
+ *(EXCLUDE_FILE(
+ *flexspi_nor_flash_ops.o
+ *fsl_flexspi.o
+ ) .text*) /* .text* sections (code) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ . = ALIGN(4);
+ } > FLASH_TEXT
+
+ .ARM.exidx :
+ {
+ *(.ARM.exidx*)
+ *(.gnu.linkonce.armexidx.*)
+ _etext = .; /* define a global symbol at end of code */
+ __etext = .; /* define a global symbol at end of code */
+ } > FLASH_TEXT
+
+ _ld_filesystem_start = ORIGIN(FLASH_FATFS);
+ _ld_filesystem_end = _ld_filesystem_start + LENGTH(FLASH_FATFS);
+
+ .data :
+ {
+ . = ALIGN(4);
+ *(.data*) /* .data* sections */
+ *flexspi_nor_flash_ops.o(.text*)
+ *fsl_flexspi.o(.text*)
+ . = ALIGN(4);
+ } > OCRAM AT> FLASH_TEXT
+ _ld_ocram_data_destination = ADDR(.data);
+ _ld_ocram_data_flash_copy = LOADADDR(.data);
+ _ld_ocram_data_size = SIZEOF(.data);
+
+ /* Uninitialized data section */
+ .bss :
+ {
+ . = ALIGN(4);
+
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ } > OCRAM
+ _ld_ocram_bss_start = ADDR(.bss);
+ _ld_ocram_bss_size = SIZEOF(.bss);
+ _ld_heap_start = _ld_ocram_bss_start + _ld_ocram_bss_size;
+ _ld_heap_end = ORIGIN(OCRAM) + LENGTH(OCRAM);
+
+ .itcm :
+ {
+ . = ALIGN(4);
+
+ *(.itcm.*)
+
+ . = ALIGN(4);
+ } > ITCM AT> FLASH_TEXT
+ _ld_itcm_destination = ADDR(.itcm);
+ _ld_itcm_flash_copy = LOADADDR(.itcm);
+ _ld_itcm_size = SIZEOF(.itcm);
+
+ .dtcm_data :
+ {
+ . = ALIGN(4);
+
+ *(.dtcm_data.*)
+
+ . = ALIGN(4);
+ } > DTCM AT> FLASH_TEXT
+ _ld_dtcm_data_destination = ADDR(.dtcm_data);
+ _ld_dtcm_data_flash_copy = LOADADDR(.dtcm_data);
+ _ld_dtcm_data_size = SIZEOF(.dtcm_data);
+
+ .dtcm_bss :
+ {
+ . = ALIGN(4);
+
+ *(.dtcm_bss.*)
+
+ . = ALIGN(4);
+ } > DTCM AT> DTCM
+ _ld_dtcm_bss_start = ADDR(.dtcm_bss);
+ _ld_dtcm_bss_size = SIZEOF(.dtcm_bss);
+
+ .stack :
+ {
+ . = ALIGN(8);
+ _ld_stack_bottom = .;
+ . += _ld_default_stack_size;
+ } > DTCM
+ _ld_stack_top = ORIGIN(DTCM) + LENGTH(DTCM);
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
diff --git a/ports/mimxrt10xx/linking/flash/AT25SF128A.ld b/ports/mimxrt10xx/linking/flash/AT25SF128A.ld
new file mode 100644
index 000000000..205d9dd83
--- /dev/null
+++ b/ports/mimxrt10xx/linking/flash/AT25SF128A.ld
@@ -0,0 +1 @@
+_ld_flash_size = 16M;
diff --git a/ports/mimxrt10xx/linking/flash/IS25LP064A.ld b/ports/mimxrt10xx/linking/flash/IS25LP064A.ld
new file mode 100644
index 000000000..53d296ec8
--- /dev/null
+++ b/ports/mimxrt10xx/linking/flash/IS25LP064A.ld
@@ -0,0 +1 @@
+_ld_flash_size = 8M;
diff --git a/ports/mimxrt10xx/linking/flash/IS25WP064A.ld b/ports/mimxrt10xx/linking/flash/IS25WP064A.ld
new file mode 100644
index 000000000..53d296ec8
--- /dev/null
+++ b/ports/mimxrt10xx/linking/flash/IS25WP064A.ld
@@ -0,0 +1 @@
+_ld_flash_size = 8M;
diff --git a/ports/mimxrt10xx/linking/flash/W25Q16JV.ld b/ports/mimxrt10xx/linking/flash/W25Q16JV.ld
new file mode 100644
index 000000000..9ce06b44a
--- /dev/null
+++ b/ports/mimxrt10xx/linking/flash/W25Q16JV.ld
@@ -0,0 +1 @@
+_ld_flash_size = 2M;
diff --git a/ports/mimxrt10xx/linking/flash/W25Q32JV.ld b/ports/mimxrt10xx/linking/flash/W25Q32JV.ld
new file mode 100644
index 000000000..3fa395c66
--- /dev/null
+++ b/ports/mimxrt10xx/linking/flash/W25Q32JV.ld
@@ -0,0 +1 @@
+_ld_flash_size = 4M;
diff --git a/ports/mimxrt10xx/linking/flash/W25Q64JV.ld b/ports/mimxrt10xx/linking/flash/W25Q64JV.ld
new file mode 100644
index 000000000..53d296ec8
--- /dev/null
+++ b/ports/mimxrt10xx/linking/flash/W25Q64JV.ld
@@ -0,0 +1 @@
+_ld_flash_size = 8M;
diff --git a/ports/mimxrt10xx/mpconfigport.h b/ports/mimxrt10xx/mpconfigport.h
index 47b793fed..745c12f7d 100644
--- a/ports/mimxrt10xx/mpconfigport.h
+++ b/ports/mimxrt10xx/mpconfigport.h
@@ -28,11 +28,17 @@
#ifndef __INCLUDED_MPCONFIGPORT_H
#define __INCLUDED_MPCONFIGPORT_H
+#include <stdint.h>
+
#define MICROPY_PY_SYS_PLATFORM "NXP IMXRT10XX"
#define SPI_FLASH_MAX_BAUDRATE 24000000
+extern uint8_t _ld_filesystem_start;
+extern uint8_t _ld_filesystem_end;
+extern uint8_t _ld_default_stack_size;
+
// 20kiB stack
-#define CIRCUITPY_DEFAULT_STACK_SIZE 0x5000
+#define CIRCUITPY_DEFAULT_STACK_SIZE ((uint32_t) &_ld_default_stack_size)
#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0)
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (0)
#define MICROPY_PY_FUNCTION_ATTRS (0)
@@ -40,6 +46,10 @@
#define MICROPY_PY_UJSON (1)
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0)
+
+#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR ((uint32_t) &_ld_filesystem_start)
+#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE ((uint32_t) (&_ld_filesystem_end - &_ld_filesystem_start))
+
#include "py/circuitpy_mpconfig.h"
#define MICROPY_PORT_ROOT_POINTERS \
diff --git a/ports/mimxrt10xx/mpconfigport.mk b/ports/mimxrt10xx/mpconfigport.mk
index f1106e88f..5881ac302 100644
--- a/ports/mimxrt10xx/mpconfigport.mk
+++ b/ports/mimxrt10xx/mpconfigport.mk
@@ -1,6 +1,4 @@
-# Define an equivalent for MICROPY_LONGINT_IMPL, to pass to $(MPY-TOOL) in py/mkrules.mk
-# $(MPY-TOOL) needs to know what kind of longint to use (if any) to freeze long integers.
-# This should correspond to the MICROPY_LONGINT_IMPL definition in mpconfigport.h.
+LD_FILE = $(FLASH).ld $(CHIP_FAMILY).ld imxrt10xx.ld
ifeq ($(LONGINT_IMPL),NONE)
MPY_TOOL_LONGINT_IMPL = -mlongint-impl=none
@@ -16,5 +14,17 @@ endif
INTERNAL_LIBM = 1
+USB_DEVICES = "CDC,MSC,HID"
USB_SERIAL_NUMBER_LENGTH = 32
USB_MSC_MAX_PACKET_SIZE = 512
+
+INTERNAL_FLASH_FILESYSTEM = 1
+
+CIRCUITPY_AUDIOIO = 0
+CIRCUITPY_AUDIOBUSIO = 0
+CIRCUITPY_FREQUENCYIO = 0
+CIRCUITPY_I2CSLAVE = 0
+CIRCUITPY_NVM = 0
+CIRCUITPY_ROTARYIO = 0
+
+LONGINT_IMPL = MPZ
diff --git a/ports/mimxrt10xx/mphalport.c b/ports/mimxrt10xx/mphalport.c
index b333730b9..06275cd83 100644
--- a/ports/mimxrt10xx/mphalport.c
+++ b/ports/mimxrt10xx/mphalport.c
@@ -49,7 +49,7 @@ void mp_hal_delay_ms(mp_uint_t delay) {
}
void mp_hal_delay_us(mp_uint_t delay) {
-#ifdef MIMXRT1011_SERIES
+#if defined(MIMXRT1011_SERIES) || defined(MIMXRT1021_SERIES)
SDK_DelayAtLeastUs(delay, SystemCoreClock);
#else
SDK_DelayAtLeastUs(delay);
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/clocks.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/clocks.c
index c03991785..854ae4dee 100644
--- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/clocks.c
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/clocks.c
@@ -129,19 +129,6 @@ void clocks_init(void) {
CLOCK_DisableClock(kCLOCK_Pit);
/* Set PERCLK_PODF. */
CLOCK_SetDiv(kCLOCK_PerclkDiv, 1);
- /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd.
- * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left
- * unchanged. Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as
- * well.*/
-#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
- /* Disable Flexspi clock gate. */
- CLOCK_DisableClock(kCLOCK_FlexSpi);
- /* Set FLEXSPI_PODF. */
- CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3);
- /* Set Flexspi clock source. */
- CLOCK_SetMux(kCLOCK_FlexspiMux, 0);
- CLOCK_SetMux(kCLOCK_FlexspiSrcMux, 0);
-#endif
/* Disable ADC_ACLK_EN clock gate. */
CCM->CSCMR2 &= ~CCM_CSCMR2_ADC_ACLK_EN_MASK;
/* Set ADC_ACLK_PODF. */
@@ -219,24 +206,6 @@ void clocks_init(void) {
CLOCK_InitSysPfd(kCLOCK_Pfd2, 18);
/* Init System pfd3. */
CLOCK_InitSysPfd(kCLOCK_Pfd3, 18);
- /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd.
- * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left
- * unchanged. Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as
- * well.*/
-#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
- /* Init Usb1 PLL. */
- CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN);
- /* Init Usb1 pfd0. */
- CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 22);
- /* Init Usb1 pfd1. */
- CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16);
- /* Init Usb1 pfd2. */
- CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17);
- /* Init Usb1 pfd3. */
- CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 18);
- /* Disable Usb1 PLL output for USBPHY1. */
- CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK;
-#endif
/* DeInit Audio PLL. */
CLOCK_DeinitAudioPll();
/* Bypass Audio PLL. */
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.c
index e9d735830..2fed6dfc6 100644
--- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.c
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.c
@@ -113,6 +113,26 @@ const mcu_periph_obj_t mcu_uart_tx_list[9] = {
PERIPH_PIN(4, 3, kIOMUXC_LPUART4_TXD_SELECT_INPUT, 1, &pin_GPIO_06),
};
+const mcu_periph_obj_t mcu_uart_rts_list[4] = {
+ PERIPH_PIN(1, 6, 0, 0, &pin_GPIO_07),
+
+ PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_AD_07),
+
+ PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_13),
+
+ PERIPH_PIN(4, 3, 0, 0, &pin_GPIO_AD_13)
+};
+
+const mcu_periph_obj_t mcu_uart_cts_list[4] = {
+ PERIPH_PIN(1, 6, 0, 0, &pin_GPIO_08),
+
+ PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_AD_08),
+
+ PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_14),
+
+ PERIPH_PIN(4, 3, 0, 0, &pin_GPIO_AD_14),
+};
+
const mcu_pwm_obj_t mcu_pwm_list[20] = {
PWM_PIN(PWM1, kPWM_Module_0, kPWM_PwmA, 2, &pin_GPIO_02),
PWM_PIN(PWM1, kPWM_Module_0, kPWM_PwmA, 2, &pin_GPIO_SD_02),
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h
index c91d5808a..d6d489537 100644
--- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h
@@ -36,6 +36,8 @@ extern const mcu_periph_obj_t mcu_spi_miso_list[4];
extern const mcu_periph_obj_t mcu_uart_rx_list[9];
extern const mcu_periph_obj_t mcu_uart_tx_list[9];
+extern const mcu_periph_obj_t mcu_uart_rts_list[4];
+extern const mcu_periph_obj_t mcu_uart_cts_list[4];
extern const mcu_pwm_obj_t mcu_pwm_list[20];
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/pins.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/pins.c
index 0b219468f..8e68e7702 100644
--- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/pins.c
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/pins.c
@@ -41,8 +41,8 @@ const mcu_pin_obj_t pin_GPIO_08 = PIN(GPIO1, 8, GPIO_08, NO_ADC, 0);
const mcu_pin_obj_t pin_GPIO_09 = PIN(GPIO1, 9, GPIO_09, NO_ADC, 0);
const mcu_pin_obj_t pin_GPIO_10 = PIN(GPIO1, 10, GPIO_10, NO_ADC, 0);
const mcu_pin_obj_t pin_GPIO_11 = PIN(GPIO1, 11, GPIO_11, NO_ADC, 0);
-const mcu_pin_obj_t pin_GPIO_12 = PIN(GPIO1, 12, GPIO_11, NO_ADC, 0);
-const mcu_pin_obj_t pin_GPIO_13 = PIN(GPIO1, 13, GPIO_11, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_12 = PIN(GPIO1, 12, GPIO_12, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_13 = PIN(GPIO1, 13, GPIO_13, NO_ADC, 0);
const mcu_pin_obj_t pin_GPIO_AD_00 = PIN(GPIO1, 14, GPIO_AD_00, ADC1, 0);
const mcu_pin_obj_t pin_GPIO_AD_01 = PIN(GPIO1, 15, GPIO_AD_01, ADC1, 1);
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/clocks.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/clocks.c
new file mode 100644
index 000000000..cb9dd34c9
--- /dev/null
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/clocks.c
@@ -0,0 +1,341 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Artur Pacholec
+ * Copyright (c) 2020 Scott Shawcroft
+ *
+ * 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.
+ */
+/*
+ * Copyright 2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "mpconfigport.h"
+
+#include "fsl_clock.h"
+#include "fsl_iomuxc.h"
+
+// These values are pulled from the SDK's devices/MIMXRT1021/project_template/clock_config.* files.
+
+#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */
+#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */
+
+#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 500000000U /*!< Core clock frequency: 500000000Hz */
+
+/* Clock outputs (values are in Hz): */
+#define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 500000000UL
+#define BOARD_BOOTCLOCKRUN_CAN_CLK_ROOT 40000000UL
+#define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL
+#define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL
+#define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL
+#define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL
+#define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL
+#define BOARD_BOOTCLOCKRUN_ENET1_TX_CLK 0UL
+#define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 0UL
+#define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 0UL
+#define BOARD_BOOTCLOCKRUN_ENET_500M_REF_CLK 500000000UL
+#define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL
+#define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 132000000UL
+#define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 62500000UL
+#define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 62500000UL
+#define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 125000000UL
+#define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL
+#define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL
+#define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL
+#define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 62500000UL
+#define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL
+#define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL
+#define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL
+#define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL
+#define BOARD_BOOTCLOCKRUN_SAI2_CLK_ROOT 63529411UL
+#define BOARD_BOOTCLOCKRUN_SAI2_MCLK1 63529411UL
+#define BOARD_BOOTCLOCKRUN_SAI2_MCLK2 0UL
+#define BOARD_BOOTCLOCKRUN_SAI2_MCLK3 30000000UL
+#define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL
+#define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL
+#define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL
+#define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL
+#define BOARD_BOOTCLOCKRUN_SEMC_CLK_ROOT 62500000UL
+#define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL
+#define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL
+#define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 117333333UL
+#define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL
+#define BOARD_BOOTCLOCKRUN_USBPHY1_CLK 0UL
+#define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 176000000UL
+#define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 176000000UL
+
+const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = {
+ .loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */
+ .numerator = 0, /* 30 bit numerator of fractional loop divider */
+ .denominator = 1, /* 30 bit denominator of fractional loop divider */
+ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
+};
+const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = {
+ .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */
+ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
+};
+const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN = {
+ .enableClkOutput = false, /* Disable the PLL providing the ENET 125MHz reference clock */
+ .enableClkOutput500M = true, /* Enable the PLL providing the ENET 500MHz reference clock */
+ .enableClkOutput25M = false, /* Disable the PLL providing the ENET 25MHz reference clock */
+ .loopDivider = 1, /* Set frequency of ethernet reference clock to 50 MHz */
+ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
+};
+
+// Based on the hello_world example in the SDK
+void clocks_init(void) {
+ /* Init RTC OSC clock frequency. */
+ CLOCK_SetRtcXtalFreq(32768U);
+ /* Enable 1MHz clock output. */
+ XTALOSC24M->OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK;
+ /* Use free 1MHz clock output. */
+ XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK;
+ /* Set XTAL 24MHz clock frequency. */
+ CLOCK_SetXtalFreq(24000000U);
+ /* Enable XTAL 24MHz clock source. */
+ CLOCK_InitExternalClk(0);
+ /* Enable internal RC. */
+ CLOCK_InitRcOsc24M();
+ /* Switch clock source to external OSC. */
+ CLOCK_SwitchOsc(kCLOCK_XtalOsc);
+ /* Set Oscillator ready counter value. */
+ CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127);
+ /* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */
+ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */
+ CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set PERIPH_CLK MUX to PERIPH_CLK2 */
+ /* Setting the VDD_SOC to 1.5V. It is necessary to config AHB to 500Mhz. */
+ DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x12);
+ /* Waiting for DCDC_STS_DC_OK bit is asserted */
+ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0))
+ {
+ }
+ /* Set AHB_PODF. */
+ CLOCK_SetDiv(kCLOCK_AhbDiv, 0);
+ /* Disable IPG clock gate. */
+ CLOCK_DisableClock(kCLOCK_Adc1);
+ CLOCK_DisableClock(kCLOCK_Adc2);
+ CLOCK_DisableClock(kCLOCK_Xbar1);
+ CLOCK_DisableClock(kCLOCK_Xbar2);
+ /* Set IPG_PODF. */
+ CLOCK_SetDiv(kCLOCK_IpgDiv, 3);
+ /* Set ARM_PODF. */
+ CLOCK_SetDiv(kCLOCK_ArmDiv, 0);
+ /* Set PERIPH_CLK2_PODF. */
+ CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0);
+ /* Disable PERCLK clock gate. */
+ CLOCK_DisableClock(kCLOCK_Gpt1);
+ CLOCK_DisableClock(kCLOCK_Gpt1S);
+ CLOCK_DisableClock(kCLOCK_Gpt2);
+ CLOCK_DisableClock(kCLOCK_Gpt2S);
+ CLOCK_DisableClock(kCLOCK_Pit);
+ /* Set PERCLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_PerclkDiv, 1);
+ /* Disable USDHC1 clock gate. */
+ CLOCK_DisableClock(kCLOCK_Usdhc1);
+ /* Set USDHC1_PODF. */
+ CLOCK_SetDiv(kCLOCK_Usdhc1Div, 2);
+ /* Set Usdhc1 clock source. */
+ CLOCK_SetMux(kCLOCK_Usdhc1Mux, 0);
+ /* Disable USDHC2 clock gate. */
+ CLOCK_DisableClock(kCLOCK_Usdhc2);
+ /* Set USDHC2_PODF. */
+ CLOCK_SetDiv(kCLOCK_Usdhc2Div, 2);
+ /* Set Usdhc2 clock source. */
+ CLOCK_SetMux(kCLOCK_Usdhc2Mux, 0);
+ /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd.
+ * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left
+ * unchanged. Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as
+ * well.*/
+#ifndef SKIP_SYSCLK_INIT
+ /* Disable Semc clock gate. */
+ CLOCK_DisableClock(kCLOCK_Semc);
+ /* Set SEMC_PODF. */
+ CLOCK_SetDiv(kCLOCK_SemcDiv, 7);
+ /* Set Semc alt clock source. */
+ CLOCK_SetMux(kCLOCK_SemcAltMux, 0);
+ /* Set Semc clock source. */
+ CLOCK_SetMux(kCLOCK_SemcMux, 0);
+#endif
+ /* Disable LPSPI clock gate. */
+ CLOCK_DisableClock(kCLOCK_Lpspi1);
+ CLOCK_DisableClock(kCLOCK_Lpspi2);
+ CLOCK_DisableClock(kCLOCK_Lpspi3);
+ CLOCK_DisableClock(kCLOCK_Lpspi4);
+ /* Set LPSPI_PODF. */
+ CLOCK_SetDiv(kCLOCK_LpspiDiv, 4);
+ /* Set Lpspi clock source. */
+ CLOCK_SetMux(kCLOCK_LpspiMux, 2);
+ /* Disable TRACE clock gate. */
+ CLOCK_DisableClock(kCLOCK_Trace);
+ /* Set TRACE_PODF. */
+ CLOCK_SetDiv(kCLOCK_TraceDiv, 2);
+ /* Set Trace clock source. */
+ CLOCK_SetMux(kCLOCK_TraceMux, 2);
+ /* Disable SAI1 clock gate. */
+ CLOCK_DisableClock(kCLOCK_Sai1);
+ /* Set SAI1_CLK_PRED. */
+ CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3);
+ /* Set SAI1_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_Sai1Div, 1);
+ /* Set Sai1 clock source. */
+ CLOCK_SetMux(kCLOCK_Sai1Mux, 0);
+ /* Disable SAI2 clock gate. */
+ CLOCK_DisableClock(kCLOCK_Sai2);
+ /* Set SAI2_CLK_PRED. */
+ CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3);
+ /* Set SAI2_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_Sai2Div, 1);
+ /* Set Sai2 clock source. */
+ CLOCK_SetMux(kCLOCK_Sai2Mux, 0);
+ /* Disable SAI3 clock gate. */
+ CLOCK_DisableClock(kCLOCK_Sai3);
+ /* Set SAI3_CLK_PRED. */
+ CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3);
+ /* Set SAI3_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_Sai3Div, 1);
+ /* Set Sai3 clock source. */
+ CLOCK_SetMux(kCLOCK_Sai3Mux, 0);
+ /* Disable Lpi2c clock gate. */
+ CLOCK_DisableClock(kCLOCK_Lpi2c1);
+ CLOCK_DisableClock(kCLOCK_Lpi2c2);
+ CLOCK_DisableClock(kCLOCK_Lpi2c3);
+ /* Set LPI2C_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0);
+ /* Set Lpi2c clock source. */
+ CLOCK_SetMux(kCLOCK_Lpi2cMux, 0);
+ /* Disable CAN clock gate. */
+ CLOCK_DisableClock(kCLOCK_Can1);
+ CLOCK_DisableClock(kCLOCK_Can2);
+ CLOCK_DisableClock(kCLOCK_Can1S);
+ CLOCK_DisableClock(kCLOCK_Can2S);
+ /* Set CAN_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_CanDiv, 1);
+ /* Set Can clock source. */
+ CLOCK_SetMux(kCLOCK_CanMux, 2);
+ /* Disable UART clock gate. */
+ CLOCK_DisableClock(kCLOCK_Lpuart1);
+ CLOCK_DisableClock(kCLOCK_Lpuart2);
+ CLOCK_DisableClock(kCLOCK_Lpuart3);
+ CLOCK_DisableClock(kCLOCK_Lpuart4);
+ CLOCK_DisableClock(kCLOCK_Lpuart5);
+ CLOCK_DisableClock(kCLOCK_Lpuart6);
+ CLOCK_DisableClock(kCLOCK_Lpuart7);
+ CLOCK_DisableClock(kCLOCK_Lpuart8);
+ /* Set UART_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_UartDiv, 0);
+ /* Set Uart clock source. */
+ CLOCK_SetMux(kCLOCK_UartMux, 0);
+ /* Disable SPDIF clock gate. */
+ CLOCK_DisableClock(kCLOCK_Spdif);
+ /* Set SPDIF0_CLK_PRED. */
+ CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1);
+ /* Set SPDIF0_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_Spdif0Div, 7);
+ /* Set Spdif clock source. */
+ CLOCK_SetMux(kCLOCK_SpdifMux, 3);
+ /* Disable Flexio1 clock gate. */
+ CLOCK_DisableClock(kCLOCK_Flexio1);
+ /* Set FLEXIO1_CLK_PRED. */
+ CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1);
+ /* Set FLEXIO1_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_Flexio1Div, 7);
+ /* Set Flexio1 clock source. */
+ CLOCK_SetMux(kCLOCK_Flexio1Mux, 3);
+ /* Set Pll3 sw clock source. */
+ CLOCK_SetMux(kCLOCK_Pll3SwMux, 0);
+ /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd.
+ * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left
+ * unchanged. Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as
+ * well.*/
+#ifndef SKIP_SYSCLK_INIT
+#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1)
+ #warning "SKIP_SYSCLK_INIT should be defined to keep system pll (selected to be SEMC source clock in SDK projects) unchanged."
+#endif
+ /* Init System PLL. */
+ CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN);
+ /* Init System pfd0. */
+ CLOCK_InitSysPfd(kCLOCK_Pfd0, 27);
+ /* Init System pfd1. */
+ CLOCK_InitSysPfd(kCLOCK_Pfd1, 16);
+ /* Init System pfd2. */
+ CLOCK_InitSysPfd(kCLOCK_Pfd2, 18);
+ /* Init System pfd3. */
+ CLOCK_InitSysPfd(kCLOCK_Pfd3, 18);
+#endif
+ /* DeInit Audio PLL. */
+ CLOCK_DeinitAudioPll();
+ /* Bypass Audio PLL. */
+ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1);
+ /* Set divider for Audio PLL. */
+ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK;
+ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK;
+ /* Enable Audio PLL output. */
+ CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK;
+ /* Init Enet PLL. */
+ CLOCK_InitEnetPll(&enetPllConfig_BOARD_BootClockRUN);
+ /* Set preperiph clock source. */
+ CLOCK_SetMux(kCLOCK_PrePeriphMux, 3);
+ /* Set periph clock source. */
+ CLOCK_SetMux(kCLOCK_PeriphMux, 0);
+ /* Set periph clock2 clock source. */
+ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0);
+ /* Set per clock source. */
+ CLOCK_SetMux(kCLOCK_PerclkMux, 0);
+ /* Set clock out1 divider. */
+ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0);
+ /* Set clock out1 source. */
+ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1);
+ /* Set clock out2 divider. */
+ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0);
+ /* Set clock out2 source. */
+ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(3);
+ /* Set clock out1 drives clock out1. */
+ CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK;
+ /* Disable clock out1. */
+ CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK;
+ /* Disable clock out2. */
+ CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK;
+ /* Set SAI1 MCLK1 clock source. */
+ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0);
+ /* Set SAI1 MCLK2 clock source. */
+ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0);
+ /* Set SAI1 MCLK3 clock source. */
+ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0);
+ /* Set SAI2 MCLK3 clock source. */
+ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0);
+ /* Set SAI3 MCLK3 clock source. */
+ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0);
+ /* Set MQS configuration. */
+ IOMUXC_MQSConfig(IOMUXC_GPR, kIOMUXC_MqsPwmOverSampleRate32, 0);
+ /* Set ENET Tx clock source. */
+ IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1RefClkMode, false);
+ /* Set GPT1 High frequency reference clock source. */
+ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK;
+ /* Set GPT2 High frequency reference clock source. */
+ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK;
+ /* Set SystemCoreClock variable. */
+ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK;
+
+ CLOCK_EnableClock(kCLOCK_Iomuxc);
+}
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c
new file mode 100644
index 000000000..0417f29cc
--- /dev/null
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c
@@ -0,0 +1,258 @@
+ /*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ * Copyright (c) 2019 Artur Pacholec
+ * Copyright (c) 2020 Scott Shawcroft
+ *
+ * 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 "py/obj.h"
+#include "py/mphal.h"
+#include "mimxrt10xx/periph.h"
+
+LPI2C_Type *mcu_i2c_banks[] = { LPI2C1, LPI2C2, LPI2C3, LPI2C4 };
+
+const mcu_periph_obj_t mcu_i2c_sda_list[8] = {
+ PERIPH_PIN(1, 0, kIOMUXC_LPI2C1_SDA_SELECT_INPUT, 0, &pin_GPIO_AD_B1_15),
+ PERIPH_PIN(1, 6, kIOMUXC_LPI2C1_SDA_SELECT_INPUT, 1, &pin_GPIO_EMC_03),
+
+ PERIPH_PIN(2, 0, kIOMUXC_LPI2C2_SDA_SELECT_INPUT, 0, &pin_GPIO_AD_B1_09),
+ PERIPH_PIN(2, 2, kIOMUXC_LPI2C2_SDA_SELECT_INPUT, 1, &pin_GPIO_EMC_18),
+
+ PERIPH_PIN(3, 1, kIOMUXC_LPI2C3_SDA_SELECT_INPUT, 0, &pin_GPIO_AD_B0_09),
+ PERIPH_PIN(3, 4, kIOMUXC_LPI2C3_SDA_SELECT_INPUT, 1, &pin_GPIO_SD_B0_01),
+
+ PERIPH_PIN(4, 2, kIOMUXC_LPI2C4_SDA_SELECT_INPUT, 0, &pin_GPIO_EMC_10),
+ PERIPH_PIN(4, 3, kIOMUXC_LPI2C4_SDA_SELECT_INPUT, 1, &pin_GPIO_SD_B1_03),
+};
+
+const mcu_periph_obj_t mcu_i2c_scl_list[8] = {
+ PERIPH_PIN(1, 0, kIOMUXC_LPI2C1_SCL_SELECT_INPUT, 0, &pin_GPIO_AD_B1_14),
+ PERIPH_PIN(1, 6, kIOMUXC_LPI2C1_SCL_SELECT_INPUT, 1, &pin_GPIO_EMC_02),
+
+ PERIPH_PIN(2, 0, kIOMUXC_LPI2C2_SCL_SELECT_INPUT, 0, &pin_GPIO_AD_B1_08),
+ PERIPH_PIN(2, 2, kIOMUXC_LPI2C2_SCL_SELECT_INPUT, 1, &pin_GPIO_EMC_19),
+
+ PERIPH_PIN(3, 1, kIOMUXC_LPI2C3_SCL_SELECT_INPUT, 0, &pin_GPIO_AD_B0_08),
+ PERIPH_PIN(3, 4, kIOMUXC_LPI2C3_SCL_SELECT_INPUT, 1, &pin_GPIO_SD_B0_00),
+
+ PERIPH_PIN(4, 2, kIOMUXC_LPI2C4_SCL_SELECT_INPUT, 0, &pin_GPIO_EMC_11),
+ PERIPH_PIN(4, 3, kIOMUXC_LPI2C4_SCL_SELECT_INPUT, 1, &pin_GPIO_SD_B1_02),
+};
+
+LPSPI_Type *mcu_spi_banks[] = { LPSPI1, LPSPI2, LPSPI3, LPSPI4 };
+
+const mcu_periph_obj_t mcu_spi_sck_list[8] = {
+ PERIPH_PIN(1, 1, kIOMUXC_LPSPI1_SCK_SELECT_INPUT, 0, &pin_GPIO_AD_B0_10),
+ PERIPH_PIN(1, 4, kIOMUXC_LPSPI1_SCK_SELECT_INPUT, 1, &pin_GPIO_SD_B0_02),
+
+ PERIPH_PIN(2, 4, kIOMUXC_LPSPI2_SCK_SELECT_INPUT, 0, &pin_GPIO_EMC_00),
+ PERIPH_PIN(2, 4, kIOMUXC_LPSPI2_SCK_SELECT_INPUT, 1, &pin_GPIO_EMC_10),
+ PERIPH_PIN(2, 4, kIOMUXC_LPSPI2_SCK_SELECT_INPUT, 2, &pin_GPIO_SD_B1_07),
+
+ PERIPH_PIN(3, 2, kIOMUXC_LPSPI2_SCK_SELECT_INPUT, 0, &pin_GPIO_AD_B1_12),
+
+ PERIPH_PIN(4, 2, kIOMUXC_LPSPI2_SCK_SELECT_INPUT, 0, &pin_GPIO_AD_B1_02),
+ PERIPH_PIN(4, 4, kIOMUXC_LPSPI2_SCK_SELECT_INPUT, 1, &pin_GPIO_EMC_32),
+};
+
+const mcu_periph_obj_t mcu_spi_mosi_list[8] = {
+ PERIPH_PIN(1, 1, kIOMUXC_LPSPI1_SDO_SELECT_INPUT, 0, &pin_GPIO_AD_B0_13),
+ PERIPH_PIN(1, 4, kIOMUXC_LPSPI1_SDO_SELECT_INPUT, 1, &pin_GPIO_SD_B0_05),
+
+ PERIPH_PIN(2, 4, kIOMUXC_LPSPI2_SDO_SELECT_INPUT, 0, &pin_GPIO_EMC_03),
+ PERIPH_PIN(2, 4, kIOMUXC_LPSPI2_SDO_SELECT_INPUT, 1, &pin_GPIO_EMC_13),
+ PERIPH_PIN(2, 4, kIOMUXC_LPSPI2_SDO_SELECT_INPUT, 2, &pin_GPIO_SD_B1_09),
+
+ PERIPH_PIN(3, 2, kIOMUXC_LPSPI2_SDO_SELECT_INPUT, 0, &pin_GPIO_AD_B1_15),
+
+ PERIPH_PIN(4, 2, kIOMUXC_LPSPI2_SDO_SELECT_INPUT, 0, &pin_GPIO_AD_B1_05),
+ PERIPH_PIN(4, 4, kIOMUXC_LPSPI2_SDO_SELECT_INPUT, 1, &pin_GPIO_EMC_35),
+};
+
+const mcu_periph_obj_t mcu_spi_miso_list[8] = {
+ PERIPH_PIN(1, 1, kIOMUXC_LPSPI1_SDI_SELECT_INPUT, 0, &pin_GPIO_AD_B0_12),
+ PERIPH_PIN(1, 4, kIOMUXC_LPSPI1_SDI_SELECT_INPUT, 1, &pin_GPIO_SD_B0_04),
+
+ PERIPH_PIN(2, 4, kIOMUXC_LPSPI2_SDI_SELECT_INPUT, 0, &pin_GPIO_EMC_02),
+ PERIPH_PIN(2, 4, kIOMUXC_LPSPI2_SDI_SELECT_INPUT, 1, &pin_GPIO_EMC_12),
+ PERIPH_PIN(2, 4, kIOMUXC_LPSPI2_SDI_SELECT_INPUT, 2, &pin_GPIO_SD_B1_08),
+
+ PERIPH_PIN(3, 2, kIOMUXC_LPSPI2_SDI_SELECT_INPUT, 0, &pin_GPIO_AD_B1_14),
+
+ PERIPH_PIN(4, 2, kIOMUXC_LPSPI2_SDI_SELECT_INPUT, 0, &pin_GPIO_AD_B1_04),
+ PERIPH_PIN(4, 4, kIOMUXC_LPSPI2_SDI_SELECT_INPUT, 1, &pin_GPIO_EMC_34),
+};
+
+LPUART_Type *mcu_uart_banks[] = { LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, LPUART6, LPUART7, LPUART8 };
+
+const mcu_periph_obj_t mcu_uart_rx_list[16] = {
+ PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_07),
+
+ PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 0, &pin_GPIO_AD_B1_09),
+ PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_23),
+
+ PERIPH_PIN(3, 2, kIOMUXC_LPUART3_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_07),
+ PERIPH_PIN(3, 2, kIOMUXC_LPUART3_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_15),
+
+ PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_03),
+ PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_11),
+ PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 2, &pin_GPIO_EMC_33),
+
+ PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 0, &pin_GPIO_AD_B0_11),
+ PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_39),
+
+ PERIPH_PIN(6, 2, kIOMUXC_LPUART6_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_13),
+ PERIPH_PIN(6, 2, kIOMUXC_LPUART6_RX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_01),
+
+ PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 0, &pin_GPIO_SD_B0_05),
+ PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_35),
+
+ PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 0, &pin_GPIO_SD_B1_03),
+ PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_27),
+};
+
+const mcu_periph_obj_t mcu_uart_tx_list[16] = {
+ PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_06),
+
+ PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 0, &pin_GPIO_AD_B1_08),
+ PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_22),
+
+ PERIPH_PIN(3, 2, kIOMUXC_LPUART3_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_06),
+ PERIPH_PIN(3, 2, kIOMUXC_LPUART3_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_14),
+
+ PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_02),
+ PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_10),
+ PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 2, &pin_GPIO_EMC_32),
+
+ PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 0, &pin_GPIO_AD_B0_10),
+ PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_38),
+
+ PERIPH_PIN(6, 2, kIOMUXC_LPUART6_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_12),
+ PERIPH_PIN(6, 2, kIOMUXC_LPUART6_TX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_00),
+
+ PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 0, &pin_GPIO_SD_B0_04),
+ PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_34),
+
+ PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 0, &pin_GPIO_SD_B1_02),
+ PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_26),
+};
+
+const mcu_periph_obj_t mcu_uart_rts_list[10] = {
+ PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_09),
+
+ PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_21),
+ PERIPH_PIN(2, 2, 0, 1, &pin_GPIO_AD_B1_07),
+
+ PERIPH_PIN(3, 2, 0, 1, &pin_GPIO_AD_B0_13),
+
+ PERIPH_PIN(4, 2, 0, 0, &pin_GPIO_EMC_01),
+ PERIPH_PIN(4, 2, 0, 1, &pin_GPIO_EMC_31),
+
+ PERIPH_PIN(5, 2, 0, 0, &pin_GPIO_EMC_37),
+
+ PERIPH_PIN(6, 2, 0, 0, &pin_GPIO_EMC_15),
+
+ PERIPH_PIN(7, 2, 0, 1, &pin_GPIO_SD_B0_03),
+
+ PERIPH_PIN(8, 2, 0, 0, &pin_GPIO_EMC_25),
+};
+
+const mcu_periph_obj_t mcu_uart_cts_list[10] = {
+ PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_08),
+
+ PERIPH_PIN(2, 2, kIOMUXC_LPUART2_CTS_B_SELECT_INPUT, 0, &pin_GPIO_AD_B1_06),
+ PERIPH_PIN(2, 2, kIOMUXC_LPUART2_CTS_B_SELECT_INPUT, 1, &pin_GPIO_EMC_20),
+
+ PERIPH_PIN(3, 2, 0, 1, &pin_GPIO_AD_B0_12),
+
+ PERIPH_PIN(4, 2, kIOMUXC_LPUART4_CTS_B_SELECT_INPUT, 0, &pin_GPIO_EMC_00),
+ PERIPH_PIN(4, 2, kIOMUXC_LPUART4_CTS_B_SELECT_INPUT, 0, &pin_GPIO_EMC_30),
+
+ PERIPH_PIN(5, 2, 0, 0, &pin_GPIO_EMC_36),
+
+ PERIPH_PIN(6, 2, 0, 0, &pin_GPIO_EMC_14),
+
+ PERIPH_PIN(7, 2, 0, 0, &pin_GPIO_SD_B0_02),
+
+ PERIPH_PIN(8, 2, 0, 0, &pin_GPIO_EMC_24),
+};
+
+const mcu_pwm_obj_t mcu_pwm_list[39] = {
+ PWM_PIN(PWM1, kPWM_Module_0, kPWM_PwmA, 1, &pin_GPIO_EMC_26),
+ PWM_PIN(PWM1, kPWM_Module_0, kPWM_PwmA, 1, &pin_GPIO_AD_B1_06),
+
+ PWM_PIN(PWM1, kPWM_Module_1, kPWM_PwmA, 1, &pin_GPIO_EMC_24),
+ PWM_PIN(PWM1, kPWM_Module_1, kPWM_PwmA, 1, &pin_GPIO_AD_B1_08),
+
+ PWM_PIN(PWM1, kPWM_Module_2, kPWM_PwmA, 1, &pin_GPIO_EMC_22),
+ PWM_PIN(PWM1, kPWM_Module_2, kPWM_PwmA, 1, &pin_GPIO_AD_B1_10),
+
+ PWM_PIN(PWM1, kPWM_Module_3, kPWM_PwmA, 1, &pin_GPIO_EMC_20),
+ PWM_PIN(PWM1, kPWM_Module_3, kPWM_PwmA, 6, &pin_GPIO_AD_B1_12),
+
+ PWM_PIN(PWM1, kPWM_Module_0, kPWM_PwmB, 1, &pin_GPIO_EMC_27),
+ PWM_PIN(PWM1, kPWM_Module_0, kPWM_PwmB, 1, &pin_GPIO_AD_B1_07),
+
+ PWM_PIN(PWM1, kPWM_Module_1, kPWM_PwmB, 1, &pin_GPIO_EMC_25),
+ PWM_PIN(PWM1, kPWM_Module_1, kPWM_PwmB, 1, &pin_GPIO_AD_B1_09),
+
+ PWM_PIN(PWM1, kPWM_Module_2, kPWM_PwmB, 1, &pin_GPIO_EMC_23),
+ PWM_PIN(PWM1, kPWM_Module_2, kPWM_PwmB, 1, &pin_GPIO_AD_B1_11),
+
+ PWM_PIN(PWM1, kPWM_Module_3, kPWM_PwmB, 1, &pin_GPIO_EMC_21),
+ PWM_PIN(PWM1, kPWM_Module_3, kPWM_PwmB, 6, &pin_GPIO_AD_B1_13),
+
+ PWM_PIN(PWM1, kPWM_Module_0, kPWM_PwmX, 7, &pin_GPIO_EMC_28),
+ PWM_PIN(PWM1, kPWM_Module_1, kPWM_PwmX, 7, &pin_GPIO_EMC_29),
+ PWM_PIN(PWM1, kPWM_Module_2, kPWM_PwmX, 7, &pin_GPIO_EMC_30),
+
+ PWM_PIN(PWM2, kPWM_Module_0, kPWM_PwmA, 1, &pin_GPIO_EMC_38),
+ PWM_PIN(PWM2, kPWM_Module_0, kPWM_PwmA, 4, &pin_GPIO_AD_B0_14),
+
+ PWM_PIN(PWM2, kPWM_Module_1, kPWM_PwmA, 1, &pin_GPIO_EMC_36),
+ PWM_PIN(PWM2, kPWM_Module_1, kPWM_PwmA, 4, &pin_GPIO_AD_B0_12),
+
+ PWM_PIN(PWM2, kPWM_Module_2, kPWM_PwmA, 1, &pin_GPIO_EMC_30),
+ PWM_PIN(PWM2, kPWM_Module_2, kPWM_PwmA, 4, &pin_GPIO_AD_B0_10),
+
+ PWM_PIN(PWM2, kPWM_Module_3, kPWM_PwmA, 1, &pin_GPIO_EMC_28),
+ PWM_PIN(PWM2, kPWM_Module_3, kPWM_PwmA, 4, &pin_GPIO_AD_B0_06),
+
+ PWM_PIN(PWM2, kPWM_Module_0, kPWM_PwmB, 1, &pin_GPIO_EMC_39),
+ PWM_PIN(PWM2, kPWM_Module_0, kPWM_PwmB, 4, &pin_GPIO_AD_B0_15),
+
+ PWM_PIN(PWM2, kPWM_Module_1, kPWM_PwmB, 1, &pin_GPIO_EMC_37),
+ PWM_PIN(PWM2, kPWM_Module_1, kPWM_PwmB, 4, &pin_GPIO_AD_B0_13),
+
+ PWM_PIN(PWM2, kPWM_Module_2, kPWM_PwmB, 1, &pin_GPIO_EMC_31),
+ PWM_PIN(PWM2, kPWM_Module_2, kPWM_PwmB, 4, &pin_GPIO_AD_B0_11),
+
+ PWM_PIN(PWM2, kPWM_Module_3, kPWM_PwmB, 1, &pin_GPIO_EMC_29),
+ PWM_PIN(PWM2, kPWM_Module_3, kPWM_PwmB, 4, &pin_GPIO_AD_B0_07),
+
+ PWM_PIN(PWM2, kPWM_Module_0, kPWM_PwmX, 6, &pin_GPIO_EMC_10),
+ PWM_PIN(PWM2, kPWM_Module_1, kPWM_PwmX, 6, &pin_GPIO_EMC_11),
+ PWM_PIN(PWM2, kPWM_Module_2, kPWM_PwmX, 6, &pin_GPIO_EMC_12),
+ PWM_PIN(PWM2, kPWM_Module_3, kPWM_PwmX, 6, &pin_GPIO_EMC_13),
+};
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h
new file mode 100644
index 000000000..ba88ef4c6
--- /dev/null
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Artur Pacholec
+ * Copyright (c) 2020 Scott Shawcroft
+ *
+ * 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_MIMXRT10XX_PERIPHERALS_MIMXRT1021_PERIPH_H
+#define MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1021_PERIPH_H
+
+extern const mcu_periph_obj_t mcu_i2c_sda_list[8];
+extern const mcu_periph_obj_t mcu_i2c_scl_list[8];
+
+extern const mcu_periph_obj_t mcu_spi_sck_list[8];
+extern const mcu_periph_obj_t mcu_spi_mosi_list[8];
+extern const mcu_periph_obj_t mcu_spi_miso_list[8];
+
+extern const mcu_periph_obj_t mcu_uart_rx_list[16];
+extern const mcu_periph_obj_t mcu_uart_tx_list[16];
+extern const mcu_periph_obj_t mcu_uart_rts_list[10];
+extern const mcu_periph_obj_t mcu_uart_cts_list[10];
+
+extern const mcu_pwm_obj_t mcu_pwm_list[39];
+
+#endif // MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1021_PERIP_H
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/pins.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/pins.c
new file mode 100644
index 000000000..4106c9bad
--- /dev/null
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/pins.c
@@ -0,0 +1,128 @@
+ /*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ * Copyright (c) 2019 Artur Pacholec
+ *
+ * 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 "py/obj.h"
+#include "py/mphal.h"
+#include "mimxrt10xx/pins.h"
+
+const mcu_pin_obj_t pin_GPIO_AD_B0_00 = PIN(GPIO1, 0, GPIO_AD_B0_00, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_01 = PIN(GPIO1, 1, GPIO_AD_B0_01, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_02 = PIN(GPIO1, 2, GPIO_AD_B0_02, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_03 = PIN(GPIO1, 3, GPIO_AD_B0_03, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_04 = PIN(GPIO1, 4, GPIO_AD_B0_04, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_05 = PIN(GPIO1, 5, GPIO_AD_B0_05, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_06 = PIN(GPIO1, 6, GPIO_AD_B0_06, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_07 = PIN(GPIO1, 7, GPIO_AD_B0_07, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_08 = PIN(GPIO1, 8, GPIO_AD_B0_08, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_09 = PIN(GPIO1, 9, GPIO_AD_B0_09, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_10 = PIN(GPIO1, 10, GPIO_AD_B0_10, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_11 = PIN(GPIO1, 11, GPIO_AD_B0_11, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_12 = PIN(GPIO1, 12, GPIO_AD_B0_12, ADC1, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_13 = PIN(GPIO1, 13, GPIO_AD_B0_13, ADC2, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B0_14 = PIN(GPIO1, 14, GPIO_AD_B0_14, ADC2, 1);
+const mcu_pin_obj_t pin_GPIO_AD_B0_15 = PIN(GPIO1, 15, GPIO_AD_B0_15, ADC1, 2);
+
+const mcu_pin_obj_t pin_GPIO_AD_B1_00 = PIN(GPIO1, 16, GPIO_AD_B1_00, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_AD_B1_01 = PIN(GPIO1, 17, GPIO_AD_B1_01, ADC1, 3);
+const mcu_pin_obj_t pin_GPIO_AD_B1_02 = PIN(GPIO1, 18, GPIO_AD_B1_02, ADC2, 3);
+const mcu_pin_obj_t pin_GPIO_AD_B1_03 = PIN(GPIO1, 19, GPIO_AD_B1_03, ADC1, 4);
+const mcu_pin_obj_t pin_GPIO_AD_B1_04 = PIN(GPIO1, 20, GPIO_AD_B1_04, ADC2, 4);
+const mcu_pin_obj_t pin_GPIO_AD_B1_05 = PIN(GPIO1, 21, GPIO_AD_B1_05, ADC2, 5);
+const mcu_pin_obj_t pin_GPIO_AD_B1_06 = PIN(GPIO1, 22, GPIO_AD_B1_06, ADC2, 6);
+const mcu_pin_obj_t pin_GPIO_AD_B1_07 = PIN(GPIO1, 23, GPIO_AD_B1_07, ADC2, 7);
+const mcu_pin_obj_t pin_GPIO_AD_B1_08 = PIN(GPIO1, 24, GPIO_AD_B1_08, ADC2, 8);
+const mcu_pin_obj_t pin_GPIO_AD_B1_09 = PIN(GPIO1, 25, GPIO_AD_B1_09, ADC2, 9);
+const mcu_pin_obj_t pin_GPIO_AD_B1_10 = PIN(GPIO1, 26, GPIO_AD_B1_10, ADC2, 10);
+const mcu_pin_obj_t pin_GPIO_AD_B1_11 = PIN(GPIO1, 27, GPIO_AD_B1_11, ADC2, 11);
+const mcu_pin_obj_t pin_GPIO_AD_B1_12 = PIN(GPIO1, 28, GPIO_AD_B1_12, ADC2, 12);
+const mcu_pin_obj_t pin_GPIO_AD_B1_13 = PIN(GPIO1, 29, GPIO_AD_B1_13, ADC2, 13);
+const mcu_pin_obj_t pin_GPIO_AD_B1_14 = PIN(GPIO1, 30, GPIO_AD_B1_14, ADC2, 14);
+const mcu_pin_obj_t pin_GPIO_AD_B1_15 = PIN(GPIO1, 31, GPIO_AD_B1_15, ADC2, 15);
+
+const mcu_pin_obj_t pin_GPIO_EMC_00 = PIN(GPIO2, 0, GPIO_EMC_00, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_01 = PIN(GPIO2, 1, GPIO_EMC_01, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_02 = PIN(GPIO2, 2, GPIO_EMC_02, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_03 = PIN(GPIO2, 3, GPIO_EMC_03, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_04 = PIN(GPIO2, 4, GPIO_EMC_04, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_05 = PIN(GPIO2, 5, GPIO_EMC_05, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_06 = PIN(GPIO2, 6, GPIO_EMC_06, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_07 = PIN(GPIO2, 7, GPIO_EMC_07, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_08 = PIN(GPIO2, 8, GPIO_EMC_08, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_09 = PIN(GPIO2, 9, GPIO_EMC_09, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_10 = PIN(GPIO2, 10, GPIO_EMC_10, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_11 = PIN(GPIO2, 11, GPIO_EMC_11, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_12 = PIN(GPIO2, 12, GPIO_EMC_12, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_13 = PIN(GPIO2, 13, GPIO_EMC_13, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_14 = PIN(GPIO2, 14, GPIO_EMC_14, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_15 = PIN(GPIO2, 15, GPIO_EMC_15, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_16 = PIN(GPIO2, 16, GPIO_EMC_16, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_17 = PIN(GPIO2, 17, GPIO_EMC_17, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_18 = PIN(GPIO2, 18, GPIO_EMC_18, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_19 = PIN(GPIO2, 19, GPIO_EMC_19, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_20 = PIN(GPIO2, 20, GPIO_EMC_20, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_21 = PIN(GPIO2, 21, GPIO_EMC_21, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_22 = PIN(GPIO2, 22, GPIO_EMC_22, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_23 = PIN(GPIO2, 23, GPIO_EMC_23, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_24 = PIN(GPIO2, 24, GPIO_EMC_24, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_25 = PIN(GPIO2, 25, GPIO_EMC_25, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_26 = PIN(GPIO2, 26, GPIO_EMC_26, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_27 = PIN(GPIO2, 27, GPIO_EMC_27, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_28 = PIN(GPIO2, 28, GPIO_EMC_28, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_29 = PIN(GPIO2, 29, GPIO_EMC_29, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_30 = PIN(GPIO2, 30, GPIO_EMC_30, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_31 = PIN(GPIO2, 31, GPIO_EMC_31, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_32 = PIN(GPIO3, 0, GPIO_EMC_32, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_33 = PIN(GPIO3, 1, GPIO_EMC_33, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_34 = PIN(GPIO3, 2, GPIO_EMC_34, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_35 = PIN(GPIO3, 3, GPIO_EMC_35, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_36 = PIN(GPIO3, 4, GPIO_EMC_36, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_37 = PIN(GPIO3, 5, GPIO_EMC_37, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_38 = PIN(GPIO3, 6, GPIO_EMC_38, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_39 = PIN(GPIO3, 7, GPIO_EMC_39, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_40 = PIN(GPIO3, 8, GPIO_EMC_40, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_EMC_41 = PIN(GPIO3, 9, GPIO_EMC_41, NO_ADC, 0);
+
+const mcu_pin_obj_t pin_GPIO_SD_B0_00 = PIN(GPIO3, 13, GPIO_SD_B0_00, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B0_01 = PIN(GPIO3, 14, GPIO_SD_B0_01, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B0_02 = PIN(GPIO3, 15, GPIO_SD_B0_02, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B0_03 = PIN(GPIO3, 16, GPIO_SD_B0_03, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B0_04 = PIN(GPIO3, 17, GPIO_SD_B0_04, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B0_05 = PIN(GPIO3, 18, GPIO_SD_B0_05, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B0_06 = PIN(GPIO3, 19, GPIO_SD_B0_06, NO_ADC, 0);
+
+const mcu_pin_obj_t pin_GPIO_SD_B1_00 = PIN(GPIO3, 20, GPIO_SD_B1_00, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B1_01 = PIN(GPIO3, 21, GPIO_SD_B1_01, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B1_02 = PIN(GPIO3, 22, GPIO_SD_B1_02, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B1_03 = PIN(GPIO3, 23, GPIO_SD_B1_03, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B1_04 = PIN(GPIO3, 24, GPIO_SD_B1_04, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B1_05 = PIN(GPIO3, 25, GPIO_SD_B1_05, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B1_06 = PIN(GPIO3, 26, GPIO_SD_B1_06, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B1_07 = PIN(GPIO3, 27, GPIO_SD_B1_07, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B1_08 = PIN(GPIO3, 28, GPIO_SD_B1_08, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B1_09 = PIN(GPIO3, 29, GPIO_SD_B1_09, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B1_10 = PIN(GPIO3, 30, GPIO_SD_B1_10, NO_ADC, 0);
+const mcu_pin_obj_t pin_GPIO_SD_B1_11 = PIN(GPIO3, 31, GPIO_SD_B1_11, NO_ADC, 0);
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/pins.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/pins.h
new file mode 100644
index 000000000..a13bacfc3
--- /dev/null
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/pins.h
@@ -0,0 +1,129 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Artur Pacholec
+ * Copyright (c) 2020 Scott Shawcroft
+ *
+ * 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_MIMXRT10XX_PERIPHERALS_MIMXRT1021_PINS_H
+#define MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1021_PINS_H
+
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_00;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_01;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_02;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_03;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_04;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_05;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_06;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_07;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_08;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_09;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_10;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_11;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_12;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_13;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_14;
+extern const mcu_pin_obj_t pin_GPIO_AD_B0_15;
+
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_00;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_01;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_02;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_03;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_04;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_05;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_06;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_07;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_08;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_09;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_10;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_11;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_12;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_13;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_14;
+extern const mcu_pin_obj_t pin_GPIO_AD_B1_15;
+
+extern const mcu_pin_obj_t pin_GPIO_EMC_00;
+extern const mcu_pin_obj_t pin_GPIO_EMC_01;
+extern const mcu_pin_obj_t pin_GPIO_EMC_02;
+extern const mcu_pin_obj_t pin_GPIO_EMC_03;
+extern const mcu_pin_obj_t pin_GPIO_EMC_04;
+extern const mcu_pin_obj_t pin_GPIO_EMC_05;
+extern const mcu_pin_obj_t pin_GPIO_EMC_06;
+extern const mcu_pin_obj_t pin_GPIO_EMC_07;
+extern const mcu_pin_obj_t pin_GPIO_EMC_08;
+extern const mcu_pin_obj_t pin_GPIO_EMC_09;
+extern const mcu_pin_obj_t pin_GPIO_EMC_10;
+extern const mcu_pin_obj_t pin_GPIO_EMC_11;
+extern const mcu_pin_obj_t pin_GPIO_EMC_12;
+extern const mcu_pin_obj_t pin_GPIO_EMC_13;
+extern const mcu_pin_obj_t pin_GPIO_EMC_14;
+extern const mcu_pin_obj_t pin_GPIO_EMC_15;
+extern const mcu_pin_obj_t pin_GPIO_EMC_16;
+extern const mcu_pin_obj_t pin_GPIO_EMC_17;
+extern const mcu_pin_obj_t pin_GPIO_EMC_18;
+extern const mcu_pin_obj_t pin_GPIO_EMC_19;
+extern const mcu_pin_obj_t pin_GPIO_EMC_20;
+extern const mcu_pin_obj_t pin_GPIO_EMC_21;
+extern const mcu_pin_obj_t pin_GPIO_EMC_22;
+extern const mcu_pin_obj_t pin_GPIO_EMC_23;
+extern const mcu_pin_obj_t pin_GPIO_EMC_24;
+extern const mcu_pin_obj_t pin_GPIO_EMC_25;
+extern const mcu_pin_obj_t pin_GPIO_EMC_26;
+extern const mcu_pin_obj_t pin_GPIO_EMC_27;
+extern const mcu_pin_obj_t pin_GPIO_EMC_28;
+extern const mcu_pin_obj_t pin_GPIO_EMC_29;
+extern const mcu_pin_obj_t pin_GPIO_EMC_30;
+extern const mcu_pin_obj_t pin_GPIO_EMC_31;
+extern const mcu_pin_obj_t pin_GPIO_EMC_32;
+extern const mcu_pin_obj_t pin_GPIO_EMC_33;
+extern const mcu_pin_obj_t pin_GPIO_EMC_34;
+extern const mcu_pin_obj_t pin_GPIO_EMC_35;
+extern const mcu_pin_obj_t pin_GPIO_EMC_36;
+extern const mcu_pin_obj_t pin_GPIO_EMC_37;
+extern const mcu_pin_obj_t pin_GPIO_EMC_38;
+extern const mcu_pin_obj_t pin_GPIO_EMC_39;
+extern const mcu_pin_obj_t pin_GPIO_EMC_40;
+extern const mcu_pin_obj_t pin_GPIO_EMC_41;
+
+extern const mcu_pin_obj_t pin_GPIO_SD_B0_00;
+extern const mcu_pin_obj_t pin_GPIO_SD_B0_01;
+extern const mcu_pin_obj_t pin_GPIO_SD_B0_02;
+extern const mcu_pin_obj_t pin_GPIO_SD_B0_03;
+extern const mcu_pin_obj_t pin_GPIO_SD_B0_04;
+extern const mcu_pin_obj_t pin_GPIO_SD_B0_05;
+extern const mcu_pin_obj_t pin_GPIO_SD_B0_06;
+
+extern const mcu_pin_obj_t pin_GPIO_SD_B1_00;
+extern const mcu_pin_obj_t pin_GPIO_SD_B1_01;
+extern const mcu_pin_obj_t pin_GPIO_SD_B1_02;
+extern const mcu_pin_obj_t pin_GPIO_SD_B1_03;
+extern const mcu_pin_obj_t pin_GPIO_SD_B1_04;
+extern const mcu_pin_obj_t pin_GPIO_SD_B1_05;
+extern const mcu_pin_obj_t pin_GPIO_SD_B1_06;
+extern const mcu_pin_obj_t pin_GPIO_SD_B1_07;
+extern const mcu_pin_obj_t pin_GPIO_SD_B1_08;
+extern const mcu_pin_obj_t pin_GPIO_SD_B1_09;
+extern const mcu_pin_obj_t pin_GPIO_SD_B1_10;
+extern const mcu_pin_obj_t pin_GPIO_SD_B1_11;
+
+#endif // MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1021_PINS_H
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/clocks.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/clocks.c
index cafc8efc3..7b9af3a6a 100644
--- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/clocks.c
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/clocks.c
@@ -130,17 +130,6 @@ void clocks_init(void) {
/* Set Semc clock source. */
CLOCK_SetMux(kCLOCK_SemcMux, 0);
#endif
- /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd.
- * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged.
- * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/
-#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
- /* Disable Flexspi clock gate. */
- CLOCK_DisableClock(kCLOCK_FlexSpi);
- /* Set FLEXSPI_PODF. */
- CLOCK_SetDiv(kCLOCK_FlexspiDiv, 1);
- /* Set Flexspi clock source. */
- CLOCK_SetMux(kCLOCK_FlexspiMux, 3);
-#endif
/* Disable LPSPI clock gate. */
CLOCK_DisableClock(kCLOCK_Lpspi1);
CLOCK_DisableClock(kCLOCK_Lpspi2);
@@ -255,23 +244,6 @@ void clocks_init(void) {
/* Init System pfd3. */
CLOCK_InitSysPfd(kCLOCK_Pfd3, 16);
#endif
- /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd.
- * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged.
- * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/
-#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
- /* Init Usb1 PLL. */
- CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN);
- /* Init Usb1 pfd0. */
- CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 33);
- /* Init Usb1 pfd1. */
- CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16);
- /* Init Usb1 pfd2. */
- CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17);
- /* Init Usb1 pfd3. */
- CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 19);
- /* Disable Usb1 PLL output for USBPHY1. */
- CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK;
-#endif
/* DeInit Audio PLL. */
CLOCK_DeinitAudioPll();
/* Bypass Audio PLL. */
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.c
index fc90e2374..9a1a4ab65 100644
--- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.c
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.c
@@ -71,7 +71,7 @@ const mcu_periph_obj_t mcu_spi_sck_list[8] = {
PERIPH_PIN(2, 2, kIOMUXC_LPSPI2_SCK_SELECT_INPUT, 1, &pin_GPIO_EMC_00),
PERIPH_PIN(3, 7, kIOMUXC_LPSPI3_SCK_SELECT_INPUT, 0, &pin_GPIO_AD_B0_00),
- PERIPH_PIN(3, 2, kIOMUXC_LPSPI3_SCK_SELECT_INPUT, 0, &pin_GPIO_AD_B1_15),
+ PERIPH_PIN(3, 2, kIOMUXC_LPSPI3_SCK_SELECT_INPUT, 1, &pin_GPIO_AD_B1_15),
PERIPH_PIN(4, 3, kIOMUXC_LPSPI4_SCK_SELECT_INPUT, 0, &pin_GPIO_B0_03),
PERIPH_PIN(4, 1, kIOMUXC_LPSPI4_SCK_SELECT_INPUT, 1, &pin_GPIO_B1_07),
@@ -127,8 +127,8 @@ const mcu_periph_obj_t mcu_uart_rx_list[18] = {
PERIPH_PIN(6, 2, kIOMUXC_LPUART6_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_26),
PERIPH_PIN(6, 2, kIOMUXC_LPUART6_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_03),
- PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_32),
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 0, &pin_GPIO_SD_B1_09),
+ PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_32),
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 0, &pin_GPIO_SD_B0_05),
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_11),
@@ -163,6 +163,44 @@ const mcu_periph_obj_t mcu_uart_tx_list[18] = {
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 2, &pin_GPIO_EMC_38),
};
+const mcu_periph_obj_t mcu_uart_rts_list[9] = {
+ PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_15),
+
+ PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_AD_B1_01),
+
+ PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_AD_B1_05),
+ PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_EMC_16),
+
+ PERIPH_PIN(4, 2, 0, 0, &pin_GPIO_EMC_18),
+
+ PERIPH_PIN(5, 2, 0, 0, &pin_GPIO_EMC_27),
+
+ PERIPH_PIN(6, 2, 0, 0, &pin_GPIO_EMC_29),
+
+ PERIPH_PIN(7, 2, 0, 0, &pin_GPIO_SD_B1_07),
+
+ PERIPH_PIN(8, 2, 0, 0, &pin_GPIO_SD_B0_03),
+};
+
+const mcu_periph_obj_t mcu_uart_cts_list[9] = {
+ PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_14),
+
+ PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_AD_B1_00),
+
+ PERIPH_PIN(3, 2, kIOMUXC_LPUART3_CTS_B_SELECT_INPUT, 0, &pin_GPIO_EMC_15),
+ PERIPH_PIN(3, 2, kIOMUXC_LPUART3_CTS_B_SELECT_INPUT, 1, &pin_GPIO_AD_B1_04),
+
+ PERIPH_PIN(4, 2, 0, 0, &pin_GPIO_EMC_17),
+
+ PERIPH_PIN(5, 2, 0, 0, &pin_GPIO_EMC_28),
+
+ PERIPH_PIN(6, 2, 0, 0, &pin_GPIO_EMC_30),
+
+ PERIPH_PIN(7, 2, 0, 0, &pin_GPIO_SD_B1_06),
+
+ PERIPH_PIN(8, 2, 0, 0, &pin_GPIO_SD_B0_02),
+};
+
const mcu_pwm_obj_t mcu_pwm_list[67] = {
PWM_PIN(PWM1, kPWM_Module_0, kPWM_PwmA, 1, &pin_GPIO_EMC_23),
PWM_PIN(PWM1, kPWM_Module_0, kPWM_PwmA, 1, &pin_GPIO_SD_B0_00),
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h
index b069ca76b..45b92f247 100644
--- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h
@@ -36,6 +36,8 @@ extern const mcu_periph_obj_t mcu_spi_miso_list[8];
extern const mcu_periph_obj_t mcu_uart_rx_list[18];
extern const mcu_periph_obj_t mcu_uart_tx_list[18];
+extern const mcu_periph_obj_t mcu_uart_rts_list[9];
+extern const mcu_periph_obj_t mcu_uart_cts_list[9];
extern const mcu_pwm_obj_t mcu_pwm_list[67];
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/periph.h
index 301eb0db4..9b9713bb4 100644
--- a/ports/mimxrt10xx/peripherals/mimxrt10xx/periph.h
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/periph.h
@@ -70,6 +70,8 @@ extern LPUART_Type *mcu_uart_banks[];
#ifdef MIMXRT1011_SERIES
#include "MIMXRT1011/periph.h"
+#elif defined(MIMXRT1021_SERIES)
+#include "MIMXRT1021/periph.h"
#elif defined(MIMXRT1062_SERIES)
#include "MIMXRT1062/periph.h"
#endif
diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.h
index 64a8324bd..404a411e1 100644
--- a/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.h
+++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.h
@@ -68,6 +68,8 @@ typedef struct {
#ifdef MIMXRT1011_SERIES
#include "MIMXRT1011/pins.h"
+#elif defined(MIMXRT1021_SERIES)
+#include "MIMXRT1021/pins.h"
#elif defined(MIMXRT1062_SERIES)
#include "MIMXRT1062/pins.h"
#endif
diff --git a/ports/mimxrt10xx/reset.c b/ports/mimxrt10xx/reset.c
index dc4a1dce1..a3a4f667d 100644
--- a/ports/mimxrt10xx/reset.c
+++ b/ports/mimxrt10xx/reset.c
@@ -35,5 +35,5 @@ void reset(void) {
}
bool bootloader_available(void) {
- return &_bootloader_dbl_tap >= 0;
+ return SNVS->LPGPR[0] >= 0;
}
diff --git a/ports/mimxrt10xx/reset.h b/ports/mimxrt10xx/reset.h
index b6dfc38cc..dc3106cf0 100644
--- a/ports/mimxrt10xx/reset.h
+++ b/ports/mimxrt10xx/reset.h
@@ -34,8 +34,6 @@
#define DBL_TAP_MAGIC 0xf01669ef // Randomly selected, adjusted to have first and last bit set
#define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef
-extern volatile uint32_t _bootloader_dbl_tap;
-
void reset_to_bootloader(void);
void reset(void);
bool bootloader_available(void);
diff --git a/ports/mimxrt10xx/sdk b/ports/mimxrt10xx/sdk
-Subproject 2251c7b79343966a57a0f36d897873dd40b692b
+Subproject 4e7438e654f4a6b4f386b4bb9e817d74a0fbffc
diff --git a/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c b/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c
index e20c67fa3..28d5115ac 100644
--- a/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c
+++ b/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c
@@ -16,19 +16,10 @@
static inline void flexspi_clock_init(void)
{
-#if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)
/* Switch to PLL2 for XIP to avoid hardfault during re-initialize clock. */
CLOCK_InitSysPfd(kCLOCK_Pfd2, 24); /* Set PLL2 PFD2 clock 396MHZ. */
CLOCK_SetMux(kCLOCK_FlexspiMux, 0x2); /* Choose PLL2 PFD2 clock as flexspi source clock. */
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2); /* flexspi clock 133M. */
-#else
- const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
-
- CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
- CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24); /* Set PLL3 PFD0 clock 360MHZ. */
- CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */
- CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2); /* flexspi clock 120M. */
-#endif
}
extern flexspi_device_config_t deviceconfig;
@@ -333,7 +324,11 @@ void flexspi_nor_flash_init(FLEXSPI_Type *base)
config.ahbConfig.enableAHBBufferable = true;
config.ahbConfig.enableReadAddressOpt = true;
config.ahbConfig.enableAHBCachable = true;
+#ifdef BOARD_USING_SECONDARY_QSPI_PINMUX
+ config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackInternally;
+#else
config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad;
+#endif
FLEXSPI_Init(base, &config);
/* Configure flash settings according to serial flash feature. */
diff --git a/ports/mimxrt10xx/supervisor/internal_flash.c b/ports/mimxrt10xx/supervisor/internal_flash.c
index e15b4962e..7e9d8fa37 100644
--- a/ports/mimxrt10xx/supervisor/internal_flash.c
+++ b/ports/mimxrt10xx/supervisor/internal_flash.c
@@ -166,11 +166,13 @@ void supervisor_flash_init(void) {
}
__enable_irq();
+ SCB_EnableDCache();
+
init_done = true;
}
static inline uint32_t lba2addr(uint32_t block) {
- return ((uint32_t)__fatfs_flash_start_addr) + block * FILESYSTEM_BLOCK_SIZE;
+ return CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR + block * FILESYSTEM_BLOCK_SIZE;
}
uint32_t supervisor_flash_get_block_size(void) {
@@ -178,7 +180,7 @@ uint32_t supervisor_flash_get_block_size(void) {
}
uint32_t supervisor_flash_get_block_count(void) {
- return ((uint32_t) __fatfs_flash_length) / FILESYSTEM_BLOCK_SIZE;
+ return CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE / FILESYSTEM_BLOCK_SIZE;
}
void supervisor_flash_flush(void) {
@@ -191,20 +193,20 @@ void supervisor_flash_flush(void) {
__disable_irq();
status = flexspi_nor_flash_erase_sector(FLEXSPI, sector_addr);
+ __enable_irq();
if (status != kStatus_Success) {
printf("Page erase failure %ld!\r\n", status);
return;
}
- __enable_irq();
for (int i = 0; i < SECTOR_SIZE / FLASH_PAGE_SIZE; ++i) {
__disable_irq();
status = flexspi_nor_flash_page_program(FLEXSPI, sector_addr + i * FLASH_PAGE_SIZE, (void *)_flash_cache + i * FLASH_PAGE_SIZE);
+ __enable_irq();
if (status != kStatus_Success) {
printf("Page program failure %ld!\r\n", status);
return;
}
- __enable_irq();
}
DCACHE_CleanInvalidateByRange(_flash_page_addr, SECTOR_SIZE);
diff --git a/ports/mimxrt10xx/supervisor/port.c b/ports/mimxrt10xx/supervisor/port.c
index 357307427..b311e8920 100644
--- a/ports/mimxrt10xx/supervisor/port.c
+++ b/ports/mimxrt10xx/supervisor/port.c
@@ -3,8 +3,8 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
- * Copyright (c) 2017 Artur Pacholec
+ * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2020 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,6 +24,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+/*
+ * Copyright 2018 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
#include "boards/board.h"
#include "supervisor/port.h"
@@ -54,16 +60,190 @@
#include "fsl_gpio.h"
#include "fsl_lpuart.h"
-void mpu_init(void)
-{
- ARM_MPU_Disable();
+// Device memories must be accessed in order.
+#define DEVICE 2
+// Normal memory can have accesses reorder and prefetched.
+#define NORMAL 0
+
+// Prevents instruction access.
+#define NO_EXECUTION 1
+#define EXECUTION 0
+
+// Shareable if the memory system manages coherency.
+#define NOT_SHAREABLE 0
+#define SHAREABLE 1
+
+//
+#define NOT_CACHEABLE 0
+#define CACHEABLE 1
+
+#define NOT_BUFFERABLE 0
+#define BUFFERABLE 1
+
+#define NO_SUBREGIONS 0
+
+extern uint32_t _ld_flash_size;
+extern uint32_t _ld_stack_top;
+
+extern uint32_t __isr_vector[];
+
+extern uint32_t _ld_ocram_bss_start;
+extern uint32_t _ld_ocram_bss_size;
+extern uint32_t _ld_ocram_data_destination;
+extern uint32_t _ld_ocram_data_size;
+extern uint32_t _ld_ocram_data_flash_copy;
+extern uint32_t _ld_dtcm_bss_start;
+extern uint32_t _ld_dtcm_bss_size;
+extern uint32_t _ld_dtcm_data_destination;
+extern uint32_t _ld_dtcm_data_size;
+extern uint32_t _ld_dtcm_data_flash_copy;
+extern uint32_t _ld_itcm_destination;
+extern uint32_t _ld_itcm_size;
+extern uint32_t _ld_itcm_flash_copy;
+
+extern void main(void);
+
+// This replaces the Reset_Handler in startup_*.S and SystemInit in system_*.c.
+__attribute__((used, naked)) void Reset_Handler(void) {
+ __disable_irq();
+ SCB->VTOR = (uint32_t) &__isr_vector;
+ __set_MSP((uint32_t) &_ld_stack_top);
+
+ /* Disable I cache and D cache */
+ SCB_DisableICache();
+ SCB_DisableDCache();
+
+ // Changing the FlexRAM must happen here where the stack is empty. If it is in a function call,
+ // then the return will jump to an invalid address.
+ // Configure FlexRAM. The e is one block of ITCM (0b11) and DTCM (0b10). The rest is two OCRAM
+ // (0b01). We shift in zeroes for all unimplemented banks.
+ IOMUXC_GPR->GPR17 = (0xe5555555) >> (32 - 2 * FSL_FEATURE_FLEXRAM_INTERNAL_RAM_TOTAL_BANK_NUMBERS);
+
+ // Switch from FlexRAM fuse config to the IOMUXC values.
+ IOMUXC_GPR->GPR16 |= IOMUXC_GPR_GPR16_FLEXRAM_BANK_CFG_SEL(1);
+
+ // Let the core know the TCM sizes changed.
+ uint32_t current_gpr14 = IOMUXC_GPR->GPR14;
+ current_gpr14 &= ~IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_MASK;
+ current_gpr14 |= IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ(0x6);
+ current_gpr14 &= ~IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_MASK;
+ current_gpr14 |= IOMUXC_GPR_GPR14_CM7_CFGITCMSZ(0x6);
+ IOMUXC_GPR->GPR14 = current_gpr14;
+
+ #if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
+ SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); /* set CP10, CP11 Full Access */
+ #endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */
+
+ /* Disable Watchdog Power Down Counter */
+ WDOG1->WMCR &= ~WDOG_WMCR_PDE_MASK;
+ WDOG2->WMCR &= ~WDOG_WMCR_PDE_MASK;
+
+ /* Watchdog disable */
+ WDOG1->WCR &= ~WDOG_WCR_WDE_MASK;
+ WDOG2->WCR &= ~WDOG_WCR_WDE_MASK;
+ RTWDOG->CNT = 0xD928C520U; /* 0xD928C520U is the update key */
+ RTWDOG->TOVAL = 0xFFFF;
+ RTWDOG->CS = (uint32_t) ((RTWDOG->CS) & ~RTWDOG_CS_EN_MASK) | RTWDOG_CS_UPDATE_MASK;
+
+ /* Disable Systick which might be enabled by bootrom */
+ if (SysTick->CTRL & SysTick_CTRL_ENABLE_Msk)
+ {
+ SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
+ }
+
+ /* Disable MPU */
+ ARM_MPU_Disable();
+
+ // Copy all of the code to run from ITCM. Do this while the MPU is disabled because we write
+ // protect it.
+ for (uint32_t i = 0; i < ((size_t) &_ld_itcm_size) / 4; i++) {
+ (&_ld_itcm_destination)[i] = (&_ld_itcm_flash_copy)[i];
+ }
+
+ // The first number in RBAR is the region number. When searching for a policy, the region with
+ // the highest number wins. If none match, then the default policy set at enable applies.
+
+ // This is an undocumented region and is likely more registers.
+ MPU->RBAR = ARM_MPU_RBAR(8, 0xC0000000U);
+ MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, DEVICE, NOT_SHAREABLE, NOT_CACHEABLE, NOT_BUFFERABLE, NO_SUBREGIONS, ARM_MPU_REGION_SIZE_512MB);
+
+ // This is the SEMC region where external RAM and 8+ flash would live. Disable for now, even though the EVKs have stuff here.
+ MPU->RBAR = ARM_MPU_RBAR(9, 0x80000000U);
+ MPU->RASR = ARM_MPU_RASR(NO_EXECUTION, ARM_MPU_AP_NONE, DEVICE, NOT_SHAREABLE, NOT_CACHEABLE, NOT_BUFFERABLE, NO_SUBREGIONS, ARM_MPU_REGION_SIZE_1GB);
+
+ // FlexSPI2 is 0x70000000
+
+ // This the first 1MB of flash is the bootloader and CircuitPython read-only data.
+ MPU->RBAR = ARM_MPU_RBAR(10, 0x60000000U);
+ MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, NO_SUBREGIONS, ARM_MPU_REGION_SIZE_1MB);
+
+ // The remainder of flash is the fat filesystem which could have code on it too. Make sure that
+ // we set the region to the minimal size so that bad data doesn't get speculatively fetched.
+ // Thanks to Damien for the tip!
+ uint32_t region_size = ARM_MPU_REGION_SIZE_32B;
+ uint32_t filesystem_size = &_ld_filesystem_end - &_ld_filesystem_start;
+ while (filesystem_size > (1u << (region_size + 1))) {
+ region_size += 1;
+ }
+ // Mask out as much of the remainder as we can. For example on an 8MB flash, 7MB are for the
+ // filesystem. The region_size here must be a power of 2 so it is 8MB. Using the subregion mask
+ // we can ignore 1/8th size chunks. So, we ignore the last 1MB using the subregion.
+ uint32_t remainder = (1u << (region_size + 1)) - filesystem_size;
+ uint32_t subregion_size = (1u << (region_size + 1)) / 8;
+ uint8_t subregion_mask = (0xff00 >> (remainder / subregion_size)) & 0xff;
+
+ MPU->RBAR = ARM_MPU_RBAR(11, 0x60100000U);
+ MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, subregion_mask, region_size);
+
+ // This the ITCM. Set it to read-only because we've loaded everything already and it's easy to
+ // accidentally write the wrong value to 0x00000000 (aka NULL).
+ MPU->RBAR = ARM_MPU_RBAR(12, 0x00000000U);
+ MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_RO, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, NO_SUBREGIONS, ARM_MPU_REGION_SIZE_32KB);
+
+ // This the DTCM.
+ MPU->RBAR = ARM_MPU_RBAR(13, 0x20000000U);
+ MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, NO_SUBREGIONS, ARM_MPU_REGION_SIZE_32KB);
+
+ // This is OCRAM.
+ MPU->RBAR = ARM_MPU_RBAR(14, 0x20200000U);
+ MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, NO_SUBREGIONS, ARM_MPU_REGION_SIZE_512KB);
+
+ // We steal 64k from FlexRAM for ITCM and DTCM so disable those memory regions here.
+ MPU->RBAR = ARM_MPU_RBAR(15, 0x20280000U);
+ MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, 0x80, ARM_MPU_REGION_SIZE_512KB);
+
+ /* Enable MPU */
+ ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk);
+
+ /* We're done mucking with memory so enable I cache and D cache */
+ SCB_EnableDCache();
+ SCB_EnableICache();
+
+ // Copy all of the data to run from DTCM.
+ for (uint32_t i = 0; i < ((size_t) &_ld_dtcm_data_size) / 4; i++) {
+ (&_ld_dtcm_data_destination)[i] = (&_ld_dtcm_data_flash_copy)[i];
+ }
+
+ // Clear DTCM bss.
+ for (uint32_t i = 0; i < ((size_t) &_ld_dtcm_bss_size) / 4; i++) {
+ (&_ld_dtcm_bss_start)[i] = 0;
+ }
+
+ // Copy all of the data to run from OCRAM.
+ for (uint32_t i = 0; i < ((size_t) &_ld_ocram_data_size) / 4; i++) {
+ (&_ld_ocram_data_destination)[i] = (&_ld_ocram_data_flash_copy)[i];
+ }
+
+ // Clear OCRAM bss.
+ for (uint32_t i = 0; i < ((size_t) &_ld_ocram_bss_size) / 4; i++) {
+ (&_ld_ocram_bss_start)[i] = 0;
+ }
- SCB_EnableDCache();
- SCB_EnableICache();
+ __enable_irq();
+ main();
}
safe_mode_t port_init(void) {
- mpu_init();
clocks_init();
// Configure millisecond timer initialization.
@@ -76,9 +256,6 @@ safe_mode_t port_init(void) {
// Reset everything into a known state before board_init.
reset_port();
- // Init the board last so everything else is ready
- board_init();
-
if (board_requests_safe_mode()) {
return USER_SAFE_MODE;
}
@@ -129,7 +306,7 @@ void reset_port(void) {
}
void reset_to_bootloader(void) {
- _bootloader_dbl_tap = DBL_TAP_MAGIC;
+ SNVS->LPGPR[0] = DBL_TAP_MAGIC;
reset();
}
@@ -137,23 +314,64 @@ void reset_cpu(void) {
reset();
}
-extern uint32_t _heap_start, _estack;
+extern uint32_t _ld_heap_start, _ld_heap_end, _ld_stack_top, _ld_stack_bottom;
uint32_t *port_stack_get_limit(void) {
- return &_heap_start;
+ return &_ld_heap_start;
}
uint32_t *port_stack_get_top(void) {
- return &_estack;
+ return &_ld_stack_top;
+}
+
+uint32_t *port_heap_get_bottom(void) {
+ return &_ld_heap_start;
+}
+
+// Get heap top address
+uint32_t *port_heap_get_top(void) {
+ return &_ld_heap_end;
}
-extern uint32_t __bss_end__;
// Place the word to save just after our BSS section that gets blanked.
void port_set_saved_word(uint32_t value) {
- __bss_end__ = value;
+ SNVS->LPGPR[1] = value;
}
uint32_t port_get_saved_word(void) {
- return __bss_end__;
+ return SNVS->LPGPR[1];
+}
+
+/**
+ * \brief Default interrupt handler for unused IRQs.
+ */
+__attribute__((used)) void MemManage_Handler(void)
+{
+ reset_into_safe_mode(MEM_MANAGE);
+ while (true) {
+ asm("nop;");
+ }
+}
+
+/**
+ * \brief Default interrupt handler for unused IRQs.
+ */
+__attribute__((used)) void BusFault_Handler(void)
+{
+ reset_into_safe_mode(MEM_MANAGE);
+ while (true) {
+ asm("nop;");
+ }
+}
+
+/**
+ * \brief Default interrupt handler for unused IRQs.
+ */
+__attribute__((used)) void UsageFault_Handler(void)
+{
+ reset_into_safe_mode(MEM_MANAGE);
+ while (true) {
+ asm("nop;");
+ }
}
/**
@@ -166,3 +384,4 @@ __attribute__((used)) void HardFault_Handler(void)
asm("nop;");
}
}
+
diff --git a/ports/mimxrt10xx/supervisor/usb.c b/ports/mimxrt10xx/supervisor/usb.c
index c38dd55b9..051fcca9d 100644
--- a/ports/mimxrt10xx/supervisor/usb.c
+++ b/ports/mimxrt10xx/supervisor/usb.c
@@ -49,6 +49,10 @@ void init_usb_hardware(void) {
phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK);
phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06);
usb_phy->TX = phytx;
+
+ // Temporarily disable the data cache until we can sort out all of the spots in TinyUSB that
+ // need the cache invalidated or cleaned.
+ SCB_DisableDCache();
}
void USB_OTG1_IRQHandler(void) {
diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile
index f38b9f684..47a5b8653 100755
--- a/ports/nrf/Makefile
+++ b/ports/nrf/Makefile
@@ -73,8 +73,6 @@ INC += -I$(BUILD)
INC += -I$(BUILD)/genhdr
INC += -I./../../lib/cmsis/inc
INC += -I./boards/$(BOARD)
-INC += -I./modules/ubluepy
-INC += -I./modules/ble
INC += -I./nrfx
INC += -I./nrfx/hal
INC += -I./nrfx/mdk
@@ -157,6 +155,7 @@ SRC_C += \
boards/$(BOARD)/pins.c \
device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \
bluetooth/ble_drv.c \
+ common-hal/_bleio/bonding.c \
lib/libc/string0.c \
lib/mp-readline/readline.c \
lib/oofatfs/ff.c \
@@ -184,6 +183,32 @@ SRC_C += \
lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c
endif
+ifeq ($(CIRCUITPY_NETWORK),1)
+CFLAGS += -DMICROPY_PY_NETWORK=1
+
+SRC_MOD += lib/netutils/netutils.c
+
+ifneq ($(MICROPY_PY_WIZNET5K),0)
+WIZNET5K_DIR=drivers/wiznet5k
+INC += -I$(TOP)/$(WIZNET5K_DIR)
+CFLAGS_MOD += -DMICROPY_PY_WIZNET5K=$(MICROPY_PY_WIZNET5K) -D_WIZCHIP_=$(MICROPY_PY_WIZNET5K)
+SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\
+ ethernet/w$(MICROPY_PY_WIZNET5K)/w$(MICROPY_PY_WIZNET5K).c \
+ ethernet/wizchip_conf.c \
+ ethernet/socket.c \
+ internet/dns/dns.c \
+ internet/dhcp/dhcp.c \
+ )
+
+endif # MICROPY_PY_WIZNET5K
+endif # CIRCUITPY_NETWORK
+
+ifeq ($(CIRCUITPY_NETWORK),1)
+ifneq ($(MICROPY_PY_WIZNET5K),0)
+SRC_SHARED_MODULE += wiznet/__init__.c wiznet/wiznet5k.c
+endif
+endif
+
SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
$(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
$(addprefix common-hal/, $(SRC_COMMON_HAL))
diff --git a/ports/nrf/background.c b/ports/nrf/background.c
index 629967b3d..966c56e0b 100644
--- a/ports/nrf/background.c
+++ b/ports/nrf/background.c
@@ -43,6 +43,7 @@
#if CIRCUITPY_BLEIO
#include "supervisor/shared/bluetooth.h"
+#include "common-hal/_bleio/bonding.h"
#endif
static bool running_background_tasks = false;
@@ -68,6 +69,7 @@ void run_background_tasks(void) {
#if CIRCUITPY_BLEIO
supervisor_bluetooth_background();
+ bonding_background();
#endif
#if CIRCUITPY_DISPLAYIO
diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c
index 28a265b7f..e410ac3b4 100644
--- a/ports/nrf/bluetooth/ble_drv.c
+++ b/ports/nrf/bluetooth/ble_drv.c
@@ -145,6 +145,9 @@ void SD_EVT_IRQHandler(void) {
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
bool done = false;
while (it != NULL) {
+ #if CIRCUITPY_VERBOSE_BLE
+ // mp_printf(&mp_plat_print, " calling handler: 0x%08lx, param: 0x%08lx\n", it->func-1, it->param);
+ #endif
done = it->func(event, it->param) || done;
it = it->next;
}
diff --git a/ports/nrf/bluetooth/ble_drv.h b/ports/nrf/bluetooth/ble_drv.h
index 91990da6d..ece4b2436 100644
--- a/ports/nrf/bluetooth/ble_drv.h
+++ b/ports/nrf/bluetooth/ble_drv.h
@@ -33,8 +33,6 @@
#include "ble.h"
-#define MAX_TX_IN_PROGRESS 10
-
#ifndef BLE_GATT_ATT_MTU_DEFAULT
#define BLE_GATT_ATT_MTU_DEFAULT GATT_MTU_SIZE_DEFAULT
#endif
diff --git a/ports/nrf/boards/aramcon_badge_2019/board.c b/ports/nrf/boards/aramcon_badge_2019/board.c
new file mode 100644
index 000000000..efb449285
--- /dev/null
+++ b/ports/nrf/boards/aramcon_badge_2019/board.c
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Uri Shaked
+ * Copyright (c) 2019 Benjamin Meisels
+ *
+ * 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 "boards/board.h"
+#include "common-hal/microcontroller/Pin.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/nrf/boards/aramcon_badge_2019/mpconfigboard.h b/ports/nrf/boards/aramcon_badge_2019/mpconfigboard.h
new file mode 100644
index 000000000..51d14721c
--- /dev/null
+++ b/ports/nrf/boards/aramcon_badge_2019/mpconfigboard.h
@@ -0,0 +1,31 @@
+#include "nrfx/hal/nrf_gpio.h"
+
+#define MICROPY_HW_BOARD_NAME "ARAMCON Badge 2019"
+#define MICROPY_HW_MCU_NAME "nRF52840"
+
+#define MICROPY_HW_LED_STATUS (&pin_P1_11)
+
+#ifdef QSPI_FLASH_FILESYSTEM
+#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 22)
+#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 20)
+#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(1, 4)
+#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(1, 6)
+#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(1, 0)
+#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 2)
+#endif
+
+#ifdef SPI_FLASH_FILESYSTEM
+#define SPI_FLASH_MOSI_PIN &pin_P0_20
+#define SPI_FLASH_MISO_PIN &pin_P0_22
+#define SPI_FLASH_SCK_PIN &pin_P1_00
+#define SPI_FLASH_CS_PIN &pin_P1_02
+#endif
+
+#define BOARD_HAS_32KHZ_XTAL 0
+
+#define DEFAULT_I2C_BUS_SCL (&pin_P0_28)
+#define DEFAULT_I2C_BUS_SDA (&pin_P0_03)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_P0_01)
+#define DEFAULT_SPI_BUS_MOSI (&pin_P1_10)
+#define DEFAULT_SPI_BUS_MISO (&pin_P1_09)
diff --git a/ports/nrf/boards/aramcon_badge_2019/mpconfigboard.mk b/ports/nrf/boards/aramcon_badge_2019/mpconfigboard.mk
new file mode 100644
index 000000000..09252ab4b
--- /dev/null
+++ b/ports/nrf/boards/aramcon_badge_2019/mpconfigboard.mk
@@ -0,0 +1,14 @@
+USB_VID = 0x239A
+USB_PID = 0x807A
+USB_PRODUCT = "ARAMCON Badge 2019"
+USB_MANUFACTURER = "ARAMCON Badge Team"
+
+MCU_CHIP = nrf52840
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "GD25Q16C"
+
+CIRCUITPY_DISPLAYIO = 1
+
+CIRCUITPY_REQUIRE_I2C_PULLUPS = 0
diff --git a/ports/nrf/boards/aramcon_badge_2019/pins.c b/ports/nrf/boards/aramcon_badge_2019/pins.c
new file mode 100644
index 000000000..82ab20013
--- /dev/null
+++ b/ports/nrf/boards/aramcon_badge_2019/pins.c
@@ -0,0 +1,34 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_LEFT_BUTTON), MP_ROM_PTR(&pin_P0_02) },
+ { MP_ROM_QSTR(MP_QSTR_MIDDLE_BUTTON), MP_ROM_PTR(&pin_P0_29) },
+ { MP_ROM_QSTR(MP_QSTR_RIGHT_BUTTON), MP_ROM_PTR(&pin_P0_31) },
+
+ { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_P1_11) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_28) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_03) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_01) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P1_10) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P1_09) },
+
+ { MP_ROM_QSTR(MP_QSTR_SND_CS), MP_ROM_PTR(&pin_P1_13) },
+ { MP_ROM_QSTR(MP_QSTR_SND_DREQ), MP_ROM_PTR(&pin_P0_13) },
+ { MP_ROM_QSTR(MP_QSTR_SND_RESET), MP_ROM_PTR(&pin_P0_00) },
+ { MP_ROM_QSTR(MP_QSTR_SND_XDCS), MP_ROM_PTR(&pin_P0_24) },
+
+ { MP_ROM_QSTR(MP_QSTR_DISP_BUSY), MP_ROM_PTR(&pin_P0_26) },
+ { MP_ROM_QSTR(MP_QSTR_DISP_CS), MP_ROM_PTR(&pin_P0_07) },
+ { MP_ROM_QSTR(MP_QSTR_DISP_DC), MP_ROM_PTR(&pin_P0_12) },
+ { MP_ROM_QSTR(MP_QSTR_DISP_RESET), MP_ROM_PTR(&pin_P0_06) },
+
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P0_08) },
+
+ { MP_ROM_QSTR(MP_QSTR_VIBRATION_MOTOR), MP_ROM_PTR(&pin_P0_17) },
+
+ { MP_ROM_QSTR(MP_QSTR_BATTERY_SENSE), MP_ROM_PTR(&pin_P0_30) },
+};
+
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/nrf/boards/circuitplayground_bluefruit/board.c b/ports/nrf/boards/circuitplayground_bluefruit/board.c
index 7c8ec8e9a..3aa6857da 100644
--- a/ports/nrf/boards/circuitplayground_bluefruit/board.c
+++ b/ports/nrf/boards/circuitplayground_bluefruit/board.c
@@ -28,6 +28,7 @@
#include "mpconfigboard.h"
#include "py/obj.h"
#include "peripherals/nrf/pins.h"
+#include "supervisor/shared/board.h"
#include "nrf_gpio.h"
@@ -47,4 +48,6 @@ void reset_board(void) {
NRF_GPIO_PIN_S0S1,
NRF_GPIO_PIN_NOSENSE);
nrf_gpio_pin_write(POWER_SWITCH_PIN->number, false);
+
+ board_reset_user_neopixels();
}
diff --git a/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h b/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h
index 7f9933b42..17b044b14 100644
--- a/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h
+++ b/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h
@@ -32,7 +32,7 @@
#define MICROPY_HW_LED_STATUS (&pin_P1_14)
-// Unusually, board does not have a 32 kHz xtal. Nearly all boards do.
+// Board does not have a 32kHz crystal. It does have a 32MHz crystal.
#define BOARD_HAS_32KHZ_XTAL (0)
#if QSPI_FLASH_FILESYSTEM
@@ -54,6 +54,8 @@
// Disables onboard peripherals and neopixels to save power.
#define POWER_SWITCH_PIN (&pin_P0_06)
+#define USER_NEOPIXELS_PIN (&pin_P0_13)
+
#define DEFAULT_I2C_BUS_SCL (&pin_P0_04)
#define DEFAULT_I2C_BUS_SDA (&pin_P0_05)
diff --git a/ports/nrf/boards/clue_nrf52840_express/board.c b/ports/nrf/boards/clue_nrf52840_express/board.c
index c118fe92f..5f5337a3d 100644
--- a/ports/nrf/boards/clue_nrf52840_express/board.c
+++ b/ports/nrf/boards/clue_nrf52840_express/board.c
@@ -40,7 +40,7 @@ displayio_fourwire_obj_t board_display_obj;
uint8_t display_init_sequence[] = {
0x01, 0 | DELAY, 150, // SWRESET
0x11, 0 | DELAY, 255, // SLPOUT
- 0x36, 1, 0x00, // _MADCTL bottom to top refresh in vsync aligned order.
+ 0x36, 1, 0b10100000, // _MADCTL for rotation 0
0x3a, 1, 0x55, // COLMOD - 16bit color
0x21, 0 | DELAY, 10, // _INVON
0x13, 0 | DELAY, 10, // _NORON
@@ -49,7 +49,7 @@ uint8_t display_init_sequence[] = {
void board_init(void) {
busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
- common_hal_busio_spi_construct(spi, &pin_P0_14, &pin_P0_15, NULL);
+ common_hal_busio_spi_construct(spi, &pin_P0_14, &pin_P0_15, mp_const_none);
common_hal_busio_spi_never_reset(spi);
displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
@@ -67,9 +67,9 @@ void board_init(void) {
bus,
240, // Width (after rotation)
240, // Height (after rotation)
- 0, // column start
+ 80, // column start
0, // row start
- 270, // rotation
+ 0, // rotation
16, // Color depth
false, // Grayscale
false, // Pixels in a byte share a row. Only used for depth < 8
diff --git a/ports/nrf/boards/clue_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/clue_nrf52840_express/mpconfigboard.h
index a239ca7ce..9cb05de09 100644
--- a/ports/nrf/boards/clue_nrf52840_express/mpconfigboard.h
+++ b/ports/nrf/boards/clue_nrf52840_express/mpconfigboard.h
@@ -50,7 +50,8 @@
#define SPI_FLASH_CS_PIN &pin_P0_20
#endif
-#define BOARD_HAS_CRYSTAL 1
+// No 32kHz crystal. THere's a 32MHz crystal in the nRF module.
+#define BOARD_HAS_32KHZ_XTAL (0)
#define DEFAULT_I2C_BUS_SCL (&pin_P0_25)
#define DEFAULT_I2C_BUS_SDA (&pin_P0_24)
diff --git a/ports/nrf/boards/clue_nrf52840_express/pins.c b/ports/nrf/boards/clue_nrf52840_express/pins.c
index b13d1977f..ab0738893 100644
--- a/ports/nrf/boards/clue_nrf52840_express/pins.c
+++ b/ports/nrf/boards/clue_nrf52840_express/pins.c
@@ -1,5 +1,8 @@
#include "shared-bindings/board/__init__.h"
+#include "boards/board.h"
+#include "shared-module/displayio/__init__.h"
+
STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_P0), MP_ROM_PTR(&pin_P0_04) },
{ MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P0_04) },
@@ -83,8 +86,15 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_P0_24) },
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_24) },
- { MP_ROM_QSTR(MP_QSTR_MICROPHONE_CLOCK), MP_ROM_PTR(&pin_P0_11) },
- { MP_ROM_QSTR(MP_QSTR_MICROPHONE_DATA), MP_ROM_PTR(&pin_P1_08) },
+ { MP_ROM_QSTR(MP_QSTR_MICROPHONE_CLOCK), MP_ROM_PTR(&pin_P0_01) },
+ { MP_ROM_QSTR(MP_QSTR_MICROPHONE_DATA), MP_ROM_PTR(&pin_P0_00) },
+
+ { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_P1_00) },
+
+ { MP_ROM_QSTR(MP_QSTR_PROXIMITY_LIGHT_INTERRUPT), MP_ROM_PTR(&pin_P0_09) },
+ { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_GYRO_INTERRUPT), MP_ROM_PTR(&pin_P1_06) },
+
+ { MP_ROM_QSTR(MP_QSTR_WHITE_LEDS), MP_ROM_PTR(&pin_P0_10) },
{ MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_P1_03) },
{ MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_P1_05) },
@@ -96,6 +106,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ 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_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}
};
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/nrf/boards/common.template.ld b/ports/nrf/boards/common.template.ld
index b110e6052..2fca16707 100644
--- a/ports/nrf/boards/common.template.ld
+++ b/ports/nrf/boards/common.template.ld
@@ -19,14 +19,15 @@ MEMORY
/* 0x2000000 - RAM:ORIGIN is reserved for Softdevice */
- /* SoftDevice 6.1.0 takes 0x7b78 bytes (30.86 kb) minimum with high ATT MTU. */
+ /* SoftDevice 6.1.0 with 5 connections and various increases takes just under 64kiB.
/* To measure the minimum required amount of memory for given configuration, set this number
high enough to work and then check the mutation of the value done by sd_ble_enable. */
- RAM (xrw) : ORIGIN = 0x20000000 + 32K, LENGTH = 256K - 32K
+ SPIM3_RAM (rw) : ORIGIN = 0x20000000 + ${SOFTDEVICE_RAM_SIZE}, LENGTH = ${SPIM3_BUFFER_SIZE}
+ RAM (xrw) : ORIGIN = 0x20000000 + ${SOFTDEVICE_RAM_SIZE} + ${SPIM3_BUFFER_SIZE}, LENGTH = 256K - ${SOFTDEVICE_RAM_SIZE} -${SPIM3_BUFFER_SIZE}
+
}
-/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 40K;
+/* produce a link error if there is not this amount of RAM available */
_minimum_heap_size = 0;
/* top end of the stack */
@@ -38,6 +39,10 @@ _estack = ORIGIN(RAM) + LENGTH(RAM);
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_end = 0x20020000; /* tunable */
+/* nrf52840 SPIM3 needs its own area to work around hardware problems. Nothing else may use this space. */
+_spim3_ram = ORIGIN(SPIM3_RAM);
+_spim3_ram_end = ORIGIN(SPIM3_RAM) + LENGTH(RAM);
+
/* define output sections */
SECTIONS
{
@@ -125,7 +130,7 @@ SECTIONS
.stack :
{
. = ALIGN(4);
- . = . + _minimum_stack_size;
+ . = . + ${CIRCUITPY_DEFAULT_STACK_SIZE};
. = ALIGN(4);
} >RAM
diff --git a/ports/nrf/boards/feather_bluefruit_sense/board.c b/ports/nrf/boards/feather_bluefruit_sense/board.c
new file mode 100644
index 000000000..4421970ee
--- /dev/null
+++ b/ports/nrf/boards/feather_bluefruit_sense/board.c
@@ -0,0 +1,38 @@
+/*
+ * 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 "boards/board.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/nrf/boards/feather_bluefruit_sense/mpconfigboard.h b/ports/nrf/boards/feather_bluefruit_sense/mpconfigboard.h
new file mode 100644
index 000000000..4b2b69e7e
--- /dev/null
+++ b/ports/nrf/boards/feather_bluefruit_sense/mpconfigboard.h
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Dan Halbert 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 "nrfx/hal/nrf_gpio.h"
+
+#define MICROPY_HW_BOARD_NAME "Adafruit Feather Bluefruit Sense"
+#define MICROPY_HW_MCU_NAME "nRF52840"
+
+#define MICROPY_HW_NEOPIXEL (&pin_P0_16)
+
+#define MICROPY_HW_LED_STATUS (&pin_P1_11)
+
+// Board does not have a 32kHz crystal. It does have a 32MHz crystal.
+#define BOARD_HAS_32KHZ_XTAL (0)
+
+#if QSPI_FLASH_FILESYSTEM
+#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 17)
+#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 22)
+#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 23)
+#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 21)
+#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19)
+#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 20)
+#endif
+
+#if SPI_FLASH_FILESYSTEM
+#define SPI_FLASH_MOSI_PIN &pin_P0_17
+#define SPI_FLASH_MISO_PIN &pin_P0_22
+#define SPI_FLASH_SCK_PIN &pin_P0_19
+#define SPI_FLASH_CS_PIN &pin_P0_20
+#endif
+
+#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
+
+#define CIRCUITPY_INTERNAL_NVM_SIZE (4096)
+
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_P0_11)
+#define DEFAULT_I2C_BUS_SDA (&pin_P0_12)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_P0_14)
+#define DEFAULT_SPI_BUS_MOSI (&pin_P0_13)
+#define DEFAULT_SPI_BUS_MISO (&pin_P0_15)
+
+#define DEFAULT_UART_BUS_RX (&pin_P0_24)
+#define DEFAULT_UART_BUS_TX (&pin_P0_25)
diff --git a/ports/nrf/boards/feather_bluefruit_sense/mpconfigboard.mk b/ports/nrf/boards/feather_bluefruit_sense/mpconfigboard.mk
new file mode 100644
index 000000000..5813e6136
--- /dev/null
+++ b/ports/nrf/boards/feather_bluefruit_sense/mpconfigboard.mk
@@ -0,0 +1,10 @@
+USB_VID = 0x239A
+USB_PID = 0x8088
+USB_PRODUCT = "Feather Bluefruit Sense"
+USB_MANUFACTURER = "Adafruit Industries LLC"
+
+MCU_CHIP = nrf52840
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "GD25Q16C"
diff --git a/ports/nrf/boards/feather_bluefruit_sense/pins.c b/ports/nrf/boards/feather_bluefruit_sense/pins.c
new file mode 100644
index 000000000..55eb76463
--- /dev/null
+++ b/ports/nrf/boards/feather_bluefruit_sense/pins.c
@@ -0,0 +1,58 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_30) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_28) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_02) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_03) },
+
+ { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_31) },
+
+ { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_29) },
+ { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_29) },
+
+ { MP_ROM_QSTR(MP_QSTR_SWITCH), MP_ROM_PTR(&pin_P1_02) },
+
+ { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) },
+ { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) },
+
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_10) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_08) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_07) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_26) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_27) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_06) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_08) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_09) },
+
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P0_16) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_14) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_13) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_15) },
+
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_25) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_24) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_12) },
+
+ { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_11) },
+ { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_11) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_11) },
+
+ { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) },
+
+ { MP_ROM_QSTR(MP_QSTR_MICROPHONE_CLOCK), MP_ROM_PTR(&pin_P0_01) },
+ { MP_ROM_QSTR(MP_QSTR_MICROPHONE_DATA), MP_ROM_PTR(&pin_P0_00) },
+
+ { MP_ROM_QSTR(MP_QSTR_PROXIMITY_LIGHT_INTERRUPT), MP_ROM_PTR(&pin_P1_00) },
+
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+};
+
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk
index d421e5210..b972bcbed 100644
--- a/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk
+++ b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk
@@ -8,3 +8,5 @@ MCU_CHIP = nrf52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "GD25Q16C"
+
+CIRCUITPY__EVE = 1
diff --git a/ports/nrf/boards/ohs2020_badge/board.c b/ports/nrf/boards/ohs2020_badge/board.c
new file mode 100644
index 000000000..7e3e05814
--- /dev/null
+++ b/ports/nrf/boards/ohs2020_badge/board.c
@@ -0,0 +1,99 @@
+/*
+ * 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 "boards/board.h"
+#include "mpconfigboard.h"
+
+#include "shared-bindings/busio/SPI.h"
+#include "shared-bindings/displayio/FourWire.h"
+#include "shared-module/displayio/__init__.h"
+#include "shared-module/displayio/mipi_constants.h"
+#include "tick.h"
+
+displayio_fourwire_obj_t board_display_obj;
+
+#define DELAY 0x80
+
+uint8_t display_init_sequence[] = {
+ 0x01, 0 | DELAY, 150, // SWRESET
+ 0x11, 0 | DELAY, 255, // SLPOUT
+ 0x36, 1, 0b10100000, // _MADCTL bottom to top refresh in vsync aligned order.
+ 0x3a, 1, 0x55, // COLMOD - 16bit color
+ 0x21, 0 | DELAY, 10, // _INVON
+ 0x13, 0 | DELAY, 10, // _NORON
+ 0x29, 0 | DELAY, 255, // _DISPON
+};
+
+void board_init(void) {
+ busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
+ common_hal_busio_spi_construct(spi, &pin_P0_11, &pin_P0_12, mp_const_none);
+ common_hal_busio_spi_never_reset(spi);
+
+ displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
+ bus->base.type = &displayio_fourwire_type;
+ common_hal_displayio_fourwire_construct(bus,
+ spi,
+ &pin_P0_08, // TFT_DC Command or data
+ &pin_P0_14, // TFT_CS Chip select
+ &pin_P0_13, // TFT_RST Reset
+ 60000000);
+
+ displayio_display_obj_t* display = &displays[0].display;
+ display->base.type = &displayio_display_type;
+ common_hal_displayio_display_construct(display,
+ bus,
+ 240, // Width (after rotation)
+ 240, // Height (after rotation)
+ 80, // column start
+ 0, // row start
+ 0, // rotation
+ 16, // Color depth
+ false, // Grayscale
+ false, // Pixels in a byte share a row. Only used for depth < 8
+ 1, // bytes per cell. Only valid for depths < 8
+ false, // reverse_pixels_in_byte. Only valid for depths < 8
+ MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command
+ MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command
+ MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command
+ 0x37, // set vertical scroll command
+ display_init_sequence,
+ sizeof(display_init_sequence),
+ NULL, // backlight pin
+ NO_BRIGHTNESS_COMMAND,
+ 1.0f, // brightness (ignored)
+ true, // auto_brightness
+ false, // single_byte_bounds
+ false, // data_as_commands
+ true, // auto_refresh
+ 60); // native_frames_per_second
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/nrf/boards/ohs2020_badge/mpconfigboard.h b/ports/nrf/boards/ohs2020_badge/mpconfigboard.h
new file mode 100644
index 000000000..8edc40423
--- /dev/null
+++ b/ports/nrf/boards/ohs2020_badge/mpconfigboard.h
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2020 Michael Welling
+ *
+ * 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 "nrfx/hal/nrf_gpio.h"
+
+#define MICROPY_HW_BOARD_NAME "Open Hardware Summit 2020 Badge"
+#define MICROPY_HW_MCU_NAME "nRF52840"
+
+#if QSPI_FLASH_FILESYSTEM
+#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 0)
+#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 22)
+#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 20)
+#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(1, 2)
+#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(1, 1)
+#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 23)
+#endif
+
+#if SPI_FLASH_FILESYSTEM
+#define SPI_FLASH_MOSI_PIN &pin_P1_00
+#define SPI_FLASH_MISO_PIN &pin_P0_22
+#define SPI_FLASH_SCK_PIN &pin_P1_01
+#define SPI_FLASH_CS_PIN &pin_P0_23
+#endif
+
+#define BOARD_HAS_CRYSTAL 1
+
+#define DEFAULT_I2C_BUS_SCL (&pin_P1_14)
+#define DEFAULT_I2C_BUS_SDA (&pin_P1_15)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_P0_11)
+#define DEFAULT_SPI_BUS_MOSI (&pin_P0_12)
+#define DEFAULT_SPI_BUS_MISO (&pin_P0_07)
diff --git a/ports/nrf/boards/ohs2020_badge/mpconfigboard.mk b/ports/nrf/boards/ohs2020_badge/mpconfigboard.mk
new file mode 100644
index 000000000..7d2c6de98
--- /dev/null
+++ b/ports/nrf/boards/ohs2020_badge/mpconfigboard.mk
@@ -0,0 +1,10 @@
+USB_VID = 0x239A
+USB_PID = 0x8080
+USB_PRODUCT = "OHS2020 Badge"
+USB_MANUFACTURER = "OSHWA"
+
+MCU_CHIP = nrf52840
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "W25Q128JV_SQ"
diff --git a/ports/nrf/boards/ohs2020_badge/pins.c b/ports/nrf/boards/ohs2020_badge/pins.c
new file mode 100644
index 000000000..2cf783cc1
--- /dev/null
+++ b/ports/nrf/boards/ohs2020_badge/pins.c
@@ -0,0 +1,29 @@
+#include "shared-bindings/board/__init__.h"
+#include "shared-module/displayio/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_MICROPHONE_CLOCK), MP_ROM_PTR(&pin_P0_25) },
+ { MP_ROM_QSTR(MP_QSTR_MICROPHONE_DATA), MP_ROM_PTR(&pin_P0_28) },
+
+ { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_P0_13) },
+ { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_P0_02) },
+ { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_P0_14) },
+ { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_P0_08) },
+ { MP_ROM_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_P0_11) },
+ { MP_ROM_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_P0_12) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P1_14) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P1_15) },
+
+ { 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_DISPLAY), MP_ROM_PTR(&displays[0].display) },
+
+ { MP_ROM_QSTR(MP_QSTR_BUTTON_SW1), MP_ROM_PTR(&pin_P0_29) },
+ { MP_ROM_QSTR(MP_QSTR_BUTTON_SW2), MP_ROM_PTR(&pin_P0_03) },
+ { MP_ROM_QSTR(MP_QSTR_BUTTON_SW3), MP_ROM_PTR(&pin_P0_17) },
+ { MP_ROM_QSTR(MP_QSTR_BUTTON_SW4), MP_ROM_PTR(&pin_P1_03) },
+};
+
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/nrf/boards/particle_argon/mpconfigboard.mk b/ports/nrf/boards/particle_argon/mpconfigboard.mk
index f8d3d2aca..a0edfda95 100644
--- a/ports/nrf/boards/particle_argon/mpconfigboard.mk
+++ b/ports/nrf/boards/particle_argon/mpconfigboard.mk
@@ -8,3 +8,7 @@ MCU_CHIP = nrf52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "MX25L3233F"
+
+# Support for the Ethernet FeatherWing
+CIRCUITPY_NETWORK = 1
+MICROPY_PY_WIZNET5K = 5500 \ No newline at end of file
diff --git a/ports/nrf/boards/particle_boron/mpconfigboard.mk b/ports/nrf/boards/particle_boron/mpconfigboard.mk
index eada97a73..ccb2d63a1 100644
--- a/ports/nrf/boards/particle_boron/mpconfigboard.mk
+++ b/ports/nrf/boards/particle_boron/mpconfigboard.mk
@@ -8,3 +8,7 @@ MCU_CHIP = nrf52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "MX25L3233F"
+
+# Support for the Ethernet FeatherWing
+CIRCUITPY_NETWORK = 1
+MICROPY_PY_WIZNET5K = 5500 \ No newline at end of file
diff --git a/ports/nrf/boards/particle_xenon/mpconfigboard.mk b/ports/nrf/boards/particle_xenon/mpconfigboard.mk
index 6062da378..3970b1d05 100644
--- a/ports/nrf/boards/particle_xenon/mpconfigboard.mk
+++ b/ports/nrf/boards/particle_xenon/mpconfigboard.mk
@@ -8,3 +8,7 @@ MCU_CHIP = nrf52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "MX25L3233F"
+
+# Support for the Ethernet FeatherWing
+CIRCUITPY_NETWORK = 1
+MICROPY_PY_WIZNET5K = 5500 \ No newline at end of file
diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c
index b9b6d2e88..09b7c95b9 100644
--- a/ports/nrf/common-hal/_bleio/Adapter.c
+++ b/ports/nrf/common-hal/_bleio/Adapter.c
@@ -32,6 +32,7 @@
#include "ble.h"
#include "ble_drv.h"
+#include "bonding.h"
#include "nrfx_power.h"
#include "nrf_nvic.h"
#include "nrf_sdm.h"
@@ -107,6 +108,9 @@ STATIC uint32_t ble_stack_enable(void) {
ble_cfg_t ble_conf;
ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM;
+ // Each additional connection costs:
+ // about 3700-4300 bytes when .hvn_tx_queue_size is 1
+ // about 9000 bytes when .hvn_tx_queue_size is 10
ble_conf.conn_cfg.params.gap_conn_cfg.conn_count = BLEIO_TOTAL_CONNECTION_COUNT;
// Event length here can influence throughput so perhaps make multiple connection profiles
// available.
@@ -117,9 +121,12 @@ STATIC uint32_t ble_stack_enable(void) {
}
memset(&ble_conf, 0, sizeof(ble_conf));
+ // adv_set_count must be == 1 for S140. Cannot be increased.
ble_conf.gap_cfg.role_count_cfg.adv_set_count = 1;
- ble_conf.gap_cfg.role_count_cfg.periph_role_count = 2;
- ble_conf.gap_cfg.role_count_cfg.central_role_count = 1;
+ // periph_role_count costs 1232 bytes for 2 to 3, then ~1840 for each further increment.
+ ble_conf.gap_cfg.role_count_cfg.periph_role_count = 4;
+ // central_role_count costs 648 bytes for 1 to 2, then ~1250 for each further increment.
+ ble_conf.gap_cfg.role_count_cfg.central_role_count = 4;
err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_conf, app_ram_start);
if (err_code != NRF_SUCCESS) {
return err_code;
@@ -127,7 +134,10 @@ STATIC uint32_t ble_stack_enable(void) {
memset(&ble_conf, 0, sizeof(ble_conf));
ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM;
- ble_conf.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = MAX_TX_IN_PROGRESS;
+ // Each increment to hvn_tx_queue_size costs 2064 bytes.
+ // DevZone recommends not setting this directly, but instead changing gap_conn_cfg.event_length.
+ // However, we are setting connection extension, so this seems to make sense.
+ ble_conf.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = 9;
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_conf, app_ram_start);
if (err_code != NRF_SUCCESS) {
return err_code;
@@ -142,10 +152,11 @@ STATIC uint32_t ble_stack_enable(void) {
return err_code;
}
- // Triple the GATT Server attribute size to accomodate both the CircuitPython built-in service
+ // Increase the GATT Server attribute size to accomodate both the CircuitPython built-in service
// and anything the user does.
memset(&ble_conf, 0, sizeof(ble_conf));
- ble_conf.gatts_cfg.attr_tab_size.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT * 3;
+ // Each increment to the BLE_GATTS_ATTR_TAB_SIZE_DEFAULT multiplier costs 1408 bytes.
+ ble_conf.gatts_cfg.attr_tab_size.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT * 5;
err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_conf, app_ram_start);
if (err_code != NRF_SUCCESS) {
return err_code;
@@ -154,7 +165,8 @@ STATIC uint32_t ble_stack_enable(void) {
// Increase the number of vendor UUIDs supported. Apple uses a complete random number per
// service and characteristic.
memset(&ble_conf, 0, sizeof(ble_conf));
- ble_conf.common_cfg.vs_uuid_cfg.vs_uuid_count = 32; // Defaults to 10.
+ // Each additional vs_uuid_count costs 16 bytes.
+ ble_conf.common_cfg.vs_uuid_cfg.vs_uuid_count = 75; // Defaults to 10.
err_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_conf, app_ram_start);
if (err_code != NRF_SUCCESS) {
return err_code;
@@ -248,6 +260,7 @@ STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
}
ble_drv_remove_event_handler(connection_on_ble_evt, connection);
connection->conn_handle = BLE_CONN_HANDLE_INVALID;
+ connection->pair_status = PAIR_NOT_PAIRED;
if (connection->connection_obj != mp_const_none) {
bleio_connection_obj_t* obj = connection->connection_obj;
obj->connection = NULL;
@@ -435,6 +448,7 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t*
.active = active
};
uint32_t err_code;
+ vm_used_ble = true;
err_code = sd_ble_gap_scan_start(&scan_params, sd_data);
if (err_code != NRF_SUCCESS) {
@@ -509,6 +523,7 @@ mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_addre
ble_drv_add_event_handler(connect_on_ble_evt, &event_info);
event_info.done = false;
+ vm_used_ble = true;
uint32_t err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM);
if (err_code != NRF_SUCCESS) {
@@ -613,6 +628,7 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
return err_code;
}
+ vm_used_ble = true;
err_code = sd_ble_gap_adv_start(adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
if (err_code != NRF_SUCCESS) {
return err_code;
@@ -630,6 +646,10 @@ void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool
check_data_fit(advertising_data_bufinfo->len, connectable);
check_data_fit(scan_response_data_bufinfo->len, connectable);
+
+ if (advertising_data_bufinfo->len > 31 && scan_response_data_bufinfo->len > 0) {
+ mp_raise_bleio_BluetoothError(translate("Extended advertisements with scan response not supported."));
+ }
// The advertising data buffers must not move, because the SoftDevice depends on them.
// So make them long-lived and reuse them onwards.
if (self->advertising_data == NULL) {
@@ -692,6 +712,10 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
return self->connection_objs;
}
+void common_hal_bleio_adapter_erase_bonding(bleio_adapter_obj_t *self) {
+ bonding_erase_storage();
+}
+
void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter) {
gc_collect_root((void**)adapter, sizeof(bleio_adapter_obj_t) / sizeof(size_t));
gc_collect_root((void**)bleio_connections, sizeof(bleio_connections) / sizeof(size_t));
@@ -703,6 +727,11 @@ void bleio_adapter_reset(bleio_adapter_obj_t* adapter) {
adapter->connection_objs = NULL;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
bleio_connection_internal_t *connection = &bleio_connections[i];
+ // Disconnect all connections with Python state cleanly. Keep any supervisor-only connections.
+ if (connection->connection_obj != mp_const_none &&
+ connection->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ common_hal_bleio_connection_disconnect(connection);
+ }
connection->connection_obj = mp_const_none;
}
}
diff --git a/ports/nrf/common-hal/_bleio/Adapter.h b/ports/nrf/common-hal/_bleio/Adapter.h
index 2ac568d66..90c88dcbe 100644
--- a/ports/nrf/common-hal/_bleio/Adapter.h
+++ b/ports/nrf/common-hal/_bleio/Adapter.h
@@ -35,7 +35,7 @@
#include "shared-bindings/_bleio/Connection.h"
#include "shared-bindings/_bleio/ScanResults.h"
-#define BLEIO_TOTAL_CONNECTION_COUNT 2
+#define BLEIO_TOTAL_CONNECTION_COUNT 5
extern bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
diff --git a/ports/nrf/common-hal/_bleio/Characteristic.c b/ports/nrf/common-hal/_bleio/Characteristic.c
index c7eec94c0..e311aceb9 100644
--- a/ports/nrf/common-hal/_bleio/Characteristic.c
+++ b/ports/nrf/common-hal/_bleio/Characteristic.c
@@ -33,6 +33,7 @@
#include "shared-bindings/_bleio/Service.h"
#include "common-hal/_bleio/Adapter.h"
+#include "common-hal/_bleio/bonding.h"
STATIC uint16_t characteristic_get_cccd(uint16_t cccd_handle, uint16_t conn_handle) {
uint16_t cccd;
diff --git a/ports/nrf/common-hal/_bleio/Connection.c b/ports/nrf/common-hal/_bleio/Connection.c
index daf5b937b..96e8b8fbe 100644
--- a/ports/nrf/common-hal/_bleio/Connection.c
+++ b/ports/nrf/common-hal/_bleio/Connection.c
@@ -46,13 +46,16 @@
#include "shared-bindings/_bleio/Characteristic.h"
#include "shared-bindings/_bleio/Service.h"
#include "shared-bindings/_bleio/UUID.h"
+#include "supervisor/shared/tick.h"
+
+#include "common-hal/_bleio/bonding.h"
#define BLE_ADV_LENGTH_FIELD_SIZE 1
#define BLE_ADV_AD_TYPE_FIELD_SIZE 1
#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1
static const ble_gap_sec_params_t pairing_sec_params = {
- .bond = 0,
+ .bond = 1,
.mitm = 0,
.lesc = 0,
.keypress = 0,
@@ -64,6 +67,13 @@ static const ble_gap_sec_params_t pairing_sec_params = {
.kdist_peer = { .enc = 1, .id = 1},
};
+#define CONNECTION_DEBUG (1)
+#if CONNECTION_DEBUG
+ #define CONNECTION_DEBUG_PRINTF(...) printf(__VA_ARGS__)
+#else
+ #define CONNECTION_DEBUG_PRINTF(...)
+#endif
+
static volatile bool m_discovery_in_process;
static volatile bool m_discovery_successful;
@@ -84,6 +94,7 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
switch (ble_evt->header.evt_id) {
case BLE_GAP_EVT_DISCONNECTED:
+ // Adapter.c does the work for this event.
break;
case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
@@ -137,6 +148,22 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
break;
}
+ case BLE_GATTS_EVT_WRITE:
+ // A client wrote a value.
+ // If we are bonded and it's a CCCD (UUID 0x2902), store the CCCD value.
+ if (self->conn_handle != BLE_CONN_HANDLE_INVALID &&
+ self->pair_status == PAIR_PAIRED &&
+ ble_evt->evt.gatts_evt.params.write.uuid.type == BLE_UUID_TYPE_BLE &&
+ ble_evt->evt.gatts_evt.params.write.uuid.uuid == 0x2902) {
+ //
+ // Save sys_attr data (CCCD state) in bonding area at
+ // next opportunity, but also remember time of this
+ // request, so we can consolidate closely-spaced requests.
+ self->do_bond_cccds = true;
+ self->do_bond_cccds_request_time = supervisor_ticks_ms64();
+ }
+ break;
+
case BLE_GATTS_EVT_SYS_ATTR_MISSING:
sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
break;
@@ -197,6 +224,15 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
break;
}
case BLE_GAP_EVT_SEC_PARAMS_REQUEST: {
+ // First time pairing.
+ // 1. Either we or peer initiate the process
+ // 2. Peer asks for security parameters using BLE_GAP_EVT_SEC_PARAMS_REQUEST.
+ // 3. Pair Key exchange ("just works" implemented now; TODO: out-of-band key pairing)
+ // 4. Connection is secured: BLE_GAP_EVT_CONN_SEC_UPDATE
+ // 5. Long-term Keys exchanged: BLE_GAP_EVT_AUTH_STATUS
+
+ bonding_clear_keys(&self->bonding_keys);
+ self->ediv = EDIV_INVALID;
ble_gap_sec_keyset_t keyset = {
.keys_own = {
.p_enc_key = &self->bonding_keys.own_enc,
@@ -214,7 +250,8 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
};
sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_SUCCESS,
- &pairing_sec_params, &keyset);
+ self->is_central ? NULL : &pairing_sec_params,
+ &keyset);
break;
}
@@ -224,13 +261,16 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
break;
case BLE_GAP_EVT_AUTH_STATUS: { // 0x19
- // Pairing process completed
+ // Key exchange completed.
ble_gap_evt_auth_status_t* status = &ble_evt->evt.gap_evt.params.auth_status;
self->sec_status = status->auth_status;
if (status->auth_status == BLE_GAP_SEC_STATUS_SUCCESS) {
- // TODO _ediv = bonding_keys->own_enc.master_id.ediv;
+ self->ediv = self->bonding_keys.own_enc.master_id.ediv;
self->pair_status = PAIR_PAIRED;
+ // Save keys in bonding area at next opportunity.
+ self->do_bond_keys = true;
} else {
+ // Inform busy-waiter pairing has failed.
self->pair_status = PAIR_NOT_PAIRED;
}
break;
@@ -242,17 +282,22 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
// - Else return NULL --> Initiate key exchange
ble_gap_evt_sec_info_request_t* sec_info_request = &ble_evt->evt.gap_evt.params.sec_info_request;
(void) sec_info_request;
- //if ( bond_load_keys(_role, sec_req->master_id.ediv, &bkeys) ) {
- //sd_ble_gap_sec_info_reply(_conn_hdl, &bkeys.own_enc.enc_info, &bkeys.peer_id.id_info, NULL);
- //
- //_ediv = bkeys.own_enc.master_id.ediv;
- // } else {
+ if ( bonding_load_keys(self->is_central, sec_info_request->master_id.ediv, &self->bonding_keys) ) {
+ sd_ble_gap_sec_info_reply(
+ self->conn_handle,
+ &self->bonding_keys.own_enc.enc_info,
+ &self->bonding_keys.peer_id.id_info,
+ NULL);
+ self->ediv = self->bonding_keys.own_enc.master_id.ediv;
+ } else {
+ // We don't have stored keys. Ask for keys.
sd_ble_gap_sec_info_reply(self->conn_handle, NULL, NULL, NULL);
- // }
- break;
+ }
+ break;
}
case BLE_GAP_EVT_CONN_SEC_UPDATE: { // 0x1a
+ // We get this both on first-time pairing and on subsequent pairings using stored keys.
ble_gap_conn_sec_t* conn_sec = &ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec;
if (conn_sec->sec_mode.sm <= 1 && conn_sec->sec_mode.lv <= 1) {
// Security setup did not succeed:
@@ -261,18 +306,17 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
// mode >=1 and/or level >=1 means encryption is set up
self->pair_status = PAIR_NOT_PAIRED;
} else {
- //if ( !bond_load_cccd(_role, _conn_hdl, _ediv) ) {
- if (true) { // TODO: no bonding yet
- // Initialize system attributes fresh.
+ if (bonding_load_cccd_info(self->is_central, self->conn_handle, self->ediv)) {
+ // Did an sd_ble_gatts_sys_attr_set() with the stored sys_attr values.
+ } else {
+ // No matching bonding found, so use fresh system attributes.
sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
}
- // Not quite paired yet: wait for BLE_GAP_EVT_AUTH_STATUS SUCCESS.
- self->ediv = self->bonding_keys.own_enc.master_id.ediv;
+ self->pair_status = PAIR_PAIRED;
}
break;
}
-
default:
return false;
}
@@ -284,8 +328,7 @@ void bleio_connection_clear(bleio_connection_internal_t *self) {
self->conn_handle = BLE_CONN_HANDLE_INVALID;
self->pair_status = PAIR_NOT_PAIRED;
-
- memset(&self->bonding_keys, 0, sizeof(self->bonding_keys));
+ bonding_clear_keys(&self->bonding_keys);
}
bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self) {
@@ -565,8 +608,7 @@ STATIC bool discovery_on_ble_evt(ble_evt_t *ble_evt, mp_obj_t payload) {
break;
default:
- // For debugging.
- // mp_printf(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id);
+ // CONNECTION_DEBUG_PRINTF(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id);
return false;
break;
}
diff --git a/ports/nrf/common-hal/_bleio/Connection.h b/ports/nrf/common-hal/_bleio/Connection.h
index 61bbea4a1..282e0c4b5 100644
--- a/ports/nrf/common-hal/_bleio/Connection.h
+++ b/ports/nrf/common-hal/_bleio/Connection.h
@@ -36,6 +36,7 @@
#include "py/objlist.h"
#include "common-hal/_bleio/__init__.h"
+#include "common-hal/_bleio/bonding.h"
#include "shared-module/_bleio/Address.h"
#include "common-hal/_bleio/Service.h"
@@ -56,16 +57,23 @@ typedef struct {
// The advertising data and scan response buffers are held by us, not by the SD, so we must
// maintain them and not change it. If we need to change the contents during advertising,
// there are tricks to get the SD to notice (see DevZone - TBS).
- // EDIV: Encrypted Diversifier: Identifies LTK during legacy pairing.
bonding_keys_t bonding_keys;
+ // EDIV: Encrypted Diversifier: Identifies LTK during legacy pairing.
uint16_t ediv;
- pair_status_t pair_status;
+ volatile pair_status_t pair_status;
uint8_t sec_status; // Internal security status.
mp_obj_t connection_obj;
ble_drv_evt_handler_entry_t handler_entry;
ble_gap_conn_params_t conn_params;
volatile bool conn_params_updating;
uint16_t mtu;
+ // Request that CCCD values for this conenction be saved, using sys_attr values.
+ volatile bool do_bond_cccds;
+ // Request that security key info for this connection be saved.
+ volatile bool do_bond_keys;
+ // Time of setting do_bond_ccds: we delay a bit to consolidate multiple CCCD changes
+ // into one write. Time is currently in ticks_ms.
+ uint64_t do_bond_cccds_request_time;
} bleio_connection_internal_t;
typedef struct {
diff --git a/ports/nrf/common-hal/_bleio/__init__.c b/ports/nrf/common-hal/_bleio/__init__.c
index 8606c89ec..58e28c8c1 100644
--- a/ports/nrf/common-hal/_bleio/__init__.c
+++ b/ports/nrf/common-hal/_bleio/__init__.c
@@ -91,11 +91,13 @@ void check_sec_status(uint8_t sec_status) {
void bleio_reset() {
bleio_adapter_reset(&common_hal_bleio_adapter_obj);
if (!vm_used_ble) {
+ // No user-code BLE operations were done, so we can maintain the supervisor state.
return;
}
if (common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) {
common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, false);
}
+ bonding_reset();
supervisor_start_bluetooth();
}
@@ -194,14 +196,17 @@ size_t common_hal_bleio_gattc_read(uint16_t handle, uint16_t conn_handle, uint8_
while (nrf_error == NRF_ERROR_BUSY) {
nrf_error = sd_ble_gattc_read(conn_handle, handle, 0);
}
- check_nrf_error(nrf_error);
+ if (nrf_error != NRF_SUCCESS) {
+ ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info);
+ check_nrf_error(nrf_error);
+ }
while (!read_info.done) {
RUN_BACKGROUND_TASKS;
}
- check_gatt_status(read_info.status);
ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info);
+ check_gatt_status(read_info.status);
return read_info.final_len;
}
diff --git a/ports/nrf/common-hal/_bleio/__init__.h b/ports/nrf/common-hal/_bleio/__init__.h
index ecacf7c85..e216795fc 100644
--- a/ports/nrf/common-hal/_bleio/__init__.h
+++ b/ports/nrf/common-hal/_bleio/__init__.h
@@ -30,9 +30,9 @@
void bleio_reset(void);
typedef struct {
- ble_gap_enc_key_t own_enc;
- ble_gap_enc_key_t peer_enc;
- ble_gap_id_key_t peer_id;
+ ble_gap_enc_key_t own_enc;
+ ble_gap_enc_key_t peer_enc;
+ ble_gap_id_key_t peer_id;
} bonding_keys_t;
// We assume variable length data.
diff --git a/ports/nrf/common-hal/_bleio/bonding.c b/ports/nrf/common-hal/_bleio/bonding.c
new file mode 100644
index 000000000..081ba992f
--- /dev/null
+++ b/ports/nrf/common-hal/_bleio/bonding.c
@@ -0,0 +1,310 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert 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 <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ble.h"
+#include "ble_drv.h"
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Adapter.h"
+#include "shared-bindings/nvm/ByteArray.h"
+#include "supervisor/shared/tick.h"
+
+#include "nrf_soc.h"
+
+#include "bonding.h"
+
+// Internal flash area reserved for bonding storage.
+#define BONDING_PAGES_START_ADDR CIRCUITPY_BLE_CONFIG_START_ADDR
+#define BONDING_PAGES_END_ADDR (CIRCUITPY_BLE_CONFIG_START_ADDR + CIRCUITPY_BLE_CONFIG_SIZE)
+
+// First and last four bytes are magic bytes for id and version. Data is in between.
+// 'BD01'
+const uint32_t BONDING_FLAG = ('1' | '0' << 8 | 'D' << 16 | 'B' << 24);
+
+#define BONDING_DATA_START_ADDR (BONDING_PAGES_START_ADDR + sizeof(BONDING_FLAG))
+#define BONDING_DATA_END_ADDR (BONDING_PAGES_END_ADDR - sizeof(BONDING_FLAG))
+
+#define BONDING_START_FLAG_ADDR BONDING_PAGES_START_ADDR
+#define BONDING_END_FLAG_ADDR BONDING_DATA_END_ADDR
+
+// Save both system and user service info.
+#define SYS_ATTR_FLAGS (BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS)
+
+#if BONDING_DEBUG
+void bonding_print_block(bonding_block_t *block) {
+ printf("at 0x%08lx: is_central: %1d, type: 0x%x, ediv: 0x%04x, data_length: %d\n",
+ (uint32_t) block, block->is_central, block->type, block->ediv, block->data_length);
+}
+
+void bonding_print_keys(bonding_keys_t *keys) {
+ for (size_t i = 0; i < sizeof(bonding_keys_t); i ++) {
+ printf("%x", ((uint8_t*) keys)[i]);
+ }
+ printf("\n");
+}
+#endif
+
+STATIC size_t compute_block_size(uint16_t data_length) {
+ // Round data size up to the nearest 32-bit address.
+ return sizeof(bonding_block_t) + ((data_length + 3) & ~0x3);
+}
+
+void bonding_erase_storage(void) {
+ // Erase all pages in the bonding area.
+ for(uint32_t page_address = BONDING_PAGES_START_ADDR;
+ page_address < BONDING_PAGES_END_ADDR;
+ page_address += FLASH_PAGE_SIZE) {
+ // Argument is page number, not address.
+ sd_flash_page_erase_sync(page_address / FLASH_PAGE_SIZE);
+ }
+ // Write marker words at the beginning and the end of the bonding area.
+ uint32_t flag = BONDING_FLAG;
+ sd_flash_write_sync((uint32_t *) BONDING_START_FLAG_ADDR, &flag, 1);
+ sd_flash_write_sync((uint32_t *) BONDING_END_FLAG_ADDR, &flag, 1);
+}
+
+// Given NULL to start or block address, return the address of the next valid block.
+// The last block returned is the unused block at the end.
+// Return NULL if we have run off the end of the bonding space.
+
+STATIC bonding_block_t *next_block(bonding_block_t *block) {
+ while (1) {
+ // Advance to next block.
+ if (block == NULL) {
+ return (bonding_block_t *) BONDING_DATA_START_ADDR;
+ } else if (block->type == BLOCK_UNUSED) {
+ // Already at last block (the unused block).
+ return NULL;
+ }
+
+ // Advance to next block.
+ block = (bonding_block_t *) ((uint8_t *) block + compute_block_size(block->data_length));
+
+ if (block >= (bonding_block_t *) BONDING_DATA_END_ADDR) {
+ // Went past end of bonding space.
+ return NULL;
+ }
+ if (block->type != BLOCK_INVALID) {
+ // Found an empty or a valid block.
+ return block;
+ }
+ // Invalid block (was erased); try again.
+ }
+}
+
+// Find the block with given is_central, type and ediv value.
+// If type == BLOCK_UNUSED, ediv is ignored and the the sole unused block at the end is returned.
+// If not found, return NULL.
+STATIC bonding_block_t *find_existing_block(bool is_central, bonding_block_type_t type, uint16_t ediv) {
+ bonding_block_t *block = NULL;
+ while (1) {
+ block = next_block(block);
+ if (block == NULL) {
+ return NULL;
+ }
+ // If types match, and block is unused, just return it.
+ // Otherwise check that is_central and ediv match.
+ if (type == block->type) {
+ if (type == BLOCK_UNUSED ||
+ (is_central == block->is_central && ediv == block->ediv)) {
+ return block;
+ }
+ }
+ }
+}
+
+// Get an empty block large enough to store data_length data.
+STATIC bonding_block_t* find_unused_block(uint16_t data_length) {
+ bonding_block_t *unused_block = find_existing_block(true, BLOCK_UNUSED, EDIV_INVALID);
+ // If no more room, erase all existing blocks and start over.
+ if (!unused_block ||
+ (uint8_t *) unused_block + compute_block_size(data_length) >= (uint8_t *) BONDING_DATA_END_ADDR) {
+ bonding_erase_storage();
+ unused_block = (bonding_block_t *) BONDING_DATA_START_ADDR;
+ }
+ return unused_block;
+}
+
+// Set the header word to all 0's, to mark the block as invalid.
+// We don't change data_length, so we can still skip over this block.
+STATIC void invalidate_block(bonding_block_t *block) {
+ uint32_t zero = 0;
+ sd_flash_write_sync((uint32_t *) block, &zero, 1);
+}
+
+// Write bonding block header.
+STATIC void write_block_header(bonding_block_t *dest_block, bonding_block_t *source_block_header) {
+ sd_flash_write_sync((uint32_t *) dest_block, (uint32_t *) source_block_header, sizeof(bonding_block_t) / 4);
+}
+
+// Write variable-length data at end of bonding block.
+STATIC void write_block_data(bonding_block_t *dest_block, uint8_t *data, uint16_t data_length) {
+ // Minimize the number of writes. Datasheet says no more than two writes per word before erasing again.
+
+ // Start writing after the current header.
+ uint32_t *flash_word_p = (uint32_t *) ((uint8_t *) dest_block + sizeof(bonding_block_t));
+ while (1) {
+ uint32_t word = 0xffffffff;
+ memcpy(&word, data, data_length >= 4 ? 4 : data_length);
+ sd_flash_write_sync(flash_word_p, &word, 1);
+ if (data_length <= 4) {
+ break;
+ }
+ data_length -= 4;
+ data += 4;
+ // Increment by word size.
+ flash_word_p++;
+ }
+}
+
+STATIC void write_sys_attr_block(bleio_connection_internal_t *connection) {
+ uint16_t length = 0;
+ // First find out how big a buffer we need, then fetch the data.
+ if(sd_ble_gatts_sys_attr_get(connection->conn_handle, NULL, &length, SYS_ATTR_FLAGS) != NRF_SUCCESS) {
+ return;
+ }
+ uint8_t sys_attr[length];
+ if(sd_ble_gatts_sys_attr_get(connection->conn_handle, sys_attr, &length, SYS_ATTR_FLAGS) != NRF_SUCCESS) {
+ return;
+ }
+
+ // Is there an existing sys_attr block that matches the current sys_attr data?
+ bonding_block_t *existing_block =
+ find_existing_block(connection->is_central, BLOCK_SYS_ATTR, connection->ediv);
+ if (existing_block) {
+ if (length == existing_block->data_length &&
+ memcmp(sys_attr, existing_block->data, length) == 0) {
+ // Identical block found. No need to store again.
+ return;
+ }
+ // Data doesn't match. Invalidate block and store a new one.
+ invalidate_block(existing_block);
+ }
+
+ bonding_block_t block_header = {
+ .is_central = connection->is_central,
+ .type = BLOCK_SYS_ATTR,
+ .ediv = connection->ediv,
+ .conn_handle = connection->conn_handle,
+ .data_length = length,
+ };
+ bonding_block_t *new_block = find_unused_block(length);
+ write_block_header(new_block, &block_header);
+ write_block_data(new_block, sys_attr, length);
+ return;
+}
+
+STATIC void write_keys_block(bleio_connection_internal_t *connection) {
+ uint16_t const ediv = connection->is_central
+ ? connection->bonding_keys.peer_enc.master_id.ediv
+ : connection->bonding_keys.own_enc.master_id.ediv;
+
+ // Is there an existing keys block that matches?
+ bonding_block_t *existing_block = find_existing_block(connection->is_central, BLOCK_KEYS, ediv);
+ if (existing_block) {
+ if (existing_block->data_length == sizeof(bonding_keys_t) &&
+ memcmp(existing_block->data, &connection->bonding_keys, sizeof(bonding_keys_t)) == 0) {
+ // Identical block found. No need to store again.
+ return;
+ }
+ // Data doesn't match. Invalidate block and store a new one.
+ invalidate_block(existing_block);
+ }
+
+ bonding_block_t block_header = {
+ .is_central = connection->is_central,
+ .type = BLOCK_KEYS,
+ .ediv = ediv,
+ .conn_handle = connection->conn_handle,
+ .data_length = sizeof(bonding_keys_t),
+ };
+ bonding_block_t *new_block = find_unused_block(sizeof(bonding_keys_t));
+ write_block_header(new_block, &block_header);
+ write_block_data(new_block, (uint8_t *) &connection->bonding_keys, sizeof(bonding_keys_t));
+}
+
+void bonding_clear_keys(bonding_keys_t *bonding_keys) {
+ memset((uint8_t*) bonding_keys, 0, sizeof(bonding_keys_t));
+}
+
+void bonding_reset(void) {
+ if (BONDING_FLAG != *((uint32_t *) BONDING_START_FLAG_ADDR) ||
+ BONDING_FLAG != *((uint32_t *) BONDING_END_FLAG_ADDR)) {
+ bonding_erase_storage();
+ }
+}
+
+// Write bonding blocks to flash. Requests have been queued during evt handlers.
+void bonding_background(void) {
+ // A paired connection will request that its keys and CCCD values be stored.
+ // The CCCD store whenever a CCCD value is written.
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &bleio_connections[i];
+
+ // Wait at least one second before saving CCCD, to consolidate
+ // writes that involve multiple CCCDs. For instance, for HID,
+ // three CCCD's are set in short succession by the HID client.
+ if (connection->do_bond_cccds) {
+ uint64_t current_ticks_ms = supervisor_ticks_ms64();
+ if (current_ticks_ms - connection->do_bond_cccds_request_time >= 1000) {
+ write_sys_attr_block(connection);
+ connection->do_bond_cccds = false;
+ }
+ }
+
+ if (connection->do_bond_keys) {
+ write_keys_block(connection);
+ connection->do_bond_keys = false;
+ }
+ }
+}
+
+bool bonding_load_cccd_info(bool is_central, uint16_t conn_handle, uint16_t ediv) {
+ bonding_block_t *block = find_existing_block(is_central, BLOCK_SYS_ATTR, ediv);
+ if (block == NULL) {
+ return false;
+ }
+
+ return NRF_SUCCESS ==
+ sd_ble_gatts_sys_attr_set(conn_handle, block->data, block->data_length, SYS_ATTR_FLAGS);
+}
+
+bool bonding_load_keys(bool is_central, uint16_t ediv, bonding_keys_t *bonding_keys) {
+ bonding_block_t *block = find_existing_block(is_central, BLOCK_KEYS, ediv);
+ if (block == NULL) {
+ return false;
+ }
+ if (sizeof(bonding_keys_t) != block->data_length) {
+ // bonding_keys_t is a fixed length, so lengths should match.
+ return false;
+ }
+
+ memcpy(bonding_keys, block->data, block->data_length);
+ return true;
+}
diff --git a/ports/nrf/common-hal/_bleio/bonding.h b/ports/nrf/common-hal/_bleio/bonding.h
new file mode 100644
index 000000000..cb8e7c427
--- /dev/null
+++ b/ports/nrf/common-hal/_bleio/bonding.h
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert 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.
+ */
+
+#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_BONDING_H
+#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_BONDING_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ble.h"
+#include "ble_drv.h"
+#include "common-hal/_bleio/__init__.h"
+
+#define EDIV_INVALID (0xffff)
+
+#define BONDING_DEBUG (1)
+#if BONDING_DEBUG
+ #define BONDING_DEBUG_PRINTF(...) printf(__VA_ARGS__)
+ #define BONDING_DEBUG_PRINT_BLOCK(block) bonding_print_block(block)
+ #define BONDING_DEBUG_PRINT_KEYS(keys) bonding_print_keys(keys)
+#else
+ #define BONDING_DEBUG_PRINTF(...)
+ #define BONDING_DEBUG_PRINT_BLOCK(block)
+ #define BONDING_DEBUG_PRINT_KEYS(keys)
+#endif
+
+// Bonding data is stored in variable-length blocks consecutively in
+// erased flash (all 1's). The blocks are 32-bit aligned, though the
+// data may be any number of bytes. We hop through the blocks using
+// the size field to find the next block. When we hit a word that is
+// all 1's, we have reached the end of the blocks. We can write a new
+// block there.
+
+typedef enum {
+ BLOCK_INVALID = 0, // Ignore this block
+ BLOCK_KEYS = 1, // Block contains bonding keys.
+ BLOCK_SYS_ATTR = 2, // Block contains sys_attr values (CCCD settings, etc.).
+ BLOCK_UNUSED = 0xff, // Initial erased value.
+} bonding_block_type_t;
+
+typedef struct {
+ bool is_central: 1; // 1 if data is for a central role.
+ uint16_t reserved: 7; // Not currently used
+ bonding_block_type_t type: 8; // What kind of data is stored in.
+ uint16_t ediv; // ediv value; used as a lookup key.
+ uint16_t conn_handle; // Connection handle: used when a BLOCK_SYS_ATTR is queued to write.
+ // Not used as a key, etc.
+ uint16_t data_length; // Length of data in bytes, including ediv, not including padding.
+ // End of block header. 32-bit boundary here.
+ uint8_t data[]; // Rest of data in the block. Needs to be 32-bit aligned.
+ // Block is padded to 32-bit alignment.
+} bonding_block_t;
+
+void bonding_background(void);
+void bonding_erase_storage(void);
+void bonding_reset(void);
+void bonding_clear_keys(bonding_keys_t *bonding_keys);
+bool bonding_load_cccd_info(bool is_central, uint16_t conn_handle, uint16_t ediv);
+bool bonding_load_keys(bool is_central, uint16_t ediv, bonding_keys_t *bonding_keys);
+
+#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_BONDING_H
diff --git a/ports/nrf/common-hal/busio/I2C.c b/ports/nrf/common-hal/busio/I2C.c
index f6f686cdf..37cb192df 100644
--- a/ports/nrf/common-hal/busio/I2C.c
+++ b/ports/nrf/common-hal/busio/I2C.c
@@ -115,6 +115,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
mp_raise_ValueError(translate("All I2C peripherals are in use"));
}
+#if CIRCUITPY_REQUIRE_I2C_PULLUPS
// Test that the pins are in a high state. (Hopefully indicating they are pulled up.)
nrf_gpio_cfg_input(scl->number, NRF_GPIO_PIN_PULLDOWN);
nrf_gpio_cfg_input(sda->number, NRF_GPIO_PIN_PULLDOWN);
@@ -132,14 +133,21 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
reset_pin_number(scl->number);
mp_raise_RuntimeError(translate("SDA or SCL needs a pull up"));
}
+#endif
nrfx_twim_config_t config = NRFX_TWIM_DEFAULT_CONFIG(scl->number, sda->number);
- // change freq. only if it's less than the default 400K
- if (frequency < 100000) {
- config.frequency = NRF_TWIM_FREQ_100K;
- } else if (frequency < 250000) {
+#if defined(TWIM_FREQUENCY_FREQUENCY_K1000)
+ if (frequency >= 1000000) {
+ config.frequency = NRF_TWIM_FREQ_1000K;
+ } else
+#endif
+ if (frequency >= 400000) {
+ config.frequency = NRF_TWIM_FREQ_400K;
+ } else if (frequency >= 250000) {
config.frequency = NRF_TWIM_FREQ_250K;
+ } else {
+ config.frequency = NRF_TWIM_FREQ_100K;
}
self->scl_pin_number = scl->number;
diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c
index 639bbcdd0..b4ebddde1 100644
--- a/ports/nrf/common-hal/busio/SPI.c
+++ b/ports/nrf/common-hal/busio/SPI.c
@@ -1,27 +1,32 @@
/*
- * SPI Master library for nRF5x.
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
*
* Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
- * Copyright (c) 2017 hathach
- * Copyright (c) 2016 Sandeep Mistry All right reserved.
- * Copyright (c) 2015 Arduino LLC
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
+ * 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:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
*
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * 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 <string.h>
+
#include "shared-bindings/busio/SPI.h"
#include "py/mperrno.h"
#include "py/runtime.h"
@@ -29,40 +34,46 @@
#include "nrfx_spim.h"
#include "nrf_gpio.h"
+// These are in order from highest available frequency to lowest (32MHz first, then 8MHz).
STATIC spim_peripheral_t spim_peripherals[] = {
#if NRFX_CHECK(NRFX_SPIM3_ENABLED)
// SPIM3 exists only on nRF52840 and supports 32MHz max. All other SPIM's are only 8MHz max.
// Allocate SPIM3 first.
{ .spim = NRFX_SPIM_INSTANCE(3),
- .max_frequency_MHz = 32,
- .max_xfer_size = SPIM3_EASYDMA_MAXCNT_SIZE,
+ .max_frequency = 32000000,
+ .max_xfer_size = MIN(SPIM3_BUFFER_SIZE, (1UL << SPIM3_EASYDMA_MAXCNT_SIZE) - 1)
},
#endif
#if NRFX_CHECK(NRFX_SPIM2_ENABLED)
// SPIM2 is not shared with a TWIM, so allocate before the shared ones.
{ .spim = NRFX_SPIM_INSTANCE(2),
- .max_frequency_MHz = 8,
- .max_xfer_size = SPIM2_EASYDMA_MAXCNT_SIZE,
+ .max_frequency = 8000000,
+ .max_xfer_size = (1UL << SPIM2_EASYDMA_MAXCNT_SIZE) - 1
},
#endif
#if NRFX_CHECK(NRFX_SPIM1_ENABLED)
// SPIM1 and TWIM1 share an address.
{ .spim = NRFX_SPIM_INSTANCE(1),
- .max_frequency_MHz = 8,
- .max_xfer_size = SPIM1_EASYDMA_MAXCNT_SIZE,
+ .max_frequency = 8000000,
+ .max_xfer_size = (1UL << SPIM1_EASYDMA_MAXCNT_SIZE) - 1
},
#endif
#if NRFX_CHECK(NRFX_SPIM0_ENABLED)
// SPIM0 and TWIM0 share an address.
{ .spim = NRFX_SPIM_INSTANCE(0),
- .max_frequency_MHz = 8,
- .max_xfer_size = SPIM0_EASYDMA_MAXCNT_SIZE,
+ .max_frequency = 8000000,
+ .max_xfer_size = (1UL << SPIM0_EASYDMA_MAXCNT_SIZE) - 1
},
#endif
};
STATIC bool never_reset[MP_ARRAY_SIZE(spim_peripherals)];
+// Separate RAM area for SPIM3 transmit buffer to avoid SPIM3 hardware errata.
+// https://infocenter.nordicsemi.com/index.jsp?topic=%2Ferrata_nRF52840_Rev2%2FERR%2FnRF52840%2FRev2%2Flatest%2Fanomaly_840_198.html
+extern uint32_t _spim3_ram;
+STATIC uint8_t *spim3_transmit_buffer = (uint8_t *) &_spim3_ram;
+
void spi_reset(void) {
for (size_t i = 0 ; i < MP_ARRAY_SIZE(spim_peripherals); i++) {
if (never_reset[i]) {
@@ -122,7 +133,7 @@ static nrf_spim_frequency_t baudrate_to_spim_frequency(const uint32_t baudrate)
}
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) {
- // Find a free instance.
+ // Find a free instance, with most desirable (highest freq and not shared) allocated first.
self->spim_peripheral = NULL;
for (size_t i = 0 ; i < MP_ARRAY_SIZE(spim_peripherals); i++) {
if ((spim_peripherals[i].spim.p_reg->ENABLE & SPIM_ENABLE_ENABLE_Msk) == 0) {
@@ -137,13 +148,14 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *
nrfx_spim_config_t config = NRFX_SPIM_DEFAULT_CONFIG(NRFX_SPIM_PIN_NOT_USED, NRFX_SPIM_PIN_NOT_USED,
NRFX_SPIM_PIN_NOT_USED, NRFX_SPIM_PIN_NOT_USED);
- config.frequency = NRF_SPIM_FREQ_8M;
+
+ config.frequency = baudrate_to_spim_frequency(self->spim_peripheral->max_frequency);
config.sck_pin = clock->number;
self->clock_pin_number = clock->number;
claim_pin(clock);
- if (mosi != (mcu_pin_obj_t*)&mp_const_none_obj) {
+ if (mosi != mp_const_none) {
config.mosi_pin = mosi->number;
self->MOSI_pin_number = mosi->number;
claim_pin(mosi);
@@ -151,7 +163,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *
self->MOSI_pin_number = NO_PIN;
}
- if (miso != (mcu_pin_obj_t*)&mp_const_none_obj) {
+ if (miso != mp_const_none) {
config.miso_pin = miso->number;
self->MISO_pin_number = mosi->number;
claim_pin(miso);
@@ -189,8 +201,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, ui
// Set desired frequency, rounding down, and don't go above available frequency for this SPIM.
nrf_spim_frequency_set(self->spim_peripheral->spim.p_reg,
- baudrate_to_spim_frequency(MIN(baudrate,
- self->spim_peripheral->max_frequency_MHz * 1000000)));
+ baudrate_to_spim_frequency(MIN(baudrate, self->spim_peripheral->max_frequency)));
nrf_spim_mode_t mode = NRF_SPIM_MODE_0;
if (polarity) {
@@ -224,74 +235,66 @@ void common_hal_busio_spi_unlock(busio_spi_obj_t *self) {
}
bool common_hal_busio_spi_write(busio_spi_obj_t *self, const uint8_t *data, size_t len) {
- if (len == 0)
- return true;
-
- const uint32_t max_xfer_size = self->spim_peripheral->max_xfer_size;
- const uint32_t parts = len / max_xfer_size;
- const uint32_t remainder = len % max_xfer_size;
-
- for (uint32_t i = 0; i < parts; ++i) {
- const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_TX(data + i * max_xfer_size, max_xfer_size);
- if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS)
- return false;
- }
-
- if (remainder > 0) {
- const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_TX(data + parts * max_xfer_size, remainder);
- if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS)
+ const bool is_spim3 = self->spim_peripheral->spim.p_reg == NRF_SPIM3;
+ uint8_t *next_chunk = (uint8_t *) data;
+
+ while (len > 0) {
+ size_t chunk_size = MIN(len, self->spim_peripheral->max_xfer_size);
+ uint8_t *chunk = next_chunk;
+ if (is_spim3) {
+ // If SPIM3, copy into unused RAM block, and do DMA from there.
+ memcpy(spim3_transmit_buffer, chunk, chunk_size);
+ chunk = spim3_transmit_buffer;
+ }
+ const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_TX(chunk, chunk_size);
+ if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS) {
return false;
+ }
+ next_chunk += chunk_size;
+ len -= chunk_size;
}
-
return true;
}
bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value) {
- if (len == 0)
- return true;
-
- const uint32_t max_xfer_size = self->spim_peripheral->max_xfer_size;
- const uint32_t parts = len / max_xfer_size;
- const uint32_t remainder = len % max_xfer_size;
-
- for (uint32_t i = 0; i < parts; ++i) {
- const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_RX(data + i * max_xfer_size, max_xfer_size);
- if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS)
- return false;
- }
+ uint8_t *next_chunk = data;
- if (remainder > 0) {
- const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_RX(data + parts * max_xfer_size, remainder);
- if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS)
+ while (len > 0) {
+ size_t chunk_size = MIN(len, self->spim_peripheral->max_xfer_size);
+ const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_RX(next_chunk, chunk_size);
+ if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS) {
return false;
+ }
+ next_chunk += chunk_size;
+ len -= chunk_size;
}
-
return true;
}
bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uint8_t *data_in, size_t len) {
- if (len == 0)
- return true;
-
-
- const uint32_t max_xfer_size = self->spim_peripheral->max_xfer_size;
- const uint32_t parts = len / max_xfer_size;
- const uint32_t remainder = len % max_xfer_size;
-
- for (uint32_t i = 0; i < parts; ++i) {
- const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_SINGLE_XFER(data_out + i * max_xfer_size, max_xfer_size,
- data_in + i * max_xfer_size, max_xfer_size);
- if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS)
+ const bool is_spim3 = self->spim_peripheral->spim.p_reg == NRF_SPIM3;
+ uint8_t *next_chunk_out = data_out;
+ uint8_t *next_chunk_in = data_in;
+
+ while (len > 0) {
+ uint8_t *chunk_out = next_chunk_out;
+ size_t chunk_size = MIN(len, self->spim_peripheral->max_xfer_size);
+ if (is_spim3) {
+ // If SPIM3, copy into unused RAM block, and do DMA from there.
+ memcpy(spim3_transmit_buffer, chunk_out, chunk_size);
+ chunk_out = spim3_transmit_buffer;
+ }
+ const nrfx_spim_xfer_desc_t xfer =
+ NRFX_SPIM_SINGLE_XFER(next_chunk_out, chunk_size,
+ next_chunk_in, chunk_size);
+ if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS) {
return false;
- }
+ }
- if (remainder > 0) {
- const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_SINGLE_XFER(data_out + parts * max_xfer_size, remainder,
- data_in + parts * max_xfer_size, remainder);
- if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS)
- return false;
+ next_chunk_out += chunk_size;
+ next_chunk_in += chunk_size;
+ len -= chunk_size;
}
-
return true;
}
@@ -325,9 +328,9 @@ uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self) {
}
uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t* self) {
- return 0;
+ return (self->spim_peripheral->spim.p_reg->CONFIG & SPIM_CONFIG_CPHA_Msk) >> SPIM_CONFIG_CPHA_Pos;
}
uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t* self) {
- return 0;
+ return (self->spim_peripheral->spim.p_reg->CONFIG & SPIM_CONFIG_CPOL_Msk) >> SPIM_CONFIG_CPOL_Pos;
}
diff --git a/ports/nrf/common-hal/busio/SPI.h b/ports/nrf/common-hal/busio/SPI.h
index 1b0de8acf..ef3ac9531 100644
--- a/ports/nrf/common-hal/busio/SPI.h
+++ b/ports/nrf/common-hal/busio/SPI.h
@@ -32,8 +32,8 @@
typedef struct {
nrfx_spim_t spim;
- uint8_t max_frequency_MHz;
- uint8_t max_xfer_size;
+ uint32_t max_frequency;
+ uint32_t max_xfer_size;
} spim_peripheral_t;
typedef struct {
diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c
index d79b65ff8..933faf17b 100644
--- a/ports/nrf/common-hal/busio/UART.c
+++ b/ports/nrf/common-hal/busio/UART.c
@@ -128,10 +128,17 @@ void uart_reset(void) {
}
}
-void common_hal_busio_uart_construct (busio_uart_obj_t *self,
- const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
- uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
- uint16_t receiver_buffer_size) {
+void common_hal_busio_uart_construct(busio_uart_obj_t *self,
+ const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx,
+ const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
+ const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
+ uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
+ mp_float_t timeout, uint16_t receiver_buffer_size) {
+
+ if ((rts != mp_const_none) || (cts != mp_const_none) || (rs485_dir != mp_const_none) || (rs485_invert)) {
+ mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device"));
+ }
+
// Find a free UART peripheral.
self->uarte = NULL;
for (size_t i = 0 ; i < MP_ARRAY_SIZE(nrfx_uartes); i++) {
diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c
index de924566c..7eb1c0614 100644
--- a/ports/nrf/common-hal/microcontroller/__init__.c
+++ b/ports/nrf/common-hal/microcontroller/__init__.c
@@ -37,8 +37,10 @@
#include "shared-bindings/microcontroller/Processor.h"
#include "supervisor/filesystem.h"
+#include "supervisor/port.h"
#include "supervisor/shared/safe_mode.h"
#include "nrfx_glue.h"
+#include "nrf_nvic.h"
// This routine should work even when interrupts are disabled. Used by OneWire
// for precise timing.
@@ -46,10 +48,38 @@ void common_hal_mcu_delay_us(uint32_t delay) {
NRFX_DELAY_US(delay);
}
+static volatile uint32_t nesting_count = 0;
+static uint8_t is_nested_critical_region;
+static uint8_t sd_is_enabled = false;
void common_hal_mcu_disable_interrupts() {
+ sd_softdevice_is_enabled(&sd_is_enabled);
+ if (sd_is_enabled) {
+ sd_nvic_critical_region_enter(&is_nested_critical_region);
+ } else {
+ __disable_irq();
+ __DMB();
+ nesting_count++;
+ }
}
void common_hal_mcu_enable_interrupts() {
+ // Don't check here if SD is enabled, because we'll crash if interrupts
+ // were turned off and sd_softdevice_is_enabled is called.
+ if (sd_is_enabled) {
+ sd_nvic_critical_region_exit(is_nested_critical_region);
+ } else {
+ if (nesting_count == 0) {
+ // This is very very bad because it means there was mismatched disable/enables so we
+ // crash.
+ reset_into_safe_mode(HARD_CRASH);
+ }
+ nesting_count--;
+ if (nesting_count > 0) {
+ return;
+ }
+ __DMB();
+ __enable_irq();
+ }
}
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
diff --git a/ports/nrf/common-hal/neopixel_write/__init__.c b/ports/nrf/common-hal/neopixel_write/__init__.c
index 91c68556f..cd1b4fe59 100644
--- a/ports/nrf/common-hal/neopixel_write/__init__.c
+++ b/ports/nrf/common-hal/neopixel_write/__init__.c
@@ -112,7 +112,7 @@ uint32_t next_start_tick_us = 1000;
void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout, uint8_t *pixels, uint32_t numBytes) {
// To support both the SoftDevice + Neopixels we use the EasyDMA
- // feature from the NRF25. However this technique implies to
+ // feature from the NRF52. However this technique implies to
// generate a pattern and store it on the memory. The actual
// memory used in bytes corresponds to the following formula:
// totalMem = numBytes*8*2+(2*2)
@@ -123,20 +123,26 @@ void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout
// using DWT
#define PATTERN_SIZE(numBytes) (numBytes * 8 * sizeof(uint16_t) + 2 * sizeof(uint16_t))
+// Allocate PWM space for up to STACK_PIXELS on the stack, to avoid malloc'ing.
+// We may need to write to the status neopixel or to Circuit Playground NeoPixels
+// when we cannot malloc, between VM instantiations.
+// We need space for at least 10 pixels for Circuit Playground, but let's choose 24
+// to handle larger NeoPixel rings without malloc'ing.
+#define STACK_PIXELS 24
uint32_t pattern_size = PATTERN_SIZE(numBytes);
uint16_t* pixels_pattern = NULL;
- // Use the stack to store 1 pixels worth of PWM data for the status led. uint32_t to ensure alignment.
- // Make it at least as big as PATTERN_SIZE(3), for one pixel of RGB data.
+ // Use the stack to store STACK_PIXEL's worth of PWM data. uint32_t to ensure alignment.
+ // It is 3*STACK_PIXELS to handle RGB.
// PATTERN_SIZE is a multiple of 4, so we don't need round up to make sure one_pixel is large enough.
- uint32_t one_pixel[PATTERN_SIZE(3)/sizeof(uint32_t)];
+ uint32_t stack_pixels[PATTERN_SIZE(3 * STACK_PIXELS) / sizeof(uint32_t)];
NRF_PWM_Type* pwm = find_free_pwm();
// only malloc if there is PWM device available
if ( pwm != NULL ) {
- if (pattern_size <= sizeof(one_pixel)) {
- pixels_pattern = (uint16_t *) one_pixel;
+ if (pattern_size <= sizeof(stack_pixels)) {
+ pixels_pattern = (uint16_t *) stack_pixels;
} else {
uint8_t sd_en = 0;
(void) sd_softdevice_is_enabled(&sd_en);
diff --git a/ports/nrf/common-hal/nvm/ByteArray.c b/ports/nrf/common-hal/nvm/ByteArray.c
index 7d733ce7b..6b2f04a61 100644
--- a/ports/nrf/common-hal/nvm/ByteArray.c
+++ b/ports/nrf/common-hal/nvm/ByteArray.c
@@ -36,21 +36,17 @@ uint32_t common_hal_nvm_bytearray_get_length(nvm_bytearray_obj_t *self) {
return self->len;
}
-static void write_page(uint32_t page_addr, uint32_t offset, uint32_t len, uint8_t *bytes) {
+static bool write_page(uint32_t page_addr, uint32_t offset, uint32_t len, uint8_t *bytes) {
// Write a whole page to flash, buffering it first and then erasing and rewriting
// it since we can only clear a whole page at a time.
- bool status;
if (offset == 0 && len == FLASH_PAGE_SIZE) {
- status = nrf_nvm_safe_flash_page_write(page_addr, bytes);
+ return nrf_nvm_safe_flash_page_write(page_addr, bytes);
} else {
uint8_t buffer[FLASH_PAGE_SIZE];
memcpy(buffer, (uint8_t *)page_addr, FLASH_PAGE_SIZE);
memcpy(buffer + offset, bytes, len);
- status = nrf_nvm_safe_flash_page_write(page_addr, buffer);
- }
- if (!status) {
- mp_raise_OSError_msg(translate("Flash write failed"));
+ return nrf_nvm_safe_flash_page_write(page_addr, buffer);
}
}
@@ -63,7 +59,9 @@ bool common_hal_nvm_bytearray_set_bytes(nvm_bytearray_obj_t *self,
while (len) {
uint32_t write_len = MIN(len, FLASH_PAGE_SIZE - offset);
- write_page(page_addr, offset, write_len, values);
+ if (!write_page(page_addr, offset, write_len, values)) {
+ return false;
+ }
len -= write_len;
values += write_len;
page_addr += FLASH_PAGE_SIZE;
diff --git a/ports/nrf/common-hal/os/__init__.c b/ports/nrf/common-hal/os/__init__.c
index e38226f94..b2ad00a5c 100644
--- a/ports/nrf/common-hal/os/__init__.c
+++ b/ports/nrf/common-hal/os/__init__.c
@@ -66,8 +66,24 @@ bool common_hal_os_urandom(uint8_t *buffer, uint32_t length) {
uint8_t sd_en = 0;
(void) sd_softdevice_is_enabled(&sd_en);
- if (sd_en)
- return NRF_SUCCESS == sd_rand_application_vector_get(buffer, length);
+ if (sd_en) {
+ while (length != 0) {
+ uint8_t available = 0;
+ sd_rand_application_bytes_available_get(&available);
+ if (available) {
+ uint32_t request = MIN(length, available);
+ uint32_t result = sd_rand_application_vector_get(buffer, request);
+ if (result != NRF_SUCCESS) {
+ return false;
+ }
+ buffer += request;
+ length -= request;
+ } else {
+ RUN_BACKGROUND_TASKS;
+ }
+ }
+ return true;
+ }
#endif
nrf_rng_event_clear(NRF_RNG, NRF_RNG_EVENT_VALRDY);
diff --git a/ports/nrf/common-hal/time/__init__.c b/ports/nrf/common-hal/time/__init__.c
index 976f519db..c85077868 100644
--- a/ports/nrf/common-hal/time/__init__.c
+++ b/ports/nrf/common-hal/time/__init__.c
@@ -32,6 +32,14 @@ uint64_t common_hal_time_monotonic(void) {
return supervisor_ticks_ms64();
}
+uint64_t common_hal_time_monotonic_ns(void) {
+ uint64_t ms;
+ uint32_t us_until_ms;
+ current_tick(&ms, &us_until_ms);
+ // us counts down.
+ return 1000 * (ms * 1000 + (1000 - us_until_ms));
+}
+
void common_hal_time_delay_ms(uint32_t delay) {
mp_hal_delay_ms(delay);
}
diff --git a/ports/nrf/ld_defines.c b/ports/nrf/ld_defines.c
index 0ec6dfdb5..ebe9c4929 100644
--- a/ports/nrf/ld_defines.c
+++ b/ports/nrf/ld_defines.c
@@ -37,3 +37,6 @@
/*BOOTLOADER_SETTINGS_START_ADDR=*/ BOOTLOADER_SETTINGS_START_ADDR;
/*BOOTLOADER_SETTINGS_SIZE=*/ BOOTLOADER_SETTINGS_SIZE;
+
+/*SOFTDEVICE_RAM_SIZE=*/ SOFTDEVICE_RAM_SIZE;
+/*SPIM3_BUFFER_SIZE=*/ SPIM3_BUFFER_SIZE;
diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h
index cb25870dc..473169e94 100644
--- a/ports/nrf/mpconfigport.h
+++ b/ports/nrf/mpconfigport.h
@@ -34,9 +34,16 @@
#include "nrf_sdm.h" // for SD_FLASH_SIZE
#include "peripherals/nrf/nvm.h" // for FLASH_PAGE_SIZE
+// Max RAM used by SoftDevice. Can be changed when SoftDevice parameters are changed.
+// See common.template.ld.
+#define SOFTDEVICE_RAM_SIZE (64*1024)
+
#ifdef NRF52840
#define MICROPY_PY_SYS_PLATFORM "nRF52840"
#define FLASH_SIZE (0x100000) // 1MiB
+// Special RAM area for SPIM3 transmit buffer, to work around hardware bug.
+// See common.template.ld.
+#define SPIM3_BUFFER_SIZE (8192)
#endif
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1)
@@ -97,6 +104,9 @@
#define ISR_START_ADDR (SD_FLASH_START_ADDR + SD_FLASH_SIZE)
#define ISR_SIZE (0x1000) // 4kiB
+// Smallest unit of flash that can be erased.
+#define FLASH_ERASE_SIZE FLASH_PAGE_SIZE
+
#define CIRCUITPY_FIRMWARE_START_ADDR (ISR_START_ADDR + ISR_SIZE)
// Define these regions starting down from the bootloader:
@@ -122,29 +132,29 @@
// The firmware space is the space left over between the fixed lower and upper regions.
#define CIRCUITPY_FIRMWARE_SIZE (CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR - CIRCUITPY_FIRMWARE_START_ADDR)
-#if BOOTLOADER_START_ADDR % FLASH_PAGE_SIZE != 0
-#error BOOTLOADER_START_ADDR must be on a flash page boundary.
+#if BOOTLOADER_START_ADDR % FLASH_ERASE_SIZE != 0
+#error BOOTLOADER_START_ADDR must be on a flash erase boundary.
#endif
-#if CIRCUITPY_INTERNAL_NVM_START_ADDR % FLASH_PAGE_SIZE != 0
-#error CIRCUITPY_INTERNAL_NVM_START_ADDR must be on a flash page boundary.
+#if CIRCUITPY_INTERNAL_NVM_START_ADDR % FLASH_ERASE_SIZE != 0
+#error CIRCUITPY_INTERNAL_NVM_START_ADDR must be on a flash erase boundary.
#endif
-#if CIRCUITPY_INTERNAL_NVM_SIZE % FLASH_PAGE_SIZE != 0
-#error CIRCUITPY_INTERNAL_NVM_SIZE must be a multiple of FLASH_PAGE_SIZE.
+#if CIRCUITPY_INTERNAL_NVM_SIZE % FLASH_ERASE_SIZE != 0
+#error CIRCUITPY_INTERNAL_NVM_SIZE must be a multiple of FLASH_ERASE_SIZE.
#endif
-#if CIRCUITPY_BLE_CONFIG_START_ADDR % FLASH_PAGE_SIZE != 0
-#error CIRCUITPY_BLE_CONFIG_SIZE must be on a flash page boundary.
+#if CIRCUITPY_BLE_CONFIG_START_ADDR % FLASH_ERASE_SIZE != 0
+#error CIRCUITPY_BLE_CONFIG_SIZE must be on a flash erase boundary.
#endif
-#if CIRCUITPY_BLE_CONFIG_SIZE % FLASH_PAGE_SIZE != 0
-#error CIRCUITPY_BLE_CONFIG_SIZE must be a multiple of FLASH_PAGE_SIZE.
+#if CIRCUITPY_BLE_CONFIG_SIZE % FLASH_ERASE_SIZE != 0
+#error CIRCUITPY_BLE_CONFIG_SIZE must be a multiple of FLASH_ERASE_SIZE.
#endif
-#if CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR % FLASH_PAGE_SIZE != 0
-#error CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE must be on a flash page boundary.
+#if CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR % FLASH_ERASE_SIZE != 0
+#error CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE must be on a flash erase boundary.
#endif
-#if CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE % FLASH_PAGE_SIZE != 0
-#error CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE must be a multiple of FLASH_PAGE_SIZE.
+#if CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE % FLASH_ERASE_SIZE != 0
+#error CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE must be a multiple of FLASH_ERASE_SIZE.
#endif
#if CIRCUITPY_FIRMWARE_SIZE < 0
@@ -152,10 +162,9 @@
#endif
-
-
#define MICROPY_PORT_ROOT_POINTERS \
CIRCUITPY_COMMON_ROOT_POINTERS \
ble_drv_evt_handler_entry_t* ble_drv_evt_handler_entries; \
+
#endif // NRF5_MPCONFIGPORT_H__
diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h
index 82f6514df..e37c60934 100644
--- a/ports/nrf/nrfx_config.h
+++ b/ports/nrf/nrfx_config.h
@@ -26,10 +26,9 @@
// CIRCUITPY_NRF_NUM_I2C is 1 or 2 to choose how many I2C (TWIM) peripherals
// to provide.
-// This can go away once we have SPIM3 working: then we can have two
-// I2C and two SPI.
+// With SPIM3 working we can have two I2C and two SPI.
#ifndef CIRCUITPY_NRF_NUM_I2C
-#define CIRCUITPY_NRF_NUM_I2C 1
+#define CIRCUITPY_NRF_NUM_I2C 2
#endif
#if CIRCUITPY_NRF_NUM_I2C != 1 && CIRCUITPY_NRF_NUM_I2C != 2
@@ -42,13 +41,12 @@
#define NRFX_SPIM1_ENABLED 1
#endif
#define NRFX_SPIM2_ENABLED 1
-// DON'T ENABLE SPIM3 DUE TO ANOMALY WORKAROUND FAILURE (SEE ABOVE).
-// #ifdef NRF52840_XXAA
-// #define NRFX_SPIM_EXTENDED_ENABLED 1
-// #define NRFX_SPIM3_ENABLED 1
-// #else
-// #define NRFX_SPIM3_ENABLED 0
-// #endif
+#ifdef NRF52840_XXAA
+ #define NRFX_SPIM_EXTENDED_ENABLED 1
+ #define NRFX_SPIM3_ENABLED 1
+#else
+ #define NRFX_SPIM3_ENABLED 0
+#endif
#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY 7
diff --git a/ports/nrf/peripherals/nrf/nrf52840/power.c b/ports/nrf/peripherals/nrf/nrf52840/power.c
index 794872c5d..d64c536bb 100644
--- a/ports/nrf/peripherals/nrf/nrf52840/power.c
+++ b/ports/nrf/peripherals/nrf/nrf52840/power.c
@@ -25,16 +25,26 @@
*/
#include "nrfx.h"
-#include "nrfx_nvmc.h"
+#include "hal/nrf_nvmc.h"
void nrf_peripherals_power_init(void) {
// Set GPIO reference voltage to 3.3V if it isn't already. REGOUT0 will get reset to 0xfffffff
// if flash is erased, which sets the default to 1.8V
// This matters only when "high voltage mode" is enabled, which is true on the PCA10059,
// and might be true on other boards.
- if (NRF_UICR->REGOUT0 == 0xffffffff) {
- nrfx_nvmc_word_write((uint32_t) &NRF_UICR->REGOUT0, UICR_REGOUT0_VOUT_3V3 << UICR_REGOUT0_VOUT_Pos);
- // Must reset to make enable change.
+ if (NRF_UICR->REGOUT0 == 0xffffffff && NRF_POWER->MAINREGSTATUS & 1) {
+ // Expand what nrf_nvmc_word_write() did.
+ // It's missing from nrfx V2.0.0, and nrfx_nvmc_word_write() does bounds
+ // checking which prevents writes to UICR.
+ // Reported: https://devzone.nordicsemi.com/f/nordic-q-a/57243/nrfx_nvmc-h-api-cannot-write-to-uicr
+ NRF_NVMC->CONFIG = NRF_NVMC_MODE_WRITE;
+ while (!(NRF_NVMC->READY & NVMC_READY_READY_Msk)) {}
+ NRF_UICR->REGOUT0 = UICR_REGOUT0_VOUT_3V3 << UICR_REGOUT0_VOUT_Pos;
+ __DMB();
+ while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {}
+ NRF_NVMC->CONFIG = NRF_NVMC_MODE_READONLY;
+
+ // Must reset to enable change.
NVIC_SystemReset();
}
}
diff --git a/ports/nrf/peripherals/nrf/nvm.c b/ports/nrf/peripherals/nrf/nvm.c
index 1501ccfc9..63b168f14 100644
--- a/ports/nrf/peripherals/nrf/nvm.c
+++ b/ports/nrf/peripherals/nrf/nvm.c
@@ -38,23 +38,62 @@
#include "ble_drv.h"
#include "nrf_sdm.h"
+STATIC bool sd_is_enabled(void) {
+ uint8_t sd_en = 0;
+ (void) sd_softdevice_is_enabled(&sd_en);
+ return sd_en;
+}
+
STATIC void sd_flash_operation_start(void) {
sd_flash_operation_status = SD_FLASH_OPERATION_IN_PROGRESS;
}
STATIC sd_flash_operation_status_t sd_flash_operation_wait_until_done(void) {
- while (sd_flash_operation_status == SD_FLASH_OPERATION_IN_PROGRESS) {
- sd_app_evt_wait();
+ // If the SD is not enabled, no events are generated, so just return immediately.
+ if (sd_is_enabled()) {
+ while (sd_flash_operation_status == SD_FLASH_OPERATION_IN_PROGRESS) {
+ sd_app_evt_wait();
+ }
+ } else {
+ sd_flash_operation_status = SD_FLASH_OPERATION_DONE;
}
return sd_flash_operation_status;
+
+}
+
+bool sd_flash_page_erase_sync(uint32_t page_number) {
+ sd_flash_operation_start();
+ if (sd_flash_page_erase(page_number) != NRF_SUCCESS) {
+ return false;
+ }
+ if (sd_flash_operation_wait_until_done() == SD_FLASH_OPERATION_ERROR) {
+ return false;
+ }
+ return true;
+}
+
+bool sd_flash_write_sync(uint32_t *dest_words, uint32_t* src_words, uint32_t num_words) {
+ sd_flash_operation_start();
+ if (sd_flash_write(dest_words, src_words, num_words) != NRF_SUCCESS) {
+ return false;
+ }
+ if (sd_flash_operation_wait_until_done() == SD_FLASH_OPERATION_ERROR) {
+ return false;
+ }
+ return true;
}
+
#endif
+// The nRF52840 datasheet specifies a maximum of two writes to a flash
+// location before an erase is necessary, even if the write is all
+// ones (erased state). So we can't avoid erases even if the page
+// appears to be already erased (all ones), unless we keep track of
+// writes to a page.
+
bool nrf_nvm_safe_flash_page_write(uint32_t page_addr, uint8_t *data) {
#ifdef BLUETOOTH_SD
- uint8_t sd_en = 0;
- (void) sd_softdevice_is_enabled(&sd_en);
- if (sd_en) {
+ if (sd_is_enabled()) {
uint32_t err_code;
sd_flash_operation_status_t status;
diff --git a/ports/nrf/peripherals/nrf/nvm.h b/ports/nrf/peripherals/nrf/nvm.h
index e54e953df..8ba95773d 100644
--- a/ports/nrf/peripherals/nrf/nvm.h
+++ b/ports/nrf/peripherals/nrf/nvm.h
@@ -27,4 +27,9 @@
#define FLASH_PAGE_SIZE (4096)
+#if BLUETOOTH_SD
+bool sd_flash_page_erase_sync(uint32_t page_number);
+bool sd_flash_write_sync(uint32_t *dest_words, uint32_t* src_words, uint32_t num_words);
+#endif
+
bool nrf_nvm_safe_flash_page_write(uint32_t page_addr, uint8_t *data);
diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c
index d240e3be0..cbe0cec54 100644
--- a/ports/nrf/supervisor/port.c
+++ b/ports/nrf/supervisor/port.c
@@ -93,9 +93,6 @@ safe_mode_t port_init(void) {
rtc_init();
#endif
- // Will do usb_init() if chip supports USB.
- board_init();
-
return NO_SAFE_MODE;
}
@@ -148,6 +145,14 @@ void reset_cpu(void) {
NVIC_SystemReset();
}
+uint32_t *port_heap_get_bottom(void) {
+ return port_stack_get_limit();
+}
+
+uint32_t *port_heap_get_top(void) {
+ return port_stack_get_top();
+}
+
uint32_t *port_stack_get_limit(void) {
return &_ebss;
}
diff --git a/ports/stm32f4/Makefile b/ports/stm32f4/Makefile
index 2727ea954..3a6191c85 100755
--- a/ports/stm32f4/Makefile
+++ b/ports/stm32f4/Makefile
@@ -22,15 +22,15 @@
# 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.
-DEBUG = 1
+# DEBUG = 1
# Select the board to build for.
ifeq ($(BOARD),)
- $(error You must provide a BOARD parameter)
+ $(error You must provide a BOARD parameter)
else
- ifeq ($(wildcard boards/$(BOARD)/.),)
- $(error Invalid BOARD specified)
- endif
+ ifeq ($(wildcard boards/$(BOARD)/.),)
+ $(error Invalid BOARD specified)
+ endif
endif
# If the build directory is not given, make it reflect the board name.
@@ -80,15 +80,17 @@ INC += -I../../supervisor/shared/usb
#Debugging/Optimization
ifeq ($(DEBUG), 1)
- CFLAGS += -ggdb
- # You may want to enable these flags to make setting breakpoints easier.
- CFLAGS += -fno-inline -fno-ipa-sra
+ CFLAGS += -ggdb
+ # You may want to enable these flags to make setting breakpoints easier.
+ CFLAGS += -fno-inline -fno-ipa-sra
else
- CFLAGS += -Os -DNDEBUG
- # TODO: Test with -flto
- ### CFLAGS += -flto
+ CFLAGS += -Os -DNDEBUG
+ CFLAGS += -ggdb
+ # TODO: Test with -flto
+ ### CFLAGS += -flto
endif
+
C_DEFS = -DMCU_PACKAGE=$(MCU_PACKAGE) -DUSE_HAL_DRIVER -DUSE_FULL_LL_DRIVER -D$(CMSIS_MCU)
CFLAGS += $(INC) -Werror -Wall -std=gnu11 -nostdlib $(BASE_CFLAGS) $(C_DEFS) $(CFLAGS_MOD) $(COPT)
@@ -110,6 +112,22 @@ CFLAGS += \
# TODO: check this
CFLAGS += -D__START=main
+#need both command and valid file to use uf2 bootloader
+ifndef LD_FILE
+ ifneq ($(and $(UF2_BOOTLOADER),$(LD_BOOT)),)
+ LD_FILE = $(LD_BOOT)
+ BOOTLOADER_OFFSET = $(UF2_OFFSET)
+ CFLAGS += -DUF2_BOOTLOADER_ENABLED
+ else
+ LD_FILE = $(LD_DEFAULT)
+ endif
+endif
+
+# Add bootloader specific items
+ifndef BOOTLOADER_OFFSET
+ BOOTLOADER_OFFSET := 0x8000000
+endif
+
LDFLAGS = $(CFLAGS) -fshort-enums -Wl,-nostdlib -Wl,-T,$(LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs
LIBS := -lgcc -lc
@@ -205,12 +223,12 @@ SRC_S = \
boards/startup_$(MCU_SUB_VARIANT).s
SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
- $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
- $(addprefix common-hal/, $(SRC_COMMON_HAL))
+ $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
+ $(addprefix common-hal/, $(SRC_COMMON_HAL))
SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
- $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \
- $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL))
+ $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \
+ $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL))
ifneq ($(FROZEN_MPY_DIR),)
@@ -256,7 +274,7 @@ $(BUILD)/firmware.hex: $(BUILD)/firmware.elf
$(BUILD)/firmware.uf2: $(BUILD)/firmware.hex
$(ECHO) "Create $@"
- $(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "$(BUILD)/firmware.uf2" $^
+ $(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -f 0x57755a57 -b $(BOOTLOADER_OFFSET) -c -o "$(BUILD)/firmware.uf2" $^
include $(TOP)/py/mkrules.mk
diff --git a/ports/stm32f4/boards/STM32F401xd_fs.ld b/ports/stm32f4/boards/STM32F401xd_fs.ld
new file mode 100644
index 000000000..c42dfcca8
--- /dev/null
+++ b/ports/stm32f4/boards/STM32F401xd_fs.ld
@@ -0,0 +1,107 @@
+/*
+ GNU linker script for STM32F401 with bootloader (such as the Meowbit)
+*/
+
+/* Specify the memory areas */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 384K /* entire flash */
+ FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
+ FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 48K /* sectors 1,2,3 are 16K */
+ FLASH_TEXT (rx) : ORIGIN = 0x08010000, LENGTH = 320K /* sector 4 is 64K, sectors 5,6,7 are 128K */
+ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K
+}
+
+/* produce a link error if there is not this amount of RAM for these sections */
+_minimum_stack_size = 2K;
+_minimum_heap_size = 16K;
+
+/* Define tho top end of the stack. The stack is full descending so begins just
+ above last byte of RAM. Note that EABI requires the stack to be 8-byte
+ aligned for a call. */
+_estack = ORIGIN(RAM) + LENGTH(RAM);
+
+/* RAM extents for the garbage collector */
+_ram_start = ORIGIN(RAM);
+_ram_end = ORIGIN(RAM) + LENGTH(RAM);
+
+ENTRY(Reset_Handler)
+
+/* define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+
+ /* This first flash block is 16K annd the isr vectors only take up
+ about 400 bytes. Micropython pads this with files, but this didn't
+ work with the size of Circuitpython's ff object. */
+
+ . = ALIGN(4);
+ } >FLASH_ISR
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text*) /* .text* sections (code) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ /* *(.glue_7) */ /* glue arm to thumb code */
+ /* *(.glue_7t) */ /* glue thumb to arm code */
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbol at end of code */
+ } >FLASH_TEXT
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* This is the initialized data section
+ The program executes knowing that the data is in the RAM
+ but the loader puts the initial values in the FLASH (inidata).
+ It is one task of the startup to copy the initial values from FLASH to RAM. */
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
+ *(.data*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
+ } >RAM AT> FLASH_TEXT
+
+ /* Uninitialized data section */
+ .bss :
+ {
+ . = ALIGN(4);
+ _sbss = .; /* define a global symbol at bss start; used by startup code */
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end; used by startup code and GC */
+ } >RAM
+
+ /* this is to define the start of the heap, and make sure we have a minimum size */
+ .heap :
+ {
+ . = ALIGN(4);
+ . = . + _minimum_heap_size;
+ . = ALIGN(4);
+ } >RAM
+
+ /* this just checks there is enough RAM for the stack */
+ .stack :
+ {
+ . = ALIGN(4);
+ . = . + _minimum_stack_size;
+ . = ALIGN(4);
+ } >RAM
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
+
diff --git a/ports/stm32f4/boards/STM32F401xe_boot.ld b/ports/stm32f4/boards/STM32F401xe_boot.ld
new file mode 100644
index 000000000..125d785fc
--- /dev/null
+++ b/ports/stm32f4/boards/STM32F401xe_boot.ld
@@ -0,0 +1,106 @@
+/*
+ GNU linker script for STM32F401 with bootloader (such as the Meowbit)
+*/
+
+/* Specify the memory areas */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x08010000, LENGTH = 512K - 64K /* entire flash, sans bootloader region */
+ FLASH_ISR (rx) : ORIGIN = 0x08010000, LENGTH = 64K /* sector 4 */
+ FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 384K /* sectors 5,6,7 are 128K */
+ RAM (xrw) : ORIGIN = 0x20000194, LENGTH = 96K - 0x194
+}
+
+/* produce a link error if there is not this amount of RAM for these sections */
+_minimum_stack_size = 2K;
+_minimum_heap_size = 16K;
+
+/* Define tho top end of the stack. The stack is full descending so begins just
+ above last byte of RAM. Note that EABI requires the stack to be 8-byte
+ aligned for a call. */
+_estack = ORIGIN(RAM) + LENGTH(RAM);
+
+/* RAM extents for the garbage collector */
+_ram_start = ORIGIN(RAM);
+_ram_end = ORIGIN(RAM) + LENGTH(RAM);
+
+ENTRY(Reset_Handler)
+
+/* define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+
+ /* This first flash block is 16K annd the isr vectors only take up
+ about 400 bytes. Micropython pads this with files, but this didn't
+ work with the size of Circuitpython's ff object. */
+
+ . = ALIGN(4);
+ } >FLASH_ISR
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text*) /* .text* sections (code) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ /* *(.glue_7) */ /* glue arm to thumb code */
+ /* *(.glue_7t) */ /* glue thumb to arm code */
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbol at end of code */
+ } >FLASH_TEXT
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* This is the initialized data section
+ The program executes knowing that the data is in the RAM
+ but the loader puts the initial values in the FLASH (inidata).
+ It is one task of the startup to copy the initial values from FLASH to RAM. */
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
+ *(.data*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
+ } >RAM AT> FLASH_TEXT
+
+ /* Uninitialized data section */
+ .bss :
+ {
+ . = ALIGN(4);
+ _sbss = .; /* define a global symbol at bss start; used by startup code */
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end; used by startup code and GC */
+ } >RAM
+
+ /* this is to define the start of the heap, and make sure we have a minimum size */
+ .heap :
+ {
+ . = ALIGN(4);
+ . = . + _minimum_heap_size;
+ . = ALIGN(4);
+ } >RAM
+
+ /* this just checks there is enough RAM for the stack */
+ .stack :
+ {
+ . = ALIGN(4);
+ . = . + _minimum_stack_size;
+ . = ALIGN(4);
+ } >RAM
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
+
diff --git a/ports/stm32f4/boards/STM32F401xe_fs.ld b/ports/stm32f4/boards/STM32F401xe_fs.ld
new file mode 100644
index 000000000..fd30e1622
--- /dev/null
+++ b/ports/stm32f4/boards/STM32F401xe_fs.ld
@@ -0,0 +1,107 @@
+/*
+ GNU linker script for STM32F401 with bootloader (such as the Meowbit)
+*/
+
+/* Specify the memory areas */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K /* entire flash */
+ FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
+ FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 48K /* sectors 1,2,3 are 16K */
+ FLASH_TEXT (rx) : ORIGIN = 0x08010000, LENGTH = 448K /* sector 4 is 64K, sectors 5,6,7 are 128K */
+ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K
+}
+
+/* produce a link error if there is not this amount of RAM for these sections */
+_minimum_stack_size = 2K;
+_minimum_heap_size = 16K;
+
+/* Define tho top end of the stack. The stack is full descending so begins just
+ above last byte of RAM. Note that EABI requires the stack to be 8-byte
+ aligned for a call. */
+_estack = ORIGIN(RAM) + LENGTH(RAM);
+
+/* RAM extents for the garbage collector */
+_ram_start = ORIGIN(RAM);
+_ram_end = ORIGIN(RAM) + LENGTH(RAM);
+
+ENTRY(Reset_Handler)
+
+/* define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+
+ /* This first flash block is 16K annd the isr vectors only take up
+ about 400 bytes. Micropython pads this with files, but this didn't
+ work with the size of Circuitpython's ff object. */
+
+ . = ALIGN(4);
+ } >FLASH_ISR
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text*) /* .text* sections (code) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ /* *(.glue_7) */ /* glue arm to thumb code */
+ /* *(.glue_7t) */ /* glue thumb to arm code */
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbol at end of code */
+ } >FLASH_TEXT
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* This is the initialized data section
+ The program executes knowing that the data is in the RAM
+ but the loader puts the initial values in the FLASH (inidata).
+ It is one task of the startup to copy the initial values from FLASH to RAM. */
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
+ *(.data*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
+ } >RAM AT> FLASH_TEXT
+
+ /* Uninitialized data section */
+ .bss :
+ {
+ . = ALIGN(4);
+ _sbss = .; /* define a global symbol at bss start; used by startup code */
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end; used by startup code and GC */
+ } >RAM
+
+ /* this is to define the start of the heap, and make sure we have a minimum size */
+ .heap :
+ {
+ . = ALIGN(4);
+ . = . + _minimum_heap_size;
+ . = ALIGN(4);
+ } >RAM
+
+ /* this just checks there is enough RAM for the stack */
+ .stack :
+ {
+ . = ALIGN(4);
+ . = . + _minimum_stack_size;
+ . = ALIGN(4);
+ } >RAM
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
+
diff --git a/ports/stm32f4/boards/STM32F405_boot.ld b/ports/stm32f4/boards/STM32F405_boot.ld
new file mode 100644
index 000000000..64da3b652
--- /dev/null
+++ b/ports/stm32f4/boards/STM32F405_boot.ld
@@ -0,0 +1,107 @@
+/*
+ GNU linker script for STM32F405 with bootloader
+ Based on Micropython
+*/
+
+/* Specify the memory areas */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x08010000, LENGTH = 1024K - 64K /* entire flash, sans bootloader region */
+ FLASH_ISR (rx) : ORIGIN = 0x08010000, LENGTH = 64K /* sector 0 */
+ FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 1024K - 64K - 64K /* sectors 5+ */
+ CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
+ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
+}
+
+/* produce a link error if there is not this amount of RAM for these sections */
+_minimum_stack_size = 2K;
+_minimum_heap_size = 16K;
+
+/* Define the top end of the stack. The stack is full descending so begins just
+ above last byte of RAM. Note that EABI requires the stack to be 8-byte
+ aligned for a call. */
+_estack = ORIGIN(RAM) + LENGTH(RAM);
+
+/* RAM extents for the garbage collector */
+_ram_start = ORIGIN(RAM);
+_ram_end = ORIGIN(RAM) + LENGTH(RAM);
+
+ENTRY(Reset_Handler)
+
+/* define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+
+ /* This first flash block is 16K annd the isr vectors only take up
+ about 400 bytes. Micropython pads this with files, but this didn't
+ work with the size of Circuitpython's ff object. */
+
+ . = ALIGN(4);
+ } >FLASH_ISR
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text*) /* .text* sections (code) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ /* *(.glue_7) */ /* glue arm to thumb code */
+ /* *(.glue_7t) */ /* glue thumb to arm code */
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbol at end of code */
+ } >FLASH_TEXT
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* This is the initialized data section
+ The program executes knowing that the data is in the RAM
+ but the loader puts the initial values in the FLASH (inidata).
+ It is one task of the startup to copy the initial values from FLASH to RAM. */
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
+ *(.data*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
+ } >RAM AT> FLASH_TEXT
+
+ /* Uninitialized data section */
+ .bss :
+ {
+ . = ALIGN(4);
+ _sbss = .; /* define a global symbol at bss start; used by startup code */
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end; used by startup code and GC */
+ } >RAM
+
+ /* this is to define the start of the heap, and make sure we have a minimum size */
+ .heap :
+ {
+ . = ALIGN(4);
+ . = . + _minimum_heap_size;
+ . = ALIGN(4);
+ } >RAM
+
+ /* this just checks there is enough RAM for the stack */
+ .stack :
+ {
+ . = ALIGN(4);
+ . = . + _minimum_stack_size;
+ . = ALIGN(4);
+ } >RAM
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
diff --git a/ports/stm32f4/boards/STM32F405_default.ld b/ports/stm32f4/boards/STM32F405_default.ld
new file mode 100644
index 000000000..c2b8c843e
--- /dev/null
+++ b/ports/stm32f4/boards/STM32F405_default.ld
@@ -0,0 +1,107 @@
+/*
+ GNU linker script for STM32F405 via Micropython
+*/
+
+/* Specify the memory areas */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* entire flash */
+ FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
+ FLASH_TEXT (rx) : ORIGIN = 0x08004000, LENGTH = 1008K /* sectors 0-7*/
+ CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
+ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
+}
+
+/* produce a link error if there is not this amount of RAM for these sections */
+_minimum_stack_size = 2K;
+_minimum_heap_size = 16K;
+
+/* Define tho top end of the stack. The stack is full descending so begins just
+ above last byte of RAM. Note that EABI requires the stack to be 8-byte
+ aligned for a call. */
+_estack = ORIGIN(RAM) + LENGTH(RAM);
+
+/* RAM extents for the garbage collector */
+_ram_start = ORIGIN(RAM);
+_ram_end = ORIGIN(RAM) + LENGTH(RAM);
+
+ENTRY(Reset_Handler)
+
+/* define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+
+ /* This first flash block is 16K annd the isr vectors only take up
+ about 400 bytes. Micropython pads this with files, but this didn't
+ work with the size of Circuitpython's ff object. */
+
+ . = ALIGN(4);
+ } >FLASH_ISR
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text*) /* .text* sections (code) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ /* *(.glue_7) */ /* glue arm to thumb code */
+ /* *(.glue_7t) */ /* glue thumb to arm code */
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbol at end of code */
+ } >FLASH_TEXT
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* This is the initialized data section
+ The program executes knowing that the data is in the RAM
+ but the loader puts the initial values in the FLASH (inidata).
+ It is one task of the startup to copy the initial values from FLASH to RAM. */
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
+ *(.data*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
+ } >RAM AT> FLASH_TEXT
+
+ /* Uninitialized data section */
+ .bss :
+ {
+ . = ALIGN(4);
+ _sbss = .; /* define a global symbol at bss start; used by startup code */
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end; used by startup code and GC */
+ } >RAM
+
+ /* this is to define the start of the heap, and make sure we have a minimum size */
+ .heap :
+ {
+ . = ALIGN(4);
+ . = . + _minimum_heap_size;
+ . = ALIGN(4);
+ } >RAM
+
+ /* this just checks there is enough RAM for the stack */
+ .stack :
+ {
+ . = ALIGN(4);
+ . = . + _minimum_stack_size;
+ . = ALIGN(4);
+ } >RAM
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
+
diff --git a/ports/stm32f4/boards/STM32F405.ld b/ports/stm32f4/boards/STM32F405_fs.ld
index 7f7c91784..7f7c91784 100644
--- a/ports/stm32f4/boards/STM32F405.ld
+++ b/ports/stm32f4/boards/STM32F405_fs.ld
diff --git a/ports/stm32f4/boards/STM32F407_fs.ld b/ports/stm32f4/boards/STM32F407_fs.ld
new file mode 100644
index 000000000..7f7c91784
--- /dev/null
+++ b/ports/stm32f4/boards/STM32F407_fs.ld
@@ -0,0 +1,108 @@
+/*
+ GNU linker script for STM32F405 via Micropython
+*/
+
+/* Specify the memory areas */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* entire flash */
+ FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
+ FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 48K /* sectors 1,2,3 are 16K */
+ FLASH_TEXT (rx) : ORIGIN = 0x08010000, LENGTH = 960K /* sector 4 is 64K, sectors 5,6,7 are 128K */
+ CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
+ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
+}
+
+/* produce a link error if there is not this amount of RAM for these sections */
+_minimum_stack_size = 2K;
+_minimum_heap_size = 16K;
+
+/* Define tho top end of the stack. The stack is full descending so begins just
+ above last byte of RAM. Note that EABI requires the stack to be 8-byte
+ aligned for a call. */
+_estack = ORIGIN(RAM) + LENGTH(RAM);
+
+/* RAM extents for the garbage collector */
+_ram_start = ORIGIN(RAM);
+_ram_end = ORIGIN(RAM) + LENGTH(RAM);
+
+ENTRY(Reset_Handler)
+
+/* define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+
+ /* This first flash block is 16K annd the isr vectors only take up
+ about 400 bytes. Micropython pads this with files, but this didn't
+ work with the size of Circuitpython's ff object. */
+
+ . = ALIGN(4);
+ } >FLASH_ISR
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text*) /* .text* sections (code) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ /* *(.glue_7) */ /* glue arm to thumb code */
+ /* *(.glue_7t) */ /* glue thumb to arm code */
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbol at end of code */
+ } >FLASH_TEXT
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* This is the initialized data section
+ The program executes knowing that the data is in the RAM
+ but the loader puts the initial values in the FLASH (inidata).
+ It is one task of the startup to copy the initial values from FLASH to RAM. */
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
+ *(.data*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
+ } >RAM AT> FLASH_TEXT
+
+ /* Uninitialized data section */
+ .bss :
+ {
+ . = ALIGN(4);
+ _sbss = .; /* define a global symbol at bss start; used by startup code */
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end; used by startup code and GC */
+ } >RAM
+
+ /* this is to define the start of the heap, and make sure we have a minimum size */
+ .heap :
+ {
+ . = ALIGN(4);
+ . = . + _minimum_heap_size;
+ . = ALIGN(4);
+ } >RAM
+
+ /* this just checks there is enough RAM for the stack */
+ .stack :
+ {
+ . = ALIGN(4);
+ . = . + _minimum_stack_size;
+ . = ALIGN(4);
+ } >RAM
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
+
diff --git a/ports/stm32f4/boards/espruino_pico/README.md b/ports/stm32f4/boards/espruino_pico/README.md
new file mode 100644
index 000000000..9f0321c47
--- /dev/null
+++ b/ports/stm32f4/boards/espruino_pico/README.md
@@ -0,0 +1,15 @@
+# Flashing the Espruino Pico
+
+The Espruino Pico is normally updated via a bootloader activated by the Espruino web app. This approach is not practical for Circuitpython as it takes too much space from the internal filesystem - thus, you will need to follow the instructions for advanced reflashing using the built-in ROM bootloader on all STM32F4 MCUs (instructions sourced from https://www.espruino.com/Pico#advanced-reflashing)
+
+ - Short out the BOOT0/BTN solder jumper on the back of the board - you can do this by drawing over it with a pencil.
+ - Install ST's DFU utility on Windows, or dfu-util for Mac or Linux
+ - **Mac**: install with Homebrew: `brew install dfu-util`
+ - **Linux**: install with apt-get: `sudo apt-get install dfu-util`
+ - **Windows**: download [ST's application](https://www.st.com/en/development-tools/stsw-stm32080.html) or install the Linux subsystem for Windows 10 and follow the linux instructions.
+ - Hold down the Pico's button while plugging it into USB (when overwriting Espruino's default firmware)
+ - Navigate to the same directory as your firmware.bin file for Circuitpython and run the following command: `sudo dfu-util -a 0 -s 0x08000000 -D firmware.bin` or use the ST utility on Windows.
+ - Restart the board.
+
+
+To reinstall Espruino, follow the same steps with the latest Espruino Pico binary from espruino.com/binaries. This will reinstall the usual Espruino bootloader. You must un-short the BOOT0/BTN jumper to re-use the original Espruino Bootloader again. If you used a Pencil mark then you may need to use cleaning fluid and a small brush to totally clear out the graphite. \ No newline at end of file
diff --git a/ports/stm32f4/boards/espruino_pico/board.c b/ports/stm32f4/boards/espruino_pico/board.c
new file mode 100644
index 000000000..82b0c506e
--- /dev/null
+++ b/ports/stm32f4/boards/espruino_pico/board.c
@@ -0,0 +1,39 @@
+/*
+ * 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 "boards/board.h"
+#include "mpconfigboard.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/stm32f4/boards/espruino_pico/mpconfigboard.h b/ports/stm32f4/boards/espruino_pico/mpconfigboard.h
new file mode 100644
index 000000000..d4430380c
--- /dev/null
+++ b/ports/stm32f4/boards/espruino_pico/mpconfigboard.h
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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.
+ */
+
+//Micropython setup
+
+#define MICROPY_HW_BOARD_NAME "Espruino Pico"
+#define MICROPY_HW_MCU_NAME "STM32F401xD"
+
+#define FLASH_SIZE (0x60000)
+#define FLASH_PAGE_SIZE (0x4000)
+
+#define AUTORESET_DELAY_MS (500)
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000)
+
+#define BOARD_OSC_DIV (8)
+
diff --git a/ports/stm32f4/boards/espruino_pico/mpconfigboard.mk b/ports/stm32f4/boards/espruino_pico/mpconfigboard.mk
new file mode 100644
index 000000000..151ca1437
--- /dev/null
+++ b/ports/stm32f4/boards/espruino_pico/mpconfigboard.mk
@@ -0,0 +1,16 @@
+USB_VID = 0x239A
+USB_PID = 0x808E
+USB_PRODUCT = "Espruino Pico"
+USB_MANUFACTURER = "Espruino"
+USB_DEVICES = "CDC,MSC"
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = NONE
+
+MCU_SERIES = m4
+MCU_VARIANT = stm32f4
+MCU_SUB_VARIANT = stm32f401xe
+MCU_PACKAGE = 48
+CMSIS_MCU = STM32F401xE
+LD_FILE = boards/STM32F401xd_fs.ld # use for internal flash
+
diff --git a/ports/stm32f4/boards/espruino_pico/pins.c b/ports/stm32f4/boards/espruino_pico/pins.c
new file mode 100644
index 000000000..55c0336c5
--- /dev/null
+++ b/ports/stm32f4/boards/espruino_pico/pins.c
@@ -0,0 +1,33 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_B15), MP_ROM_PTR(&pin_PB15) },
+ { MP_ROM_QSTR(MP_QSTR_B14), MP_ROM_PTR(&pin_PB14) },
+ { MP_ROM_QSTR(MP_QSTR_B13), MP_ROM_PTR(&pin_PB13) },
+ { MP_ROM_QSTR(MP_QSTR_B10), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_B1), MP_ROM_PTR(&pin_PB01) },
+ { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA05) },
+
+ { MP_ROM_QSTR(MP_QSTR_B3), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_B4), MP_ROM_PTR(&pin_PB04) },
+ { MP_ROM_QSTR(MP_QSTR_B5), MP_ROM_PTR(&pin_PB05) },
+ { MP_ROM_QSTR(MP_QSTR_B6), MP_ROM_PTR(&pin_PB06) },
+ { MP_ROM_QSTR(MP_QSTR_B7), MP_ROM_PTR(&pin_PB07) },
+ { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA08) },
+
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_B9), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_B8), MP_ROM_PTR(&pin_PB08) },
+
+ { MP_ROM_QSTR(MP_QSTR_BTN), MP_ROM_PTR(&pin_PC13) },
+ { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_PB12) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/stm32f4/boards/espruino_pico/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/espruino_pico/stm32f4xx_hal_conf.h
new file mode 100644
index 000000000..ab04df318
--- /dev/null
+++ b/ports/stm32f4/boards/espruino_pico/stm32f4xx_hal_conf.h
@@ -0,0 +1,440 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_conf_template.h
+ * @author MCD Application Team
+ * @brief HAL configuration template file.
+ * This file should be copied to the application folder and renamed
+ * to stm32f4xx_hal_conf.h.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_CONF_H
+#define __STM32F4xx_HAL_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* ########################## Module Selection ############################## */
+/**
+ * @brief This is the list of modules to be used in the HAL driver
+ */
+#define HAL_MODULE_ENABLED
+
+#define HAL_ADC_MODULE_ENABLED
+/* #define HAL_CRYP_MODULE_ENABLED */
+/* #define HAL_CAN_MODULE_ENABLED */
+/* #define HAL_CRC_MODULE_ENABLED */
+/* #define HAL_CRYP_MODULE_ENABLED */
+#define HAL_DAC_MODULE_ENABLED
+/* #define HAL_DCMI_MODULE_ENABLED */
+/* #define HAL_DMA2D_MODULE_ENABLED */
+/* #define HAL_ETH_MODULE_ENABLED */
+/* #define HAL_NAND_MODULE_ENABLED */
+/* #define HAL_NOR_MODULE_ENABLED */
+/* #define HAL_PCCARD_MODULE_ENABLED */
+/* #define HAL_SRAM_MODULE_ENABLED */
+/* #define HAL_SDRAM_MODULE_ENABLED */
+/* #define HAL_HASH_MODULE_ENABLED */
+#define HAL_I2C_MODULE_ENABLED
+#define HAL_I2S_MODULE_ENABLED
+/* #define HAL_IWDG_MODULE_ENABLED */
+/* #define HAL_LTDC_MODULE_ENABLED */
+/* #define HAL_RNG_MODULE_ENABLED */
+/* #define HAL_RTC_MODULE_ENABLED */
+/* #define HAL_SAI_MODULE_ENABLED */
+/* #define HAL_SD_MODULE_ENABLED */
+/* #define HAL_MMC_MODULE_ENABLED */
+#define HAL_SPI_MODULE_ENABLED
+#define HAL_TIM_MODULE_ENABLED
+#define HAL_UART_MODULE_ENABLED
+#define HAL_USART_MODULE_ENABLED
+/* #define HAL_IRDA_MODULE_ENABLED */
+/* #define HAL_SMARTCARD_MODULE_ENABLED */
+/* #define HAL_WWDG_MODULE_ENABLED */
+#define HAL_PCD_MODULE_ENABLED
+/* #define HAL_HCD_MODULE_ENABLED */
+/* #define HAL_DSI_MODULE_ENABLED */
+/* #define HAL_QSPI_MODULE_ENABLED */
+/* #define HAL_QSPI_MODULE_ENABLED */
+/* #define HAL_CEC_MODULE_ENABLED */
+/* #define HAL_FMPI2C_MODULE_ENABLED */
+/* #define HAL_SPDIFRX_MODULE_ENABLED */
+/* #define HAL_DFSDM_MODULE_ENABLED */
+/* #define HAL_LPTIM_MODULE_ENABLED */
+/* #define HAL_EXTI_MODULE_ENABLED */
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_EXTI_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+
+/* ########################## HSE/HSI Values adaptation ##################### */
+/**
+ * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSE is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (HSE_STARTUP_TIMEOUT)
+ #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief Internal High Speed oscillator (HSI) value.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSI is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+ * @brief Internal Low Speed oscillator (LSI) value.
+ */
+#if !defined (LSI_VALUE)
+ #define LSI_VALUE ((uint32_t)40000)
+#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
+ The real value may vary depending on the variations
+ in voltage and temperature. */
+/**
+ * @brief External Low Speed oscillator (LSE) value.
+ */
+#if !defined (LSE_VALUE)
+ #define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */
+#endif /* LSE_VALUE */
+
+#if !defined (LSE_STARTUP_TIMEOUT)
+ #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
+#endif /* LSE_STARTUP_TIMEOUT */
+
+
+/**
+ * @brief External clock source for I2S peripheral
+ * This value is used by the I2S HAL module to compute the I2S clock source
+ * frequency, this source is inserted directly through I2S_CKIN pad.
+ */
+#if !defined (EXTERNAL_CLOCK_VALUE)
+ #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/
+#endif /* EXTERNAL_CLOCK_VALUE */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+ === you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+ * @brief This is the HAL system configuration section
+ */
+#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
+#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
+#define USE_RTOS 0U
+#define PREFETCH_ENABLE 1U
+#define INSTRUCTION_CACHE_ENABLE 1U
+#define DATA_CACHE_ENABLE 1U
+
+/* ########################## Assert Selection ############################## */
+/**
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * HAL drivers code
+ */
+/* #define USE_FULL_ASSERT 1U */
+
+/* ################## Ethernet peripheral configuration ##################### */
+
+/* Section 1 : Ethernet peripheral configuration */
+
+/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
+#define MAC_ADDR0 2U
+#define MAC_ADDR1 0U
+#define MAC_ADDR2 0U
+#define MAC_ADDR3 0U
+#define MAC_ADDR4 0U
+#define MAC_ADDR5 0U
+
+/* Definition of the Ethernet driver buffers size and count */
+#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
+#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
+#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
+
+/* Section 2: PHY configuration section */
+
+/* DP83848_PHY_ADDRESS Address*/
+#define DP83848_PHY_ADDRESS 0x01U
+/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
+#define PHY_RESET_DELAY ((uint32_t)0x000000FFU)
+/* PHY Configuration delay */
+#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU)
+
+#define PHY_READ_TO ((uint32_t)0x0000FFFFU)
+#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU)
+
+/* Section 3: Common PHY Registers */
+
+#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */
+#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
+
+#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
+#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
+#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
+#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
+#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
+#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
+#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
+#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
+#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
+#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
+
+#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
+#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
+#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
+
+/* Section 4: Extended PHY Registers */
+#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
+
+#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
+#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
+
+/* ################## SPI peripheral configuration ########################## */
+
+/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
+* Activated: CRC code is present inside driver
+* Deactivated: CRC code cleaned from driver
+*/
+
+#define USE_SPI_CRC 0U
+
+/* Includes ------------------------------------------------------------------*/
+/**
+ * @brief Include module's header file
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_EXTI_MODULE_ENABLED
+ #include "stm32f4xx_hal_exti.h"
+#endif /* HAL_EXTI_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+ #include "stm32f4xx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+ #include "stm32f4xx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+ #include "stm32f4xx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_CAN_MODULE_ENABLED
+ #include "stm32f4xx_hal_can.h"
+#endif /* HAL_CAN_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+ #include "stm32f4xx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_CRYP_MODULE_ENABLED
+ #include "stm32f4xx_hal_cryp.h"
+#endif /* HAL_CRYP_MODULE_ENABLED */
+
+#ifdef HAL_DMA2D_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma2d.h"
+#endif /* HAL_DMA2D_MODULE_ENABLED */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+ #include "stm32f4xx_hal_dac.h"
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+#ifdef HAL_DCMI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dcmi.h"
+#endif /* HAL_DCMI_MODULE_ENABLED */
+
+#ifdef HAL_ETH_MODULE_ENABLED
+ #include "stm32f4xx_hal_eth.h"
+#endif /* HAL_ETH_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+ #include "stm32f4xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+ #include "stm32f4xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_PCCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pccard.h"
+#endif /* HAL_PCCARD_MODULE_ENABLED */
+
+#ifdef HAL_SDRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sdram.h"
+#endif /* HAL_SDRAM_MODULE_ENABLED */
+
+#ifdef HAL_HASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_hash.h"
+#endif /* HAL_HASH_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2s.h"
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_LTDC_MODULE_ENABLED
+ #include "stm32f4xx_hal_ltdc.h"
+#endif /* HAL_LTDC_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+ #include "stm32f4xx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_RNG_MODULE_ENABLED
+ #include "stm32f4xx_hal_rng.h"
+#endif /* HAL_RNG_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_SAI_MODULE_ENABLED
+ #include "stm32f4xx_hal_sai.h"
+#endif /* HAL_SAI_MODULE_ENABLED */
+
+#ifdef HAL_SD_MODULE_ENABLED
+ #include "stm32f4xx_hal_sd.h"
+#endif /* HAL_SD_MODULE_ENABLED */
+
+#ifdef HAL_MMC_MODULE_ENABLED
+ #include "stm32f4xx_hal_mmc.h"
+#endif /* HAL_MMC_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+ #include "stm32f4xx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+ #include "stm32f4xx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32f4xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_HCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_hcd.h"
+#endif /* HAL_HCD_MODULE_ENABLED */
+
+#ifdef HAL_DSI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dsi.h"
+#endif /* HAL_DSI_MODULE_ENABLED */
+
+#ifdef HAL_QSPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_qspi.h"
+#endif /* HAL_QSPI_MODULE_ENABLED */
+
+#ifdef HAL_CEC_MODULE_ENABLED
+ #include "stm32f4xx_hal_cec.h"
+#endif /* HAL_CEC_MODULE_ENABLED */
+
+#ifdef HAL_FMPI2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_fmpi2c.h"
+#endif /* HAL_FMPI2C_MODULE_ENABLED */
+
+#ifdef HAL_SPDIFRX_MODULE_ENABLED
+ #include "stm32f4xx_hal_spdifrx.h"
+#endif /* HAL_SPDIFRX_MODULE_ENABLED */
+
+#ifdef HAL_DFSDM_MODULE_ENABLED
+ #include "stm32f4xx_hal_dfsdm.h"
+#endif /* HAL_DFSDM_MODULE_ENABLED */
+
+#ifdef HAL_LPTIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_lptim.h"
+#endif /* HAL_LPTIM_MODULE_ENABLED */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr: If expr is false, it calls assert_failed function
+ * which reports the name of the source file and the source
+ * line number of the call that failed.
+ * If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_HAL_CONF_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/ports/stm32f4/boards/espruino_wifi/README.MD b/ports/stm32f4/boards/espruino_wifi/README.MD
new file mode 100644
index 000000000..8c2cd3be2
--- /dev/null
+++ b/ports/stm32f4/boards/espruino_wifi/README.MD
@@ -0,0 +1,15 @@
+# Flashing the Espruino Wifi
+
+The Espruino Wifi is normally updated via a bootloader activated by the Espruino web app. This approach is not practical for Circuitpython as it takes too much space from the internal filesystem - thus, you will need to follow the instructions for advanced reflashing using the built-in ROM bootloader on all STM32F4 MCUs (instructions sourced from https://www.espruino.com/Wifi#advanced-reflashing)
+
+ - Short out the BOOT0/BTN solder jumper on the back of the board - you can do this by drawing over it with a pencil.
+ - Install ST's DFU utility on Windows, or dfu-util for Mac or Linux
+ - **Mac**: install with Homebrew: `brew install dfu-util`
+ - **Linux**: install with apt-get: `sudo apt-get install dfu-util`
+ - **Windows**: download [ST's application](https://www.st.com/en/development-tools/stsw-stm32080.html) or install the Linux subsystem for Windows 10 and follow the linux instructions.
+ - Hold down the Wifi's button while plugging it into USB (when overwriting Espruino's default firmware)
+ - Navigate to the same directory as your firmware.bin file for Circuitpython and run the following command: `sudo dfu-util -a 0 -s 0x08000000 -D firmware.bin` or use the ST utility on Windows.
+ - Restart the board.
+
+
+To reinstall Espruino, follow the same steps with the latest Espruino Wifi binary from espruino.com/binaries. This will reinstall the usual Espruino bootloader. You must un-short the BOOT0/BTN jumper to re-use the original Espruino Bootloader again. If you used a Pencil mark then you may need to use cleaning fluid and a small brush to totally clear out the graphite. \ No newline at end of file
diff --git a/ports/stm32f4/boards/espruino_wifi/board.c b/ports/stm32f4/boards/espruino_wifi/board.c
new file mode 100644
index 000000000..4421970ee
--- /dev/null
+++ b/ports/stm32f4/boards/espruino_wifi/board.c
@@ -0,0 +1,38 @@
+/*
+ * 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 "boards/board.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/stm32f4/boards/espruino_wifi/mpconfigboard.h b/ports/stm32f4/boards/espruino_wifi/mpconfigboard.h
new file mode 100644
index 000000000..abdc9e8fa
--- /dev/null
+++ b/ports/stm32f4/boards/espruino_wifi/mpconfigboard.h
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Lucian Copeland 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.
+ */
+
+//Micropython setup
+
+#define MICROPY_HW_BOARD_NAME "Espruino Wifi"
+#define MICROPY_HW_MCU_NAME "STM32F411xE"
+
+#define FLASH_SIZE (0x80000) //512K
+#define FLASH_PAGE_SIZE (0x4000) //16K
+
+#define BOARD_OSC_DIV (8)
+#define BOARD_OVERWRITE_SWD (1)
diff --git a/ports/stm32f4/boards/espruino_wifi/mpconfigboard.mk b/ports/stm32f4/boards/espruino_wifi/mpconfigboard.mk
new file mode 100644
index 000000000..8b28cf07c
--- /dev/null
+++ b/ports/stm32f4/boards/espruino_wifi/mpconfigboard.mk
@@ -0,0 +1,16 @@
+USB_VID = 0x239A
+USB_PID = 0x8090
+USB_PRODUCT = "Espruino Wifi"
+USB_MANUFACTURER = "Espruino"
+USB_DEVICES = "CDC,MSC"
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = NONE
+
+MCU_SERIES = m4
+MCU_VARIANT = stm32f4
+MCU_SUB_VARIANT = stm32f411xe
+MCU_PACKAGE = 48
+CMSIS_MCU = STM32F411xE
+LD_FILE = boards/STM32F411VETx_FLASH.ld
+
diff --git a/ports/stm32f4/boards/espruino_wifi/pins.c b/ports/stm32f4/boards/espruino_wifi/pins.c
new file mode 100644
index 000000000..8800317d5
--- /dev/null
+++ b/ports/stm32f4/boards/espruino_wifi/pins.c
@@ -0,0 +1,39 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ //P1
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_B1), MP_ROM_PTR(&pin_PB01) },
+ { MP_ROM_QSTR(MP_QSTR_B10), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_B13), MP_ROM_PTR(&pin_PB13) },
+ { MP_ROM_QSTR(MP_QSTR_B14), MP_ROM_PTR(&pin_PB14) },
+ { MP_ROM_QSTR(MP_QSTR_B15), MP_ROM_PTR(&pin_PB15) },
+
+ { MP_ROM_QSTR(MP_QSTR_B0), MP_ROM_PTR(&pin_PB00) },
+ { MP_ROM_QSTR(MP_QSTR_B9), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_B8), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_B7), MP_ROM_PTR(&pin_PB07) },
+ { MP_ROM_QSTR(MP_QSTR_B6), MP_ROM_PTR(&pin_PB06) },
+ { MP_ROM_QSTR(MP_QSTR_B5), MP_ROM_PTR(&pin_PB05) },
+ { MP_ROM_QSTR(MP_QSTR_B4), MP_ROM_PTR(&pin_PB04) },
+ { MP_ROM_QSTR(MP_QSTR_B3), MP_ROM_PTR(&pin_PB03) },
+
+ { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA08) },
+
+ { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_PB12) },
+ { MP_ROM_QSTR(MP_QSTR_BTN), MP_ROM_PTR(&pin_PC13) },
+
+ { MP_ROM_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_ESP_TX), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_ESP_GPIO0), MP_ROM_PTR(&pin_PA13) },
+ { MP_ROM_QSTR(MP_QSTR_ESP_CHPD), MP_ROM_PTR(&pin_PA14) },
+ { MP_ROM_QSTR(MP_QSTR_ESP_GPIO13), MP_ROM_PTR(&pin_PA15) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/stm32f4/boards/espruino_wifi/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/espruino_wifi/stm32f4xx_hal_conf.h
new file mode 100644
index 000000000..18d9d60eb
--- /dev/null
+++ b/ports/stm32f4/boards/espruino_wifi/stm32f4xx_hal_conf.h
@@ -0,0 +1,439 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_conf_template.h
+ * @author MCD Application Team
+ * @brief HAL configuration template file.
+ * This file should be copied to the application folder and renamed
+ * to stm32f4xx_hal_conf.h.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_CONF_H
+#define __STM32F4xx_HAL_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* ########################## Module Selection ############################## */
+/**
+ * @brief This is the list of modules to be used in the HAL driver
+ */
+#define HAL_MODULE_ENABLED
+
+#define HAL_ADC_MODULE_ENABLED
+/* #define HAL_CRYP_MODULE_ENABLED */
+/* #define HAL_CAN_MODULE_ENABLED */
+/* #define HAL_CRC_MODULE_ENABLED */
+/* #define HAL_CRYP_MODULE_ENABLED */
+/* #define HAL_DAC_MODULE_ENABLED */
+/* #define HAL_DCMI_MODULE_ENABLED */
+/* #define HAL_DMA2D_MODULE_ENABLED */
+/* #define HAL_ETH_MODULE_ENABLED */
+/* #define HAL_NAND_MODULE_ENABLED */
+/* #define HAL_NOR_MODULE_ENABLED */
+/* #define HAL_PCCARD_MODULE_ENABLED */
+/* #define HAL_SRAM_MODULE_ENABLED */
+/* #define HAL_SDRAM_MODULE_ENABLED */
+/* #define HAL_HASH_MODULE_ENABLED */
+#define HAL_I2C_MODULE_ENABLED
+#define HAL_I2S_MODULE_ENABLED
+/* #define HAL_IWDG_MODULE_ENABLED */
+/* #define HAL_LTDC_MODULE_ENABLED */
+/* #define HAL_RNG_MODULE_ENABLED */
+/* #define HAL_RTC_MODULE_ENABLED */
+/* #define HAL_SAI_MODULE_ENABLED */
+/* #define HAL_SD_MODULE_ENABLED */
+/* #define HAL_MMC_MODULE_ENABLED */
+#define HAL_SPI_MODULE_ENABLED
+#define HAL_TIM_MODULE_ENABLED
+#define HAL_UART_MODULE_ENABLED
+/* #define HAL_USART_MODULE_ENABLED */
+/* #define HAL_IRDA_MODULE_ENABLED */
+/* #define HAL_SMARTCARD_MODULE_ENABLED */
+/* #define HAL_WWDG_MODULE_ENABLED */
+#define HAL_PCD_MODULE_ENABLED
+/* #define HAL_HCD_MODULE_ENABLED */
+/* #define HAL_DSI_MODULE_ENABLED */
+/* #define HAL_QSPI_MODULE_ENABLED */
+/* #define HAL_QSPI_MODULE_ENABLED */
+/* #define HAL_CEC_MODULE_ENABLED */
+/* #define HAL_FMPI2C_MODULE_ENABLED */
+/* #define HAL_SPDIFRX_MODULE_ENABLED */
+/* #define HAL_DFSDM_MODULE_ENABLED */
+/* #define HAL_LPTIM_MODULE_ENABLED */
+/* #define HAL_EXTI_MODULE_ENABLED */
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_EXTI_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+
+/* ########################## HSE/HSI Values adaptation ##################### */
+/**
+ * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSE is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (HSE_STARTUP_TIMEOUT)
+ #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief Internal High Speed oscillator (HSI) value.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSI is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+ * @brief Internal Low Speed oscillator (LSI) value.
+ */
+#if !defined (LSI_VALUE)
+ #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/
+#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
+ The real value may vary depending on the variations
+ in voltage and temperature.*/
+/**
+ * @brief External Low Speed oscillator (LSE) value.
+ */
+#if !defined (LSE_VALUE)
+ #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */
+#endif /* LSE_VALUE */
+
+#if !defined (LSE_STARTUP_TIMEOUT)
+ #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
+#endif /* LSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief External clock source for I2S peripheral
+ * This value is used by the I2S HAL module to compute the I2S clock source
+ * frequency, this source is inserted directly through I2S_CKIN pad.
+ */
+#if !defined (EXTERNAL_CLOCK_VALUE)
+ #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/
+#endif /* EXTERNAL_CLOCK_VALUE */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+ === you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+ * @brief This is the HAL system configuration section
+ */
+#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
+#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
+#define USE_RTOS 0U
+#define PREFETCH_ENABLE 1U
+#define INSTRUCTION_CACHE_ENABLE 1U
+#define DATA_CACHE_ENABLE 1U
+
+/* ########################## Assert Selection ############################## */
+/**
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * HAL drivers code
+ */
+/* #define USE_FULL_ASSERT 1U */
+
+/* ################## Ethernet peripheral configuration ##################### */
+
+/* Section 1 : Ethernet peripheral configuration */
+
+/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
+#define MAC_ADDR0 2U
+#define MAC_ADDR1 0U
+#define MAC_ADDR2 0U
+#define MAC_ADDR3 0U
+#define MAC_ADDR4 0U
+#define MAC_ADDR5 0U
+
+/* Definition of the Ethernet driver buffers size and count */
+#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
+#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
+#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
+
+/* Section 2: PHY configuration section */
+
+/* DP83848_PHY_ADDRESS Address*/
+#define DP83848_PHY_ADDRESS 0x01U
+/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
+#define PHY_RESET_DELAY ((uint32_t)0x000000FFU)
+/* PHY Configuration delay */
+#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU)
+
+#define PHY_READ_TO ((uint32_t)0x0000FFFFU)
+#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU)
+
+/* Section 3: Common PHY Registers */
+
+#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */
+#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
+
+#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
+#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
+#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
+#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
+#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
+#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
+#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
+#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
+#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
+#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
+
+#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
+#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
+#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
+
+/* Section 4: Extended PHY Registers */
+#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
+
+#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
+#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
+
+/* ################## SPI peripheral configuration ########################## */
+
+/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
+* Activated: CRC code is present inside driver
+* Deactivated: CRC code cleaned from driver
+*/
+
+#define USE_SPI_CRC 0U
+
+/* Includes ------------------------------------------------------------------*/
+/**
+ * @brief Include module's header file
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_EXTI_MODULE_ENABLED
+ #include "stm32f4xx_hal_exti.h"
+#endif /* HAL_EXTI_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+ #include "stm32f4xx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+ #include "stm32f4xx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+ #include "stm32f4xx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_CAN_MODULE_ENABLED
+ #include "stm32f4xx_hal_can.h"
+#endif /* HAL_CAN_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+ #include "stm32f4xx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_CRYP_MODULE_ENABLED
+ #include "stm32f4xx_hal_cryp.h"
+#endif /* HAL_CRYP_MODULE_ENABLED */
+
+#ifdef HAL_DMA2D_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma2d.h"
+#endif /* HAL_DMA2D_MODULE_ENABLED */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+ #include "stm32f4xx_hal_dac.h"
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+#ifdef HAL_DCMI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dcmi.h"
+#endif /* HAL_DCMI_MODULE_ENABLED */
+
+#ifdef HAL_ETH_MODULE_ENABLED
+ #include "stm32f4xx_hal_eth.h"
+#endif /* HAL_ETH_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+ #include "stm32f4xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+ #include "stm32f4xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_PCCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pccard.h"
+#endif /* HAL_PCCARD_MODULE_ENABLED */
+
+#ifdef HAL_SDRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sdram.h"
+#endif /* HAL_SDRAM_MODULE_ENABLED */
+
+#ifdef HAL_HASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_hash.h"
+#endif /* HAL_HASH_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2s.h"
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_LTDC_MODULE_ENABLED
+ #include "stm32f4xx_hal_ltdc.h"
+#endif /* HAL_LTDC_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+ #include "stm32f4xx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_RNG_MODULE_ENABLED
+ #include "stm32f4xx_hal_rng.h"
+#endif /* HAL_RNG_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_SAI_MODULE_ENABLED
+ #include "stm32f4xx_hal_sai.h"
+#endif /* HAL_SAI_MODULE_ENABLED */
+
+#ifdef HAL_SD_MODULE_ENABLED
+ #include "stm32f4xx_hal_sd.h"
+#endif /* HAL_SD_MODULE_ENABLED */
+
+#ifdef HAL_MMC_MODULE_ENABLED
+ #include "stm32f4xx_hal_mmc.h"
+#endif /* HAL_MMC_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+ #include "stm32f4xx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+ #include "stm32f4xx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32f4xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_HCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_hcd.h"
+#endif /* HAL_HCD_MODULE_ENABLED */
+
+#ifdef HAL_DSI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dsi.h"
+#endif /* HAL_DSI_MODULE_ENABLED */
+
+#ifdef HAL_QSPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_qspi.h"
+#endif /* HAL_QSPI_MODULE_ENABLED */
+
+#ifdef HAL_CEC_MODULE_ENABLED
+ #include "stm32f4xx_hal_cec.h"
+#endif /* HAL_CEC_MODULE_ENABLED */
+
+#ifdef HAL_FMPI2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_fmpi2c.h"
+#endif /* HAL_FMPI2C_MODULE_ENABLED */
+
+#ifdef HAL_SPDIFRX_MODULE_ENABLED
+ #include "stm32f4xx_hal_spdifrx.h"
+#endif /* HAL_SPDIFRX_MODULE_ENABLED */
+
+#ifdef HAL_DFSDM_MODULE_ENABLED
+ #include "stm32f4xx_hal_dfsdm.h"
+#endif /* HAL_DFSDM_MODULE_ENABLED */
+
+#ifdef HAL_LPTIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_lptim.h"
+#endif /* HAL_LPTIM_MODULE_ENABLED */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr: If expr is false, it calls assert_failed function
+ * which reports the name of the source file and the source
+ * line number of the call that failed.
+ * If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_HAL_CONF_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h b/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h
index a1d83a25a..6600fcf67 100644
--- a/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h
+++ b/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h
@@ -34,12 +34,19 @@
#define MICROPY_HW_NEOPIXEL (&pin_PC00)
+#define BOARD_OSC_DIV (12)
+
// On-board flash
#define SPI_FLASH_MOSI_PIN (&pin_PB05)
#define SPI_FLASH_MISO_PIN (&pin_PB04)
#define SPI_FLASH_SCK_PIN (&pin_PB03)
#define SPI_FLASH_CS_PIN (&pin_PA15)
+// Bootloader only
+#ifdef UF2_BOOTLOADER_ENABLED
+ #define BOARD_VTOR_DEFER (1) //Leave VTOR relocation to bootloader
+#endif
+
#define DEFAULT_I2C_BUS_SCL (&pin_PB06)
#define DEFAULT_I2C_BUS_SDA (&pin_PB07)
diff --git a/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.mk b/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.mk
index 5bad4e81f..312ca6b48 100644
--- a/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.mk
+++ b/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.mk
@@ -14,6 +14,9 @@ MCU_VARIANT = stm32f4
MCU_SUB_VARIANT = stm32f405xx
MCU_PACKAGE = 64
CMSIS_MCU = STM32F405xx
-LD_FILE = boards/STM32F405.ld
-TEXT0_ADDR = 0x08000000
-TEXT1_ADDR = 0x08010000 \ No newline at end of file
+
+# Default includes filesystem, but uses external flash
+LD_DEFAULT = boards/STM32F405_default.ld
+LD_BOOT = boards/STM32F405_boot.ld # UF2 boot option
+UF2_OFFSET = 0x8010000
+
diff --git a/ports/stm32f4/boards/meowbit_v121/board.c b/ports/stm32f4/boards/meowbit_v121/board.c
new file mode 100644
index 000000000..a0ae98824
--- /dev/null
+++ b/ports/stm32f4/boards/meowbit_v121/board.c
@@ -0,0 +1,121 @@
+/*
+ * 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 "boards/board.h"
+#include "mpconfigboard.h"
+
+#include "shared-bindings/board/__init__.h"
+#include "shared-bindings/displayio/FourWire.h"
+#include "shared-module/displayio/__init__.h"
+#include "shared-module/displayio/mipi_constants.h"
+#include "shared-bindings/busio/SPI.h"
+
+#include "supervisor/spi_flash_api.h"
+
+#include "tick.h"
+
+displayio_fourwire_obj_t board_display_obj;
+
+#define DELAY 0x80
+
+uint8_t display_init_sequence[] = {
+ 0x01, 0 | DELAY, 150, // SWRESET
+ 0x11, 0 | DELAY, 255, // SLPOUT
+ 0xb1, 3, 0x01, 0x2C, 0x2D, // _FRMCTR1
+ 0xb2, 3, 0x01, 0x2C, 0x2D, //
+ 0xb3, 6, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D,
+ 0xb4, 1, 0x07, // _INVCTR line inversion
+ 0xc0, 3, 0xa2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA
+ 0xc1, 1, 0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V
+ 0xc2, 2, 0x0a, 0x00, // _PWCTR3 Opamp current small, Boost frequency
+ 0xc3, 2, 0x8a, 0x2a,
+ 0xc4, 2, 0x8a, 0xee,
+ 0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V
+ 0x20, 0, // _INVOFF //MISMATCh 0x2a vs 0x20
+ 0x36, 1, 0x18, // _MADCTL bottom to top refresh
+ // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie,
+ // fix on VTL
+ 0x3a, 1, 0x05, // COLMOD - 16bit color
+ 0xe0, 0x10, 0x02, 0x1c, 0x07, 0x12,
+ 0x37, 0x32, 0x29, 0x2d,
+ 0x29, 0x25, 0x2B, 0x39,
+ 0x00, 0x01, 0x03, 0x10, // _GMCTRP1 Gamma
+ 0xe1, 0x10, 0x03, 0x1d, 0x07, 0x06,
+ 0x2E, 0x2C, 0x29, 0x2D,
+ 0x2E, 0x2E, 0x37, 0x3F,
+ 0x00, 0x00, 0x02, 0x10, // _GMCTRN1
+ 0x13, 0 | DELAY, 10, // _NORON
+ 0x29, 0 | DELAY, 100, // _DISPON
+};
+
+void board_init(void) {
+ displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
+ bus->base.type = &displayio_fourwire_type;
+ busio_spi_obj_t *internal_spi = &supervisor_flash_spi_bus;
+ common_hal_displayio_fourwire_construct(bus,
+ internal_spi,
+ &pin_PA08, // Command or data
+ &pin_PB12, // Chip select
+ &pin_PB10, // Reset
+ 24000000);
+
+ displayio_display_obj_t* display = &displays[0].display;
+ display->base.type = &displayio_display_type;
+ common_hal_displayio_display_construct(display,
+ bus,
+ 160, // Width
+ 128, // Height
+ 0, // column start
+ 0, // row start
+ 90, // rotation
+ 16, // Color depth
+ false, // Grayscale
+ false, // Pixels in a byte share a row. Only used for depth < 8
+ 1, // bytes per cell. Only valid for depths < 8
+ false, // reverse_pixels_in_byte. Only valid for depths < 8
+ MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command
+ MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command
+ MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command
+ 0x37, // set vertical scroll command
+ display_init_sequence,
+ sizeof(display_init_sequence),
+ &pin_PB03,
+ NO_BRIGHTNESS_COMMAND,
+ 1.0f, // brightness (ignored)
+ true, // auto_brightness
+ false, // single_byte_bounds
+ false, // data_as_commands
+ true, // auto_refresh
+ 60); // native_frames_per_second
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/stm32f4/boards/meowbit_v121/mpconfigboard.h b/ports/stm32f4/boards/meowbit_v121/mpconfigboard.h
new file mode 100644
index 000000000..babf54a3a
--- /dev/null
+++ b/ports/stm32f4/boards/meowbit_v121/mpconfigboard.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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.
+ */
+
+//Micropython setup
+
+#define MICROPY_HW_BOARD_NAME "MEOWBIT"
+#define MICROPY_HW_MCU_NAME "STM32F401xE"
+
+#define FLASH_SIZE (0x80000)
+#define FLASH_PAGE_SIZE (0x4000)
+
+#define AUTORESET_DELAY_MS 500
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000)
+
+#define BOARD_OSC_DIV (12)
+#define BOARD_NO_VBUS_SENSE (1)
+#define BOARD_VTOR_DEFER (1) //Leave VTOR relocation to bootloader
+#define BOARD_USE_INTERNAL_SPI
+
+// On-board flash
+#define SPI_FLASH_MOSI_PIN (&pin_PB15)
+#define SPI_FLASH_MISO_PIN (&pin_PB14)
+#define SPI_FLASH_SCK_PIN (&pin_PB13)
+#define SPI_FLASH_CS_PIN (&pin_PB01)
diff --git a/ports/stm32f4/boards/meowbit_v121/mpconfigboard.mk b/ports/stm32f4/boards/meowbit_v121/mpconfigboard.mk
new file mode 100644
index 000000000..16268ba11
--- /dev/null
+++ b/ports/stm32f4/boards/meowbit_v121/mpconfigboard.mk
@@ -0,0 +1,24 @@
+USB_VID = 0x239A
+USB_PID = 0x805A
+USB_PRODUCT = "Meowbit"
+USB_MANUFACTURER = "Kittenbot"
+USB_DEVICES = "CDC,MSC"
+
+SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = W25Q16JV_IQ
+LONGINT_IMPL = MPZ
+
+BOOTLOADER_OFFSET = 0x8010000
+
+# INTERNAL_FLASH_FILESYSTEM = 1
+# LONGINT_IMPL = NONE
+
+MCU_SERIES = m4
+MCU_VARIANT = stm32f4
+MCU_SUB_VARIANT = stm32f401xe
+MCU_PACKAGE = 64
+CMSIS_MCU = STM32F401xE
+LD_FILE = boards/STM32F401xe_boot.ld
+# LD_FILE = boards/STM32F401xe_fs.ld # use for internal flash
+
diff --git a/ports/stm32f4/boards/meowbit_v121/pins.c b/ports/stm32f4/boards/meowbit_v121/pins.c
new file mode 100644
index 000000000..af896fad8
--- /dev/null
+++ b/ports/stm32f4/boards/meowbit_v121/pins.c
@@ -0,0 +1,68 @@
+#include "shared-bindings/board/__init__.h"
+#include "supervisor/spi_flash_api.h"
+
+#include "shared-module/displayio/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_LED_RED), MP_ROM_PTR(&pin_PB04) },
+ { MP_ROM_QSTR(MP_QSTR_LED_GREEN), MP_ROM_PTR(&pin_PB05) },
+
+ { MP_ROM_QSTR(MP_QSTR_DISP_SCK), MP_ROM_PTR(&pin_PB13) },
+ { MP_ROM_QSTR(MP_QSTR_DISP_MISO), MP_ROM_PTR(&pin_PB14) },
+ { MP_ROM_QSTR(MP_QSTR_DISP_MOSI), MP_ROM_PTR(&pin_PB15) },
+ { MP_ROM_QSTR(MP_QSTR_DISP_CS), MP_ROM_PTR(&pin_PB12) },
+ { MP_ROM_QSTR(MP_QSTR_DISP_DC), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_DISP_RST), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_DISP_BL), MP_ROM_PTR(&pin_PB03) },
+
+ { MP_ROM_QSTR(MP_QSTR_BUZZ), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_BTNA), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_BTNB), MP_ROM_PTR(&pin_PC03) },
+ { MP_ROM_QSTR(MP_QSTR_RIGHT), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_DOWN), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_LEFT), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_TEMP), MP_ROM_PTR(&pin_PC05) },
+ { MP_ROM_QSTR(MP_QSTR_UP), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PC02) },
+ { MP_ROM_QSTR(MP_QSTR_MENU), MP_ROM_PTR(&pin_PC15) },
+
+ { MP_ROM_QSTR(MP_QSTR_JACK_TX), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_JACK_PWREN), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_JACK_SND), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_ACC_INT), MP_ROM_PTR(&pin_PC14) },
+ { MP_ROM_QSTR(MP_QSTR_ACC_SCL), MP_ROM_PTR(&pin_PB06) },
+ { MP_ROM_QSTR(MP_QSTR_ACC_SDA), MP_ROM_PTR(&pin_PB07) },
+
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB07) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB06) },
+ // { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PC06) }, //these are wrong on Meowbit diagram.
+ // { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA03) }, //they cannot be used together (UART2 vs 6)
+ { MP_ROM_QSTR(MP_QSTR_NSS), MP_ROM_PTR(&pin_PA15) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PC12) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PC11) },
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PC10) },
+
+ { MP_ROM_QSTR(MP_QSTR_P20), MP_ROM_PTR(&pin_PB07) },
+ { MP_ROM_QSTR(MP_QSTR_P19), MP_ROM_PTR(&pin_PB06) },
+ { MP_ROM_QSTR(MP_QSTR_P16), MP_ROM_PTR(&pin_PA15) },
+ { MP_ROM_QSTR(MP_QSTR_P15), MP_ROM_PTR(&pin_PC12) },
+ { MP_ROM_QSTR(MP_QSTR_P14), MP_ROM_PTR(&pin_PC11) },
+ { MP_ROM_QSTR(MP_QSTR_P13), MP_ROM_PTR(&pin_PC10) },
+ { MP_ROM_QSTR(MP_QSTR_P2), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_P12), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_P11), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_P10), MP_ROM_PTR(&pin_PC00) },
+ { MP_ROM_QSTR(MP_QSTR_P9), MP_ROM_PTR(&pin_PC06) },
+ { MP_ROM_QSTR(MP_QSTR_P8), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_P1), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_P7), MP_ROM_PTR(&pin_PA10) }, //in use by USB
+ { MP_ROM_QSTR(MP_QSTR_P6), MP_ROM_PTR(&pin_PC07) },
+ { MP_ROM_QSTR(MP_QSTR_P5), MP_ROM_PTR(&pin_PB05) },
+ { MP_ROM_QSTR(MP_QSTR_P4), MP_ROM_PTR(&pin_PC01) },
+ { MP_ROM_QSTR(MP_QSTR_P0), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_P3), MP_ROM_PTR(&pin_PB00) },
+
+ { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)},
+ { MP_ROM_QSTR(MP_QSTR_INTERNAL_SPI), MP_ROM_PTR(&supervisor_flash_spi_bus) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/stm32f4/boards/meowbit_v121/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/meowbit_v121/stm32f4xx_hal_conf.h
new file mode 100644
index 000000000..68a49b4ba
--- /dev/null
+++ b/ports/stm32f4/boards/meowbit_v121/stm32f4xx_hal_conf.h
@@ -0,0 +1,440 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_conf_template.h
+ * @author MCD Application Team
+ * @brief HAL configuration template file.
+ * This file should be copied to the application folder and renamed
+ * to stm32f4xx_hal_conf.h.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_CONF_H
+#define __STM32F4xx_HAL_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* ########################## Module Selection ############################## */
+/**
+ * @brief This is the list of modules to be used in the HAL driver
+ */
+#define HAL_MODULE_ENABLED
+
+#define HAL_ADC_MODULE_ENABLED
+/* #define HAL_CRYP_MODULE_ENABLED */
+/* #define HAL_CAN_MODULE_ENABLED */
+/* #define HAL_CRC_MODULE_ENABLED */
+/* #define HAL_CRYP_MODULE_ENABLED */
+#define HAL_DAC_MODULE_ENABLED
+/* #define HAL_DCMI_MODULE_ENABLED */
+/* #define HAL_DMA2D_MODULE_ENABLED */
+/* #define HAL_ETH_MODULE_ENABLED */
+/* #define HAL_NAND_MODULE_ENABLED */
+/* #define HAL_NOR_MODULE_ENABLED */
+/* #define HAL_PCCARD_MODULE_ENABLED */
+/* #define HAL_SRAM_MODULE_ENABLED */
+/* #define HAL_SDRAM_MODULE_ENABLED */
+/* #define HAL_HASH_MODULE_ENABLED */
+#define HAL_I2C_MODULE_ENABLED
+#define HAL_I2S_MODULE_ENABLED
+/* #define HAL_IWDG_MODULE_ENABLED */
+/* #define HAL_LTDC_MODULE_ENABLED */
+/* #define HAL_RNG_MODULE_ENABLED */
+/* #define HAL_RTC_MODULE_ENABLED */
+/* #define HAL_SAI_MODULE_ENABLED */
+/* #define HAL_SD_MODULE_ENABLED */
+/* #define HAL_MMC_MODULE_ENABLED */
+#define HAL_SPI_MODULE_ENABLED
+#define HAL_TIM_MODULE_ENABLED
+#define HAL_UART_MODULE_ENABLED
+#define HAL_USART_MODULE_ENABLED
+/* #define HAL_IRDA_MODULE_ENABLED */
+/* #define HAL_SMARTCARD_MODULE_ENABLED */
+/* #define HAL_WWDG_MODULE_ENABLED */
+#define HAL_PCD_MODULE_ENABLED
+/* #define HAL_HCD_MODULE_ENABLED */
+/* #define HAL_DSI_MODULE_ENABLED */
+/* #define HAL_QSPI_MODULE_ENABLED */
+/* #define HAL_QSPI_MODULE_ENABLED */
+/* #define HAL_CEC_MODULE_ENABLED */
+/* #define HAL_FMPI2C_MODULE_ENABLED */
+/* #define HAL_SPDIFRX_MODULE_ENABLED */
+/* #define HAL_DFSDM_MODULE_ENABLED */
+/* #define HAL_LPTIM_MODULE_ENABLED */
+/* #define HAL_EXTI_MODULE_ENABLED */
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_EXTI_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+
+/* ########################## HSE/HSI Values adaptation ##################### */
+/**
+ * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSE is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)12000000) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (HSE_STARTUP_TIMEOUT)
+ #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief Internal High Speed oscillator (HSI) value.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSI is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+ * @brief Internal Low Speed oscillator (LSI) value.
+ */
+#if !defined (LSI_VALUE)
+ #define LSI_VALUE ((uint32_t)40000)
+#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
+ The real value may vary depending on the variations
+ in voltage and temperature. */
+/**
+ * @brief External Low Speed oscillator (LSE) value.
+ */
+#if !defined (LSE_VALUE)
+ #define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */
+#endif /* LSE_VALUE */
+
+#if !defined (LSE_STARTUP_TIMEOUT)
+ #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
+#endif /* LSE_STARTUP_TIMEOUT */
+
+
+/**
+ * @brief External clock source for I2S peripheral
+ * This value is used by the I2S HAL module to compute the I2S clock source
+ * frequency, this source is inserted directly through I2S_CKIN pad.
+ */
+#if !defined (EXTERNAL_CLOCK_VALUE)
+ #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/
+#endif /* EXTERNAL_CLOCK_VALUE */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+ === you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+ * @brief This is the HAL system configuration section
+ */
+#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
+#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
+#define USE_RTOS 0U
+#define PREFETCH_ENABLE 1U
+#define INSTRUCTION_CACHE_ENABLE 1U
+#define DATA_CACHE_ENABLE 1U
+
+/* ########################## Assert Selection ############################## */
+/**
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * HAL drivers code
+ */
+/* #define USE_FULL_ASSERT 1U */
+
+/* ################## Ethernet peripheral configuration ##################### */
+
+/* Section 1 : Ethernet peripheral configuration */
+
+/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
+#define MAC_ADDR0 2U
+#define MAC_ADDR1 0U
+#define MAC_ADDR2 0U
+#define MAC_ADDR3 0U
+#define MAC_ADDR4 0U
+#define MAC_ADDR5 0U
+
+/* Definition of the Ethernet driver buffers size and count */
+#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
+#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
+#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
+
+/* Section 2: PHY configuration section */
+
+/* DP83848_PHY_ADDRESS Address*/
+#define DP83848_PHY_ADDRESS 0x01U
+/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
+#define PHY_RESET_DELAY ((uint32_t)0x000000FFU)
+/* PHY Configuration delay */
+#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU)
+
+#define PHY_READ_TO ((uint32_t)0x0000FFFFU)
+#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU)
+
+/* Section 3: Common PHY Registers */
+
+#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */
+#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
+
+#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
+#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
+#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
+#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
+#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
+#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
+#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
+#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
+#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
+#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
+
+#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
+#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
+#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
+
+/* Section 4: Extended PHY Registers */
+#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
+
+#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
+#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
+
+/* ################## SPI peripheral configuration ########################## */
+
+/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
+* Activated: CRC code is present inside driver
+* Deactivated: CRC code cleaned from driver
+*/
+
+#define USE_SPI_CRC 0U
+
+/* Includes ------------------------------------------------------------------*/
+/**
+ * @brief Include module's header file
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_EXTI_MODULE_ENABLED
+ #include "stm32f4xx_hal_exti.h"
+#endif /* HAL_EXTI_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+ #include "stm32f4xx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+ #include "stm32f4xx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+ #include "stm32f4xx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_CAN_MODULE_ENABLED
+ #include "stm32f4xx_hal_can.h"
+#endif /* HAL_CAN_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+ #include "stm32f4xx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_CRYP_MODULE_ENABLED
+ #include "stm32f4xx_hal_cryp.h"
+#endif /* HAL_CRYP_MODULE_ENABLED */
+
+#ifdef HAL_DMA2D_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma2d.h"
+#endif /* HAL_DMA2D_MODULE_ENABLED */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+ #include "stm32f4xx_hal_dac.h"
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+#ifdef HAL_DCMI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dcmi.h"
+#endif /* HAL_DCMI_MODULE_ENABLED */
+
+#ifdef HAL_ETH_MODULE_ENABLED
+ #include "stm32f4xx_hal_eth.h"
+#endif /* HAL_ETH_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+ #include "stm32f4xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+ #include "stm32f4xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_PCCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pccard.h"
+#endif /* HAL_PCCARD_MODULE_ENABLED */
+
+#ifdef HAL_SDRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sdram.h"
+#endif /* HAL_SDRAM_MODULE_ENABLED */
+
+#ifdef HAL_HASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_hash.h"
+#endif /* HAL_HASH_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2s.h"
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_LTDC_MODULE_ENABLED
+ #include "stm32f4xx_hal_ltdc.h"
+#endif /* HAL_LTDC_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+ #include "stm32f4xx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_RNG_MODULE_ENABLED
+ #include "stm32f4xx_hal_rng.h"
+#endif /* HAL_RNG_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_SAI_MODULE_ENABLED
+ #include "stm32f4xx_hal_sai.h"
+#endif /* HAL_SAI_MODULE_ENABLED */
+
+#ifdef HAL_SD_MODULE_ENABLED
+ #include "stm32f4xx_hal_sd.h"
+#endif /* HAL_SD_MODULE_ENABLED */
+
+#ifdef HAL_MMC_MODULE_ENABLED
+ #include "stm32f4xx_hal_mmc.h"
+#endif /* HAL_MMC_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+ #include "stm32f4xx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+ #include "stm32f4xx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32f4xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_HCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_hcd.h"
+#endif /* HAL_HCD_MODULE_ENABLED */
+
+#ifdef HAL_DSI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dsi.h"
+#endif /* HAL_DSI_MODULE_ENABLED */
+
+#ifdef HAL_QSPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_qspi.h"
+#endif /* HAL_QSPI_MODULE_ENABLED */
+
+#ifdef HAL_CEC_MODULE_ENABLED
+ #include "stm32f4xx_hal_cec.h"
+#endif /* HAL_CEC_MODULE_ENABLED */
+
+#ifdef HAL_FMPI2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_fmpi2c.h"
+#endif /* HAL_FMPI2C_MODULE_ENABLED */
+
+#ifdef HAL_SPDIFRX_MODULE_ENABLED
+ #include "stm32f4xx_hal_spdifrx.h"
+#endif /* HAL_SPDIFRX_MODULE_ENABLED */
+
+#ifdef HAL_DFSDM_MODULE_ENABLED
+ #include "stm32f4xx_hal_dfsdm.h"
+#endif /* HAL_DFSDM_MODULE_ENABLED */
+
+#ifdef HAL_LPTIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_lptim.h"
+#endif /* HAL_LPTIM_MODULE_ENABLED */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr: If expr is false, it calls assert_failed function
+ * which reports the name of the source file and the source
+ * line number of the call that failed.
+ * If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_HAL_CONF_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/ports/stm32f4/boards/openocd_stm32f4.cfg b/ports/stm32f4/boards/openocd_stm32f4.cfg
new file mode 100644
index 000000000..19631a7c8
--- /dev/null
+++ b/ports/stm32f4/boards/openocd_stm32f4.cfg
@@ -0,0 +1,44 @@
+# This script configures OpenOCD for use with an ST-Link V2 programmer/debugger
+# and an STM32F4 target microcontroller.
+#
+# To flash your firmware:
+#
+# $ openocd -f openocd_stm32f4.cfg \
+# -c "stm_flash build-BOARD/firmware0.bin 0x08000000 build-BOARD/firmware1.bin 0x08020000"
+#
+# For a gdb server on port 3333:
+#
+# $ openocd -f openocd_stm32f4.cfg
+
+
+source [find interface/stlink-v2.cfg]
+transport select hla_swd
+source [find target/stm32f4x.cfg]
+reset_config srst_only
+init
+
+proc stm_flash { BIN0 ADDR0 {BIN1 ""} {ADDR1 ""} } {
+ reset halt
+ sleep 100
+ wait_halt 2
+ flash write_image erase $BIN0 $ADDR0
+ sleep 100
+ verify_image $BIN0 $ADDR0
+ sleep 100
+ if {$BIN1 ne ""} {
+ flash write_image erase $BIN1 $ADDR1
+ sleep 100
+ verify_image $BIN1 $ADDR1
+ sleep 100
+ }
+ reset run
+ shutdown
+}
+
+proc stm_erase {} {
+ reset halt
+ sleep 100
+ stm32f4x mass_erase 0
+ sleep 100
+ shutdown
+}
diff --git a/ports/stm32f4/boards/pyb_nano_v2/mpconfigboard.h b/ports/stm32f4/boards/pyb_nano_v2/mpconfigboard.h
index 7980ca93d..965e7d5ff 100644
--- a/ports/stm32f4/boards/pyb_nano_v2/mpconfigboard.h
+++ b/ports/stm32f4/boards/pyb_nano_v2/mpconfigboard.h
@@ -32,7 +32,7 @@
#define FLASH_SIZE (0x80000)
#define FLASH_PAGE_SIZE (0x4000)
-#define BOARD_OSC_DIV 8
+#define BOARD_OSC_DIV (8)
// On-board flash
#define SPI_FLASH_MOSI_PIN (&pin_PB15)
@@ -40,8 +40,8 @@
#define SPI_FLASH_SCK_PIN (&pin_PB13)
#define SPI_FLASH_CS_PIN (&pin_PB12)
-#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
+#define CIRCUITPY_AUTORELOAD_DELAY_MS (500)
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x2000 - 0xC000)
-#define AUTORESET_DELAY_MS 500
+#define AUTORESET_DELAY_MS (500)
diff --git a/ports/stm32f4/boards/pyb_nano_v2/mpconfigboard.mk b/ports/stm32f4/boards/pyb_nano_v2/mpconfigboard.mk
index d46ee0b08..a8472608b 100644
--- a/ports/stm32f4/boards/pyb_nano_v2/mpconfigboard.mk
+++ b/ports/stm32f4/boards/pyb_nano_v2/mpconfigboard.mk
@@ -15,5 +15,4 @@ MCU_SUB_VARIANT = stm32f411xe
MCU_PACKAGE = 48
CMSIS_MCU = STM32F411xE
LD_FILE = boards/STM32F411VETx_FLASH.ld
-TEXT0_ADDR = 0x08000000
-TEXT1_ADDR = 0x08020000 \ No newline at end of file
+
diff --git a/ports/stm32f4/boards/pyboard_v11/mpconfigboard.h b/ports/stm32f4/boards/pyboard_v11/mpconfigboard.h
index 7093442d0..398731d30 100644
--- a/ports/stm32f4/boards/pyboard_v11/mpconfigboard.h
+++ b/ports/stm32f4/boards/pyboard_v11/mpconfigboard.h
@@ -32,6 +32,7 @@
#define FLASH_SIZE (0x100000)
#define FLASH_PAGE_SIZE (0x4000)
+#define BOARD_OSC_DIV (12)
#define DEFAULT_I2C_BUS_SCL (&pin_PB06)
#define DEFAULT_I2C_BUS_SDA (&pin_PB07)
diff --git a/ports/stm32f4/boards/pyboard_v11/mpconfigboard.mk b/ports/stm32f4/boards/pyboard_v11/mpconfigboard.mk
index a01ff7923..ef1b8f0ca 100644
--- a/ports/stm32f4/boards/pyboard_v11/mpconfigboard.mk
+++ b/ports/stm32f4/boards/pyboard_v11/mpconfigboard.mk
@@ -12,6 +12,5 @@ MCU_VARIANT = stm32f4
MCU_SUB_VARIANT = stm32f405xx
MCU_PACKAGE = 64
CMSIS_MCU = STM32F405xx
-LD_FILE = boards/STM32F405.ld
-TEXT0_ADDR = 0x08000000
-TEXT1_ADDR = 0x08010000
+LD_FILE = boards/STM32F405_fs.ld
+
diff --git a/ports/stm32f4/boards/startup_stm32f401xe.s b/ports/stm32f4/boards/startup_stm32f401xe.s
new file mode 100644
index 000000000..815ac1719
--- /dev/null
+++ b/ports/stm32f4/boards/startup_stm32f401xe.s
@@ -0,0 +1,448 @@
+/**
+ ******************************************************************************
+ * @file startup_stm32f401xe.s
+ * @author MCD Application Team
+ * @brief STM32F401xExx Devices vector table for GCC based toolchains.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M4 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2017 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m4
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
+
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+ ldr sp, =_estack /* set stack pointer */
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ /* bl __libc_init_array */
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ * @param None
+ * @retval None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+*******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+g_pfnVectors:
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+
+ /* External Interrupts */
+ .word WWDG_IRQHandler /* Window WatchDog */
+ .word PVD_IRQHandler /* PVD through EXTI Line detection */
+ .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */
+ .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */
+ .word FLASH_IRQHandler /* FLASH */
+ .word RCC_IRQHandler /* RCC */
+ .word EXTI0_IRQHandler /* EXTI Line0 */
+ .word EXTI1_IRQHandler /* EXTI Line1 */
+ .word EXTI2_IRQHandler /* EXTI Line2 */
+ .word EXTI3_IRQHandler /* EXTI Line3 */
+ .word EXTI4_IRQHandler /* EXTI Line4 */
+ .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */
+ .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */
+ .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */
+ .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */
+ .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */
+ .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */
+ .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */
+ .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word EXTI9_5_IRQHandler /* External Line[9:5]s */
+ .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */
+ .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */
+ .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */
+ .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
+ .word TIM2_IRQHandler /* TIM2 */
+ .word TIM3_IRQHandler /* TIM3 */
+ .word TIM4_IRQHandler /* TIM4 */
+ .word I2C1_EV_IRQHandler /* I2C1 Event */
+ .word I2C1_ER_IRQHandler /* I2C1 Error */
+ .word I2C2_EV_IRQHandler /* I2C2 Event */
+ .word I2C2_ER_IRQHandler /* I2C2 Error */
+ .word SPI1_IRQHandler /* SPI1 */
+ .word SPI2_IRQHandler /* SPI2 */
+ .word USART1_IRQHandler /* USART1 */
+ .word USART2_IRQHandler /* USART2 */
+ .word 0 /* Reserved */
+ .word EXTI15_10_IRQHandler /* External Line[15:10]s */
+ .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */
+ .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */
+ .word 0 /* Reserved */
+ .word SDIO_IRQHandler /* SDIO */
+ .word TIM5_IRQHandler /* TIM5 */
+ .word SPI3_IRQHandler /* SPI3 */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */
+ .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */
+ .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */
+ .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */
+ .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word OTG_FS_IRQHandler /* USB OTG FS */
+ .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */
+ .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */
+ .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */
+ .word USART6_IRQHandler /* USART6 */
+ .word I2C3_EV_IRQHandler /* I2C3 event */
+ .word I2C3_ER_IRQHandler /* I2C3 error */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word FPU_IRQHandler /* FPU */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word SPI4_IRQHandler /* SPI4 */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMP_STAMP_IRQHandler
+ .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
+
+ .weak RTC_WKUP_IRQHandler
+ .thumb_set RTC_WKUP_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream0_IRQHandler
+ .thumb_set DMA1_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream1_IRQHandler
+ .thumb_set DMA1_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream2_IRQHandler
+ .thumb_set DMA1_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream3_IRQHandler
+ .thumb_set DMA1_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream4_IRQHandler
+ .thumb_set DMA1_Stream4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream5_IRQHandler
+ .thumb_set DMA1_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream6_IRQHandler
+ .thumb_set DMA1_Stream6_IRQHandler,Default_Handler
+
+ .weak ADC_IRQHandler
+ .thumb_set ADC_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_TIM9_IRQHandler
+ .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_TIM10_IRQHandler
+ .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_TIM11_IRQHandler
+ .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak OTG_FS_WKUP_IRQHandler
+ .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream7_IRQHandler
+ .thumb_set DMA1_Stream7_IRQHandler,Default_Handler
+
+ .weak SDIO_IRQHandler
+ .thumb_set SDIO_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream0_IRQHandler
+ .thumb_set DMA2_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream1_IRQHandler
+ .thumb_set DMA2_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream2_IRQHandler
+ .thumb_set DMA2_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream3_IRQHandler
+ .thumb_set DMA2_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream4_IRQHandler
+ .thumb_set DMA2_Stream4_IRQHandler,Default_Handler
+
+ .weak OTG_FS_IRQHandler
+ .thumb_set OTG_FS_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream5_IRQHandler
+ .thumb_set DMA2_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream6_IRQHandler
+ .thumb_set DMA2_Stream6_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream7_IRQHandler
+ .thumb_set DMA2_Stream7_IRQHandler,Default_Handler
+
+ .weak USART6_IRQHandler
+ .thumb_set USART6_IRQHandler,Default_Handler
+
+ .weak I2C3_EV_IRQHandler
+ .thumb_set I2C3_EV_IRQHandler,Default_Handler
+
+ .weak I2C3_ER_IRQHandler
+ .thumb_set I2C3_ER_IRQHandler,Default_Handler
+
+ .weak FPU_IRQHandler
+ .thumb_set FPU_IRQHandler,Default_Handler
+
+ .weak SPI4_IRQHandler
+ .thumb_set SPI4_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/ports/stm32f4/boards/startup_stm32f407xx.s b/ports/stm32f4/boards/startup_stm32f407xx.s
new file mode 100644
index 000000000..6b77655ca
--- /dev/null
+++ b/ports/stm32f4/boards/startup_stm32f407xx.s
@@ -0,0 +1,516 @@
+/**
+ ******************************************************************************
+ * @file startup_stm32f405xx.s
+ * @author MCD Application Team
+ * @brief STM32F405xx Devices vector table for GCC based toolchains.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M4 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2017 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m4
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
+
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+ ldr sp, =_estack /* set stack pointer */
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+/* bl __libc_init_array */
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ * @param None
+ * @retval None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+*******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+
+g_pfnVectors:
+ .word _estack
+ .word Reset_Handler
+
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+
+ /* External Interrupts */
+ .word WWDG_IRQHandler /* Window WatchDog */
+ .word PVD_IRQHandler /* PVD through EXTI Line detection */
+ .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */
+ .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */
+ .word FLASH_IRQHandler /* FLASH */
+ .word RCC_IRQHandler /* RCC */
+ .word EXTI0_IRQHandler /* EXTI Line0 */
+ .word EXTI1_IRQHandler /* EXTI Line1 */
+ .word EXTI2_IRQHandler /* EXTI Line2 */
+ .word EXTI3_IRQHandler /* EXTI Line3 */
+ .word EXTI4_IRQHandler /* EXTI Line4 */
+ .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */
+ .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */
+ .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */
+ .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */
+ .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */
+ .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */
+ .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */
+ .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */
+ .word CAN1_TX_IRQHandler /* CAN1 TX */
+ .word CAN1_RX0_IRQHandler /* CAN1 RX0 */
+ .word CAN1_RX1_IRQHandler /* CAN1 RX1 */
+ .word CAN1_SCE_IRQHandler /* CAN1 SCE */
+ .word EXTI9_5_IRQHandler /* External Line[9:5]s */
+ .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */
+ .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */
+ .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */
+ .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
+ .word TIM2_IRQHandler /* TIM2 */
+ .word TIM3_IRQHandler /* TIM3 */
+ .word TIM4_IRQHandler /* TIM4 */
+ .word I2C1_EV_IRQHandler /* I2C1 Event */
+ .word I2C1_ER_IRQHandler /* I2C1 Error */
+ .word I2C2_EV_IRQHandler /* I2C2 Event */
+ .word I2C2_ER_IRQHandler /* I2C2 Error */
+ .word SPI1_IRQHandler /* SPI1 */
+ .word SPI2_IRQHandler /* SPI2 */
+ .word USART1_IRQHandler /* USART1 */
+ .word USART2_IRQHandler /* USART2 */
+ .word USART3_IRQHandler /* USART3 */
+ .word EXTI15_10_IRQHandler /* External Line[15:10]s */
+ .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */
+ .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */
+ .word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */
+ .word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */
+ .word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */
+ .word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
+ .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */
+ .word FSMC_IRQHandler /* FSMC */
+ .word SDIO_IRQHandler /* SDIO */
+ .word TIM5_IRQHandler /* TIM5 */
+ .word SPI3_IRQHandler /* SPI3 */
+ .word UART4_IRQHandler /* UART4 */
+ .word UART5_IRQHandler /* UART5 */
+ .word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */
+ .word TIM7_IRQHandler /* TIM7 */
+ .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */
+ .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */
+ .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */
+ .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */
+ .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word CAN2_TX_IRQHandler /* CAN2 TX */
+ .word CAN2_RX0_IRQHandler /* CAN2 RX0 */
+ .word CAN2_RX1_IRQHandler /* CAN2 RX1 */
+ .word CAN2_SCE_IRQHandler /* CAN2 SCE */
+ .word OTG_FS_IRQHandler /* USB OTG FS */
+ .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */
+ .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */
+ .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */
+ .word USART6_IRQHandler /* USART6 */
+ .word I2C3_EV_IRQHandler /* I2C3 event */
+ .word I2C3_ER_IRQHandler /* I2C3 error */
+ .word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */
+ .word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */
+ .word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */
+ .word OTG_HS_IRQHandler /* USB OTG HS */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word HASH_RNG_IRQHandler /* Hash and Rng */
+ .word FPU_IRQHandler /* FPU */
+
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMP_STAMP_IRQHandler
+ .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
+
+ .weak RTC_WKUP_IRQHandler
+ .thumb_set RTC_WKUP_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream0_IRQHandler
+ .thumb_set DMA1_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream1_IRQHandler
+ .thumb_set DMA1_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream2_IRQHandler
+ .thumb_set DMA1_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream3_IRQHandler
+ .thumb_set DMA1_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream4_IRQHandler
+ .thumb_set DMA1_Stream4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream5_IRQHandler
+ .thumb_set DMA1_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream6_IRQHandler
+ .thumb_set DMA1_Stream6_IRQHandler,Default_Handler
+
+ .weak ADC_IRQHandler
+ .thumb_set ADC_IRQHandler,Default_Handler
+
+ .weak CAN1_TX_IRQHandler
+ .thumb_set CAN1_TX_IRQHandler,Default_Handler
+
+ .weak CAN1_RX0_IRQHandler
+ .thumb_set CAN1_RX0_IRQHandler,Default_Handler
+
+ .weak CAN1_RX1_IRQHandler
+ .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+ .weak CAN1_SCE_IRQHandler
+ .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_TIM9_IRQHandler
+ .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_TIM10_IRQHandler
+ .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_TIM11_IRQHandler
+ .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak OTG_FS_WKUP_IRQHandler
+ .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
+
+ .weak TIM8_BRK_TIM12_IRQHandler
+ .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
+
+ .weak TIM8_UP_TIM13_IRQHandler
+ .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
+
+ .weak TIM8_TRG_COM_TIM14_IRQHandler
+ .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
+
+ .weak TIM8_CC_IRQHandler
+ .thumb_set TIM8_CC_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream7_IRQHandler
+ .thumb_set DMA1_Stream7_IRQHandler,Default_Handler
+
+ .weak FSMC_IRQHandler
+ .thumb_set FSMC_IRQHandler,Default_Handler
+
+ .weak SDIO_IRQHandler
+ .thumb_set SDIO_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak UART4_IRQHandler
+ .thumb_set UART4_IRQHandler,Default_Handler
+
+ .weak UART5_IRQHandler
+ .thumb_set UART5_IRQHandler,Default_Handler
+
+ .weak TIM6_DAC_IRQHandler
+ .thumb_set TIM6_DAC_IRQHandler,Default_Handler
+
+ .weak TIM7_IRQHandler
+ .thumb_set TIM7_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream0_IRQHandler
+ .thumb_set DMA2_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream1_IRQHandler
+ .thumb_set DMA2_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream2_IRQHandler
+ .thumb_set DMA2_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream3_IRQHandler
+ .thumb_set DMA2_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream4_IRQHandler
+ .thumb_set DMA2_Stream4_IRQHandler,Default_Handler
+
+ .weak CAN2_TX_IRQHandler
+ .thumb_set CAN2_TX_IRQHandler,Default_Handler
+
+ .weak CAN2_RX0_IRQHandler
+ .thumb_set CAN2_RX0_IRQHandler,Default_Handler
+
+ .weak CAN2_RX1_IRQHandler
+ .thumb_set CAN2_RX1_IRQHandler,Default_Handler
+
+ .weak CAN2_SCE_IRQHandler
+ .thumb_set CAN2_SCE_IRQHandler,Default_Handler
+
+ .weak OTG_FS_IRQHandler
+ .thumb_set OTG_FS_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream5_IRQHandler
+ .thumb_set DMA2_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream6_IRQHandler
+ .thumb_set DMA2_Stream6_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream7_IRQHandler
+ .thumb_set DMA2_Stream7_IRQHandler,Default_Handler
+
+ .weak USART6_IRQHandler
+ .thumb_set USART6_IRQHandler,Default_Handler
+
+ .weak I2C3_EV_IRQHandler
+ .thumb_set I2C3_EV_IRQHandler,Default_Handler
+
+ .weak I2C3_ER_IRQHandler
+ .thumb_set I2C3_ER_IRQHandler,Default_Handler
+
+ .weak OTG_HS_EP1_OUT_IRQHandler
+ .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler
+
+ .weak OTG_HS_EP1_IN_IRQHandler
+ .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler
+
+ .weak OTG_HS_WKUP_IRQHandler
+ .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler
+
+ .weak OTG_HS_IRQHandler
+ .thumb_set OTG_HS_IRQHandler,Default_Handler
+
+ .weak HASH_RNG_IRQHandler
+ .thumb_set HASH_RNG_IRQHandler,Default_Handler
+
+ .weak FPU_IRQHandler
+ .thumb_set FPU_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
diff --git a/ports/stm32f4/boards/stm32f411ce_blackpill/mpconfigboard.h b/ports/stm32f4/boards/stm32f411ce_blackpill/mpconfigboard.h
index 05e2a384a..2ae1a2926 100644
--- a/ports/stm32f4/boards/stm32f411ce_blackpill/mpconfigboard.h
+++ b/ports/stm32f4/boards/stm32f411ce_blackpill/mpconfigboard.h
@@ -32,8 +32,8 @@
#define FLASH_SIZE (0x80000)
#define FLASH_PAGE_SIZE (0x4000)
-#define BOARD_OSC_DIV 25
-#define BOARD_NO_VBUS_SENSE
+#define BOARD_OSC_DIV (25)
+#define BOARD_NO_VBUS_SENSE (1)
// On-board flash
// #define SPI_FLASH_MOSI_PIN (&pin_PA07)
@@ -41,8 +41,8 @@
// #define SPI_FLASH_SCK_PIN (&pin_PA05)
// #define SPI_FLASH_CS_PIN (&pin_PA04)
-#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
+#define CIRCUITPY_AUTORELOAD_DELAY_MS (500)
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x2000 - 0xC000)
-#define AUTORESET_DELAY_MS 500
+#define AUTORESET_DELAY_MS (500)
diff --git a/ports/stm32f4/boards/stm32f411ce_blackpill/mpconfigboard.mk b/ports/stm32f4/boards/stm32f411ce_blackpill/mpconfigboard.mk
index d4f0f9577..68c6a1eea 100644
--- a/ports/stm32f4/boards/stm32f411ce_blackpill/mpconfigboard.mk
+++ b/ports/stm32f4/boards/stm32f411ce_blackpill/mpconfigboard.mk
@@ -18,5 +18,4 @@ MCU_SUB_VARIANT = stm32f411xe
MCU_PACKAGE = 48
CMSIS_MCU = STM32F411xE
LD_FILE = boards/STM32F411VETx_FLASH.ld
-TEXT0_ADDR = 0x08000000
-TEXT1_ADDR = 0x08020000
+
diff --git a/ports/stm32f4/boards/stm32f411ce_blackpill/pins.c b/ports/stm32f4/boards/stm32f411ce_blackpill/pins.c
index 5797a9762..aa9736fc4 100644
--- a/ports/stm32f4/boards/stm32f411ce_blackpill/pins.c
+++ b/ports/stm32f4/boards/stm32f411ce_blackpill/pins.c
@@ -34,7 +34,6 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_C15), MP_ROM_PTR(&pin_PC15) },
{ MP_ROM_QSTR(MP_QSTR_C14), MP_ROM_PTR(&pin_PC14) },
{ MP_ROM_QSTR(MP_QSTR_C13), MP_ROM_PTR(&pin_PC13) },
-
{ MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PC13) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h
index 7a5335407..49ef80cdd 100644
--- a/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h
+++ b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h
@@ -32,4 +32,4 @@
#define FLASH_SIZE (0x80000) //512K
#define FLASH_PAGE_SIZE (0x4000) //16K
-#define BOARD_OSC_DIV 8
+#define BOARD_OSC_DIV (8)
diff --git a/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.mk b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.mk
index d6f369b6e..64e2b4dc5 100644
--- a/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.mk
+++ b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.mk
@@ -13,5 +13,4 @@ MCU_SUB_VARIANT = stm32f411xe
MCU_PACKAGE = 100
CMSIS_MCU = STM32F411xE
LD_FILE = boards/STM32F411VETx_FLASH.ld
-TEXT0_ADDR = 0x08000000
-TEXT1_ADDR = 0x08020000 \ No newline at end of file
+
diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h
index 3ab9a5585..f34b830fb 100644
--- a/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h
+++ b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h
@@ -32,5 +32,7 @@
#define FLASH_SIZE (0x100000)
#define FLASH_PAGE_SIZE (0x4000)
+#define BOARD_OSC_DIV (8)
+
#define DEFAULT_I2C_BUS_SCL (&pin_PB10)
#define DEFAULT_I2C_BUS_SDA (&pin_PB09)
diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk
index d642f243e..b0205fc73 100644
--- a/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk
+++ b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk
@@ -18,6 +18,5 @@ MCU_SUB_VARIANT = stm32f412zx
MCU_PACKAGE = 144
CMSIS_MCU = STM32F412Zx
LD_FILE = boards/STM32F412ZGTx_FLASH.ld
-TEXT0_ADDR = 0x08000000
-TEXT1_ADDR = 0x08020000
+
diff --git a/ports/stm32f4/boards/stm32f4_discovery/board.c b/ports/stm32f4/boards/stm32f4_discovery/board.c
new file mode 100644
index 000000000..4421970ee
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f4_discovery/board.c
@@ -0,0 +1,38 @@
+/*
+ * 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 "boards/board.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/stm32f4/boards/stm32f4_discovery/mpconfigboard.h b/ports/stm32f4/boards/stm32f4_discovery/mpconfigboard.h
new file mode 100644
index 000000000..fcd7aa09c
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f4_discovery/mpconfigboard.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Lucian Copeland 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.
+ */
+
+//Micropython setup
+
+#define MICROPY_HW_BOARD_NAME "STM32F4_DISCO"
+#define MICROPY_HW_MCU_NAME "STM32F407VG"
+
+#define FLASH_SIZE (0x100000)
+#define FLASH_PAGE_SIZE (0x4000)
+
+#define BOARD_OSC_DIV (8)
diff --git a/ports/stm32f4/boards/stm32f4_discovery/mpconfigboard.mk b/ports/stm32f4/boards/stm32f4_discovery/mpconfigboard.mk
new file mode 100644
index 000000000..312a20f65
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f4_discovery/mpconfigboard.mk
@@ -0,0 +1,18 @@
+USB_VID = 0x239A
+USB_PID = 0x808A
+USB_PRODUCT = "STM32F407VG Discovery Board - CPy"
+USB_MANUFACTURER = "STMicroelectronics"
+USB_DEVICES = "CDC,MSC"
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = NONE
+
+# This is technically a F407 but there's no difference
+# other than the camera and ethernet, which aren't supported.
+MCU_SERIES = m4
+MCU_VARIANT = stm32f4
+MCU_SUB_VARIANT = stm32f407xx
+MCU_PACKAGE = 100
+CMSIS_MCU = STM32F407xx
+LD_FILE = boards/STM32F407_fs.ld
+
diff --git a/ports/stm32f4/boards/stm32f4_discovery/pins.c b/ports/stm32f4/boards/stm32f4_discovery/pins.c
new file mode 100644
index 000000000..712932145
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f4_discovery/pins.c
@@ -0,0 +1,107 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ //P1
+ { MP_ROM_QSTR(MP_QSTR_PC00), MP_ROM_PTR(&pin_PC00) },
+ { MP_ROM_QSTR(MP_QSTR_PC01), MP_ROM_PTR(&pin_PC01) },
+ { MP_ROM_QSTR(MP_QSTR_PC02), MP_ROM_PTR(&pin_PC02) },
+ { MP_ROM_QSTR(MP_QSTR_PC03), MP_ROM_PTR(&pin_PC03) },
+ { MP_ROM_QSTR(MP_QSTR_PA00), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_PA01), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_PA02), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_PA03), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_PA04), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_PA05), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_PA06), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_PA07), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_PC04), MP_ROM_PTR(&pin_PC04) },
+ { MP_ROM_QSTR(MP_QSTR_PC05), MP_ROM_PTR(&pin_PC05) },
+ { MP_ROM_QSTR(MP_QSTR_PB00), MP_ROM_PTR(&pin_PB00) },
+ { MP_ROM_QSTR(MP_QSTR_PB01), MP_ROM_PTR(&pin_PB01) },
+ { MP_ROM_QSTR(MP_QSTR_PB02), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_PE07), MP_ROM_PTR(&pin_PE07) },
+ { MP_ROM_QSTR(MP_QSTR_PE08), MP_ROM_PTR(&pin_PE08) },
+ { MP_ROM_QSTR(MP_QSTR_PE09), MP_ROM_PTR(&pin_PE09) },
+ { MP_ROM_QSTR(MP_QSTR_PE10), MP_ROM_PTR(&pin_PE10) },
+ { MP_ROM_QSTR(MP_QSTR_PE11), MP_ROM_PTR(&pin_PE11) },
+ { MP_ROM_QSTR(MP_QSTR_PE12), MP_ROM_PTR(&pin_PE12) },
+ { MP_ROM_QSTR(MP_QSTR_PE13), MP_ROM_PTR(&pin_PE13) },
+ { MP_ROM_QSTR(MP_QSTR_PE14), MP_ROM_PTR(&pin_PE14) },
+ { MP_ROM_QSTR(MP_QSTR_PE15), MP_ROM_PTR(&pin_PE15) },
+ { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) }, // Differs from F411
+ { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) },
+ { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) },
+ { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) },
+ { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) },
+ { MP_ROM_QSTR(MP_QSTR_PD08), MP_ROM_PTR(&pin_PD08) },
+ { MP_ROM_QSTR(MP_QSTR_PD09), MP_ROM_PTR(&pin_PD09) },
+ { MP_ROM_QSTR(MP_QSTR_PD10), MP_ROM_PTR(&pin_PD10) },
+ { MP_ROM_QSTR(MP_QSTR_PD11), MP_ROM_PTR(&pin_PD11) },
+ { MP_ROM_QSTR(MP_QSTR_PD12), MP_ROM_PTR(&pin_PD12) },
+ { MP_ROM_QSTR(MP_QSTR_PD13), MP_ROM_PTR(&pin_PD13) },
+ { MP_ROM_QSTR(MP_QSTR_PD14), MP_ROM_PTR(&pin_PD14) },
+ { MP_ROM_QSTR(MP_QSTR_PD15), MP_ROM_PTR(&pin_PD15) },
+ //P2
+ { MP_ROM_QSTR(MP_QSTR_PC14), MP_ROM_PTR(&pin_PC14) },
+ { MP_ROM_QSTR(MP_QSTR_PC15), MP_ROM_PTR(&pin_PC15) },
+ { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) },
+ { MP_ROM_QSTR(MP_QSTR_PE06), MP_ROM_PTR(&pin_PE06) },
+ { MP_ROM_QSTR(MP_QSTR_PE05), MP_ROM_PTR(&pin_PE05) },
+ { MP_ROM_QSTR(MP_QSTR_PE04), MP_ROM_PTR(&pin_PE04) },
+ { MP_ROM_QSTR(MP_QSTR_PE03), MP_ROM_PTR(&pin_PE03) },
+ { MP_ROM_QSTR(MP_QSTR_PE02), MP_ROM_PTR(&pin_PE02) },
+ { MP_ROM_QSTR(MP_QSTR_PE01), MP_ROM_PTR(&pin_PE01) },
+ { MP_ROM_QSTR(MP_QSTR_PE00), MP_ROM_PTR(&pin_PE00) },
+ { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) },
+ { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) },
+ { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) },
+ { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) },
+ { MP_ROM_QSTR(MP_QSTR_PB03), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_PD07), MP_ROM_PTR(&pin_PD07) },
+ { MP_ROM_QSTR(MP_QSTR_PD06), MP_ROM_PTR(&pin_PD06) },
+ { MP_ROM_QSTR(MP_QSTR_PD05), MP_ROM_PTR(&pin_PD05) },
+ { MP_ROM_QSTR(MP_QSTR_PD04), MP_ROM_PTR(&pin_PD04) },
+ { MP_ROM_QSTR(MP_QSTR_PD03), MP_ROM_PTR(&pin_PD03) },
+ { MP_ROM_QSTR(MP_QSTR_PD02), MP_ROM_PTR(&pin_PD02) },
+ { MP_ROM_QSTR(MP_QSTR_PD01), MP_ROM_PTR(&pin_PD01) },
+ { MP_ROM_QSTR(MP_QSTR_PD00), MP_ROM_PTR(&pin_PD00) },
+ { MP_ROM_QSTR(MP_QSTR_PC12), MP_ROM_PTR(&pin_PC12) },
+ { MP_ROM_QSTR(MP_QSTR_PC11), MP_ROM_PTR(&pin_PC11) },
+ { MP_ROM_QSTR(MP_QSTR_PC10), MP_ROM_PTR(&pin_PC10) },
+ { MP_ROM_QSTR(MP_QSTR_PA15), MP_ROM_PTR(&pin_PA15) },
+ { MP_ROM_QSTR(MP_QSTR_PA14), MP_ROM_PTR(&pin_PA14) },
+ { MP_ROM_QSTR(MP_QSTR_PA13), MP_ROM_PTR(&pin_PA13) },
+ { MP_ROM_QSTR(MP_QSTR_PA10), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_PA09), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_PA08), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_PC09), MP_ROM_PTR(&pin_PC09) },
+ { MP_ROM_QSTR(MP_QSTR_PC08), MP_ROM_PTR(&pin_PC08) },
+ { MP_ROM_QSTR(MP_QSTR_PC07), MP_ROM_PTR(&pin_PC07) },
+ { MP_ROM_QSTR(MP_QSTR_PC06), MP_ROM_PTR(&pin_PC06) },
+ //ST LED names
+ { MP_ROM_QSTR(MP_QSTR_LD3), MP_ROM_PTR(&pin_PD13) },
+ { MP_ROM_QSTR(MP_QSTR_LD4), MP_ROM_PTR(&pin_PD12) },
+ { MP_ROM_QSTR(MP_QSTR_LD5), MP_ROM_PTR(&pin_PD14) },
+ { MP_ROM_QSTR(MP_QSTR_LD6), MP_ROM_PTR(&pin_PD15) },
+ //more useful LED names
+ { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_PD13) },
+ { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_PD12) },
+ { MP_ROM_QSTR(MP_QSTR_LED3), MP_ROM_PTR(&pin_PD14) },
+ { MP_ROM_QSTR(MP_QSTR_LED4), MP_ROM_PTR(&pin_PD15) },
+ //AnalogIO names
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA05) },
+ //actual LED names
+ { MP_ROM_QSTR(MP_QSTR_LED_ORANGE), MP_ROM_PTR(&pin_PD13) },
+ { MP_ROM_QSTR(MP_QSTR_LED_GREEN), MP_ROM_PTR(&pin_PD12) },
+ { MP_ROM_QSTR(MP_QSTR_LED_RED), MP_ROM_PTR(&pin_PD14) },
+ { MP_ROM_QSTR(MP_QSTR_LED_BLUE), MP_ROM_PTR(&pin_PD15) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/stm32f4/boards/stm32f4_discovery/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/stm32f4_discovery/stm32f4xx_hal_conf.h
new file mode 100644
index 000000000..ee5832d49
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f4_discovery/stm32f4xx_hal_conf.h
@@ -0,0 +1,439 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_conf_template.h
+ * @author MCD Application Team
+ * @brief HAL configuration template file.
+ * This file should be copied to the application folder and renamed
+ * to stm32f4xx_hal_conf.h.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_CONF_H
+#define __STM32F4xx_HAL_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* ########################## Module Selection ############################## */
+/**
+ * @brief This is the list of modules to be used in the HAL driver
+ */
+#define HAL_MODULE_ENABLED
+
+#define HAL_ADC_MODULE_ENABLED
+/* #define HAL_CRYP_MODULE_ENABLED */
+/* #define HAL_CAN_MODULE_ENABLED */
+/* #define HAL_CRC_MODULE_ENABLED */
+/* #define HAL_CRYP_MODULE_ENABLED */
+#define HAL_DAC_MODULE_ENABLED
+/* #define HAL_DCMI_MODULE_ENABLED */
+/* #define HAL_DMA2D_MODULE_ENABLED */
+/* #define HAL_ETH_MODULE_ENABLED */
+/* #define HAL_NAND_MODULE_ENABLED */
+/* #define HAL_NOR_MODULE_ENABLED */
+/* #define HAL_PCCARD_MODULE_ENABLED */
+/* #define HAL_SRAM_MODULE_ENABLED */
+/* #define HAL_SDRAM_MODULE_ENABLED */
+/* #define HAL_HASH_MODULE_ENABLED */
+#define HAL_I2C_MODULE_ENABLED
+#define HAL_I2S_MODULE_ENABLED
+/* #define HAL_IWDG_MODULE_ENABLED */
+/* #define HAL_LTDC_MODULE_ENABLED */
+#define HAL_RNG_MODULE_ENABLED
+/* #define HAL_RTC_MODULE_ENABLED */
+/* #define HAL_SAI_MODULE_ENABLED */
+/* #define HAL_SD_MODULE_ENABLED */
+/* #define HAL_MMC_MODULE_ENABLED */
+#define HAL_SPI_MODULE_ENABLED
+#define HAL_TIM_MODULE_ENABLED
+#define HAL_UART_MODULE_ENABLED
+#define HAL_USART_MODULE_ENABLED
+/* #define HAL_IRDA_MODULE_ENABLED */
+/* #define HAL_SMARTCARD_MODULE_ENABLED */
+/* #define HAL_WWDG_MODULE_ENABLED */
+#define HAL_PCD_MODULE_ENABLED
+/* #define HAL_HCD_MODULE_ENABLED */
+/* #define HAL_DSI_MODULE_ENABLED */
+/* #define HAL_QSPI_MODULE_ENABLED */
+/* #define HAL_QSPI_MODULE_ENABLED */
+/* #define HAL_CEC_MODULE_ENABLED */
+/* #define HAL_FMPI2C_MODULE_ENABLED */
+/* #define HAL_SPDIFRX_MODULE_ENABLED */
+/* #define HAL_DFSDM_MODULE_ENABLED */
+/* #define HAL_LPTIM_MODULE_ENABLED */
+/* #define HAL_EXTI_MODULE_ENABLED */
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_EXTI_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+
+/* ########################## HSE/HSI Values adaptation ##################### */
+/**
+ * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSE is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (HSE_STARTUP_TIMEOUT)
+ #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief Internal High Speed oscillator (HSI) value.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSI is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+ * @brief Internal Low Speed oscillator (LSI) value.
+ */
+#if !defined (LSI_VALUE)
+ #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/
+#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
+ The real value may vary depending on the variations
+ in voltage and temperature.*/
+/**
+ * @brief External Low Speed oscillator (LSE) value.
+ */
+#if !defined (LSE_VALUE)
+ #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */
+#endif /* LSE_VALUE */
+
+#if !defined (LSE_STARTUP_TIMEOUT)
+ #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
+#endif /* LSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief External clock source for I2S peripheral
+ * This value is used by the I2S HAL module to compute the I2S clock source
+ * frequency, this source is inserted directly through I2S_CKIN pad.
+ */
+#if !defined (EXTERNAL_CLOCK_VALUE)
+ #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/
+#endif /* EXTERNAL_CLOCK_VALUE */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+ === you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+ * @brief This is the HAL system configuration section
+ */
+#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
+#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
+#define USE_RTOS 0U
+#define PREFETCH_ENABLE 1U
+#define INSTRUCTION_CACHE_ENABLE 1U
+#define DATA_CACHE_ENABLE 1U
+
+/* ########################## Assert Selection ############################## */
+/**
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * HAL drivers code
+ */
+/* #define USE_FULL_ASSERT 1U */
+
+/* ################## Ethernet peripheral configuration ##################### */
+
+/* Section 1 : Ethernet peripheral configuration */
+
+/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
+#define MAC_ADDR0 2U
+#define MAC_ADDR1 0U
+#define MAC_ADDR2 0U
+#define MAC_ADDR3 0U
+#define MAC_ADDR4 0U
+#define MAC_ADDR5 0U
+
+/* Definition of the Ethernet driver buffers size and count */
+#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
+#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
+#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
+
+/* Section 2: PHY configuration section */
+
+/* DP83848_PHY_ADDRESS Address*/
+#define DP83848_PHY_ADDRESS 0x01U
+/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
+#define PHY_RESET_DELAY ((uint32_t)0x000000FFU)
+/* PHY Configuration delay */
+#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU)
+
+#define PHY_READ_TO ((uint32_t)0x0000FFFFU)
+#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU)
+
+/* Section 3: Common PHY Registers */
+
+#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */
+#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
+
+#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
+#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
+#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
+#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
+#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
+#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
+#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
+#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
+#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
+#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
+
+#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
+#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
+#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
+
+/* Section 4: Extended PHY Registers */
+#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
+
+#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
+#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
+
+/* ################## SPI peripheral configuration ########################## */
+
+/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
+* Activated: CRC code is present inside driver
+* Deactivated: CRC code cleaned from driver
+*/
+
+#define USE_SPI_CRC 0U
+
+/* Includes ------------------------------------------------------------------*/
+/**
+ * @brief Include module's header file
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_EXTI_MODULE_ENABLED
+ #include "stm32f4xx_hal_exti.h"
+#endif /* HAL_EXTI_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+ #include "stm32f4xx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+ #include "stm32f4xx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+ #include "stm32f4xx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_CAN_MODULE_ENABLED
+ #include "stm32f4xx_hal_can.h"
+#endif /* HAL_CAN_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+ #include "stm32f4xx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_CRYP_MODULE_ENABLED
+ #include "stm32f4xx_hal_cryp.h"
+#endif /* HAL_CRYP_MODULE_ENABLED */
+
+#ifdef HAL_DMA2D_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma2d.h"
+#endif /* HAL_DMA2D_MODULE_ENABLED */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+ #include "stm32f4xx_hal_dac.h"
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+#ifdef HAL_DCMI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dcmi.h"
+#endif /* HAL_DCMI_MODULE_ENABLED */
+
+#ifdef HAL_ETH_MODULE_ENABLED
+ #include "stm32f4xx_hal_eth.h"
+#endif /* HAL_ETH_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+ #include "stm32f4xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+ #include "stm32f4xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_PCCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pccard.h"
+#endif /* HAL_PCCARD_MODULE_ENABLED */
+
+#ifdef HAL_SDRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sdram.h"
+#endif /* HAL_SDRAM_MODULE_ENABLED */
+
+#ifdef HAL_HASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_hash.h"
+#endif /* HAL_HASH_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2s.h"
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_LTDC_MODULE_ENABLED
+ #include "stm32f4xx_hal_ltdc.h"
+#endif /* HAL_LTDC_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+ #include "stm32f4xx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_RNG_MODULE_ENABLED
+ #include "stm32f4xx_hal_rng.h"
+#endif /* HAL_RNG_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_SAI_MODULE_ENABLED
+ #include "stm32f4xx_hal_sai.h"
+#endif /* HAL_SAI_MODULE_ENABLED */
+
+#ifdef HAL_SD_MODULE_ENABLED
+ #include "stm32f4xx_hal_sd.h"
+#endif /* HAL_SD_MODULE_ENABLED */
+
+#ifdef HAL_MMC_MODULE_ENABLED
+ #include "stm32f4xx_hal_mmc.h"
+#endif /* HAL_MMC_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+ #include "stm32f4xx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+ #include "stm32f4xx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32f4xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_HCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_hcd.h"
+#endif /* HAL_HCD_MODULE_ENABLED */
+
+#ifdef HAL_DSI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dsi.h"
+#endif /* HAL_DSI_MODULE_ENABLED */
+
+#ifdef HAL_QSPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_qspi.h"
+#endif /* HAL_QSPI_MODULE_ENABLED */
+
+#ifdef HAL_CEC_MODULE_ENABLED
+ #include "stm32f4xx_hal_cec.h"
+#endif /* HAL_CEC_MODULE_ENABLED */
+
+#ifdef HAL_FMPI2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_fmpi2c.h"
+#endif /* HAL_FMPI2C_MODULE_ENABLED */
+
+#ifdef HAL_SPDIFRX_MODULE_ENABLED
+ #include "stm32f4xx_hal_spdifrx.h"
+#endif /* HAL_SPDIFRX_MODULE_ENABLED */
+
+#ifdef HAL_DFSDM_MODULE_ENABLED
+ #include "stm32f4xx_hal_dfsdm.h"
+#endif /* HAL_DFSDM_MODULE_ENABLED */
+
+#ifdef HAL_LPTIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_lptim.h"
+#endif /* HAL_LPTIM_MODULE_ENABLED */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr: If expr is false, it calls assert_failed function
+ * which reports the name of the source file and the source
+ * line number of the call that failed.
+ * If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_HAL_CONF_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/ports/stm32f4/common-hal/busio/I2C.c b/ports/stm32f4/common-hal/busio/I2C.c
index d2292845e..1437e5e78 100644
--- a/ports/stm32f4/common-hal/busio/I2C.c
+++ b/ports/stm32f4/common-hal/busio/I2C.c
@@ -35,51 +35,46 @@
#include "supervisor/shared/translate.h"
#include "common-hal/microcontroller/Pin.h"
-STATIC bool reserved_i2c[3];
-STATIC bool never_reset[3];
+//arrays use 0 based numbering: I2C1 is stored at index 0
+#define MAX_I2C 3
+STATIC bool reserved_i2c[MAX_I2C];
+STATIC bool never_reset_i2c[MAX_I2C];
-void i2c_reset(void) {
- //Note: I2Cs are also forcibly reset in construct, due to silicon error
- #ifdef I2C1
- reserved_i2c[0] = false;
- __HAL_RCC_I2C1_CLK_DISABLE();
- #endif
- #ifdef I2C2
- reserved_i2c[1] = false;
- __HAL_RCC_I2C2_CLK_DISABLE();
- #endif
- #ifdef I2C3
- reserved_i2c[2] = false;
- __HAL_RCC_I2C3_CLK_DISABLE();
- #endif
-}
-
-void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
- for (size_t i = 0 ; i < MP_ARRAY_SIZE(mcu_i2c_banks); i++) {
- if (self->handle.Instance == mcu_i2c_banks[i]) {
- never_reset[i] = true;
+#define ALL_CLOCKS 0xFF
+STATIC void i2c_clock_enable(uint8_t mask);
+STATIC void i2c_clock_disable(uint8_t mask);
- never_reset_pin_number(self->scl->pin->port, self->scl->pin->number);
- never_reset_pin_number(self->sda->pin->port, self->scl->pin->number);
- break;
+void i2c_reset(void) {
+ uint16_t never_reset_mask = 0x00;
+ for(int i = 0; i < MAX_I2C; i++) {
+ if (!never_reset_i2c[i]) {
+ reserved_i2c[i] = false;
+ } else {
+ never_reset_mask |= 1 << i;
}
}
+ i2c_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
}
-
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t frequency, uint32_t timeout) {
//match pins to I2C objects
I2C_TypeDef * I2Cx;
+ uint8_t sda_len = MP_ARRAY_SIZE(mcu_i2c_sda_list);
+ uint8_t scl_len = MP_ARRAY_SIZE(mcu_i2c_scl_list);
+ bool i2c_taken = false;
- uint8_t sda_len = sizeof(mcu_i2c_sda_list)/sizeof(*mcu_i2c_sda_list);
- uint8_t scl_len = sizeof(mcu_i2c_scl_list)/sizeof(*mcu_i2c_scl_list);
- for(uint i=0; i<sda_len;i++) {
+ for (uint i = 0; i < sda_len; i++) {
if (mcu_i2c_sda_list[i].pin == sda) {
- for(uint j=0; j<scl_len;j++) {
+ for (uint j = 0; j < scl_len; j++) {
if ((mcu_i2c_scl_list[j].pin == scl)
&& (mcu_i2c_scl_list[j].i2c_index == mcu_i2c_sda_list[i].i2c_index)) {
+ //keep looking if the I2C is taken, could be another SCL that works
+ if (reserved_i2c[mcu_i2c_scl_list[i].i2c_index - 1]) {
+ i2c_taken = true;
+ continue;
+ }
self->scl = &mcu_i2c_scl_list[j];
self->sda = &mcu_i2c_sda_list[i];
break;
@@ -89,14 +84,14 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
}
//handle typedef selection, errors
- if(self->sda!=NULL && self->scl!=NULL ) {
- I2Cx = mcu_i2c_banks[self->sda->i2c_index-1];
+ if (self->sda != NULL && self->scl != NULL ) {
+ I2Cx = mcu_i2c_banks[self->sda->i2c_index - 1];
} else {
- mp_raise_RuntimeError(translate("Invalid I2C pin selection"));
- }
-
- if(reserved_i2c[self->sda->i2c_index-1]) {
- mp_raise_RuntimeError(translate("Hardware busy, try alternative pins"));
+ if (i2c_taken) {
+ mp_raise_ValueError(translate("Hardware busy, try alternative pins"));
+ } else {
+ mp_raise_ValueError(translate("Invalid I2C pin selection"));
+ }
}
//Start GPIO for each pin
@@ -115,44 +110,9 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
GPIO_InitStruct.Alternate = self->scl->altfn_index;
HAL_GPIO_Init(pin_port(scl->port), &GPIO_InitStruct);
- //Fix for HAL error caused by soft reboot GPIO init SDA pin voltage drop. See Eratta.
- //Must be in this exact spot or I2C will get stuck in infinite loop.
- //TODO: See git issue #2172
- #ifdef I2C1
- __HAL_RCC_I2C1_FORCE_RESET();
- HAL_Delay(2);
- __HAL_RCC_I2C1_RELEASE_RESET();
- #endif
- #ifdef I2C2
- __HAL_RCC_I2C2_FORCE_RESET();
- HAL_Delay(2);
- __HAL_RCC_I2C2_RELEASE_RESET();
- #endif
- #ifdef I2C3
- __HAL_RCC_I2C3_FORCE_RESET();
- HAL_Delay(2);
- __HAL_RCC_I2C3_RELEASE_RESET();
- #endif
-
- //Keep separate so above hack can be cleanly replaced
- #ifdef I2C1
- if(I2Cx==I2C1) {
- reserved_i2c[0] = true;
- __HAL_RCC_I2C1_CLK_ENABLE();
- }
- #endif
- #ifdef I2C2
- if(I2Cx==I2C2) {
- reserved_i2c[1] = true;
- __HAL_RCC_I2C2_CLK_ENABLE();
- }
- #endif
- #ifdef I2C3
- if(I2Cx==I2C3) {
- reserved_i2c[2] = true;
- __HAL_RCC_I2C3_CLK_ENABLE();
- }
- #endif
+ //Note: due to I2C soft reboot issue, do not relocate clock init.
+ i2c_clock_enable(1 << (self->sda->i2c_index - 1));
+ reserved_i2c[self->sda->i2c_index - 1] = true;
self->handle.Instance = I2Cx;
self->handle.Init.ClockSpeed = 100000;
@@ -163,13 +123,26 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
self->handle.Init.OwnAddress2 = 0;
self->handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
self->handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
- if(HAL_I2C_Init(&(self->handle)) != HAL_OK) {
+ self->handle.State = HAL_I2C_STATE_RESET;
+ if (HAL_I2C_Init(&(self->handle)) != HAL_OK) {
mp_raise_RuntimeError(translate("I2C Init Error"));
}
claim_pin(sda);
claim_pin(scl);
}
+void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
+ for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_i2c_banks); i++) {
+ if (self->handle.Instance == mcu_i2c_banks[i]) {
+ never_reset_i2c[i] = true;
+
+ never_reset_pin_number(self->scl->pin->port, self->scl->pin->number);
+ never_reset_pin_number(self->sda->pin->port, self->sda->pin->number);
+ break;
+ }
+ }
+}
+
bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) {
return self->sda->pin == mp_const_none;
}
@@ -178,27 +151,11 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
if (common_hal_busio_i2c_deinited(self)) {
return;
}
- #ifdef I2C1
- if(self->handle.Instance==I2C1) {
- never_reset[0] = false;
- reserved_i2c[0] = false;
- __HAL_RCC_I2C1_CLK_DISABLE();
- }
- #endif
- #ifdef I2C2
- if(self->handle.Instance==I2C2) {
- never_reset[1] = false;
- reserved_i2c[1] = false;
- __HAL_RCC_I2C2_CLK_DISABLE();
- }
- #endif
- #ifdef I2C3
- if(self->handle.Instance==I2C3) {
- never_reset[2] = false;
- reserved_i2c[2] = false;
- __HAL_RCC_I2C3_CLK_DISABLE();
- }
- #endif
+
+ i2c_clock_disable(1 << (self->sda->i2c_index - 1));
+ reserved_i2c[self->sda->i2c_index - 1] = false;
+ never_reset_i2c[self->sda->i2c_index - 1] = false;
+
reset_pin_number(self->sda->pin->port,self->sda->pin->number);
reset_pin_number(self->scl->pin->port,self->scl->pin->number);
self->sda = mp_const_none;
@@ -206,7 +163,7 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
}
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
- return HAL_I2C_IsDeviceReady(&(self->handle), (uint16_t)(addr<<1),2,2) == HAL_OK;
+ return HAL_I2C_IsDeviceReady(&(self->handle), (uint16_t)(addr << 1), 2, 2) == HAL_OK;
}
bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) {
@@ -238,11 +195,56 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
const uint8_t *data, size_t len, bool transmit_stop_bit) {
- HAL_StatusTypeDef result = HAL_I2C_Master_Transmit(&(self->handle), (uint16_t)(addr<<1), (uint8_t *)data, (uint16_t)len, 500);
+ HAL_StatusTypeDef result = HAL_I2C_Master_Transmit(&(self->handle), (uint16_t)(addr << 1),
+ (uint8_t *)data, (uint16_t)len, 500);
return result == HAL_OK ? 0 : MP_EIO;
}
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *data, size_t len) {
- return HAL_I2C_Master_Receive(&(self->handle), (uint16_t)(addr<<1), data, (uint16_t)len, 500) == HAL_OK ? 0 : MP_EIO;
+ return HAL_I2C_Master_Receive(&(self->handle), (uint16_t)(addr<<1), data, (uint16_t)len, 500)
+ == HAL_OK ? 0 : MP_EIO;
+}
+
+STATIC void i2c_clock_enable(uint8_t mask) {
+ //Note: hard reset required due to soft reboot issue.
+ #ifdef I2C1
+ if (mask & (1 << 0)) {
+ __HAL_RCC_I2C1_CLK_ENABLE();
+ __HAL_RCC_I2C1_FORCE_RESET();
+ __HAL_RCC_I2C1_RELEASE_RESET();
+ }
+ #endif
+ #ifdef I2C2
+ if (mask & (1 << 1)) {
+ __HAL_RCC_I2C2_CLK_ENABLE();
+ __HAL_RCC_I2C2_FORCE_RESET();
+ __HAL_RCC_I2C2_RELEASE_RESET();
+ }
+ #endif
+ #ifdef I2C3
+ if (mask & (1 << 2)) {
+ __HAL_RCC_I2C3_CLK_ENABLE();
+ __HAL_RCC_I2C3_FORCE_RESET();
+ __HAL_RCC_I2C3_RELEASE_RESET();
+ }
+ #endif
+}
+
+STATIC void i2c_clock_disable(uint8_t mask) {
+ #ifdef I2C1
+ if (mask & (1 << 0)) {
+ __HAL_RCC_I2C1_CLK_DISABLE();
+ }
+ #endif
+ #ifdef I2C2
+ if (mask & (1 << 1)) {
+ __HAL_RCC_I2C2_CLK_DISABLE();
+ }
+ #endif
+ #ifdef I2C3
+ if (mask & (1 << 2)) {
+ __HAL_RCC_I2C3_CLK_DISABLE();
+ }
+ #endif
}
diff --git a/ports/stm32f4/common-hal/busio/SPI.c b/ports/stm32f4/common-hal/busio/SPI.c
index 32089887f..e00b5e9f0 100644
--- a/ports/stm32f4/common-hal/busio/SPI.c
+++ b/ports/stm32f4/common-hal/busio/SPI.c
@@ -36,34 +36,62 @@
#include "supervisor/shared/translate.h"
#include "common-hal/microcontroller/Pin.h"
-#define MAX_SPI 6 //TODO; replace this as part of periph cleanup
-#define ALL_CLOCKS 0xFF
+// Note that any bugs introduced in this file can cause crashes at startup
+// for chips using external SPI flash.
//arrays use 0 based numbering: SPI1 is stored at index 0
+#define MAX_SPI 6
STATIC bool reserved_spi[MAX_SPI];
STATIC bool never_reset_spi[MAX_SPI];
+#define ALL_CLOCKS 0xFF
STATIC void spi_clock_enable(uint8_t mask);
STATIC void spi_clock_disable(uint8_t mask);
STATIC uint32_t get_busclock(SPI_TypeDef * instance) {
//SPI2 and 3 are on PCLK1, if they exist.
#ifdef SPI2
- if(instance == SPI2) return HAL_RCC_GetPCLK1Freq();
+ if (instance == SPI2) return HAL_RCC_GetPCLK1Freq();
#endif
#ifdef SPI3
- if(instance == SPI3) return HAL_RCC_GetPCLK1Freq();
+ if (instance == SPI3) return HAL_RCC_GetPCLK1Freq();
#endif
return HAL_RCC_GetPCLK2Freq();
}
+STATIC uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t * prescaler, uint32_t busclock) {
+ static const uint32_t baud_map[8][2] = {
+ {2,SPI_BAUDRATEPRESCALER_2},
+ {4,SPI_BAUDRATEPRESCALER_4},
+ {8,SPI_BAUDRATEPRESCALER_8},
+ {16,SPI_BAUDRATEPRESCALER_16},
+ {32,SPI_BAUDRATEPRESCALER_32},
+ {64,SPI_BAUDRATEPRESCALER_64},
+ {128,SPI_BAUDRATEPRESCALER_128},
+ {256,SPI_BAUDRATEPRESCALER_256}
+ };
+ size_t i = 0;
+ uint16_t divisor;
+ do {
+ divisor = baud_map[i][0];
+ if (baudrate >= (busclock/divisor)) {
+ *prescaler = divisor;
+ return baud_map[i][1];
+ }
+ i++;
+ } while (divisor != 256);
+ //only gets here if requested baud is lower than minimum
+ *prescaler = 256;
+ return SPI_BAUDRATEPRESCALER_256;
+}
+
void spi_reset(void) {
uint16_t never_reset_mask = 0x00;
- for(int i=0;i<MAX_SPI;i++) {
+ for (int i = 0; i < MAX_SPI; i++) {
if (!never_reset_spi[i]) {
- reserved_spi[i] = 0x00;
+ reserved_spi[i] = false;
} else {
- never_reset_mask |= 1<<i;
+ never_reset_mask |= 1 << i;
}
}
spi_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
@@ -76,42 +104,84 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
//match pins to SPI objects
SPI_TypeDef * SPIx;
- uint8_t sck_len = sizeof(mcu_spi_sck_list)/sizeof(*mcu_spi_sck_list);
- uint8_t mosi_len = sizeof(mcu_spi_mosi_list)/sizeof(*mcu_spi_mosi_list);
- uint8_t miso_len = sizeof(mcu_spi_miso_list)/sizeof(*mcu_spi_miso_list);
-
+ uint8_t sck_len = MP_ARRAY_SIZE(mcu_spi_sck_list);
+ uint8_t mosi_len = MP_ARRAY_SIZE(mcu_spi_mosi_list);
+ uint8_t miso_len = MP_ARRAY_SIZE(mcu_spi_miso_list);
bool spi_taken = false;
- //sck
- for(uint i=0; i<sck_len;i++) {
+
+ //SCK is not optional. MOSI and MISO are
+ for (uint i = 0; i < sck_len; i++) {
if (mcu_spi_sck_list[i].pin == sck) {
- //mosi
- for(uint j=0; j<mosi_len;j++) {
- if (mcu_spi_mosi_list[j].pin == mosi) {
- //miso
- for(uint k=0; k<miso_len;k++) {
- if ((mcu_spi_miso_list[k].pin == miso) //everything needs the same index
- && (mcu_spi_sck_list[i].spi_index == mcu_spi_mosi_list[j].spi_index)
- && (mcu_spi_sck_list[i].spi_index == mcu_spi_miso_list[k].spi_index)) {
- //keep looking if the SPI is taken, edge case
- if(reserved_spi[mcu_spi_sck_list[i].spi_index-1]) {
- spi_taken = true;
- continue;
+ //if both MOSI and MISO exist, loop search normally
+ if ((mosi != mp_const_none) && (miso != mp_const_none)) {
+ //MOSI
+ for (uint j = 0; j < mosi_len; j++) {
+ if (mcu_spi_mosi_list[j].pin == mosi) {
+ //MISO
+ for (uint k = 0; k < miso_len; k++) {
+ if ((mcu_spi_miso_list[k].pin == miso) //everything needs the same index
+ && (mcu_spi_sck_list[i].spi_index == mcu_spi_mosi_list[j].spi_index)
+ && (mcu_spi_sck_list[i].spi_index == mcu_spi_miso_list[k].spi_index)) {
+ //keep looking if the SPI is taken, edge case
+ if (reserved_spi[mcu_spi_sck_list[i].spi_index - 1]) {
+ spi_taken = true;
+ continue;
+ }
+ //store pins if not
+ self->sck = &mcu_spi_sck_list[i];
+ self->mosi = &mcu_spi_mosi_list[j];
+ self->miso = &mcu_spi_miso_list[k];
+ break;
}
- //store pins if not
- self->sck = &mcu_spi_sck_list[i];
- self->mosi = &mcu_spi_mosi_list[j];
- self->miso = &mcu_spi_miso_list[k];
- break;
- }
- }
+ }
+ }
}
+ // if just MISO, reduce search
+ } else if (miso != mp_const_none) {
+ for (uint j = 0; j < miso_len; j++) {
+ if ((mcu_spi_miso_list[j].pin == miso) //only SCK and MISO need the same index
+ && (mcu_spi_sck_list[i].spi_index == mcu_spi_miso_list[j].spi_index)) {
+ //keep looking if the SPI is taken, edge case
+ if (reserved_spi[mcu_spi_sck_list[i].spi_index - 1]) {
+ spi_taken = true;
+ continue;
+ }
+ //store pins if not
+ self->sck = &mcu_spi_sck_list[i];
+ self->mosi = NULL;
+ self->miso = &mcu_spi_miso_list[j];
+ break;
+ }
+ }
+ // if just MOSI, reduce search
+ } else if (mosi != mp_const_none) {
+ for (uint j = 0; j < mosi_len; j++) {
+ if ((mcu_spi_mosi_list[j].pin == mosi) //only SCK and MOSI need the same index
+ && (mcu_spi_sck_list[i].spi_index == mcu_spi_mosi_list[j].spi_index)) {
+ //keep looking if the SPI is taken, edge case
+ if (reserved_spi[mcu_spi_sck_list[i].spi_index - 1]) {
+ spi_taken = true;
+ continue;
+ }
+ //store pins if not
+ self->sck = &mcu_spi_sck_list[i];
+ self->mosi = &mcu_spi_mosi_list[j];
+ self->miso = NULL;
+ break;
+ }
+ }
+ } else {
+ //throw an error immediately
+ mp_raise_ValueError(translate("Must provide MISO or MOSI pin"));
}
}
}
//handle typedef selection, errors
- if(self->sck!=NULL && self->mosi!=NULL && self->miso!=NULL ) {
- SPIx = mcu_spi_banks[self->sck->spi_index-1];
+ if ( (self->sck != NULL && self->mosi != NULL && self->miso != NULL) ||
+ (self->sck != NULL && self->mosi != NULL && miso == mp_const_none) ||
+ (self->sck != NULL && self->miso != NULL && mosi == mp_const_none)) {
+ SPIx = mcu_spi_banks[self->sck->spi_index - 1];
} else {
if (spi_taken) {
mp_raise_ValueError(translate("Hardware busy, try alternative pins"));
@@ -129,26 +199,31 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
GPIO_InitStruct.Alternate = self->sck->altfn_index;
HAL_GPIO_Init(pin_port(sck->port), &GPIO_InitStruct);
- GPIO_InitStruct.Pin = pin_mask(mosi->number);
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.Alternate = self->mosi->altfn_index;
- HAL_GPIO_Init(pin_port(mosi->port), &GPIO_InitStruct);
+ if (self->mosi != NULL) {
+ GPIO_InitStruct.Pin = pin_mask(mosi->number);
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = self->mosi->altfn_index;
+ HAL_GPIO_Init(pin_port(mosi->port), &GPIO_InitStruct);
+ }
- GPIO_InitStruct.Pin = pin_mask(miso->number);
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.Alternate = self->miso->altfn_index;
- HAL_GPIO_Init(pin_port(miso->port), &GPIO_InitStruct);
+ if (self->miso != NULL) {
+ GPIO_InitStruct.Pin = pin_mask(miso->number);
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = self->miso->altfn_index;
+ HAL_GPIO_Init(pin_port(miso->port), &GPIO_InitStruct);
+ }
- spi_clock_enable(1<<(self->sck->spi_index - 1));
+ spi_clock_enable(1 << (self->sck->spi_index - 1));
reserved_spi[self->sck->spi_index - 1] = true;
self->handle.Instance = SPIx;
self->handle.Init.Mode = SPI_MODE_MASTER;
- self->handle.Init.Direction = SPI_DIRECTION_2LINES;
+ // Direction change only required for RX-only, see RefMan RM0090:884
+ self->handle.Init.Direction = (self->mosi == NULL) ? SPI_CR1_RXONLY : SPI_DIRECTION_2LINES;
self->handle.Init.DataSize = SPI_DATASIZE_8BIT;
self->handle.Init.CLKPolarity = SPI_POLARITY_LOW;
self->handle.Init.CLKPhase = SPI_PHASE_1EDGE;
@@ -162,24 +237,32 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
{
mp_raise_ValueError(translate("SPI Init Error"));
}
- self->baudrate = (get_busclock(SPIx)/16);
+ self->baudrate = (get_busclock(SPIx) / 16);
self->prescaler = 16;
self->polarity = 0;
self->phase = 0;
self->bits = 8;
claim_pin(sck);
- claim_pin(mosi);
- claim_pin(miso);
+ if (self->mosi != NULL) {
+ claim_pin(mosi);
+ }
+ if (self->miso != NULL) {
+ claim_pin(miso);
+ }
}
void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) {
- for(size_t i = 0 ; i < MP_ARRAY_SIZE(mcu_spi_banks); i++) {
+ for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_spi_banks); i++) {
if (mcu_spi_banks[i] == self->handle.Instance) {
never_reset_spi[i] = true;
never_reset_pin_number(self->sck->pin->port, self->sck->pin->number);
- never_reset_pin_number(self->mosi->pin->port, self->mosi->pin->number);
- never_reset_pin_number(self->miso->pin->port, self->miso->pin->number);
+ if (self->mosi != NULL) {
+ never_reset_pin_number(self->mosi->pin->port, self->mosi->pin->number);
+ }
+ if (self->miso != NULL) {
+ never_reset_pin_number(self->miso->pin->port, self->miso->pin->number);
+ }
break;
}
}
@@ -190,49 +273,32 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) {
}
void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
+ if (common_hal_busio_spi_deinited(self)) {
+ return;
+ }
spi_clock_disable(1<<(self->sck->spi_index - 1));
reserved_spi[self->sck->spi_index - 1] = false;
never_reset_spi[self->sck->spi_index - 1] = false;
reset_pin_number(self->sck->pin->port,self->sck->pin->number);
- reset_pin_number(self->mosi->pin->port,self->mosi->pin->number);
- reset_pin_number(self->miso->pin->port,self->miso->pin->number);
+ if (self->mosi != NULL) {
+ reset_pin_number(self->mosi->pin->port,self->mosi->pin->number);
+ }
+ if (self->miso != NULL) {
+ reset_pin_number(self->miso->pin->port,self->miso->pin->number);
+ }
self->sck = mp_const_none;
self->mosi = mp_const_none;
self->miso = mp_const_none;
}
-STATIC uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t * prescaler, uint32_t busclock) {
- static const uint32_t baud_map[8][2] = {
- {2,SPI_BAUDRATEPRESCALER_2},
- {4,SPI_BAUDRATEPRESCALER_4},
- {8,SPI_BAUDRATEPRESCALER_8},
- {16,SPI_BAUDRATEPRESCALER_16},
- {32,SPI_BAUDRATEPRESCALER_32},
- {64,SPI_BAUDRATEPRESCALER_64},
- {128,SPI_BAUDRATEPRESCALER_128},
- {256,SPI_BAUDRATEPRESCALER_256}
- };
- size_t i = 0;
- uint16_t divisor;
- do {
- divisor = baud_map[i][0];
- if (baudrate >= (busclock/divisor)) {
- *prescaler = divisor;
- return baud_map[i][1];
- }
- i++;
- } while (divisor != 256);
- //only gets here if requested baud is lower than minimum
- *prescaler = 256;
- return SPI_BAUDRATEPRESCALER_256;
-}
-
bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) {
//This resets the SPI, so check before updating it redundantly
if (baudrate == self->baudrate && polarity== self->polarity
- && phase == self->phase && bits == self->bits) return true;
+ && phase == self->phase && bits == self->bits) {
+ return true;
+ }
//Deinit SPI
HAL_SPI_DeInit(&self->handle);
@@ -243,13 +309,6 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
self->handle.Init.BaudRatePrescaler = stm32_baud_to_spi_div(baudrate, &self->prescaler,
get_busclock(self->handle.Instance));
- self->handle.Init.Mode = SPI_MODE_MASTER;
- self->handle.Init.Direction = SPI_DIRECTION_2LINES;
- self->handle.Init.NSS = SPI_NSS_SOFT;
- self->handle.Init.FirstBit = SPI_FIRSTBIT_MSB;
- self->handle.Init.TIMode = SPI_TIMODE_DISABLE;
- self->handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
- self->handle.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&self->handle) != HAL_OK)
{
@@ -292,18 +351,27 @@ void common_hal_busio_spi_unlock(busio_spi_obj_t *self) {
bool common_hal_busio_spi_write(busio_spi_obj_t *self,
const uint8_t *data, size_t len) {
+ if (self->mosi == NULL) {
+ mp_raise_ValueError(translate("No MOSI Pin"));
+ }
HAL_StatusTypeDef result = HAL_SPI_Transmit (&self->handle, (uint8_t *)data, (uint16_t)len, HAL_MAX_DELAY);
return result == HAL_OK;
}
bool common_hal_busio_spi_read(busio_spi_obj_t *self,
uint8_t *data, size_t len, uint8_t write_value) {
+ if (self->miso == NULL) {
+ mp_raise_ValueError(translate("No MISO Pin"));
+ }
HAL_StatusTypeDef result = HAL_SPI_Receive (&self->handle, data, (uint16_t)len, HAL_MAX_DELAY);
return result == HAL_OK;
}
bool common_hal_busio_spi_transfer(busio_spi_obj_t *self,
uint8_t *data_out, uint8_t *data_in, size_t len) {
+ if (self->miso == NULL || self->mosi == NULL) {
+ mp_raise_ValueError(translate("Missing MISO or MOSI Pin"));
+ }
HAL_StatusTypeDef result = HAL_SPI_TransmitReceive (&self->handle,
data_out, data_in, (uint16_t)len,HAL_MAX_DELAY);
return result == HAL_OK;
@@ -325,42 +393,78 @@ uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t* self) {
STATIC void spi_clock_enable(uint8_t mask) {
#ifdef SPI1
- if (mask & 1<<0) __HAL_RCC_SPI1_CLK_ENABLE();
+ if (mask & (1 << 0)) {
+ __HAL_RCC_SPI1_CLK_ENABLE();
+ }
#endif
#ifdef SPI2
- if (mask & 1<<1) __HAL_RCC_SPI2_CLK_ENABLE();
+ if (mask & (1 << 1)) {
+ __HAL_RCC_SPI2_CLK_ENABLE();
+ }
#endif
#ifdef SPI3
- if (mask & 1<<2) __HAL_RCC_SPI3_CLK_ENABLE();
+ if (mask & (1 << 2)) {
+ __HAL_RCC_SPI3_CLK_ENABLE();
+ }
#endif
#ifdef SPI4
- if (mask & 1<<3) __HAL_RCC_SPI4_CLK_ENABLE();
+ if (mask & (1 << 3)) {
+ __HAL_RCC_SPI4_CLK_ENABLE();
+ }
#endif
#ifdef SPI5
- if (mask & 1<<4) __HAL_RCC_SPI5_CLK_ENABLE();
+ if (mask & (1 << 4)) {
+ __HAL_RCC_SPI5_CLK_ENABLE();
+ }
#endif
#ifdef SPI6
- if (mask & 1<<5) __HAL_RCC_SPI6_CLK_ENABLE();
+ if (mask & (1 << 5)) {
+ __HAL_RCC_SPI6_CLK_ENABLE();
+ }
#endif
}
STATIC void spi_clock_disable(uint8_t mask) {
#ifdef SPI1
- if (mask & 1<<0) __HAL_RCC_SPI1_CLK_DISABLE();
+ if (mask & (1 << 0)) {
+ __HAL_RCC_SPI1_CLK_DISABLE();
+ __HAL_RCC_SPI1_FORCE_RESET();
+ __HAL_RCC_SPI1_RELEASE_RESET();
+ }
#endif
#ifdef SPI2
- if (mask & 1<<1) __HAL_RCC_SPI2_CLK_DISABLE();
+ if (mask & (1 << 1)) {
+ __HAL_RCC_SPI2_CLK_DISABLE();
+ __HAL_RCC_SPI2_FORCE_RESET();
+ __HAL_RCC_SPI2_RELEASE_RESET();
+ }
#endif
#ifdef SPI3
- if (mask & 1<<2) __HAL_RCC_SPI3_CLK_DISABLE();
+ if (mask & (1 << 2)) {
+ __HAL_RCC_SPI3_CLK_DISABLE();
+ __HAL_RCC_SPI3_FORCE_RESET();
+ __HAL_RCC_SPI3_RELEASE_RESET();
+ }
#endif
#ifdef SPI4
- if (mask & 1<<3) __HAL_RCC_SPI4_CLK_DISABLE();
+ if (mask & (1 << 3)) {
+ __HAL_RCC_SPI4_CLK_DISABLE();
+ __HAL_RCC_SPI4_FORCE_RESET();
+ __HAL_RCC_SPI4_RELEASE_RESET();
+ }
#endif
#ifdef SPI5
- if (mask & 1<<4) __HAL_RCC_SPI5_CLK_DISABLE();
+ if (mask & (1 << 4)) {
+ __HAL_RCC_SPI5_CLK_DISABLE();
+ __HAL_RCC_SPI5_FORCE_RESET();
+ __HAL_RCC_SPI5_RELEASE_RESET();
+ }
#endif
#ifdef SPI6
- if (mask & 1<<5) __HAL_RCC_SPI6_CLK_DISABLE();
+ if (mask & (1 << 5)) {
+ __HAL_RCC_SPI6_CLK_DISABLE();
+ __HAL_RCC_SPI6_FORCE_RESET();
+ __HAL_RCC_SPI6_RELEASE_RESET();
+ }
#endif
}
diff --git a/ports/stm32f4/common-hal/busio/UART.c b/ports/stm32f4/common-hal/busio/UART.c
index aa792dae1..3c1909259 100644
--- a/ports/stm32f4/common-hal/busio/UART.c
+++ b/ports/stm32f4/common-hal/busio/UART.c
@@ -40,6 +40,7 @@
#define ALL_UARTS 0xFFFF
+//arrays use 0 based numbering: UART1 is stored at index 0
STATIC bool reserved_uart[MAX_UART];
int errflag; //Used to restart read halts
@@ -47,14 +48,6 @@ STATIC void uart_clock_enable(uint16_t mask);
STATIC void uart_clock_disable(uint16_t mask);
STATIC void uart_assign_irq(busio_uart_obj_t* self, USART_TypeDef* USARTx);
-void uart_reset(void) {
- for (uint8_t i = 0; i < MAX_UART; i++) {
- reserved_uart[i] = false;
- MP_STATE_PORT(cpy_uart_obj_all)[i] = NULL;
- }
- uart_clock_disable(ALL_UARTS);
-}
-
STATIC USART_TypeDef * assign_uart_or_throw(busio_uart_obj_t* self, bool pin_eval,
int uart_index, bool uart_taken) {
if (pin_eval) {
@@ -70,19 +63,33 @@ STATIC USART_TypeDef * assign_uart_or_throw(busio_uart_obj_t* self, bool pin_eva
}
}
-void common_hal_busio_uart_construct(busio_uart_obj_t* self,
- const mcu_pin_obj_t* tx, const mcu_pin_obj_t* rx, uint32_t baudrate,
- uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
- uint16_t receiver_buffer_size) {
+void uart_reset(void) {
+ for (uint8_t i = 0; i < MAX_UART; i++) {
+ reserved_uart[i] = false;
+ MP_STATE_PORT(cpy_uart_obj_all)[i] = NULL;
+ }
+ uart_clock_disable(ALL_UARTS);
+}
+
+void common_hal_busio_uart_construct(busio_uart_obj_t *self,
+ const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx,
+ const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
+ const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
+ uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
+ mp_float_t timeout, uint16_t receiver_buffer_size) {
//match pins to UART objects
USART_TypeDef * USARTx;
- uint8_t tx_len = sizeof(mcu_uart_tx_list)/sizeof(*mcu_uart_tx_list);
- uint8_t rx_len = sizeof(mcu_uart_rx_list)/sizeof(*mcu_uart_rx_list);
+ uint8_t tx_len = MP_ARRAY_SIZE(mcu_uart_tx_list);
+ uint8_t rx_len = MP_ARRAY_SIZE(mcu_uart_rx_list);
bool uart_taken = false;
uint8_t uart_index = 0; //origin 0 corrected
+ if ((rts != mp_const_none) || (cts != mp_const_none) || (rs485_dir != mp_const_none) || (rs485_invert == true)) {
+ mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device"));
+ }
+
//Can have both pins, or either
if ((tx != mp_const_none) && (rx != mp_const_none)) {
//normal find loop if both pins exist
@@ -567,33 +574,53 @@ STATIC void uart_clock_disable(uint16_t mask) {
STATIC void uart_assign_irq(busio_uart_obj_t *self, USART_TypeDef * USARTx) {
#ifdef USART1
- if (USARTx == USART1) self->irq = USART1_IRQn;
+ if (USARTx == USART1) {
+ self->irq = USART1_IRQn;
+ }
#endif
#ifdef USART2
- if (USARTx == USART2) self->irq = USART2_IRQn;
+ if (USARTx == USART2) {
+ self->irq = USART2_IRQn;
+ }
#endif
#ifdef USART3
- if (USARTx == USART3) self->irq = USART3_IRQn;
+ if (USARTx == USART3) {
+ self->irq = USART3_IRQn;
+ }
#endif
#ifdef UART4
- if (USARTx == UART4) self->irq = UART4_IRQn;
+ if (USARTx == UART4) {
+ self->irq = UART4_IRQn;
+ }
#endif
#ifdef UART5
- if (USARTx == UART5) self->irq = UART5_IRQn;
+ if (USARTx == UART5) {
+ self->irq = UART5_IRQn;
+ }
#endif
#ifdef USART6
- if (USARTx == USART6) self->irq = USART6_IRQn;
+ if (USARTx == USART6) {
+ self->irq = USART6_IRQn;
+ }
#endif
#ifdef UART7
- if (USARTx == UART7) self->irq = UART7_IRQn;
+ if (USARTx == UART7) {
+ self->irq = UART7_IRQn;
+ }
#endif
#ifdef UART8
- if (USARTx == UART8) self->irq = UART8_IRQn;
+ if (USARTx == UART8) {
+ self->irq = UART8_IRQn;
+ }
#endif
#ifdef UART9
- if (USARTx == UART9) self->irq = UART9_IRQn;
+ if (USARTx == UART9) {
+ self->irq = UART9_IRQn;
+ }
#endif
#ifdef UART10
- if (USARTx == UART10) self->irq = UART10_IRQn;
+ if (USARTx == UART10) {
+ self->irq = UART10_IRQn;
+ }
#endif
}
diff --git a/ports/stm32f4/common-hal/microcontroller/Pin.c b/ports/stm32f4/common-hal/microcontroller/Pin.c
index 615e48358..1d4d45b97 100644
--- a/ports/stm32f4/common-hal/microcontroller/Pin.c
+++ b/ports/stm32f4/common-hal/microcontroller/Pin.c
@@ -76,6 +76,7 @@ void reset_pin_number(uint8_t pin_port, uint8_t pin_number) {
}
// Clear claimed bit & reset
claimed_pins[pin_port] &= ~(1<<pin_number);
+ never_reset_pins[pin_port] &= ~(1<<pin_number);
HAL_GPIO_DeInit(ports[pin_port], 1<<pin_number);
#ifdef MICROPY_HW_NEOPIXEL
diff --git a/ports/stm32f4/common-hal/microcontroller/Processor.c b/ports/stm32f4/common-hal/microcontroller/Processor.c
index 3ab746685..324659cef 100644
--- a/ports/stm32f4/common-hal/microcontroller/Processor.c
+++ b/ports/stm32f4/common-hal/microcontroller/Processor.c
@@ -3,7 +3,6 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Dan Halbert for Adafruit Industries
* Copyright (c) 2019 Lucian Copeland for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -34,12 +33,87 @@
#define STM32_UUID ((uint32_t *)0x1FFF7A10)
+//Factory calibration locations
+#define ADC_CAL_ADDRESS (0x1fff7a2a)
+#define ADC_CAL1 ((uint16_t*)(ADC_CAL_ADDRESS + 2))
+#define ADC_CAL2 ((uint16_t*)(ADC_CAL_ADDRESS + 4))
+#define VREFIN_CAL ((uint16_t *)ADC_CAL_ADDRESS)
+
+// correction factor for reference value
+STATIC volatile float adc_refcor = 1.0f;
+
+STATIC void set_adc_params(ADC_HandleTypeDef *AdcHandle) {
+ AdcHandle->Instance = ADC1;
+ AdcHandle->Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
+ AdcHandle->Init.Resolution = ADC_RESOLUTION_12B;
+ AdcHandle->Init.ScanConvMode = DISABLE;
+ AdcHandle->Init.ContinuousConvMode = DISABLE;
+ AdcHandle->Init.DiscontinuousConvMode = DISABLE;
+ AdcHandle->Init.NbrOfDiscConversion = 0;
+ AdcHandle->Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
+ AdcHandle->Init.ExternalTrigConv = ADC_SOFTWARE_START;
+ AdcHandle->Init.DataAlign = ADC_DATAALIGN_RIGHT;
+ AdcHandle->Init.NbrOfConversion = 1;
+ AdcHandle->Init.DMAContinuousRequests = DISABLE;
+ AdcHandle->Init.EOCSelection = ADC_EOC_SINGLE_CONV;
+}
+
float common_hal_mcu_processor_get_temperature(void) {
- return NAN;
+ __HAL_RCC_ADC1_CLK_ENABLE();
+
+ //HAL Implementation
+ ADC_HandleTypeDef AdcHandle;
+ ADC_ChannelConfTypeDef sConfig;
+ set_adc_params(&AdcHandle);
+ HAL_ADC_Init(&AdcHandle);
+
+ ADC->CCR |= ADC_CCR_TSVREFE;
+ ADC->CCR &= ~ADC_CCR_VBATE; // If this somehow got turned on, it'll return bad values.
+
+ sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; //either 16 or 18, depending on chip
+ sConfig.Rank = 1;
+ sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; // Temp sensor likes 10us minimum
+ HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
+
+ HAL_ADC_Start(&AdcHandle);
+ if (HAL_ADC_PollForConversion(&AdcHandle,1) != HAL_OK) {
+ mp_raise_RuntimeError(translate("Temperature read timed out"));
+ }
+ uint32_t value = (uint32_t)HAL_ADC_GetValue(&AdcHandle);
+ HAL_ADC_Stop(&AdcHandle);
+
+ //There's no F4 specific appnote for this but it works the same as the L1 in AN3964
+ float core_temp_avg_slope = (*ADC_CAL2 - *ADC_CAL1) / 80.0;
+ return (((float)value * adc_refcor - *ADC_CAL1) / core_temp_avg_slope) + 30.0f;
}
float common_hal_mcu_processor_get_voltage(void) {
- return NAN;
+ __HAL_RCC_ADC1_CLK_ENABLE();
+
+ //HAL Implementation
+ ADC_HandleTypeDef AdcHandle;
+ ADC_ChannelConfTypeDef sConfig;
+ set_adc_params(&AdcHandle);
+ HAL_ADC_Init(&AdcHandle);
+
+ ADC->CCR |= ADC_CCR_TSVREFE;
+
+ sConfig.Channel = ADC_CHANNEL_VREFINT;
+ sConfig.Rank = 1;
+ sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
+ HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
+
+ HAL_ADC_Start(&AdcHandle);
+ if (HAL_ADC_PollForConversion(&AdcHandle,1) != HAL_OK) {
+ mp_raise_RuntimeError(translate("Voltage read timed out"));
+ }
+ uint32_t value = (uint32_t)HAL_ADC_GetValue(&AdcHandle);
+ HAL_ADC_Stop(&AdcHandle);
+
+ //This value could be used to actively correct ADC values.
+ adc_refcor = ((float)(*VREFIN_CAL)) / ((float)value);
+
+ return adc_refcor * 3.3f;
}
uint32_t common_hal_mcu_processor_get_frequency(void) {
diff --git a/ports/stm32f4/common-hal/microcontroller/__init__.c b/ports/stm32f4/common-hal/microcontroller/__init__.c
index 16cc056c1..0c680eb05 100644
--- a/ports/stm32f4/common-hal/microcontroller/__init__.c
+++ b/ports/stm32f4/common-hal/microcontroller/__init__.c
@@ -169,7 +169,7 @@ STATIC const mp_rom_map_elem_t mcu_pin_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_PE15), MP_ROM_PTR(&pin_PE15) },
#endif
{ MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) },
-#if MCU_PACKAGE == 144
+#if MCU_PACKAGE == 144 || defined STM32F405xx
{ MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) },
#endif
{ MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) },
diff --git a/ports/stm32f4/common-hal/pulseio/PWMOut.c b/ports/stm32f4/common-hal/pulseio/PWMOut.c
index 16b1b5b89..50bacbb51 100644
--- a/ports/stm32f4/common-hal/pulseio/PWMOut.c
+++ b/ports/stm32f4/common-hal/pulseio/PWMOut.c
@@ -69,15 +69,15 @@ STATIC uint32_t timer_get_source_freq(uint32_t tim_id) {
STATIC uint32_t timer_get_internal_duty(uint16_t duty, uint32_t period) {
//duty cycle is duty/0xFFFF fraction x (number of pulses per period)
- return (duty*period)/((1<<16)-1);
+ return (duty*period) / ((1 << 16) - 1);
}
STATIC void timer_get_optimal_divisors(uint32_t*period, uint32_t*prescaler,
uint32_t frequency, uint32_t source_freq) {
//Find the largest possible period supported by this frequency
- for (int i=0; i<(1 << 16);i++) {
- *period = source_freq/(i*frequency);
- if (*period < (1 << 16) && *period>=2) {
+ for (int i = 0; i < (1 << 16); i++) {
+ *period = source_freq / (i * frequency);
+ if (*period < (1 << 16) && *period >= 2) {
*prescaler = i;
break;
}
@@ -89,59 +89,40 @@ STATIC void timer_get_optimal_divisors(uint32_t*period, uint32_t*prescaler,
void pwmout_reset(void) {
uint16_t never_reset_mask = 0x00;
- for(int i=0;i<TIM_BANK_ARRAY_LEN;i++) {
+ for (int i = 0; i < TIM_BANK_ARRAY_LEN; i++) {
if (!never_reset_tim[i]) {
reserved_tim[i] = 0x00;
tim_frequencies[i] = 0x00;
} else {
- never_reset_mask |= 1<<i;
+ never_reset_mask |= 1 << i;
}
}
tim_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
}
-void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) {
- for(size_t i = 0 ; i < TIM_BANK_ARRAY_LEN; i++) {
- if (mcu_tim_banks[i] == self->handle.Instance) {
- never_reset_tim[i] = true;
- never_reset_pin_number(self->tim->pin->port, self->tim->pin->number);
- break;
- }
- }
-}
-
-void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) {
- for(size_t i = 0 ; i < TIM_BANK_ARRAY_LEN; i++) {
- if (mcu_tim_banks[i] == self->handle.Instance) {
- never_reset_tim[i] = false;
- break;
- }
- }
-}
-
pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
const mcu_pin_obj_t* pin,
uint16_t duty,
uint32_t frequency,
bool variable_frequency) {
TIM_TypeDef * TIMx;
- uint8_t tim_num = sizeof(mcu_tim_pin_list)/sizeof(*mcu_tim_pin_list);
+ uint8_t tim_num = MP_ARRAY_SIZE(mcu_tim_pin_list);
bool tim_chan_taken = false;
bool tim_taken_f_mismatch = false;
bool var_freq_mismatch = false;
bool first_time_setup = true;
- for(uint i = 0; i < tim_num; i++) {
- mcu_tim_pin_obj_t l_tim = mcu_tim_pin_list[i];
- uint8_t l_tim_index = l_tim.tim_index-1;
- uint8_t l_tim_channel = l_tim.channel_index-1;
+ for (uint i = 0; i < tim_num; i++) {
+ const mcu_tim_pin_obj_t * l_tim = &mcu_tim_pin_list[i];
+ uint8_t l_tim_index = l_tim->tim_index - 1;
+ uint8_t l_tim_channel = l_tim->channel_index - 1;
//if pin is same
- if (l_tim.pin == pin) {
+ if (l_tim->pin == pin) {
//check if the timer has a channel active
if (reserved_tim[l_tim_index] != 0) {
//is it the same channel? (or all channels reserved by a var-freq)
- if (reserved_tim[l_tim_index] & 1<<(l_tim_channel)) {
+ if (reserved_tim[l_tim_index] & 1 << (l_tim_channel)) {
tim_chan_taken = true;
continue; //keep looking, might be another viable option
}
@@ -158,27 +139,27 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
first_time_setup = false; //skip setting up the timer
}
//No problems taken, so set it up
- self->tim = &l_tim;
+ self->tim = l_tim;
break;
}
}
//handle valid/invalid timer instance
- if (self->tim!=NULL) {
+ if (self->tim != NULL) {
//create instance
- TIMx = mcu_tim_banks[self->tim->tim_index-1];
+ TIMx = mcu_tim_banks[self->tim->tim_index - 1];
//reserve timer/channel
if (variable_frequency) {
- reserved_tim[self->tim->tim_index-1] = 0x0F;
+ reserved_tim[self->tim->tim_index - 1] = 0x0F;
} else {
- reserved_tim[self->tim->tim_index-1] |= 1<<(self->tim->channel_index-1);
+ reserved_tim[self->tim->tim_index - 1] |= 1 << (self->tim->channel_index - 1);
}
- tim_frequencies[self->tim->tim_index-1] = frequency;
+ tim_frequencies[self->tim->tim_index - 1] = frequency;
} else { //no match found
if (tim_chan_taken) {
mp_raise_ValueError(translate("No more timers available on this pin."));
} else if (tim_taken_f_mismatch) {
- mp_raise_ValueError(translate("Frequency must be the same as as the existing PWMOut using this timer"));
+ mp_raise_ValueError(translate("Frequency must match existing PWMOut using this timer"));
} else if (var_freq_mismatch) {
mp_raise_ValueError(translate("Cannot vary frequency on a timer that is already in use"));
} else {
@@ -194,14 +175,15 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
GPIO_InitStruct.Alternate = self->tim->altfn_index;
HAL_GPIO_Init(pin_port(pin->port), &GPIO_InitStruct);
- tim_clock_enable(1<<(self->tim->tim_index - 1));
+ tim_clock_enable(1 << (self->tim->tim_index - 1));
//translate channel into handle value
self->channel = 4 * (self->tim->channel_index - 1);
uint32_t prescaler = 0; //prescaler is 15 bit
uint32_t period = 0; //period is 16 bit
- timer_get_optimal_divisors(&period, &prescaler,frequency,timer_get_source_freq(self->tim->tim_index));
+ timer_get_optimal_divisors(&period, &prescaler, frequency,
+ timer_get_source_freq(self->tim->tim_index));
//Timer init
self->handle.Instance = TIMx;
@@ -221,11 +203,8 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
//Channel/PWM init
self->chan_handle.OCMode = TIM_OCMODE_PWM1;
self->chan_handle.Pulse = timer_get_internal_duty(duty, period);
- self->chan_handle.OCPolarity = TIM_OCPOLARITY_LOW;
+ self->chan_handle.OCPolarity = TIM_OCPOLARITY_HIGH;
self->chan_handle.OCFastMode = TIM_OCFAST_DISABLE;
- self->chan_handle.OCNPolarity = TIM_OCNPOLARITY_LOW; // needed for TIM1 and TIM8
- self->chan_handle.OCIdleState = TIM_OCIDLESTATE_SET; // needed for TIM1 and TIM8
- self->chan_handle.OCNIdleState = TIM_OCNIDLESTATE_SET; // needed for TIM1 and TIM8
if (HAL_TIM_PWM_ConfigChannel(&self->handle, &self->chan_handle, self->channel) != HAL_OK) {
mp_raise_ValueError(translate("Could not initialize channel"));
}
@@ -241,6 +220,25 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
return PWMOUT_OK;
}
+void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) {
+ for (size_t i = 0; i < TIM_BANK_ARRAY_LEN; i++) {
+ if (mcu_tim_banks[i] == self->handle.Instance) {
+ never_reset_tim[i] = true;
+ never_reset_pin_number(self->tim->pin->port, self->tim->pin->number);
+ break;
+ }
+ }
+}
+
+void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) {
+ for(size_t i = 0; i < TIM_BANK_ARRAY_LEN; i++) {
+ if (mcu_tim_banks[i] == self->handle.Instance) {
+ never_reset_tim[i] = false;
+ break;
+ }
+ }
+}
+
bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) {
return self->tim == mp_const_none;
}
@@ -251,18 +249,18 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
}
//var freq shuts down entire timer, others just their channel
if (self->variable_frequency) {
- reserved_tim[self->tim->tim_index-1] = 0x00;
+ reserved_tim[self->tim->tim_index - 1] = 0x00;
} else {
- reserved_tim[self->tim->tim_index-1] &= ~(1<<self->tim->channel_index);
+ reserved_tim[self->tim->tim_index - 1] &= ~(1 << self->tim->channel_index);
HAL_TIM_PWM_Stop(&self->handle, self->channel);
}
reset_pin_number(self->tim->pin->port,self->tim->pin->number);
self->tim = mp_const_none;
//if reserved timer has no active channels, we can disable it
- if (!reserved_tim[self->tim->tim_index-1]) {
- tim_frequencies[self->tim->tim_index-1] = 0x00;
- tim_clock_disable(1<<(self->tim->tim_index-1));
+ if (!reserved_tim[self->tim->tim_index - 1]) {
+ tim_frequencies[self->tim->tim_index - 1] = 0x00;
+ tim_clock_disable(1 << (self->tim->tim_index - 1));
}
}
@@ -278,11 +276,14 @@ uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency) {
//don't halt setup for the same frequency
- if (frequency == self->frequency) return;
+ if (frequency == self->frequency) {
+ return;
+ }
uint32_t prescaler = 0;
uint32_t period = 0;
- timer_get_optimal_divisors(&period, &prescaler,frequency,timer_get_source_freq(self->tim->tim_index));
+ timer_get_optimal_divisors(&period, &prescaler, frequency,
+ timer_get_source_freq(self->tim->tim_index));
//shut down
HAL_TIM_PWM_Stop(&self->handle, self->channel);
@@ -305,7 +306,7 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_
mp_raise_ValueError(translate("Could not restart PWM"));
}
- tim_frequencies[self->tim->tim_index-1] = frequency;
+ tim_frequencies[self->tim->tim_index - 1] = frequency;
self->frequency = frequency;
self->period = period;
}
@@ -320,80 +321,128 @@ bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self
STATIC void tim_clock_enable(uint16_t mask) {
#ifdef TIM1
- if (mask & 1<<0) __HAL_RCC_TIM1_CLK_ENABLE();
+ if (mask & (1 << 0)) {
+ __HAL_RCC_TIM1_CLK_ENABLE();
+ }
#endif
#ifdef TIM2
- if (mask & 1<<1) __HAL_RCC_TIM2_CLK_ENABLE();
+ if (mask & (1 << 1)) {
+ __HAL_RCC_TIM2_CLK_ENABLE();
+ }
#endif
#ifdef TIM3
- if (mask & 1<<2) __HAL_RCC_TIM3_CLK_ENABLE();
+ if (mask & (1 << 2)) {
+ __HAL_RCC_TIM3_CLK_ENABLE();
+ }
#endif
#ifdef TIM4
- if (mask & 1<<3) __HAL_RCC_TIM4_CLK_ENABLE();
+ if (mask & (1 << 3)) {
+ __HAL_RCC_TIM4_CLK_ENABLE();
+ }
#endif
#ifdef TIM5
- if (mask & 1<<4) __HAL_RCC_TIM5_CLK_ENABLE();
+ if (mask & (1 << 4)) {
+ __HAL_RCC_TIM5_CLK_ENABLE();
+ }
#endif
//6 and 7 are reserved ADC timers
#ifdef TIM8
- if (mask & 1<<7) __HAL_RCC_TIM8_CLK_ENABLE();
+ if (mask & (1 << 7)) {
+ __HAL_RCC_TIM8_CLK_ENABLE();
+ }
#endif
#ifdef TIM9
- if (mask & 1<<8) __HAL_RCC_TIM9_CLK_ENABLE();
+ if (mask & (1 << 8)) {
+ __HAL_RCC_TIM9_CLK_ENABLE();
+ }
#endif
#ifdef TIM10
- if (mask & 1<<9) __HAL_RCC_TIM10_CLK_ENABLE();
+ if (mask & (1 << 9)) {
+ __HAL_RCC_TIM10_CLK_ENABLE();
+ }
#endif
#ifdef TIM11
- if (mask & 1<<10) __HAL_RCC_TIM11_CLK_ENABLE();
+ if (mask & (1 << 10)) {
+ __HAL_RCC_TIM11_CLK_ENABLE();
+ }
#endif
#ifdef TIM12
- if (mask & 1<<11) __HAL_RCC_TIM12_CLK_ENABLE();
+ if (mask & (1 << 11)) {
+ __HAL_RCC_TIM12_CLK_ENABLE();
+ }
#endif
#ifdef TIM13
- if (mask & 1<<12) __HAL_RCC_TIM13_CLK_ENABLE();
+ if (mask & (1 << 12)) {
+ __HAL_RCC_TIM13_CLK_ENABLE();
+ }
#endif
#ifdef TIM14
- if (mask & 1<<13) __HAL_RCC_TIM14_CLK_ENABLE();
+ if (mask & (1 << 13)) {
+ __HAL_RCC_TIM14_CLK_ENABLE();
+ }
#endif
}
STATIC void tim_clock_disable(uint16_t mask) {
#ifdef TIM1
- if (mask & 1<<0) __HAL_RCC_TIM1_CLK_DISABLE();
+ if (mask & (1 << 0)) {
+ __HAL_RCC_TIM1_CLK_DISABLE();
+ }
#endif
#ifdef TIM2
- if (mask & 1<<1) __HAL_RCC_TIM2_CLK_DISABLE();
+ if (mask & (1 << 1)) {
+ __HAL_RCC_TIM2_CLK_DISABLE();
+ }
#endif
#ifdef TIM3
- if (mask & 1<<2) __HAL_RCC_TIM3_CLK_DISABLE();
+ if (mask & (1 << 2)) {
+ __HAL_RCC_TIM3_CLK_DISABLE();
+ }
#endif
#ifdef TIM4
- if (mask & 1<<3) __HAL_RCC_TIM4_CLK_DISABLE();
+ if (mask & (1 << 3)) {
+ __HAL_RCC_TIM4_CLK_DISABLE();
+ }
#endif
#ifdef TIM5
- if (mask & 1<<4) __HAL_RCC_TIM5_CLK_DISABLE();
+ if (mask & (1 << 4)) {
+ __HAL_RCC_TIM5_CLK_DISABLE();
+ }
#endif
//6 and 7 are reserved ADC timers
#ifdef TIM8
- if (mask & 1<<7) __HAL_RCC_TIM8_CLK_DISABLE();
+ if (mask & (1 << 7)) {
+ __HAL_RCC_TIM8_CLK_DISABLE();
+ }
#endif
#ifdef TIM9
- if (mask & 1<<8) __HAL_RCC_TIM9_CLK_DISABLE();
+ if (mask & (1 << 8)) {
+ __HAL_RCC_TIM9_CLK_DISABLE();
+ }
#endif
#ifdef TIM10
- if (mask & 1<<9) __HAL_RCC_TIM10_CLK_DISABLE();
+ if (mask & (1 << 9)) {
+ __HAL_RCC_TIM10_CLK_DISABLE();
+ }
#endif
#ifdef TIM11
- if (mask & 1<<10) __HAL_RCC_TIM11_CLK_DISABLE();
+ if (mask & (1 << 10)) {
+ __HAL_RCC_TIM11_CLK_DISABLE();
+ }
#endif
#ifdef TIM12
- if (mask & 1<<11) __HAL_RCC_TIM12_CLK_DISABLE();
+ if (mask & (1 << 11)) {
+ __HAL_RCC_TIM12_CLK_DISABLE();
+ }
#endif
#ifdef TIM13
- if (mask & 1<<12) __HAL_RCC_TIM13_CLK_DISABLE();
+ if (mask & (1 << 12)) {
+ __HAL_RCC_TIM13_CLK_DISABLE();
+ }
#endif
#ifdef TIM14
- if (mask & 1<<13) __HAL_RCC_TIM14_CLK_DISABLE();
+ if (mask & (1 << 13)) {
+ __HAL_RCC_TIM14_CLK_DISABLE();
+ }
#endif
}
diff --git a/ports/stm32f4/common-hal/time/__init__.c b/ports/stm32f4/common-hal/time/__init__.c
index 976f519db..c85077868 100644
--- a/ports/stm32f4/common-hal/time/__init__.c
+++ b/ports/stm32f4/common-hal/time/__init__.c
@@ -32,6 +32,14 @@ uint64_t common_hal_time_monotonic(void) {
return supervisor_ticks_ms64();
}
+uint64_t common_hal_time_monotonic_ns(void) {
+ uint64_t ms;
+ uint32_t us_until_ms;
+ current_tick(&ms, &us_until_ms);
+ // us counts down.
+ return 1000 * (ms * 1000 + (1000 - us_until_ms));
+}
+
void common_hal_time_delay_ms(uint32_t delay) {
mp_hal_delay_ms(delay);
}
diff --git a/ports/stm32f4/mpconfigport.h b/ports/stm32f4/mpconfigport.h
index 7737bda8d..283984ea9 100644
--- a/ports/stm32f4/mpconfigport.h
+++ b/ports/stm32f4/mpconfigport.h
@@ -39,6 +39,17 @@
#include "py/circuitpy_mpconfig.h"
+//Board flags:
+#ifndef BOARD_OVERWRITE_SWD
+#define BOARD_OVERWRITE_SWD (0)
+#endif
+#ifndef BOARD_VTOR_DEFER
+#define BOARD_VTOR_DEFER (0)
+#endif
+#ifndef BOARD_NO_VBUS_SENSE
+#define BOARD_NO_VBUS_SENSE (0)
+#endif
+
#define MAX_UART 10 //how many UART are implemented
#define MICROPY_PORT_ROOT_POINTERS \
diff --git a/ports/stm32f4/mpconfigport.mk b/ports/stm32f4/mpconfigport.mk
index 42f390572..f214282cb 100644
--- a/ports/stm32f4/mpconfigport.mk
+++ b/ports/stm32f4/mpconfigport.mk
@@ -69,9 +69,7 @@ ifndef CIRCUITPY_DISPLAYIO
CIRCUITPY_DISPLAYIO = 1
endif
-ifndef MICROPY_CPYTHON_COMPAT
-MICROPY_CPYTHON_COMPAT = 1
-endif
+CFLAGS += -DMICROPY_CPYTHON_COMPAT=1
#ifeq ($(MCU_SUB_VARIANT), stm32f412zx)
#endif
diff --git a/ports/stm32f4/mphalport.c b/ports/stm32f4/mphalport.c
index f78e9c750..a3cf501c0 100644
--- a/ports/stm32f4/mphalport.c
+++ b/ports/stm32f4/mphalport.c
@@ -31,18 +31,15 @@
#include "py/mpstate.h"
#include "py/gc.h"
+#include "shared-bindings/microcontroller/__init__.h"
#include "supervisor/shared/tick.h"
+#include "stm32f4xx_hal.h"
-/*------------------------------------------------------------------*/
-/* delay
- *------------------------------------------------------------------*/
void mp_hal_delay_ms(mp_uint_t delay) {
uint64_t start_tick = supervisor_ticks_ms64();
uint64_t duration = 0;
while (duration < delay) {
- #ifdef MICROPY_VM_HOOK_LOOP
- MICROPY_VM_HOOK_LOOP
- #endif
+ RUN_BACKGROUND_TASKS;
// Check to see if we've been CTRL-Ced by autoreload or the user.
if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) ||
MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
@@ -52,3 +49,15 @@ void mp_hal_delay_ms(mp_uint_t delay) {
// TODO(tannewt): Go to sleep for a little while while we wait.
}
}
+
+void mp_hal_delay_us(mp_uint_t delay) {
+ common_hal_mcu_delay_us(delay);
+}
+
+void mp_hal_disable_all_interrupts(void) {
+ common_hal_mcu_disable_interrupts();
+}
+
+void mp_hal_enable_all_interrupts(void) {
+ common_hal_mcu_enable_interrupts();
+}
diff --git a/ports/stm32f4/mphalport.h b/ports/stm32f4/mphalport.h
index df2f0ca65..b392cb0f8 100644
--- a/ports/stm32f4/mphalport.h
+++ b/ports/stm32f4/mphalport.h
@@ -24,20 +24,28 @@
* THE SOFTWARE.
*/
-#ifndef __STM32F4_HAL
-#define __STM32F4_HAL
+#ifndef MICROPY_INCLUDED_STM32F4_MPHALPORT_H
+#define MICROPY_INCLUDED_STM32F4_MPHALPORT_H
-#include <stdbool.h>
-#include <stdint.h>
+#include "py/obj.h"
+
+#include "lib/oofatfs/ff.h"
-#include "lib/utils/interrupt_char.h"
-#include "py/mpconfig.h"
#include "supervisor/shared/tick.h"
+// Global millisecond tick count (driven by SysTick interrupt).
+static inline mp_uint_t mp_hal_ticks_ms(void) {
+ return supervisor_ticks_ms32();
+}
+// Number of bytes in receive buffer
+volatile uint8_t usb_rx_count;
+volatile bool mp_cdc_enabled;
+
+int receive_usb(void);
-#define mp_hal_ticks_ms() ((mp_uint_t) supervisor_ticks_ms32())
-//#define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us))
+void mp_hal_set_interrupt_char(int c);
-bool mp_hal_stdin_any(void);
+void mp_hal_disable_all_interrupts(void);
+void mp_hal_enable_all_interrupts(void);
-#endif
+#endif // MICROPY_INCLUDED_STM32F4_MPHALPORT_H
diff --git a/ports/stm32f4/peripherals/stm32f4/periph.h b/ports/stm32f4/peripherals/stm32f4/periph.h
index 0d1374e85..969a8e79b 100644
--- a/ports/stm32f4/peripherals/stm32f4/periph.h
+++ b/ports/stm32f4/peripherals/stm32f4/periph.h
@@ -140,6 +140,12 @@ typedef struct {
//Starter Lines
+#ifdef STM32F401xE
+#define HAS_DAC 0
+#define HAS_TRNG 0
+#include "stm32f401xe/periph.h"
+#endif
+
#ifdef STM32F411xE
#define HAS_DAC 0
#define HAS_TRNG 0
@@ -160,4 +166,10 @@ typedef struct {
#include "stm32f405xx/periph.h"
#endif
+#ifdef STM32F407xx
+#define HAS_DAC 1
+#define HAS_TRNG 1
+#include "stm32f407xx/periph.h"
+#endif
+
#endif // __MICROPY_INCLUDED_STM32F4_PERIPHERALS_PERIPH_H__
diff --git a/ports/stm32f4/peripherals/stm32f4/pins.h b/ports/stm32f4/peripherals/stm32f4/pins.h
index ced83562e..44ef4c1ba 100644
--- a/ports/stm32f4/peripherals/stm32f4/pins.h
+++ b/ports/stm32f4/peripherals/stm32f4/pins.h
@@ -77,13 +77,20 @@ extern const mp_obj_type_t mcu_pin_type;
#define NO_PIN 0xff
// Choose based on chip
-#ifdef STM32F412Zx
-#include "stm32f412zx/pins.h"
+#ifdef STM32F401xE
+#include "stm32f401xe/pins.h"
#endif
#ifdef STM32F411xE
#include "stm32f411xe/pins.h"
#endif
+#ifdef STM32F412Zx
+#include "stm32f412zx/pins.h"
+#endif
#ifdef STM32F405xx
#include "stm32f405xx/pins.h"
#endif
+#ifdef STM32F407xx
+#include "stm32f407xx/pins.h"
+#endif
+
#endif // __MICROPY_INCLUDED_STM32F4_PERIPHERALS_PINS_H__
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f401xe/clocks.c b/ports/stm32f4/peripherals/stm32f4/stm32f401xe/clocks.c
new file mode 100644
index 000000000..53810af26
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f401xe/clocks.c
@@ -0,0 +1,62 @@
+
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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 "stm32f4xx_hal.h"
+#include "py/mpconfig.h"
+
+void stm32f4_peripherals_clocks_init(void) {
+ //System clock init
+ RCC_ClkInitTypeDef RCC_ClkInitStruct;
+ RCC_OscInitTypeDef RCC_OscInitStruct;
+
+ /* Enable Power Control clock */
+ __HAL_RCC_PWR_CLK_ENABLE();
+
+ /* The voltage scaling allows optimizing the power consumption when the device is
+ clocked below the maximum system frequency, to update the voltage scaling value
+ regarding system frequency refer to product datasheet. */
+ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
+
+ /* Enable HSE Oscillator and activate PLL with HSE as source */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+ RCC_OscInitStruct.PLL.PLLM = BOARD_OSC_DIV;
+ RCC_OscInitStruct.PLL.PLLN = 336;
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
+ RCC_OscInitStruct.PLL.PLLQ = 7;
+ HAL_RCC_OscConfig(&RCC_OscInitStruct);
+
+ /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
+ clocks dividers */
+ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+ HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);
+}
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f401xe/gpio.c b/ports/stm32f4/peripherals/stm32f4/stm32f401xe/gpio.c
new file mode 100644
index 000000000..7bd619662
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f401xe/gpio.c
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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 "stm32f4xx_hal.h"
+#include "stm32f4/gpio.h"
+#include "common-hal/microcontroller/Pin.h"
+
+void stm32f4_peripherals_gpio_init(void) {
+ /* GPIO Ports Clock Enable */
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOH_CLK_ENABLE();
+
+ //Never reset pins
+ never_reset_pin_number(2,14); //PC14 OSC32_IN
+ never_reset_pin_number(2,15); //PC15 OSC32_OUT
+ never_reset_pin_number(0,13); //PA13 SWDIO
+ never_reset_pin_number(0,14); //PA14 SWCLK
+}
+
+//LEDs are inverted on F411 DISCO
+void stm32f4_peripherals_status_led(uint8_t led, uint8_t state) {
+}
+
+
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f401xe/periph.c b/ports/stm32f4/peripherals/stm32f4/stm32f401xe/periph.c
new file mode 100644
index 000000000..b12084186
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f401xe/periph.c
@@ -0,0 +1,173 @@
+ /*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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 "py/obj.h"
+#include "py/mphal.h"
+#include "stm32f4/pins.h"
+#include "stm32f4/periph.h"
+
+// I2C
+
+I2C_TypeDef * mcu_i2c_banks[3] = {I2C1, I2C2, I2C3};
+
+const mcu_i2c_sda_obj_t mcu_i2c_sda_list[5] = {
+ I2C_SDA(1, 4, &pin_PB07),
+ I2C_SDA(1, 4, &pin_PB09),
+ I2C_SDA(2, 9, &pin_PB03),
+ I2C_SDA(3, 4, &pin_PC09),
+ I2C_SDA(3, 9, &pin_PB04),
+};
+
+const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4] = {
+ I2C_SCL(1, 4, &pin_PB06),
+ I2C_SCL(1, 4, &pin_PB08),
+ I2C_SCL(2, 4, &pin_PB10),
+ I2C_SCL(3, 4, &pin_PA08)
+};
+
+// SPI
+
+SPI_TypeDef * mcu_spi_banks[4] = {SPI1, SPI2, SPI3, SPI4};
+
+const mcu_spi_sck_obj_t mcu_spi_sck_list[9] = {
+ SPI(1, 5, &pin_PA05),
+ SPI(1, 5, &pin_PB03),
+ SPI(2, 5, &pin_PB10),
+ SPI(2, 5, &pin_PB13),
+ SPI(2, 5, &pin_PD03),
+ SPI(3, 6, &pin_PB03),
+ SPI(3, 6, &pin_PC10),
+ SPI(4, 5, &pin_PE02),
+ SPI(4, 5, &pin_PE12),
+};
+
+const mcu_spi_mosi_obj_t mcu_spi_mosi_list[9] = {
+ SPI(1, 5, &pin_PA07),
+ SPI(1, 5, &pin_PB05),
+ SPI(2, 5, &pin_PB15),
+ SPI(2, 5, &pin_PC03),
+ SPI(3, 6, &pin_PB05),
+ SPI(3, 6, &pin_PC12),
+ SPI(3, 5, &pin_PD06),
+ SPI(4, 5, &pin_PE06),
+ SPI(4, 5, &pin_PE14),
+};
+
+const mcu_spi_miso_obj_t mcu_spi_miso_list[8] = {
+ SPI(1, 5, &pin_PA06),
+ SPI(1, 5, &pin_PB04),
+ SPI(2, 5, &pin_PB14),
+ SPI(2, 5, &pin_PC02),
+ SPI(3, 6, &pin_PB04),
+ SPI(3, 6, &pin_PC11),
+ SPI(4, 5, &pin_PE05),
+ SPI(4, 5, &pin_PE13),
+};
+
+const mcu_spi_nss_obj_t mcu_spi_nss_list[9] = {
+ SPI(1, 5, &pin_PA04),
+ SPI(1, 5, &pin_PA15),
+ SPI(2, 5, &pin_PB09),
+ SPI(2, 5, &pin_PB12),
+ SPI(3, 6, &pin_PA04),
+ SPI(3, 6, &pin_PA15),
+ SPI(4, 6, &pin_PB12),
+ SPI(4, 5, &pin_PE04),
+ SPI(4, 5, &pin_PE11),
+};
+
+USART_TypeDef * mcu_uart_banks[MAX_UART] = {USART1, USART2, NULL, NULL, NULL, USART6};
+bool mcu_uart_has_usart[MAX_UART] = {true, true, false, false, false, true};
+
+const mcu_uart_tx_obj_t mcu_uart_tx_list[6] = {
+ UART(2, 7, &pin_PA02),
+ UART(1, 7, &pin_PA09),
+ UART(6, 8, &pin_PA11),
+ UART(1, 7, &pin_PB06),
+ UART(6, 8, &pin_PC06),
+ UART(2, 7, &pin_PD05),
+};
+
+const mcu_uart_rx_obj_t mcu_uart_rx_list[6] = {
+ UART(2, 7, &pin_PA03),
+ UART(1, 7, &pin_PA10),
+ UART(6, 8, &pin_PA12),
+ UART(1, 7, &pin_PB07),
+ UART(6, 8, &pin_PC07),
+ UART(2, 7, &pin_PD06),
+};
+
+//Timers
+//TIM6 and TIM7 are basic timers that are only used by DAC, and don't have pins
+TIM_TypeDef * mcu_tim_banks[14] = {TIM1, TIM2, TIM3, TIM4, TIM5, NULL, NULL, NULL, TIM9, TIM10,
+ TIM11, NULL, NULL, NULL};
+
+//#define TIM(index, alt, channel, tim_pin)
+const mcu_tim_pin_obj_t mcu_tim_pin_list[44] = {
+ TIM(2,1,1,&pin_PA00),
+ TIM(5,2,1,&pin_PA00),
+ TIM(2,1,2,&pin_PA01),
+ TIM(5,2,2,&pin_PA01),
+ TIM(2,1,3,&pin_PA02),
+ TIM(5,2,3,&pin_PA02),
+ TIM(2,1,4,&pin_PA03),
+ TIM(5,2,4,&pin_PA03),
+ TIM(9,3,1,&pin_PA02),
+ TIM(9,3,2,&pin_PA03),
+ TIM(3,2,1,&pin_PA06),
+ TIM(3,2,2,&pin_PA07),
+ TIM(1,1,1,&pin_PA08),
+ TIM(1,1,2,&pin_PA09),
+ TIM(1,1,3,&pin_PA10),
+ TIM(1,1,4,&pin_PA11),
+ TIM(2,1,1,&pin_PA15),
+ TIM(3,2,3,&pin_PB00),
+ TIM(3,2,4,&pin_PB01),
+ TIM(2,1,2,&pin_PB03),
+ TIM(3,2,1,&pin_PB04),
+ TIM(3,2,2,&pin_PB05),
+ TIM(4,2,1,&pin_PB06),
+ TIM(4,2,2,&pin_PB07),
+ TIM(4,2,3,&pin_PB08),
+ TIM(10,2,1,&pin_PB08),
+ TIM(4,2,4,&pin_PB09),
+ TIM(11,2,1,&pin_PB09),
+ TIM(2,1,3,&pin_PB10),
+ TIM(3,2,1,&pin_PC06),
+ TIM(3,2,2,&pin_PC07),
+ TIM(3,2,3,&pin_PC08),
+ TIM(3,2,4,&pin_PC09),
+ TIM(4,2,1,&pin_PD12),
+ TIM(4,2,2,&pin_PD13),
+ TIM(4,2,3,&pin_PD14),
+ TIM(4,2,4,&pin_PD15),
+ TIM(9,3,1,&pin_PE05),
+ TIM(9,3,2,&pin_PE06),
+ TIM(1,1,1,&pin_PE09),
+ TIM(1,1,2,&pin_PE11),
+ TIM(1,1,3,&pin_PE13),
+ TIM(1,1,4,&pin_PE14),
+};
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f401xe/periph.h b/ports/stm32f4/peripherals/stm32f4/stm32f401xe/periph.h
new file mode 100644
index 000000000..6085f1ff2
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f401xe/periph.h
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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.
+ */
+
+#ifndef MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F401XE_PERIPH_H
+#define MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F401XE_PERIPH_H
+
+//I2C
+extern I2C_TypeDef * mcu_i2c_banks[3];
+
+extern const mcu_i2c_sda_obj_t mcu_i2c_sda_list[5];
+extern const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4];
+
+//SPI
+extern SPI_TypeDef * mcu_spi_banks[4];
+
+extern const mcu_spi_sck_obj_t mcu_spi_sck_list[9];
+extern const mcu_spi_mosi_obj_t mcu_spi_mosi_list[9];
+extern const mcu_spi_miso_obj_t mcu_spi_miso_list[8];
+extern const mcu_spi_nss_obj_t mcu_spi_nss_list[9];
+
+//UART
+extern USART_TypeDef * mcu_uart_banks[MAX_UART];
+extern bool mcu_uart_has_usart[MAX_UART];
+
+extern const mcu_uart_tx_obj_t mcu_uart_tx_list[6];
+extern const mcu_uart_rx_obj_t mcu_uart_rx_list[6];
+
+//Timers
+#define TIM_BANK_ARRAY_LEN 14
+#define TIM_PIN_ARRAY_LEN 44
+TIM_TypeDef * mcu_tim_banks[TIM_BANK_ARRAY_LEN];
+const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN];
+
+#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F401XE_PERIPH_H \ No newline at end of file
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f401xe/pins.c b/ports/stm32f4/peripherals/stm32f4/stm32f401xe/pins.c
new file mode 100644
index 000000000..7e88c3dcb
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f401xe/pins.c
@@ -0,0 +1,123 @@
+ /*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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 "py/obj.h"
+#include "py/mphal.h"
+#include "stm32f4/pins.h"
+
+const mcu_pin_obj_t pin_PE02 = PIN(4, 2, NO_ADC);
+const mcu_pin_obj_t pin_PE03 = PIN(4, 3, NO_ADC);
+const mcu_pin_obj_t pin_PE04 = PIN(4, 4, NO_ADC);
+const mcu_pin_obj_t pin_PE05 = PIN(4, 5, NO_ADC);
+const mcu_pin_obj_t pin_PE06 = PIN(4, 6, NO_ADC);
+
+const mcu_pin_obj_t pin_PC13 = PIN(2, 13, NO_ADC); //anti-tamp
+const mcu_pin_obj_t pin_PC14 = PIN(2, 14, NO_ADC); //OSC32_IN
+const mcu_pin_obj_t pin_PC15 = PIN(2, 15, NO_ADC); //OSC32_OUT
+
+const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_1,10));
+const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_1,11));
+const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_1,12));
+const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_1,13));
+
+const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1,0));
+const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1,1));
+const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1,2));
+const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1,3));
+const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1,4));
+const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1,5));
+const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1,6));
+const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1,7));
+
+const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_1,14));
+const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_1,15));
+
+const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1,8));
+const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1,9));
+const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC);
+
+const mcu_pin_obj_t pin_PE07 = PIN(4, 7, NO_ADC);
+const mcu_pin_obj_t pin_PE08 = PIN(4, 8, NO_ADC);
+const mcu_pin_obj_t pin_PE09 = PIN(4, 9, NO_ADC);
+const mcu_pin_obj_t pin_PE10 = PIN(4, 10, NO_ADC);
+const mcu_pin_obj_t pin_PE11 = PIN(4, 11, NO_ADC);
+const mcu_pin_obj_t pin_PE12 = PIN(4, 12, NO_ADC);
+const mcu_pin_obj_t pin_PE13 = PIN(4, 13, NO_ADC);
+const mcu_pin_obj_t pin_PE14 = PIN(4, 14, NO_ADC);
+const mcu_pin_obj_t pin_PE15 = PIN(4, 15, NO_ADC);
+
+const mcu_pin_obj_t pin_PB10 = PIN(1, 10, NO_ADC);
+const mcu_pin_obj_t pin_PB12 = PIN(1, 12, NO_ADC);
+const mcu_pin_obj_t pin_PB13 = PIN(1, 13, NO_ADC);
+const mcu_pin_obj_t pin_PB14 = PIN(1, 14, NO_ADC);
+const mcu_pin_obj_t pin_PB15 = PIN(1, 15, NO_ADC);
+
+const mcu_pin_obj_t pin_PD08 = PIN(3, 8, NO_ADC);
+const mcu_pin_obj_t pin_PD09 = PIN(3, 9, NO_ADC);
+const mcu_pin_obj_t pin_PD10 = PIN(3, 10, NO_ADC);
+const mcu_pin_obj_t pin_PD11 = PIN(3, 11, NO_ADC);
+const mcu_pin_obj_t pin_PD12 = PIN(3, 12, NO_ADC);
+const mcu_pin_obj_t pin_PD13 = PIN(3, 13, NO_ADC);
+const mcu_pin_obj_t pin_PD14 = PIN(3, 14, NO_ADC);
+const mcu_pin_obj_t pin_PD15 = PIN(3, 15, NO_ADC);
+
+const mcu_pin_obj_t pin_PC06 = PIN(2, 6, NO_ADC);
+const mcu_pin_obj_t pin_PC07 = PIN(2, 7, NO_ADC);
+const mcu_pin_obj_t pin_PC08 = PIN(2, 8, NO_ADC);
+const mcu_pin_obj_t pin_PC09 = PIN(2, 9, NO_ADC);
+
+const mcu_pin_obj_t pin_PA08 = PIN(0, 8, NO_ADC);
+const mcu_pin_obj_t pin_PA09 = PIN(0, 9, NO_ADC);
+const mcu_pin_obj_t pin_PA10 = PIN(0, 10, NO_ADC);
+const mcu_pin_obj_t pin_PA11 = PIN(0, 11, NO_ADC);
+const mcu_pin_obj_t pin_PA12 = PIN(0, 12, NO_ADC);
+const mcu_pin_obj_t pin_PA13 = PIN(0, 13, NO_ADC); //SWDIO
+const mcu_pin_obj_t pin_PA14 = PIN(0, 14, NO_ADC); //SWCLK
+const mcu_pin_obj_t pin_PA15 = PIN(0, 15, NO_ADC); //JTDI
+
+const mcu_pin_obj_t pin_PC10 = PIN(2, 10, NO_ADC);
+const mcu_pin_obj_t pin_PC11 = PIN(2, 11, NO_ADC);
+const mcu_pin_obj_t pin_PC12 = PIN(2, 12, NO_ADC);
+
+const mcu_pin_obj_t pin_PD00 = PIN(3, 0, NO_ADC);
+const mcu_pin_obj_t pin_PD01 = PIN(3, 1, NO_ADC);
+const mcu_pin_obj_t pin_PD02 = PIN(3, 2, NO_ADC);
+const mcu_pin_obj_t pin_PD03 = PIN(3, 3, NO_ADC);
+const mcu_pin_obj_t pin_PD04 = PIN(3, 4, NO_ADC);
+const mcu_pin_obj_t pin_PD05 = PIN(3, 5, NO_ADC);
+const mcu_pin_obj_t pin_PD06 = PIN(3, 6, NO_ADC);
+const mcu_pin_obj_t pin_PD07 = PIN(3, 7, NO_ADC);
+
+const mcu_pin_obj_t pin_PB03 = PIN(1, 3, NO_ADC);
+const mcu_pin_obj_t pin_PB04 = PIN(1, 4, NO_ADC);
+const mcu_pin_obj_t pin_PB05 = PIN(1, 5, NO_ADC);
+const mcu_pin_obj_t pin_PB06 = PIN(1, 6, NO_ADC);
+const mcu_pin_obj_t pin_PB07 = PIN(1, 7, NO_ADC);
+const mcu_pin_obj_t pin_PB08 = PIN(1, 8, NO_ADC);
+const mcu_pin_obj_t pin_PB09 = PIN(1, 9, NO_ADC);
+
+const mcu_pin_obj_t pin_PE00 = PIN(4, 0, NO_ADC);
+const mcu_pin_obj_t pin_PE01 = PIN(4, 1, NO_ADC); \ No newline at end of file
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f401xe/pins.h b/ports/stm32f4/peripherals/stm32f4/stm32f401xe/pins.h
new file mode 100644
index 000000000..09bc8f13e
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f401xe/pins.h
@@ -0,0 +1,121 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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.
+ */
+
+#ifndef MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F401XE_PINS_H
+#define MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F401XE_PINS_H
+
+//Pins in datasheet order: DocID026289 Rev 7 page 38. LQFP100 only
+//pg 38
+extern const mcu_pin_obj_t pin_PE02;
+extern const mcu_pin_obj_t pin_PE03;
+extern const mcu_pin_obj_t pin_PE04;
+extern const mcu_pin_obj_t pin_PE05;
+//pg 39
+extern const mcu_pin_obj_t pin_PE06;
+extern const mcu_pin_obj_t pin_PC13;
+extern const mcu_pin_obj_t pin_PC14;
+extern const mcu_pin_obj_t pin_PC15;
+extern const mcu_pin_obj_t pin_PC00;
+extern const mcu_pin_obj_t pin_PC01;
+extern const mcu_pin_obj_t pin_PC02;
+extern const mcu_pin_obj_t pin_PC03;
+//pg 40
+extern const mcu_pin_obj_t pin_PA00;
+extern const mcu_pin_obj_t pin_PA01;
+extern const mcu_pin_obj_t pin_PA02;
+extern const mcu_pin_obj_t pin_PA03;
+extern const mcu_pin_obj_t pin_PA04;
+extern const mcu_pin_obj_t pin_PA05;
+extern const mcu_pin_obj_t pin_PA06;
+extern const mcu_pin_obj_t pin_PA07;
+//pg 41
+extern const mcu_pin_obj_t pin_PC04;
+extern const mcu_pin_obj_t pin_PC05;
+extern const mcu_pin_obj_t pin_PB00;
+extern const mcu_pin_obj_t pin_PB01;
+extern const mcu_pin_obj_t pin_PB02;
+extern const mcu_pin_obj_t pin_PE07;
+extern const mcu_pin_obj_t pin_PE08;
+extern const mcu_pin_obj_t pin_PE09;
+extern const mcu_pin_obj_t pin_PE10;
+extern const mcu_pin_obj_t pin_PE11;
+extern const mcu_pin_obj_t pin_PE12;
+extern const mcu_pin_obj_t pin_PE13;
+extern const mcu_pin_obj_t pin_PE14;
+extern const mcu_pin_obj_t pin_PE15;
+//pg 42
+extern const mcu_pin_obj_t pin_PB10;
+extern const mcu_pin_obj_t pin_PB12;
+extern const mcu_pin_obj_t pin_PB13;
+extern const mcu_pin_obj_t pin_PB14;
+extern const mcu_pin_obj_t pin_PB15;
+extern const mcu_pin_obj_t pin_PD08;
+extern const mcu_pin_obj_t pin_PD09;
+extern const mcu_pin_obj_t pin_PD10;
+extern const mcu_pin_obj_t pin_PD11;
+extern const mcu_pin_obj_t pin_PD12;
+//pg 43
+extern const mcu_pin_obj_t pin_PD13;
+extern const mcu_pin_obj_t pin_PD14;
+extern const mcu_pin_obj_t pin_PD15;
+extern const mcu_pin_obj_t pin_PC06;
+extern const mcu_pin_obj_t pin_PC07;
+extern const mcu_pin_obj_t pin_PC08;
+extern const mcu_pin_obj_t pin_PC09;
+extern const mcu_pin_obj_t pin_PA08;
+extern const mcu_pin_obj_t pin_PA09;
+//pg 44
+extern const mcu_pin_obj_t pin_PA10;
+extern const mcu_pin_obj_t pin_PA11;
+extern const mcu_pin_obj_t pin_PA12;
+extern const mcu_pin_obj_t pin_PA13;
+extern const mcu_pin_obj_t pin_PA14;
+extern const mcu_pin_obj_t pin_PA15;
+extern const mcu_pin_obj_t pin_PC10;
+extern const mcu_pin_obj_t pin_PC11;
+extern const mcu_pin_obj_t pin_PC12;
+//pg 45
+extern const mcu_pin_obj_t pin_PD00;
+extern const mcu_pin_obj_t pin_PD01;
+extern const mcu_pin_obj_t pin_PD02;
+extern const mcu_pin_obj_t pin_PD03;
+extern const mcu_pin_obj_t pin_PD04;
+extern const mcu_pin_obj_t pin_PD05;
+extern const mcu_pin_obj_t pin_PD06;
+extern const mcu_pin_obj_t pin_PD07;
+extern const mcu_pin_obj_t pin_PB03;
+extern const mcu_pin_obj_t pin_PB04;
+extern const mcu_pin_obj_t pin_PB05;
+extern const mcu_pin_obj_t pin_PB06;
+//pg 46
+extern const mcu_pin_obj_t pin_PB07;
+extern const mcu_pin_obj_t pin_PB08;
+extern const mcu_pin_obj_t pin_PB09;
+extern const mcu_pin_obj_t pin_PE00;
+extern const mcu_pin_obj_t pin_PE01;
+
+
+#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F401XE_PINS_H
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/clocks.c b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/clocks.c
index c259f54fa..2afca64e8 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/clocks.c
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/clocks.c
@@ -25,6 +25,7 @@
* THE SOFTWARE.
*/
#include "stm32f4xx_hal.h"
+#include "py/mpconfig.h"
void stm32f4_peripherals_clocks_init(void) {
//TODO: All parameters must be moved to board level, due to relationship with HSE Osc.
@@ -46,7 +47,7 @@ void stm32f4_peripherals_clocks_init(void) {
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLM = 12;
+ RCC_OscInitStruct.PLL.PLLM = BOARD_OSC_DIV;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f407xx/clocks.c b/ports/stm32f4/peripherals/stm32f4/stm32f407xx/clocks.c
new file mode 100644
index 000000000..2afca64e8
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f407xx/clocks.c
@@ -0,0 +1,64 @@
+
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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 "stm32f4xx_hal.h"
+#include "py/mpconfig.h"
+
+void stm32f4_peripherals_clocks_init(void) {
+ //TODO: All parameters must be moved to board level, due to relationship with HSE Osc.
+
+ //System clock init
+ RCC_ClkInitTypeDef RCC_ClkInitStruct;
+ RCC_OscInitTypeDef RCC_OscInitStruct;
+
+ /* Enable Power Control clock */
+ __HAL_RCC_PWR_CLK_ENABLE();
+
+ /* The voltage scaling allows optimizing the power consumption when the device is
+ clocked below the maximum system frequency, to update the voltage scaling value
+ regarding system frequency refer to product datasheet. */
+ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
+
+ /* Enable HSE Oscillator and activate PLL with HSE as source */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+ RCC_OscInitStruct.PLL.PLLM = BOARD_OSC_DIV;
+ RCC_OscInitStruct.PLL.PLLN = 336;
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
+ RCC_OscInitStruct.PLL.PLLQ = 7;
+ HAL_RCC_OscConfig(&RCC_OscInitStruct);
+
+ /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
+ clocks dividers */
+ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
+ HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
+}
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f407xx/gpio.c b/ports/stm32f4/peripherals/stm32f4/stm32f407xx/gpio.c
new file mode 100644
index 000000000..f9be3b4ec
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f407xx/gpio.c
@@ -0,0 +1,56 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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 "stm32f4xx_hal.h"
+#include "stm32f4/gpio.h"
+#include "common-hal/microcontroller/Pin.h"
+
+void stm32f4_peripherals_gpio_init(void) {
+ //Enable all GPIO for now
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+
+ //Never reset pins
+ never_reset_pin_number(2,13); //PC13 anti tamp
+ never_reset_pin_number(2,14); //PC14 OSC32_IN
+ never_reset_pin_number(2,15); //PC15 OSC32_OUT
+ never_reset_pin_number(0,13); //PA13 SWDIO
+ never_reset_pin_number(0,14); //PA14 SWCLK
+ // never_reset_pin_number(0,15); //PA15 JTDI
+ // never_reset_pin_number(1,3); //PB3 JTDO
+ // never_reset_pin_number(1,4); //PB4 JTRST
+
+ // Port H is not included in GPIO port array
+ // never_reset_pin_number(5,0); //PH0 JTDO
+ // never_reset_pin_number(5,1); //PH1 JTRST
+}
+
+void stm32f4_peripherals_status_led(uint8_t led, uint8_t state) {
+
+}
+
+
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f407xx/periph.c b/ports/stm32f4/peripherals/stm32f4/stm32f407xx/periph.c
new file mode 100644
index 000000000..bc03f7c7b
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f407xx/periph.c
@@ -0,0 +1,194 @@
+ /*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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 "py/obj.h"
+#include "py/mphal.h"
+#include "stm32f4/pins.h"
+#include "stm32f4/periph.h"
+
+// I2C
+
+I2C_TypeDef * mcu_i2c_banks[3] = {I2C1, I2C2, I2C3};
+
+const mcu_i2c_sda_obj_t mcu_i2c_sda_list[4] = {
+ I2C_SDA(1, 4, &pin_PB07),
+ I2C_SDA(1, 4, &pin_PB09),
+ I2C_SDA(2, 4, &pin_PB11),
+ I2C_SDA(3, 4, &pin_PC09),
+};
+
+const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4] = {
+ I2C_SCL(1, 4, &pin_PB06),
+ I2C_SCL(1, 4, &pin_PB08),
+ I2C_SCL(2, 4, &pin_PB10),
+ I2C_SCL(3, 4, &pin_PA08)
+};
+
+SPI_TypeDef * mcu_spi_banks[3] = {SPI1, SPI2, SPI3};
+
+const mcu_spi_sck_obj_t mcu_spi_sck_list[7] = {
+ SPI(1, 5, &pin_PA05),
+ SPI(1, 5, &pin_PB03),
+ SPI(2, 5, &pin_PB10),
+ SPI(2, 5, &pin_PB13),
+ SPI(2, 5, &pin_PC07),
+ SPI(3, 6, &pin_PB03),
+ SPI(3, 6, &pin_PC10),
+};
+
+const mcu_spi_mosi_obj_t mcu_spi_mosi_list[6] = {
+ SPI(1, 5, &pin_PA07),
+ SPI(1, 5, &pin_PB05),
+ SPI(2, 5, &pin_PB15),
+ SPI(2, 5, &pin_PC03),
+ SPI(3, 6, &pin_PB05),
+ SPI(3, 6, &pin_PC12),
+};
+
+const mcu_spi_miso_obj_t mcu_spi_miso_list[6] = {
+ SPI(1, 5, &pin_PA06),
+ SPI(1, 5, &pin_PB04),
+ SPI(2, 5, &pin_PB14),
+ SPI(2, 5, &pin_PC02),
+ SPI(3, 6, &pin_PB04),
+ SPI(3, 6, &pin_PC11),
+};
+
+const mcu_spi_nss_obj_t mcu_spi_nss_list[6] = {
+ SPI(1, 5, &pin_PA04),
+ SPI(1, 5, &pin_PA15),
+ SPI(2, 5, &pin_PB09),
+ SPI(2, 5, &pin_PB12),
+ SPI(3, 6, &pin_PA04),
+ SPI(3, 6, &pin_PA15),
+};
+
+USART_TypeDef * mcu_uart_banks[MAX_UART] = {USART1, USART2, USART3, UART4, UART5, USART6};
+bool mcu_uart_has_usart[MAX_UART] = {true, true, true, false, false, true};
+
+const mcu_uart_tx_obj_t mcu_uart_tx_list[12] = {
+ UART(4, 8, &pin_PA00),
+ UART(2, 7, &pin_PA02),
+ UART(1, 7, &pin_PA09),
+ UART(1, 7, &pin_PB06),
+ UART(3, 7, &pin_PB10),
+ UART(6, 8, &pin_PC06),
+ UART(3, 7, &pin_PC10),
+ UART(4, 8, &pin_PC10),
+ UART(5, 8, &pin_PC12),
+ UART(2, 7, &pin_PD05),
+ UART(3, 7, &pin_PD08),
+ UART(6, 8, &pin_PG14),
+};
+
+const mcu_uart_rx_obj_t mcu_uart_rx_list[12] = {
+ UART(4, 8, &pin_PA01),
+ UART(2, 7, &pin_PA03),
+ UART(1, 7, &pin_PA10),
+ UART(1, 7, &pin_PB07),
+ UART(3, 7, &pin_PB11),
+ UART(6, 8, &pin_PC07),
+ UART(3, 7, &pin_PC11),
+ UART(4, 8, &pin_PC11),
+ UART(5, 8, &pin_PD02),
+ UART(2, 7, &pin_PD06),
+ UART(3, 7, &pin_PD09),
+ UART(6, 8, &pin_PG09),
+};
+
+//Timers
+//TIM6 and TIM7 are basic timers that are only used by DAC, and don't have pins
+TIM_TypeDef * mcu_tim_banks[14] = {TIM1, TIM2, TIM3, TIM4, TIM5, NULL, NULL, TIM8, TIM9, TIM10,
+ TIM11, TIM12, TIM13, TIM14};
+
+const mcu_tim_pin_obj_t mcu_tim_pin_list[56] = {
+ TIM(2,1,1,&pin_PA00),
+ TIM(5,2,1,&pin_PA00),
+ TIM(2,1,2,&pin_PA01),
+ TIM(5,2,2,&pin_PA01),
+ TIM(2,1,3,&pin_PA02),
+ TIM(5,2,3,&pin_PA02),
+ TIM(2,1,4,&pin_PA03),
+ TIM(5,2,4,&pin_PA03),
+ TIM(9,3,1,&pin_PA02),
+ TIM(9,3,2,&pin_PA03),
+ TIM(3,2,1,&pin_PA06),
+ TIM(13,9,1,&pin_PA06),
+ TIM(3,2,2,&pin_PA07),
+ TIM(14,9,1,&pin_PA07),
+ TIM(1,1,1,&pin_PA08),
+ TIM(1,1,2,&pin_PA09),
+ TIM(1,1,3,&pin_PA10),
+ TIM(1,1,4,&pin_PA11),
+ TIM(2,1,1,&pin_PA15),
+ TIM(3,2,3,&pin_PB00),
+ TIM(3,2,4,&pin_PB01),
+ TIM(2,1,2,&pin_PB03),
+ TIM(3,2,1,&pin_PB04),
+ TIM(3,2,2,&pin_PB05),
+ TIM(4,2,1,&pin_PB06),
+ TIM(4,2,2,&pin_PB07),
+ TIM(4,2,3,&pin_PB08),
+ TIM(10,2,1,&pin_PB08),
+ TIM(4,2,4,&pin_PB09),
+ TIM(11,2,1,&pin_PB09),
+ TIM(2,1,3,&pin_PB10),
+ TIM(2,1,4,&pin_PB11),
+ TIM(12,9,1,&pin_PB14),
+ TIM(12,9,2,&pin_PB15),
+ TIM(3,2,1,&pin_PC06),
+ TIM(3,2,2,&pin_PC07),
+ TIM(3,2,3,&pin_PC08),
+ TIM(3,2,4,&pin_PC09),
+ TIM(8,3,1,&pin_PC06),
+ TIM(8,3,2,&pin_PC07),
+ TIM(8,3,3,&pin_PC08),
+ TIM(8,3,4,&pin_PC09),
+ TIM(4,2,1,&pin_PD12),
+ TIM(4,2,2,&pin_PD13),
+ TIM(4,2,3,&pin_PD14),
+ TIM(4,2,4,&pin_PD15),
+ TIM(9,3,1,&pin_PE05),
+ TIM(9,3,2,&pin_PE06),
+ TIM(1,1,1,&pin_PE09),
+ TIM(1,1,2,&pin_PE11),
+ TIM(1,1,3,&pin_PE13),
+ TIM(1,1,4,&pin_PE14),
+ TIM(10,3,1,&pin_PF06),
+ TIM(11,3,1,&pin_PF07),
+ TIM(13,9,1,&pin_PF08),
+ TIM(14,9,1,&pin_PF09),
+ // TIM(12,9,1,&pin_PH06), //TODO: include these when pin map is expanded
+ // TIM(12,9,2,&pin_PH09),
+ // TIM(5,2,1,&pin_PH10),
+ // TIM(5,2,2,&pin_PH11),
+ // TIM(5,2,3,&pin_PH12),
+ // TIM(5,2,4,&pin_PI00),
+ // TIM(8,3,4,&pin_PI02),
+ // TIM(8,3,1,&pin_PI05),
+ // TIM(8,3,2,&pin_PI06),
+ // TIM(8,3,3,&pin_PI07),
+};
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f407xx/periph.h b/ports/stm32f4/peripherals/stm32f4/stm32f407xx/periph.h
new file mode 100644
index 000000000..e87e79857
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f407xx/periph.h
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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.
+ */
+
+#ifndef MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F405XX_PERIPH_H
+#define MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F405XX_PERIPH_H
+
+//I2C
+extern I2C_TypeDef * mcu_i2c_banks[3];
+
+extern const mcu_i2c_sda_obj_t mcu_i2c_sda_list[4];
+extern const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4];
+
+//SPI
+extern SPI_TypeDef * mcu_spi_banks[3];
+
+extern const mcu_spi_sck_obj_t mcu_spi_sck_list[7];
+extern const mcu_spi_mosi_obj_t mcu_spi_mosi_list[6];
+extern const mcu_spi_miso_obj_t mcu_spi_miso_list[6];
+extern const mcu_spi_nss_obj_t mcu_spi_nss_list[6];
+
+//UART
+extern USART_TypeDef * mcu_uart_banks[MAX_UART];
+extern bool mcu_uart_has_usart[MAX_UART];
+
+extern const mcu_uart_tx_obj_t mcu_uart_tx_list[12];
+extern const mcu_uart_rx_obj_t mcu_uart_rx_list[12];
+
+//Timers
+#define TIM_BANK_ARRAY_LEN 14
+#define TIM_PIN_ARRAY_LEN 56
+TIM_TypeDef * mcu_tim_banks[TIM_BANK_ARRAY_LEN];
+const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN];
+
+#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F405XX_PERIPH_H \ No newline at end of file
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f407xx/pins.c b/ports/stm32f4/peripherals/stm32f4/stm32f407xx/pins.c
new file mode 100644
index 000000000..86445fe14
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f407xx/pins.c
@@ -0,0 +1,161 @@
+ /*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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 "py/obj.h"
+#include "py/mphal.h"
+#include "stm32f4/pins.h"
+
+const mcu_pin_obj_t pin_PE02 = PIN(4, 2, NO_ADC);
+const mcu_pin_obj_t pin_PE03 = PIN(4, 3, NO_ADC);
+const mcu_pin_obj_t pin_PE04 = PIN(4, 4, NO_ADC);
+const mcu_pin_obj_t pin_PE05 = PIN(4, 5, NO_ADC);
+const mcu_pin_obj_t pin_PE06 = PIN(4, 6, NO_ADC);
+
+const mcu_pin_obj_t pin_PC13 = PIN(2, 13, NO_ADC); //anti-tamp
+const mcu_pin_obj_t pin_PC14 = PIN(2, 14, NO_ADC); //OSC32_IN
+const mcu_pin_obj_t pin_PC15 = PIN(2, 15, NO_ADC); //OSC32_OUT
+
+const mcu_pin_obj_t pin_PF00 = PIN(5, 0, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PF01 = PIN(5, 1, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PF02 = PIN(5, 2, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PF03 = PIN(5, 3, ADC_INPUT(ADC_3,9)); // 144 only
+const mcu_pin_obj_t pin_PF04 = PIN(5, 4, ADC_INPUT(ADC_3,14)); // 144 only
+const mcu_pin_obj_t pin_PF05 = PIN(5, 5, ADC_INPUT(ADC_3,15)); // 144 only
+const mcu_pin_obj_t pin_PF06 = PIN(5, 6, ADC_INPUT(ADC_3,4)); // 144 only
+const mcu_pin_obj_t pin_PF07 = PIN(5, 7, ADC_INPUT(ADC_3,5)); // 144 only
+const mcu_pin_obj_t pin_PF08 = PIN(5, 8, ADC_INPUT(ADC_3,6)); // 144 only
+const mcu_pin_obj_t pin_PF09 = PIN(5, 9, ADC_INPUT(ADC_3,7)); // 144 only
+const mcu_pin_obj_t pin_PF10 = PIN(5, 10, ADC_INPUT(ADC_3,8)); // 144 only
+
+const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_123,10));
+const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_123,11));
+const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_123,12));
+const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_123,13));
+
+const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_123,0));
+const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_123,1));
+const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_123,2));
+const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_123,3));
+const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_12,4));
+const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_12,5));
+const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_12,6));
+const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_12,7));
+
+const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_12,14));
+const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_12,15));
+
+const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_12,8));
+const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_12,9));
+const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); //BOOT1
+
+const mcu_pin_obj_t pin_PF11 = PIN(5, 11, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PF12 = PIN(5, 12, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PF13 = PIN(5, 13, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PF14 = PIN(5, 14, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PF15 = PIN(5, 15, NO_ADC); // 144 only
+
+const mcu_pin_obj_t pin_PG00 = PIN(6, 0, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PG01 = PIN(6, 1, NO_ADC); // 144 only
+
+const mcu_pin_obj_t pin_PE07 = PIN(4, 7, NO_ADC);
+const mcu_pin_obj_t pin_PE08 = PIN(4, 8, NO_ADC);
+const mcu_pin_obj_t pin_PE09 = PIN(4, 9, NO_ADC);
+const mcu_pin_obj_t pin_PE10 = PIN(4, 10, NO_ADC);
+const mcu_pin_obj_t pin_PE11 = PIN(4, 11, NO_ADC);
+const mcu_pin_obj_t pin_PE12 = PIN(4, 12, NO_ADC);
+const mcu_pin_obj_t pin_PE13 = PIN(4, 13, NO_ADC);
+const mcu_pin_obj_t pin_PE14 = PIN(4, 14, NO_ADC);
+const mcu_pin_obj_t pin_PE15 = PIN(4, 15, NO_ADC);
+
+const mcu_pin_obj_t pin_PB10 = PIN(1, 10, NO_ADC);
+const mcu_pin_obj_t pin_PB11 = PIN(1, 11, NO_ADC);
+const mcu_pin_obj_t pin_PB12 = PIN(1, 12, NO_ADC);
+const mcu_pin_obj_t pin_PB13 = PIN(1, 13, NO_ADC);
+const mcu_pin_obj_t pin_PB14 = PIN(1, 14, NO_ADC);
+const mcu_pin_obj_t pin_PB15 = PIN(1, 15, NO_ADC);
+
+const mcu_pin_obj_t pin_PD08 = PIN(3, 8, NO_ADC);
+const mcu_pin_obj_t pin_PD09 = PIN(3, 9, NO_ADC);
+const mcu_pin_obj_t pin_PD10 = PIN(3, 10, NO_ADC);
+const mcu_pin_obj_t pin_PD11 = PIN(3, 11, NO_ADC);
+const mcu_pin_obj_t pin_PD12 = PIN(3, 12, NO_ADC);
+const mcu_pin_obj_t pin_PD13 = PIN(3, 13, NO_ADC);
+const mcu_pin_obj_t pin_PD14 = PIN(3, 14, NO_ADC);
+const mcu_pin_obj_t pin_PD15 = PIN(3, 15, NO_ADC);
+
+const mcu_pin_obj_t pin_PG02 = PIN(6, 2, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PG03 = PIN(6, 3, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PG04 = PIN(6, 4, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PG05 = PIN(6, 5, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PG06 = PIN(6, 6, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PG07 = PIN(6, 7, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PG08 = PIN(6, 8, NO_ADC); // 144 only
+
+const mcu_pin_obj_t pin_PC06 = PIN(2, 6, NO_ADC);
+const mcu_pin_obj_t pin_PC07 = PIN(2, 7, NO_ADC);
+const mcu_pin_obj_t pin_PC08 = PIN(2, 8, NO_ADC);
+const mcu_pin_obj_t pin_PC09 = PIN(2, 9, NO_ADC);
+
+const mcu_pin_obj_t pin_PA08 = PIN(0, 8, NO_ADC);
+const mcu_pin_obj_t pin_PA09 = PIN(0, 9, NO_ADC);
+const mcu_pin_obj_t pin_PA10 = PIN(0, 10, NO_ADC);
+const mcu_pin_obj_t pin_PA11 = PIN(0, 11, NO_ADC);
+const mcu_pin_obj_t pin_PA12 = PIN(0, 12, NO_ADC);
+const mcu_pin_obj_t pin_PA13 = PIN(0, 13, NO_ADC);
+const mcu_pin_obj_t pin_PA14 = PIN(0, 14, NO_ADC);
+const mcu_pin_obj_t pin_PA15 = PIN(0, 15, NO_ADC);
+
+const mcu_pin_obj_t pin_PC10 = PIN(2, 10, NO_ADC);
+const mcu_pin_obj_t pin_PC11 = PIN(2, 11, NO_ADC);
+const mcu_pin_obj_t pin_PC12 = PIN(2, 12, NO_ADC);
+
+const mcu_pin_obj_t pin_PD00 = PIN(3, 0, NO_ADC);
+const mcu_pin_obj_t pin_PD01 = PIN(3, 1, NO_ADC);
+const mcu_pin_obj_t pin_PD02 = PIN(3, 2, NO_ADC);
+const mcu_pin_obj_t pin_PD03 = PIN(3, 3, NO_ADC);
+const mcu_pin_obj_t pin_PD04 = PIN(3, 4, NO_ADC);
+const mcu_pin_obj_t pin_PD05 = PIN(3, 5, NO_ADC);
+const mcu_pin_obj_t pin_PD06 = PIN(3, 6, NO_ADC);
+const mcu_pin_obj_t pin_PD07 = PIN(3, 7, NO_ADC);
+
+const mcu_pin_obj_t pin_PG09 = PIN(6, 9, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PG10 = PIN(6, 10, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PG11 = PIN(6, 11, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PG12 = PIN(6, 12, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PG13 = PIN(6, 13, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PG14 = PIN(6, 14, NO_ADC); // 144 only
+const mcu_pin_obj_t pin_PG15 = PIN(6, 15, NO_ADC); // 144 only
+
+const mcu_pin_obj_t pin_PB03 = PIN(1, 3, NO_ADC);
+const mcu_pin_obj_t pin_PB04 = PIN(1, 4, NO_ADC);
+const mcu_pin_obj_t pin_PB05 = PIN(1, 5, NO_ADC);
+const mcu_pin_obj_t pin_PB06 = PIN(1, 6, NO_ADC);
+const mcu_pin_obj_t pin_PB07 = PIN(1, 7, NO_ADC);
+const mcu_pin_obj_t pin_PB08 = PIN(1, 8, NO_ADC);
+const mcu_pin_obj_t pin_PB09 = PIN(1, 9, NO_ADC);
+
+const mcu_pin_obj_t pin_PE00 = PIN(4, 0, NO_ADC);
+const mcu_pin_obj_t pin_PE01 = PIN(4, 1, NO_ADC);
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f407xx/pins.h b/ports/stm32f4/peripherals/stm32f4/stm32f407xx/pins.h
new file mode 100644
index 000000000..180f5c316
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f407xx/pins.h
@@ -0,0 +1,158 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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.
+ */
+
+#ifndef MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F412ZG_PINS_H
+#define MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F412ZG_PINS_H
+
+//Pins in datasheet order: DocID028087 Rev 7 page 50. LQFP100 only
+//pg 50
+extern const mcu_pin_obj_t pin_PE02;
+extern const mcu_pin_obj_t pin_PE03;
+extern const mcu_pin_obj_t pin_PE04;
+extern const mcu_pin_obj_t pin_PE05;
+extern const mcu_pin_obj_t pin_PE06;
+extern const mcu_pin_obj_t pin_PC13;
+extern const mcu_pin_obj_t pin_PC14;
+//pg 51
+extern const mcu_pin_obj_t pin_PC15;
+extern const mcu_pin_obj_t pin_PF00; // 144 only
+extern const mcu_pin_obj_t pin_PF01; // 144 only
+extern const mcu_pin_obj_t pin_PF02; // 144 only
+extern const mcu_pin_obj_t pin_PF03; // 144 only
+extern const mcu_pin_obj_t pin_PF04; // 144 only
+extern const mcu_pin_obj_t pin_PF05; // 144 only
+extern const mcu_pin_obj_t pin_PF06; // 144 only
+extern const mcu_pin_obj_t pin_PF07; // 144 only
+extern const mcu_pin_obj_t pin_PF08; // 144 only
+extern const mcu_pin_obj_t pin_PF09; // 144 only
+extern const mcu_pin_obj_t pin_PF10; // 144 only
+//pg 52
+extern const mcu_pin_obj_t pin_PC00;
+extern const mcu_pin_obj_t pin_PC01;
+extern const mcu_pin_obj_t pin_PC02;
+extern const mcu_pin_obj_t pin_PC03;
+extern const mcu_pin_obj_t pin_PA00;
+extern const mcu_pin_obj_t pin_PA01;
+extern const mcu_pin_obj_t pin_PA02;
+//pg 53
+extern const mcu_pin_obj_t pin_PA03;
+extern const mcu_pin_obj_t pin_PA04;
+extern const mcu_pin_obj_t pin_PA05;
+extern const mcu_pin_obj_t pin_PA06;
+extern const mcu_pin_obj_t pin_PA07;
+extern const mcu_pin_obj_t pin_PC04;
+//pg 54
+extern const mcu_pin_obj_t pin_PC05;
+extern const mcu_pin_obj_t pin_PB00;
+extern const mcu_pin_obj_t pin_PB01;
+extern const mcu_pin_obj_t pin_PB02;
+extern const mcu_pin_obj_t pin_PF11; // 144 only
+extern const mcu_pin_obj_t pin_PF12; // 144 only
+extern const mcu_pin_obj_t pin_PF13; // 144 only
+extern const mcu_pin_obj_t pin_PF14; // 144 only
+extern const mcu_pin_obj_t pin_PF15; // 144 only
+extern const mcu_pin_obj_t pin_PG00; // 144 only
+extern const mcu_pin_obj_t pin_PG01; // 144 only
+//pg 55
+extern const mcu_pin_obj_t pin_PE07;
+extern const mcu_pin_obj_t pin_PE08;
+extern const mcu_pin_obj_t pin_PE09;
+extern const mcu_pin_obj_t pin_PE10;
+extern const mcu_pin_obj_t pin_PE11;
+extern const mcu_pin_obj_t pin_PE12;
+extern const mcu_pin_obj_t pin_PE13;
+extern const mcu_pin_obj_t pin_PE14;
+//pg 56
+extern const mcu_pin_obj_t pin_PE15;
+extern const mcu_pin_obj_t pin_PB10;
+extern const mcu_pin_obj_t pin_PB11; // 144 only
+extern const mcu_pin_obj_t pin_PB12;
+extern const mcu_pin_obj_t pin_PB13;
+//pg 57
+extern const mcu_pin_obj_t pin_PB14;
+extern const mcu_pin_obj_t pin_PB15;
+extern const mcu_pin_obj_t pin_PD08;
+extern const mcu_pin_obj_t pin_PD09;
+extern const mcu_pin_obj_t pin_PD10;
+extern const mcu_pin_obj_t pin_PD11;
+extern const mcu_pin_obj_t pin_PD12;
+//pg 58
+extern const mcu_pin_obj_t pin_PD13;
+extern const mcu_pin_obj_t pin_PD14;
+extern const mcu_pin_obj_t pin_PD15;
+extern const mcu_pin_obj_t pin_PG02; // 144 only
+extern const mcu_pin_obj_t pin_PG03; // 144 only
+extern const mcu_pin_obj_t pin_PG04; // 144 only
+extern const mcu_pin_obj_t pin_PG05; // 144 only
+extern const mcu_pin_obj_t pin_PG06; // 144 only
+extern const mcu_pin_obj_t pin_PG07; // 144 only
+extern const mcu_pin_obj_t pin_PG08; // 144 only
+//pg 59
+extern const mcu_pin_obj_t pin_PC06;
+extern const mcu_pin_obj_t pin_PC07;
+extern const mcu_pin_obj_t pin_PC08;
+extern const mcu_pin_obj_t pin_PC09;
+extern const mcu_pin_obj_t pin_PA08;
+extern const mcu_pin_obj_t pin_PA09;
+extern const mcu_pin_obj_t pin_PA10;
+//pg 60
+extern const mcu_pin_obj_t pin_PA11;
+extern const mcu_pin_obj_t pin_PA12;
+extern const mcu_pin_obj_t pin_PA13;
+extern const mcu_pin_obj_t pin_PA14;
+extern const mcu_pin_obj_t pin_PA15;
+extern const mcu_pin_obj_t pin_PC10;
+extern const mcu_pin_obj_t pin_PC11;
+//pg 61
+extern const mcu_pin_obj_t pin_PC12;
+extern const mcu_pin_obj_t pin_PD00;
+extern const mcu_pin_obj_t pin_PD01;
+extern const mcu_pin_obj_t pin_PD02;
+extern const mcu_pin_obj_t pin_PD03;
+extern const mcu_pin_obj_t pin_PD04;
+extern const mcu_pin_obj_t pin_PD05;
+extern const mcu_pin_obj_t pin_PD06;
+extern const mcu_pin_obj_t pin_PD07;
+//pg 62
+extern const mcu_pin_obj_t pin_PG09; // 144 only
+extern const mcu_pin_obj_t pin_PG10; // 144 only
+extern const mcu_pin_obj_t pin_PG11; // 144 only
+extern const mcu_pin_obj_t pin_PG12; // 144 only
+extern const mcu_pin_obj_t pin_PG13; // 144 only
+extern const mcu_pin_obj_t pin_PG14; // 144 only
+extern const mcu_pin_obj_t pin_PG15; // 144 only
+extern const mcu_pin_obj_t pin_PB03;
+extern const mcu_pin_obj_t pin_PB04;
+//pg 63
+extern const mcu_pin_obj_t pin_PB05;
+extern const mcu_pin_obj_t pin_PB06;
+extern const mcu_pin_obj_t pin_PB07;
+extern const mcu_pin_obj_t pin_PB08;
+extern const mcu_pin_obj_t pin_PB09;
+extern const mcu_pin_obj_t pin_PE00;
+extern const mcu_pin_obj_t pin_PE01;
+
+#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F412ZG_PINS_H
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c
index 651aea269..aee0bd5eb 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c
@@ -26,6 +26,7 @@
#include "stm32f4xx_hal.h"
#include "stm32f4/gpio.h"
+#include "py/mpconfig.h"
#include "common-hal/microcontroller/Pin.h"
void stm32f4_peripherals_gpio_init(void) {
@@ -40,8 +41,11 @@ void stm32f4_peripherals_gpio_init(void) {
//Never reset pins
never_reset_pin_number(2,14); //PC14 OSC32_IN
never_reset_pin_number(2,15); //PC15 OSC32_OUT
+
+ #if !(BOARD_OVERWRITE_SWD)
never_reset_pin_number(0,13); //PA13 SWDIO
never_reset_pin_number(0,14); //PA14 SWCLK
+ #endif
// Port H is not included in GPIO port array
// never_reset_pin_number(5,0); //PH0 JTDO
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/clocks.c b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/clocks.c
index 107056550..b208f9dfb 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/clocks.c
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/clocks.c
@@ -25,6 +25,7 @@
* THE SOFTWARE.
*/
#include "stm32f4xx_hal.h"
+#include "py/mpconfig.h"
void stm32f4_peripherals_clocks_init(void) {
//System clock init
@@ -46,7 +47,7 @@ void stm32f4_peripherals_clocks_init(void) {
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLM = 8;
+ RCC_OscInitStruct.PLL.PLLM = BOARD_OSC_DIV;
RCC_OscInitStruct.PLL.PLLN = 200;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
diff --git a/ports/stm32f4/supervisor/internal_flash.h b/ports/stm32f4/supervisor/internal_flash.h
index b6d26a07f..9f16a799d 100644
--- a/ports/stm32f4/supervisor/internal_flash.h
+++ b/ports/stm32f4/supervisor/internal_flash.h
@@ -32,6 +32,11 @@
#include "py/mpconfig.h"
+#ifdef STM32F401xE
+#define STM32_FLASH_SIZE 0x80000 //512KiB
+#define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 //48KiB
+#endif
+
#ifdef STM32F411xE
#define STM32_FLASH_SIZE 0x80000 //512KiB
#define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 //48KiB
@@ -47,6 +52,11 @@
#define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 //48KiB
#endif
+#ifdef STM32F407xx
+#define STM32_FLASH_SIZE 0x100000 //1MB
+#define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 //48KiB
+#endif
+
#define STM32_FLASH_OFFSET 0x8000000 //All STM32 chips map to this flash location
#define INTERNAL_FLASH_FILESYSTEM_START_ADDR 0x08004000
diff --git a/ports/stm32f4/supervisor/port.c b/ports/stm32f4/supervisor/port.c
index df5a70cd1..e9e4720d7 100644
--- a/ports/stm32f4/supervisor/port.c
+++ b/ports/stm32f4/supervisor/port.c
@@ -50,7 +50,6 @@ safe_mode_t port_init(void) {
stm32f4_peripherals_gpio_init();
tick_init();
- board_init();
return NO_SAFE_MODE;
}
@@ -71,6 +70,14 @@ void reset_cpu(void) {
NVIC_SystemReset();
}
+uint32_t *port_heap_get_bottom(void) {
+ return port_stack_get_limit();
+}
+
+uint32_t *port_heap_get_top(void) {
+ return port_stack_get_top();
+}
+
uint32_t *port_stack_get_limit(void) {
return &_ebss;
}
diff --git a/ports/stm32f4/supervisor/usb.c b/ports/stm32f4/supervisor/usb.c
index 0d2d5cce9..358c2de5b 100644
--- a/ports/stm32f4/supervisor/usb.c
+++ b/ports/stm32f4/supervisor/usb.c
@@ -38,7 +38,7 @@
STATIC void init_usb_vbus_sense(void) {
-#ifdef BOARD_NO_VBUS_SENSE
+#if (BOARD_NO_VBUS_SENSE)
// Disable VBUS sensing
#ifdef USB_OTG_GCCFG_VBDEN
USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
@@ -58,7 +58,6 @@ STATIC void init_usb_vbus_sense(void) {
#endif
}
-
void init_usb_hardware(void) {
//TODO: if future chips overload this with options, move to peripherals management.
@@ -106,6 +105,7 @@ void init_usb_hardware(void) {
#endif
/* Peripheral clock enable */
+ __HAL_RCC_USB_OTG_FS_CLK_DISABLE();
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
init_usb_vbus_sense();
diff --git a/ports/stm32f4/system_stm32f4xx.c b/ports/stm32f4/system_stm32f4xx.c
index 3303f969d..caa4f9caf 100644
--- a/ports/stm32f4/system_stm32f4xx.c
+++ b/ports/stm32f4/system_stm32f4xx.c
@@ -1,3 +1,27 @@
+/*
+ * Taken from ST Cube library and modified. See below for original header.
+ *
+ * Modifications copyright (c) 2019 Lucian Copeland 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.
+ */
+
/**
******************************************************************************
* @file system_stm32f4xx.c
@@ -63,6 +87,7 @@
#include "stm32f4xx.h"
+#include "py/mpconfig.h"
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
@@ -193,10 +218,12 @@ void SystemInit(void)
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
/* Configure the Vector Table location add offset address ------------------*/
-#ifdef VECT_TAB_SRAM
- SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
-#else
- SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
+#if !(BOARD_VTOR_DEFER) //only set VTOR if the bootloader hasn't already
+ #ifdef VECT_TAB_SRAM
+ SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
+ #else
+ SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
+ #endif
#endif
}