From 122d901ef1b624c26771532cb4725eaa8f85e0f4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 2 Sep 2021 12:37:00 +1000 Subject: [PATCH 001/335] extmod/machine_i2c: Make SoftI2C configurable via macro option. The zephyr port doesn't support SoftI2C so it's not enabled, and the legacy I2C constructor check can be removed. Signed-off-by: Damien George --- extmod/machine_i2c.c | 12 ++++++++++-- ports/esp32/mpconfigport.h | 1 + ports/esp8266/mpconfigport.h | 1 + ports/mimxrt/mpconfigport.h | 1 + ports/nrf/mpconfigport.h | 1 + ports/rp2/mpconfigport.h | 1 + ports/stm32/mpconfigport.h | 1 + ports/zephyr/machine_i2c.c | 2 -- py/mpconfig.h | 5 +++++ 9 files changed, 21 insertions(+), 4 deletions(-) diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c index 44161fbbb9..b2e39c534d 100644 --- a/extmod/machine_i2c.c +++ b/extmod/machine_i2c.c @@ -33,7 +33,7 @@ #include "py/runtime.h" #include "extmod/machine_i2c.h" -#if MICROPY_PY_MACHINE_I2C +#if MICROPY_PY_MACHINE_SOFTI2C typedef mp_machine_soft_i2c_obj_t machine_i2c_obj_t; @@ -240,9 +240,13 @@ int mp_machine_soft_i2c_transfer(mp_obj_base_t *self_in, uint16_t addr, size_t n return transfer_ret; } +#endif // MICROPY_PY_MACHINE_SOFTI2C + /******************************************************************************/ // Generic helper functions +#if MICROPY_PY_MACHINE_I2C || MICROPY_PY_MACHINE_SOFTI2C + // For use by ports that require a single buffer of data for a read/write transfer int mp_machine_i2c_transfer_adaptor(mp_obj_base_t *self, uint16_t addr, size_t n, mp_machine_i2c_buf_t *bufs, unsigned int flags) { size_t len; @@ -628,9 +632,13 @@ STATIC const mp_rom_map_elem_t machine_i2c_locals_dict_table[] = { }; MP_DEFINE_CONST_DICT(mp_machine_i2c_locals_dict, machine_i2c_locals_dict_table); +#endif // MICROPY_PY_MACHINE_I2C || MICROPY_PY_MACHINE_SOFTI2C + /******************************************************************************/ // Implementation of soft I2C +#if MICROPY_PY_MACHINE_SOFTI2C + STATIC void mp_machine_soft_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { mp_machine_soft_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "SoftI2C(scl=" MP_HAL_PIN_FMT ", sda=" MP_HAL_PIN_FMT ", freq=%u)", @@ -711,4 +719,4 @@ const mp_obj_type_t mp_machine_soft_i2c_type = { .locals_dict = (mp_obj_dict_t *)&mp_machine_i2c_locals_dict, }; -#endif // MICROPY_PY_MACHINE_I2C +#endif // MICROPY_PY_MACHINE_SOFTI2C diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 057251fa49..b9e1337186 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -159,6 +159,7 @@ #define MICROPY_PY_MACHINE_BITSTREAM (1) #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_I2C (1) +#define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SPI_MSB (0) #define MICROPY_PY_MACHINE_SPI_LSB (1) diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h index c7e2f4a44b..4e234683b9 100644 --- a/ports/esp8266/mpconfigport.h +++ b/ports/esp8266/mpconfigport.h @@ -82,6 +82,7 @@ #define MICROPY_PY_MACHINE_BITSTREAM (1) #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_I2C (1) +#define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_UWEBSOCKET (1) #define MICROPY_PY_WEBREPL (1) diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 1066b93e16..76716f705a 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -126,6 +126,7 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_I2C (1) +#define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_FRAMEBUF (1) diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 8a622d811c..6290f85e87 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -136,6 +136,7 @@ #define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_PY_MACHINE (1) #define MICROPY_PY_MACHINE_PULSE (0) +#define MICROPY_PY_MACHINE_SOFTI2C (MICROPY_PY_MACHINE_I2C) #define MICROPY_PY_MACHINE_SPI (0) #define MICROPY_PY_MACHINE_SPI_MIN_DELAY (0) #define MICROPY_PY_FRAMEBUF (0) diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index 8d053ac1cd..04a2e48161 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -132,6 +132,7 @@ #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_I2C (1) +#define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SPI_MSB (SPI_MSB_FIRST) #define MICROPY_PY_MACHINE_SPI_LSB (SPI_LSB_FIRST) diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 6f97377d9b..e2863f192c 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -201,6 +201,7 @@ #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new #define MICROPY_PY_MACHINE_I2C (1) +#define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SPI_MSB (SPI_FIRSTBIT_MSB) #define MICROPY_PY_MACHINE_SPI_LSB (SPI_FIRSTBIT_LSB) diff --git a/ports/zephyr/machine_i2c.c b/ports/zephyr/machine_i2c.c index aa8823392d..810c3e5a9e 100644 --- a/ports/zephyr/machine_i2c.c +++ b/ports/zephyr/machine_i2c.c @@ -53,8 +53,6 @@ STATIC void machine_hard_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp } mp_obj_t machine_hard_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - MP_MACHINE_I2C_CHECK_FOR_LEGACY_SOFTI2C_CONSTRUCTION(n_args, n_kw, all_args); - enum { ARG_id, ARG_scl, ARG_sda, ARG_freq, ARG_timeout }; static const mp_arg_t allowed_args[] = { { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ }, diff --git a/py/mpconfig.h b/py/mpconfig.h index 71440da394..cc302c3cb7 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1485,6 +1485,11 @@ typedef double mp_float_t; #define MICROPY_PY_MACHINE_I2C (0) #endif +// Whether to provide the "machine.SoftI2C" class +#ifndef MICROPY_PY_MACHINE_SOFTI2C +#define MICROPY_PY_MACHINE_SOFTI2C (0) +#endif + #ifndef MICROPY_PY_MACHINE_SPI #define MICROPY_PY_MACHINE_SPI (0) #endif From afe0634c989d81f0c887308a7bc152061cb5d319 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 2 Sep 2021 12:39:28 +1000 Subject: [PATCH 002/335] extmod/machine_spi: Make SoftSPI configurable via macro option. Signed-off-by: Damien George --- extmod/machine_spi.c | 11 +++++++---- ports/esp32/mpconfigport.h | 1 + ports/esp8266/mpconfigport.h | 1 + ports/mimxrt/mpconfigport.h | 1 + ports/rp2/mpconfigport.h | 1 + ports/stm32/mpconfigport.h | 1 + py/mpconfig.h | 5 +++++ 7 files changed, 17 insertions(+), 4 deletions(-) diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c index c951a5137c..ae5e6677d2 100644 --- a/extmod/machine_spi.c +++ b/extmod/machine_spi.c @@ -30,8 +30,6 @@ #include "py/runtime.h" #include "extmod/machine_spi.h" -#if MICROPY_PY_MACHINE_SPI - // if a port didn't define MSB/LSB constants then provide them #ifndef MICROPY_PY_MACHINE_SPI_MSB #define MICROPY_PY_MACHINE_SPI_MSB (0) @@ -41,6 +39,8 @@ /******************************************************************************/ // MicroPython bindings for generic machine.SPI +#if MICROPY_PY_MACHINE_SPI || MICROPY_PY_MACHINE_SOFTSPI + STATIC mp_obj_t machine_spi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]); mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)s->type->protocol; @@ -115,12 +115,15 @@ STATIC const mp_rom_map_elem_t machine_spi_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_MSB), MP_ROM_INT(MICROPY_PY_MACHINE_SPI_MSB) }, { MP_ROM_QSTR(MP_QSTR_LSB), MP_ROM_INT(MICROPY_PY_MACHINE_SPI_LSB) }, }; - MP_DEFINE_CONST_DICT(mp_machine_spi_locals_dict, machine_spi_locals_dict_table); +#endif // MICROPY_PY_MACHINE_SPI || MICROPY_PY_MACHINE_SOFTSPI + /******************************************************************************/ // Implementation of soft SPI +#if MICROPY_PY_MACHINE_SOFTSPI + STATIC uint32_t baudrate_from_delay_half(uint32_t delay_half) { #ifdef MICROPY_HW_SOFTSPI_MIN_DELAY if (delay_half == MICROPY_HW_SOFTSPI_MIN_DELAY) { @@ -258,4 +261,4 @@ const mp_obj_type_t mp_machine_soft_spi_type = { .locals_dict = (mp_obj_dict_t *)&mp_machine_spi_locals_dict, }; -#endif // MICROPY_PY_MACHINE_SPI +#endif // MICROPY_PY_MACHINE_SOFTSPI diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index b9e1337186..f8b26bfe84 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -163,6 +163,7 @@ #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SPI_MSB (0) #define MICROPY_PY_MACHINE_SPI_LSB (1) +#define MICROPY_PY_MACHINE_SOFTSPI (1) #ifndef MICROPY_PY_MACHINE_DAC #define MICROPY_PY_MACHINE_DAC (1) #endif diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h index 4e234683b9..5364dd58b5 100644 --- a/ports/esp8266/mpconfigport.h +++ b/ports/esp8266/mpconfigport.h @@ -84,6 +84,7 @@ #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) +#define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_UWEBSOCKET (1) #define MICROPY_PY_WEBREPL (1) #define MICROPY_PY_WEBREPL_DELAY (20) diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 76716f705a..88e1872cfc 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -128,6 +128,7 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) +#define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_FRAMEBUF (1) // Use VfsLfs2's types for fileio/textio diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index 04a2e48161..ad3de396b0 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -136,6 +136,7 @@ #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SPI_MSB (SPI_MSB_FIRST) #define MICROPY_PY_MACHINE_SPI_LSB (SPI_LSB_FIRST) +#define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_FRAMEBUF (1) #define MICROPY_VFS (1) #define MICROPY_VFS_LFS2 (1) diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index e2863f192c..eff90cb25f 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -205,6 +205,7 @@ #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SPI_MSB (SPI_FIRSTBIT_MSB) #define MICROPY_PY_MACHINE_SPI_LSB (SPI_FIRSTBIT_LSB) +#define MICROPY_PY_MACHINE_SOFTSPI (1) #endif #define MICROPY_HW_SOFTSPI_MIN_DELAY (0) #define MICROPY_HW_SOFTSPI_MAX_BAUDRATE (HAL_RCC_GetSysClockFreq() / 48) diff --git a/py/mpconfig.h b/py/mpconfig.h index cc302c3cb7..288b105375 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1494,6 +1494,11 @@ typedef double mp_float_t; #define MICROPY_PY_MACHINE_SPI (0) #endif +// Whether to provide the "machine.SoftSPI" class +#ifndef MICROPY_PY_MACHINE_SOFTSPI +#define MICROPY_PY_MACHINE_SOFTSPI (0) +#endif + #ifndef MICROPY_PY_USSL #define MICROPY_PY_USSL (0) // Whether to add finaliser code to ussl objects From d41f6dde568df53a0f66a01a3c362e1c1e35ef14 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 2 Sep 2021 12:39:50 +1000 Subject: [PATCH 003/335] extmod/modonewire: Make _onewire module configurable via macro option. Signed-off-by: Damien George --- extmod/modonewire.c | 4 ++++ ports/esp32/mpconfigport.h | 1 + ports/esp8266/mpconfigport.h | 1 + ports/mimxrt/mpconfigport.h | 1 + ports/rp2/mpconfigport.h | 1 + py/mpconfig.h | 5 +++++ 6 files changed, 13 insertions(+) diff --git a/extmod/modonewire.c b/extmod/modonewire.c index 6abe3dfad9..8b34268157 100644 --- a/extmod/modonewire.c +++ b/extmod/modonewire.c @@ -30,6 +30,8 @@ #include "py/obj.h" #include "py/mphal.h" +#if MICROPY_PY_ONEWIRE + /******************************************************************************/ // Low-level 1-Wire routines @@ -160,3 +162,5 @@ const mp_obj_module_t mp_module_onewire = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t *)&onewire_module_globals, }; + +#endif // MICROPY_PY_ONEWIRE diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index f8b26bfe84..b306be937d 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -182,6 +182,7 @@ #define MICROPY_PY_WEBREPL (1) #define MICROPY_PY_FRAMEBUF (1) #define MICROPY_PY_BTREE (1) +#define MICROPY_PY_ONEWIRE (1) #define MICROPY_PY_USOCKET_EVENTS (MICROPY_PY_WEBREPL) #define MICROPY_PY_BLUETOOTH_RANDOM_ADDR (1) #define MICROPY_PY_BLUETOOTH_DEFAULT_GAP_NAME ("ESP32") diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h index 5364dd58b5..78263efec5 100644 --- a/ports/esp8266/mpconfigport.h +++ b/ports/esp8266/mpconfigport.h @@ -86,6 +86,7 @@ #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_UWEBSOCKET (1) +#define MICROPY_PY_ONEWIRE (1) #define MICROPY_PY_WEBREPL (1) #define MICROPY_PY_WEBREPL_DELAY (20) #define MICROPY_PY_WEBREPL_STATIC_FILEBUF (1) diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 88e1872cfc..be2b87e6a2 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -130,6 +130,7 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_FRAMEBUF (1) +#define MICROPY_PY_ONEWIRE (1) // Use VfsLfs2's types for fileio/textio #define mp_type_fileio mp_type_vfs_lfs2_fileio diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index ad3de396b0..4da34cd038 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -138,6 +138,7 @@ #define MICROPY_PY_MACHINE_SPI_LSB (SPI_LSB_FIRST) #define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_FRAMEBUF (1) +#define MICROPY_PY_ONEWIRE (1) #define MICROPY_VFS (1) #define MICROPY_VFS_LFS2 (1) #define MICROPY_VFS_FAT (1) diff --git a/py/mpconfig.h b/py/mpconfig.h index 288b105375..1b41b6bd0f 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1517,6 +1517,11 @@ typedef double mp_float_t; #define MICROPY_PY_BTREE (0) #endif +// Whether to provide the low-level "_onewire" module +#ifndef MICROPY_PY_ONEWIRE +#define MICROPY_PY_ONEWIRE (0) +#endif + /*****************************************************************************/ /* Hooks for a port to add builtins */ From 1083cb2f334f4891e4dc8094f3eaaa839d2e2626 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 2 Sep 2021 12:40:48 +1000 Subject: [PATCH 004/335] zephyr/mphalport.h: Remove unused and unimplemented C-level pin API. It gives compile warnings. Signed-off-by: Damien George --- ports/zephyr/mphalport.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/ports/zephyr/mphalport.h b/ports/zephyr/mphalport.h index ba902a76aa..ffe68da246 100644 --- a/ports/zephyr/mphalport.h +++ b/ports/zephyr/mphalport.h @@ -33,10 +33,3 @@ static inline uint64_t mp_hal_time_ns(void) { } #define mp_hal_delay_us_fast(us) (mp_hal_delay_us(us)) - -// C-level pin API is not currently implemented -#define MP_HAL_PIN_FMT "%d" -#define mp_hal_pin_name(p) (0) -#define mp_hal_pin_od_low(p) (mp_raise_NotImplementedError("mp_hal_pin_od_low")) -#define mp_hal_pin_od_high(p) (mp_raise_NotImplementedError("mp_hal_pin_od_high")) -#define mp_hal_pin_open_drain(p) (mp_raise_NotImplementedError("mp_hal_pin_open_drain")) From 05cd17e36fbc5d3606e34e430dc72549bd1d6708 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 2 Sep 2021 13:02:49 +1000 Subject: [PATCH 005/335] stm32/pin: Enable GPIO clock of pin if it's constructed without init. Fixes issue #7363. Signed-off-by: Damien George --- ports/stm32/pin.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ports/stm32/pin.c b/ports/stm32/pin.c index f1c5eee850..ad153311e3 100644 --- a/ports/stm32/pin.c +++ b/ports/stm32/pin.c @@ -256,6 +256,9 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); pin_obj_init_helper(pin, n_args - 1, args + 1, &kw_args); + } else { + // enable the peripheral clock so pin reading at least works + mp_hal_gpio_clock_enable(pin->gpio); } return MP_OBJ_FROM_PTR(pin); From 9792c9105f13f8d0196677e3e4bf003a96998c7b Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 2 Sep 2021 13:03:47 +1000 Subject: [PATCH 006/335] stm32/main: Don't unconditionally enable GPIO A,B,C,D clocks. Rely on them being enabled only when needed. Signed-off-by: Damien George --- ports/stm32/main.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/ports/stm32/main.c b/ports/stm32/main.c index d55f1a2c30..ccc8fd1ae7 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -369,14 +369,6 @@ void stm32_main(uint32_t reset_mode) { // set the system clock to be HSE SystemClock_Config(); - // enable GPIO clocks - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - __HAL_RCC_GPIOC_CLK_ENABLE(); - #if defined(GPIOD) - __HAL_RCC_GPIOD_CLK_ENABLE(); - #endif - #if defined(STM32F4) || defined(STM32F7) #if defined(__HAL_RCC_DTCMRAMEN_CLK_ENABLE) // The STM32F746 doesn't really have CCM memory, but it does have DTCM, From af64c2ddbd758ab6bac0fcca94c66d89046663be Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 24 Jun 2021 12:37:50 +1000 Subject: [PATCH 007/335] extmod/machine_pwm: Factor out machine.PWM bindings to common code. This commit refactors machine.PWM and creates extmod/machine_pwm.c. The esp8266, esp32 and rp2 ports all use this and provide implementations of the required PWM functionality. This helps to reduce code duplication and keep the same Python API across ports. This commit does not make any functional changes. Signed-off-by: Damien George --- extmod/extmod.cmake | 1 + extmod/machine_pwm.c | 143 +++++++++++++++++++++++++++ extmod/machine_pwm.h | 55 +++++++++++ ports/esp32/machine_pwm.c | 114 ++++++--------------- ports/esp32/main/CMakeLists.txt | 1 - ports/esp32/modmachine.c | 1 + ports/esp32/modmachine.h | 1 - ports/esp32/mpconfigport.h | 4 + ports/esp8266/Makefile | 1 - ports/esp8266/machine_pwm.c | 93 ++++++------------ ports/esp8266/modmachine.c | 3 +- ports/esp8266/modmachine.h | 1 - ports/esp8266/mpconfigport.h | 4 + ports/rp2/CMakeLists.txt | 2 - ports/rp2/machine_pwm.c | 169 +++++++++++++------------------- ports/rp2/modmachine.c | 1 + ports/rp2/modmachine.h | 1 - ports/rp2/mpconfigport.h | 3 + py/py.mk | 1 + 19 files changed, 342 insertions(+), 257 deletions(-) create mode 100644 extmod/machine_pwm.c create mode 100644 extmod/machine_pwm.h diff --git a/extmod/extmod.cmake b/extmod/extmod.cmake index c6b45b0d3e..69ec39759b 100644 --- a/extmod/extmod.cmake +++ b/extmod/extmod.cmake @@ -10,6 +10,7 @@ set(MICROPY_SOURCE_EXTMOD ${MICROPY_EXTMOD_DIR}/machine_i2c.c ${MICROPY_EXTMOD_DIR}/machine_mem.c ${MICROPY_EXTMOD_DIR}/machine_pulse.c + ${MICROPY_EXTMOD_DIR}/machine_pwm.c ${MICROPY_EXTMOD_DIR}/machine_signal.c ${MICROPY_EXTMOD_DIR}/machine_spi.c ${MICROPY_EXTMOD_DIR}/modbluetooth.c diff --git a/extmod/machine_pwm.c b/extmod/machine_pwm.c new file mode 100644 index 0000000000..ddf49c1358 --- /dev/null +++ b/extmod/machine_pwm.c @@ -0,0 +1,143 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020-2021 Damien P. George + * + * 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/runtime.h" + +#if MICROPY_PY_MACHINE_PWM + +#include "extmod/machine_pwm.h" + +#ifdef MICROPY_PY_MACHINE_PWM_INCLUDEFILE +#include MICROPY_PY_MACHINE_PWM_INCLUDEFILE +#endif + +#if MICROPY_PY_MACHINE_PWM_INIT +STATIC mp_obj_t machine_pwm_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_machine_pwm_init_helper(args[0], n_args - 1, args + 1, kw_args); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_pwm_init_obj, 1, machine_pwm_init); +#endif + +// PWM.deinit() +STATIC mp_obj_t machine_pwm_deinit(mp_obj_t self_in) { + machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_machine_pwm_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pwm_deinit_obj, machine_pwm_deinit); + +// PWM.freq([value]) +STATIC mp_obj_t machine_pwm_freq(size_t n_args, const mp_obj_t *args) { + machine_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (n_args == 1) { + // Get frequency. + return mp_machine_pwm_freq_get(self); + } else { + // Set the frequency. + mp_int_t freq = mp_obj_get_int(args[1]); + mp_machine_pwm_freq_set(self, freq); + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pwm_freq_obj, 1, 2, machine_pwm_freq); + +#if MICROPY_PY_MACHINE_PWM_DUTY +// PWM.duty([duty]) +STATIC mp_obj_t machine_pwm_duty(size_t n_args, const mp_obj_t *args) { + machine_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (n_args == 1) { + // Get duty cycle. + return mp_machine_pwm_duty_get(self); + } else { + // Set duty cycle. + mp_int_t duty = mp_obj_get_int(args[1]); + mp_machine_pwm_duty_set(self, duty); + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pwm_duty_obj, 1, 2, machine_pwm_duty); +#endif + +#if MICROPY_PY_MACHINE_PWM_DUTY_U16_NS + +// PWM.duty_u16([value]) +STATIC mp_obj_t machine_pwm_duty_u16(size_t n_args, const mp_obj_t *args) { + machine_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (n_args == 1) { + // Get duty cycle. + return mp_machine_pwm_duty_get_u16(self); + } else { + // Set duty cycle. + mp_int_t duty_u16 = mp_obj_get_int(args[1]); + mp_machine_pwm_duty_set_u16(self, duty_u16); + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pwm_duty_u16_obj, 1, 2, machine_pwm_duty_u16); + +// PWM.duty_ns([value]) +STATIC mp_obj_t machine_pwm_duty_ns(size_t n_args, const mp_obj_t *args) { + machine_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (n_args == 1) { + // Get duty cycle. + return mp_machine_pwm_duty_get_ns(self); + } else { + // Set duty cycle. + mp_int_t duty_ns = mp_obj_get_int(args[1]); + mp_machine_pwm_duty_set_ns(self, duty_ns); + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pwm_duty_ns_obj, 1, 2, machine_pwm_duty_ns); + +#endif + +STATIC const mp_rom_map_elem_t machine_pwm_locals_dict_table[] = { + #if MICROPY_PY_MACHINE_PWM_INIT + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_pwm_init_obj) }, + #endif + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_pwm_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&machine_pwm_freq_obj) }, + #if MICROPY_PY_MACHINE_PWM_DUTY + { MP_ROM_QSTR(MP_QSTR_duty), MP_ROM_PTR(&machine_pwm_duty_obj) }, + #endif + #if MICROPY_PY_MACHINE_PWM_DUTY_U16_NS + { MP_ROM_QSTR(MP_QSTR_duty_u16), MP_ROM_PTR(&machine_pwm_duty_u16_obj) }, + { MP_ROM_QSTR(MP_QSTR_duty_ns), MP_ROM_PTR(&machine_pwm_duty_ns_obj) }, + #endif +}; +STATIC MP_DEFINE_CONST_DICT(machine_pwm_locals_dict, machine_pwm_locals_dict_table); + +const mp_obj_type_t machine_pwm_type = { + { &mp_type_type }, + .name = MP_QSTR_PWM, + .print = mp_machine_pwm_print, + .make_new = mp_machine_pwm_make_new, + .locals_dict = (mp_obj_dict_t *)&machine_pwm_locals_dict, +}; + +#endif // MICROPY_PY_MACHINE_PWM diff --git a/extmod/machine_pwm.h b/extmod/machine_pwm.h new file mode 100644 index 0000000000..f0953014ca --- /dev/null +++ b/extmod/machine_pwm.h @@ -0,0 +1,55 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Damien P. George + * + * 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_EXTMOD_MACHINE_PWM_H +#define MICROPY_INCLUDED_EXTMOD_MACHINE_PWM_H + +#include "py/obj.h" + +// A port must provide this type, but it's otherwise opaque. +typedef struct _machine_pwm_obj_t machine_pwm_obj_t; + +// This PWM class is implemented by machine_pwm.c. +extern const mp_obj_type_t machine_pwm_type; + +// A port must provide implementations of these low-level PWM functions, either as global +// linker symbols, or included directly if MICROPY_PY_MACHINE_PWM_INCLUDEFILE is defined. +#ifndef MICROPY_PY_MACHINE_PWM_INCLUDEFILE +void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); +mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); +void mp_machine_pwm_init_helper(machine_pwm_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); +void mp_machine_pwm_deinit(machine_pwm_obj_t *self); +mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self); +void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq); +mp_obj_t mp_machine_pwm_duty_get(machine_pwm_obj_t *self); +void mp_machine_pwm_duty_set(machine_pwm_obj_t *self, mp_int_t duty); +mp_obj_t mp_machine_pwm_duty_get_u16(machine_pwm_obj_t *self); +void mp_machine_pwm_duty_set_u16(machine_pwm_obj_t *self, mp_int_t duty_u16); +mp_obj_t mp_machine_pwm_duty_get_ns(machine_pwm_obj_t *self); +void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty_ns); +#endif + +#endif // MICROPY_INCLUDED_EXTMOD_MACHINE_PWM_H diff --git a/ports/esp32/machine_pwm.c b/ports/esp32/machine_pwm.c index a7d7d29df8..9fe06aa699 100644 --- a/ports/esp32/machine_pwm.c +++ b/ports/esp32/machine_pwm.c @@ -23,25 +23,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include + +#include "py/runtime.h" +#include "py/mphal.h" + #include "driver/ledc.h" #include "esp_err.h" -#include "py/nlr.h" -#include "py/runtime.h" -#include "modmachine.h" -#include "mphalport.h" - -// Forward dec'l -extern const mp_obj_type_t machine_pwm_type; - -typedef struct _esp32_pwm_obj_t { - mp_obj_base_t base; - gpio_num_t pin; - uint8_t active; - uint8_t channel; -} esp32_pwm_obj_t; - // Which channel has which GPIO pin assigned? // (-1 if not assigned) STATIC int chan_gpio[LEDC_CHANNEL_MAX]; @@ -110,11 +98,17 @@ STATIC int set_freq(int newval) { } /******************************************************************************/ - // MicroPython bindings for PWM -STATIC void esp32_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - esp32_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); +typedef struct _machine_pwm_obj_t { + mp_obj_base_t base; + gpio_num_t pin; + uint8_t active; + uint8_t channel; +} machine_pwm_obj_t; + +STATIC void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "PWM(%u", self->pin); if (self->active) { mp_printf(print, ", freq=%u, duty=%u", timer_cfg.freq_hz, @@ -123,7 +117,7 @@ STATIC void esp32_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ mp_printf(print, ")"); } -STATIC void esp32_pwm_init_helper(esp32_pwm_obj_t *self, +STATIC void mp_machine_pwm_init_helper(machine_pwm_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_freq, ARG_duty }; static const mp_arg_t allowed_args[] = { @@ -192,13 +186,13 @@ STATIC void esp32_pwm_init_helper(esp32_pwm_obj_t *self, } } -STATIC mp_obj_t esp32_pwm_make_new(const mp_obj_type_t *type, +STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); gpio_num_t pin_id = machine_pin_get_id(args[0]); // create PWM object from the given pin - esp32_pwm_obj_t *self = m_new_obj(esp32_pwm_obj_t); + machine_pwm_obj_t *self = m_new_obj(machine_pwm_obj_t); self->base.type = &machine_pwm_type; self->pin = pin_id; self->active = 0; @@ -213,20 +207,12 @@ STATIC mp_obj_t esp32_pwm_make_new(const mp_obj_type_t *type, // start the PWM running for this channel mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - esp32_pwm_init_helper(self, n_args - 1, args + 1, &kw_args); + mp_machine_pwm_init_helper(self, n_args - 1, args + 1, &kw_args); return MP_OBJ_FROM_PTR(self); } -STATIC mp_obj_t esp32_pwm_init(size_t n_args, - const mp_obj_t *args, mp_map_t *kw_args) { - esp32_pwm_init_helper(args[0], n_args - 1, args + 1, kw_args); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(esp32_pwm_init_obj, 1, esp32_pwm_init); - -STATIC mp_obj_t esp32_pwm_deinit(mp_obj_t self_in) { - esp32_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC void mp_machine_pwm_deinit(machine_pwm_obj_t *self) { int chan = self->channel; // Valid channel? @@ -238,63 +224,27 @@ STATIC mp_obj_t esp32_pwm_deinit(mp_obj_t self_in) { self->channel = -1; gpio_matrix_out(self->pin, SIG_GPIO_OUT_IDX, false, false); } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_pwm_deinit_obj, esp32_pwm_deinit); - -STATIC mp_obj_t esp32_pwm_freq(size_t n_args, const mp_obj_t *args) { - if (n_args == 1) { - // get - return MP_OBJ_NEW_SMALL_INT(timer_cfg.freq_hz); - } - - // set - int tval = mp_obj_get_int(args[1]); - if (!set_freq(tval)) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("bad frequency %d"), tval); - } - return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp32_pwm_freq_obj, 1, 2, esp32_pwm_freq); +STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) { + return MP_OBJ_NEW_SMALL_INT(timer_cfg.freq_hz); +} -STATIC mp_obj_t esp32_pwm_duty(size_t n_args, const mp_obj_t *args) { - esp32_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]); - int duty; - - if (n_args == 1) { - // get - duty = ledc_get_duty(PWMODE, self->channel); - duty <<= PWRES - timer_cfg.duty_resolution; - return MP_OBJ_NEW_SMALL_INT(duty); +STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) { + if (!set_freq(freq)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("bad frequency %d"), freq); } +} - // set - duty = mp_obj_get_int(args[1]); +STATIC mp_obj_t mp_machine_pwm_duty_get(machine_pwm_obj_t *self) { + int duty = ledc_get_duty(PWMODE, self->channel); + duty <<= PWRES - timer_cfg.duty_resolution; + return MP_OBJ_NEW_SMALL_INT(duty); +} + +STATIC void mp_machine_pwm_duty_set(machine_pwm_obj_t *self, mp_int_t duty) { duty &= ((1 << PWRES) - 1); duty >>= PWRES - timer_cfg.duty_resolution; ledc_set_duty(PWMODE, self->channel, duty); ledc_update_duty(PWMODE, self->channel); - - return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp32_pwm_duty_obj, - 1, 2, esp32_pwm_duty); - -STATIC const mp_rom_map_elem_t esp32_pwm_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&esp32_pwm_init_obj) }, - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&esp32_pwm_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&esp32_pwm_freq_obj) }, - { MP_ROM_QSTR(MP_QSTR_duty), MP_ROM_PTR(&esp32_pwm_duty_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(esp32_pwm_locals_dict, - esp32_pwm_locals_dict_table); - -const mp_obj_type_t machine_pwm_type = { - { &mp_type_type }, - .name = MP_QSTR_PWM, - .print = esp32_pwm_print, - .make_new = esp32_pwm_make_new, - .locals_dict = (mp_obj_dict_t *)&esp32_pwm_locals_dict, -}; diff --git a/ports/esp32/main/CMakeLists.txt b/ports/esp32/main/CMakeLists.txt index 057ec02441..75e123f4e0 100644 --- a/ports/esp32/main/CMakeLists.txt +++ b/ports/esp32/main/CMakeLists.txt @@ -62,7 +62,6 @@ set(MICROPY_SOURCE_PORT ${PROJECT_DIR}/machine_dac.c ${PROJECT_DIR}/machine_i2c.c ${PROJECT_DIR}/machine_i2s.c - ${PROJECT_DIR}/machine_pwm.c ${PROJECT_DIR}/machine_uart.c ${PROJECT_DIR}/modmachine.c ${PROJECT_DIR}/modnetwork.c diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c index 5f94007d49..00271a37ed 100644 --- a/ports/esp32/modmachine.c +++ b/ports/esp32/modmachine.c @@ -53,6 +53,7 @@ #include "extmod/machine_mem.h" #include "extmod/machine_signal.h" #include "extmod/machine_pulse.h" +#include "extmod/machine_pwm.h" #include "extmod/machine_i2c.h" #include "extmod/machine_spi.h" #include "modmachine.h" diff --git a/ports/esp32/modmachine.h b/ports/esp32/modmachine.h index 7bf03b0cab..afc2ab07f4 100644 --- a/ports/esp32/modmachine.h +++ b/ports/esp32/modmachine.h @@ -15,7 +15,6 @@ extern const mp_obj_type_t machine_pin_type; extern const mp_obj_type_t machine_touchpad_type; extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_dac_type; -extern const mp_obj_type_t machine_pwm_type; extern const mp_obj_type_t machine_hw_i2c_type; extern const mp_obj_type_t machine_hw_spi_type; extern const mp_obj_type_t machine_i2s_type; diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index b306be937d..6a48ce5023 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -158,6 +158,10 @@ #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new #define MICROPY_PY_MACHINE_BITSTREAM (1) #define MICROPY_PY_MACHINE_PULSE (1) +#define MICROPY_PY_MACHINE_PWM (1) +#define MICROPY_PY_MACHINE_PWM_INIT (1) +#define MICROPY_PY_MACHINE_PWM_DUTY (1) +#define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/esp32/machine_pwm.c" #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile index 9ea4498f41..e771d8f7d3 100644 --- a/ports/esp8266/Makefile +++ b/ports/esp8266/Makefile @@ -96,7 +96,6 @@ SRC_C = \ modmachine.c \ machine_bitstream.c \ machine_pin.c \ - machine_pwm.c \ machine_rtc.c \ machine_adc.c \ machine_uart.c \ diff --git a/ports/esp8266/machine_pwm.c b/ports/esp8266/machine_pwm.c index 1d6a6cfe58..f8cd937b80 100644 --- a/ports/esp8266/machine_pwm.c +++ b/ports/esp8266/machine_pwm.c @@ -24,28 +24,25 @@ * THE SOFTWARE. */ -#include -#include - -#include "esppwm.h" - #include "py/runtime.h" #include "modmachine.h" -typedef struct _pyb_pwm_obj_t { +#include "esppwm.h" + +typedef struct _machine_pwm_obj_t { mp_obj_base_t base; pyb_pin_obj_t *pin; uint8_t active; uint8_t channel; -} pyb_pwm_obj_t; +} machine_pwm_obj_t; STATIC bool pwm_inited = false; /******************************************************************************/ // MicroPython bindings for PWM -STATIC void pyb_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - pyb_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "PWM(%u", self->pin->phys_port); if (self->active) { mp_printf(print, ", freq=%u, duty=%u", @@ -54,7 +51,7 @@ STATIC void pyb_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki mp_printf(print, ")"); } -STATIC void pyb_pwm_init_helper(pyb_pwm_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +STATIC void mp_machine_pwm_init_helper(machine_pwm_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_freq, ARG_duty }; static const mp_arg_t allowed_args[] = { { MP_QSTR_freq, MP_ARG_INT, {.u_int = -1} }, @@ -80,13 +77,13 @@ STATIC void pyb_pwm_init_helper(pyb_pwm_obj_t *self, size_t n_args, const mp_obj pwm_start(); } -STATIC mp_obj_t pyb_pwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); pyb_pin_obj_t *pin = mp_obj_get_pin_obj(args[0]); // create PWM object from the given pin - pyb_pwm_obj_t *self = m_new_obj(pyb_pwm_obj_t); - self->base.type = &pyb_pwm_type; + machine_pwm_obj_t *self = m_new_obj(machine_pwm_obj_t); + self->base.type = &machine_pwm_type; self->pin = pin; self->active = 0; self->channel = -1; @@ -100,71 +97,39 @@ STATIC mp_obj_t pyb_pwm_make_new(const mp_obj_type_t *type, size_t n_args, size_ // start the PWM running for this channel mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - pyb_pwm_init_helper(self, n_args - 1, args + 1, &kw_args); + mp_machine_pwm_init_helper(self, n_args - 1, args + 1, &kw_args); return MP_OBJ_FROM_PTR(self); } -STATIC mp_obj_t pyb_pwm_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - pyb_pwm_init_helper(args[0], n_args - 1, args + 1, kw_args); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(pyb_pwm_init_obj, 1, pyb_pwm_init); - -STATIC mp_obj_t pyb_pwm_deinit(mp_obj_t self_in) { - pyb_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC void mp_machine_pwm_deinit(machine_pwm_obj_t *self) { pwm_delete(self->channel); self->active = 0; pwm_start(); - return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_pwm_deinit_obj, pyb_pwm_deinit); -STATIC mp_obj_t pyb_pwm_freq(size_t n_args, const mp_obj_t *args) { - // pyb_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]); - if (n_args == 1) { - // get - return MP_OBJ_NEW_SMALL_INT(pwm_get_freq(0)); - } else { - // set - pwm_set_freq(mp_obj_get_int(args[1]), 0); - pwm_start(); - return mp_const_none; - } +STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) { + return MP_OBJ_NEW_SMALL_INT(pwm_get_freq(0)); } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_pwm_freq_obj, 1, 2, pyb_pwm_freq); -STATIC mp_obj_t pyb_pwm_duty(size_t n_args, const mp_obj_t *args) { - pyb_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]); +STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) { + pwm_set_freq(freq, 0); + pwm_start(); +} + +STATIC mp_obj_t mp_machine_pwm_duty_get(machine_pwm_obj_t *self) { if (!self->active) { pwm_add(self->pin->phys_port, self->pin->periph, self->pin->func); self->active = 1; } - if (n_args == 1) { - // get - return MP_OBJ_NEW_SMALL_INT(pwm_get_duty(self->channel)); - } else { - // set - pwm_set_duty(mp_obj_get_int(args[1]), self->channel); - pwm_start(); - return mp_const_none; - } + return MP_OBJ_NEW_SMALL_INT(pwm_get_duty(self->channel)); } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_pwm_duty_obj, 1, 2, pyb_pwm_duty); -STATIC const mp_rom_map_elem_t pyb_pwm_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_pwm_init_obj) }, - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_pwm_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&pyb_pwm_freq_obj) }, - { MP_ROM_QSTR(MP_QSTR_duty), MP_ROM_PTR(&pyb_pwm_duty_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(pyb_pwm_locals_dict, pyb_pwm_locals_dict_table); - -const mp_obj_type_t pyb_pwm_type = { - { &mp_type_type }, - .name = MP_QSTR_PWM, - .print = pyb_pwm_print, - .make_new = pyb_pwm_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_pwm_locals_dict, -}; +STATIC void mp_machine_pwm_duty_set(machine_pwm_obj_t *self, mp_int_t duty) { + if (!self->active) { + pwm_add(self->pin->phys_port, self->pin->periph, self->pin->func); + self->active = 1; + } + pwm_set_duty(duty, self->channel); + pwm_start(); +} diff --git a/ports/esp8266/modmachine.c b/ports/esp8266/modmachine.c index 6cd4583431..39a890f56f 100644 --- a/ports/esp8266/modmachine.c +++ b/ports/esp8266/modmachine.c @@ -39,6 +39,7 @@ #include "extmod/machine_mem.h" #include "extmod/machine_signal.h" #include "extmod/machine_pulse.h" +#include "extmod/machine_pwm.h" #include "extmod/machine_i2c.h" #include "extmod/machine_spi.h" #include "modmachine.h" @@ -423,7 +424,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&esp_wdt_type) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pyb_pin_type) }, { MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) }, - { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&pyb_pwm_type) }, + { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) }, #if MICROPY_PY_MACHINE_I2C diff --git a/ports/esp8266/modmachine.h b/ports/esp8266/modmachine.h index be4debd335..4a73d3b8e8 100644 --- a/ports/esp8266/modmachine.h +++ b/ports/esp8266/modmachine.h @@ -4,7 +4,6 @@ #include "py/obj.h" extern const mp_obj_type_t pyb_pin_type; -extern const mp_obj_type_t pyb_pwm_type; extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t pyb_rtc_type; extern const mp_obj_type_t pyb_uart_type; diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h index 78263efec5..7d6d0a34c3 100644 --- a/ports/esp8266/mpconfigport.h +++ b/ports/esp8266/mpconfigport.h @@ -81,6 +81,10 @@ #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new #define MICROPY_PY_MACHINE_BITSTREAM (1) #define MICROPY_PY_MACHINE_PULSE (1) +#define MICROPY_PY_MACHINE_PWM (1) +#define MICROPY_PY_MACHINE_PWM_INIT (1) +#define MICROPY_PY_MACHINE_PWM_DUTY (1) +#define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/esp8266/machine_pwm.c" #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index fd7ec65e0f..2e7347fd53 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -85,7 +85,6 @@ set(MICROPY_SOURCE_PORT machine_adc.c machine_i2c.c machine_pin.c - machine_pwm.c machine_rtc.c machine_spi.c machine_timer.c @@ -113,7 +112,6 @@ set(MICROPY_SOURCE_QSTR ${PROJECT_SOURCE_DIR}/machine_adc.c ${PROJECT_SOURCE_DIR}/machine_i2c.c ${PROJECT_SOURCE_DIR}/machine_pin.c - ${PROJECT_SOURCE_DIR}/machine_pwm.c ${PROJECT_SOURCE_DIR}/machine_rtc.c ${PROJECT_SOURCE_DIR}/machine_spi.c ${PROJECT_SOURCE_DIR}/machine_timer.c diff --git a/ports/rp2/machine_pwm.c b/ports/rp2/machine_pwm.c index ff40c5503f..2952a43062 100644 --- a/ports/rp2/machine_pwm.c +++ b/ports/rp2/machine_pwm.c @@ -34,8 +34,6 @@ /******************************************************************************/ // MicroPython bindings for machine.PWM -const mp_obj_type_t machine_pwm_type; - typedef struct _machine_pwm_obj_t { mp_obj_base_t base; uint8_t slice; @@ -61,13 +59,13 @@ STATIC machine_pwm_obj_t machine_pwm_obj[] = { {{&machine_pwm_type}, 7, PWM_CHAN_B}, }; -STATIC void machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { +STATIC void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "", self->slice, self->channel); } // PWM(pin) -STATIC mp_obj_t machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { +STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { // Check number of arguments mp_arg_check_num(n_args, n_kw, 1, 1, false); @@ -85,113 +83,78 @@ STATIC mp_obj_t machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args, s return MP_OBJ_FROM_PTR(self); } -STATIC mp_obj_t machine_pwm_deinit(mp_obj_t self_in) { - machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC void mp_machine_pwm_deinit(machine_pwm_obj_t *self) { pwm_set_enabled(self->slice, false); - return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pwm_deinit_obj, machine_pwm_deinit); -// PWM.freq([value]) -STATIC mp_obj_t machine_pwm_freq(size_t n_args, const mp_obj_t *args) { - machine_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]); +STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) { uint32_t source_hz = clock_get_hz(clk_sys); - if (n_args == 1) { - // Get frequency. - uint32_t div16 = pwm_hw->slice[self->slice].div; - uint32_t top = pwm_hw->slice[self->slice].top; - uint32_t pwm_freq = 16 * source_hz / div16 / top; - return MP_OBJ_NEW_SMALL_INT(pwm_freq); - } else { - // Set the frequency, making "top" as large as possible for maximum resolution. - // Maximum "top" is set at 65534 to be able to achieve 100% duty with 65535. - #define TOP_MAX 65534 - mp_int_t freq = mp_obj_get_int(args[1]); - uint32_t div16_top = 16 * source_hz / freq; - uint32_t top = 1; - for (;;) { - // Try a few small prime factors to get close to the desired frequency. - if (div16_top >= 16 * 5 && div16_top % 5 == 0 && top * 5 <= TOP_MAX) { - div16_top /= 5; - top *= 5; - } else if (div16_top >= 16 * 3 && div16_top % 3 == 0 && top * 3 <= TOP_MAX) { - div16_top /= 3; - top *= 3; - } else if (div16_top >= 16 * 2 && top * 2 <= TOP_MAX) { - div16_top /= 2; - top *= 2; - } else { - break; - } - } - if (div16_top < 16) { - mp_raise_ValueError(MP_ERROR_TEXT("freq too large")); - } else if (div16_top >= 256 * 16) { - mp_raise_ValueError(MP_ERROR_TEXT("freq too small")); - } - pwm_hw->slice[self->slice].div = div16_top; - pwm_hw->slice[self->slice].top = top; - return mp_const_none; - } -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pwm_freq_obj, 1, 2, machine_pwm_freq); - -// PWM.duty_u16([value]) -STATIC mp_obj_t machine_pwm_duty_u16(size_t n_args, const mp_obj_t *args) { - machine_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]); + uint32_t div16 = pwm_hw->slice[self->slice].div; uint32_t top = pwm_hw->slice[self->slice].top; - if (n_args == 1) { - // Get duty cycle. - uint32_t cc = pwm_hw->slice[self->slice].cc; - cc = (cc >> (self->channel ? PWM_CH0_CC_B_LSB : PWM_CH0_CC_A_LSB)) & 0xffff; - return MP_OBJ_NEW_SMALL_INT(cc * 65535 / (top + 1)); - } else { - // Set duty cycle. - mp_int_t duty_u16 = mp_obj_get_int(args[1]); - uint32_t cc = duty_u16 * (top + 1) / 65535; - pwm_set_chan_level(self->slice, self->channel, cc); - pwm_set_enabled(self->slice, true); - return mp_const_none; - } + uint32_t pwm_freq = 16 * source_hz / div16 / top; + return MP_OBJ_NEW_SMALL_INT(pwm_freq); } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pwm_duty_u16_obj, 1, 2, machine_pwm_duty_u16); -// PWM.duty_ns([value]) -STATIC mp_obj_t machine_pwm_duty_ns(size_t n_args, const mp_obj_t *args) { - machine_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]); +STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) { + // Set the frequency, making "top" as large as possible for maximum resolution. + // Maximum "top" is set at 65534 to be able to achieve 100% duty with 65535. + #define TOP_MAX 65534 + uint32_t source_hz = clock_get_hz(clk_sys); + uint32_t div16_top = 16 * source_hz / freq; + uint32_t top = 1; + for (;;) { + // Try a few small prime factors to get close to the desired frequency. + if (div16_top >= 16 * 5 && div16_top % 5 == 0 && top * 5 <= TOP_MAX) { + div16_top /= 5; + top *= 5; + } else if (div16_top >= 16 * 3 && div16_top % 3 == 0 && top * 3 <= TOP_MAX) { + div16_top /= 3; + top *= 3; + } else if (div16_top >= 16 * 2 && top * 2 <= TOP_MAX) { + div16_top /= 2; + top *= 2; + } else { + break; + } + } + if (div16_top < 16) { + mp_raise_ValueError(MP_ERROR_TEXT("freq too large")); + } else if (div16_top >= 256 * 16) { + mp_raise_ValueError(MP_ERROR_TEXT("freq too small")); + } + pwm_hw->slice[self->slice].div = div16_top; + pwm_hw->slice[self->slice].top = top; +} + +STATIC mp_obj_t mp_machine_pwm_duty_get_u16(machine_pwm_obj_t *self) { + uint32_t top = pwm_hw->slice[self->slice].top; + uint32_t cc = pwm_hw->slice[self->slice].cc; + cc = (cc >> (self->channel ? PWM_CH0_CC_B_LSB : PWM_CH0_CC_A_LSB)) & 0xffff; + return MP_OBJ_NEW_SMALL_INT(cc * 65535 / (top + 1)); +} + +STATIC void mp_machine_pwm_duty_set_u16(machine_pwm_obj_t *self, mp_int_t duty_u16) { + uint32_t top = pwm_hw->slice[self->slice].top; + uint32_t cc = duty_u16 * (top + 1) / 65535; + pwm_set_chan_level(self->slice, self->channel, cc); + pwm_set_enabled(self->slice, true); +} + +STATIC mp_obj_t mp_machine_pwm_duty_get_ns(machine_pwm_obj_t *self) { uint32_t source_hz = clock_get_hz(clk_sys); uint32_t slice_hz = 16 * source_hz / pwm_hw->slice[self->slice].div; - if (n_args == 1) { - // Get duty cycle. - uint32_t cc = pwm_hw->slice[self->slice].cc; - cc = (cc >> (self->channel ? PWM_CH0_CC_B_LSB : PWM_CH0_CC_A_LSB)) & 0xffff; - return MP_OBJ_NEW_SMALL_INT((uint64_t)cc * 1000000000ULL / slice_hz); - } else { - // Set duty cycle. - mp_int_t duty_ns = mp_obj_get_int(args[1]); - uint32_t cc = (uint64_t)duty_ns * slice_hz / 1000000000ULL; - if (cc > 65535) { - mp_raise_ValueError(MP_ERROR_TEXT("duty larger than period")); - } - pwm_set_chan_level(self->slice, self->channel, cc); - pwm_set_enabled(self->slice, true); - return mp_const_none; - } + uint32_t cc = pwm_hw->slice[self->slice].cc; + cc = (cc >> (self->channel ? PWM_CH0_CC_B_LSB : PWM_CH0_CC_A_LSB)) & 0xffff; + return MP_OBJ_NEW_SMALL_INT((uint64_t)cc * 1000000000ULL / slice_hz); } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pwm_duty_ns_obj, 1, 2, machine_pwm_duty_ns); -STATIC const mp_rom_map_elem_t machine_pwm_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_pwm_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&machine_pwm_freq_obj) }, - { MP_ROM_QSTR(MP_QSTR_duty_u16), MP_ROM_PTR(&machine_pwm_duty_u16_obj) }, - { MP_ROM_QSTR(MP_QSTR_duty_ns), MP_ROM_PTR(&machine_pwm_duty_ns_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(machine_pwm_locals_dict, machine_pwm_locals_dict_table); - -const mp_obj_type_t machine_pwm_type = { - { &mp_type_type }, - .name = MP_QSTR_PWM, - .print = machine_pwm_print, - .make_new = machine_pwm_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_pwm_locals_dict, -}; +STATIC void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty_ns) { + uint32_t source_hz = clock_get_hz(clk_sys); + uint32_t slice_hz = 16 * source_hz / pwm_hw->slice[self->slice].div; + uint32_t cc = (uint64_t)duty_ns * slice_hz / 1000000000ULL; + if (cc > 65535) { + mp_raise_ValueError(MP_ERROR_TEXT("duty larger than period")); + } + pwm_set_chan_level(self->slice, self->channel, cc); + pwm_set_enabled(self->slice, true); +} diff --git a/ports/rp2/modmachine.c b/ports/rp2/modmachine.c index 1b2b2adad7..32dc3d22cc 100644 --- a/ports/rp2/modmachine.c +++ b/ports/rp2/modmachine.c @@ -30,6 +30,7 @@ #include "extmod/machine_i2c.h" #include "extmod/machine_mem.h" #include "extmod/machine_pulse.h" +#include "extmod/machine_pwm.h" #include "extmod/machine_signal.h" #include "extmod/machine_spi.h" diff --git a/ports/rp2/modmachine.h b/ports/rp2/modmachine.h index c79bcfdad1..0c48565299 100644 --- a/ports/rp2/modmachine.h +++ b/ports/rp2/modmachine.h @@ -6,7 +6,6 @@ extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_hw_i2c_type; extern const mp_obj_type_t machine_pin_type; -extern const mp_obj_type_t machine_pwm_type; extern const mp_obj_type_t machine_rtc_type; extern const mp_obj_type_t machine_spi_type; extern const mp_obj_type_t machine_timer_type; diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index 4da34cd038..dea3775a85 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -131,6 +131,9 @@ #define MICROPY_PY_MACHINE (1) #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new #define MICROPY_PY_MACHINE_PULSE (1) +#define MICROPY_PY_MACHINE_PWM (1) +#define MICROPY_PY_MACHINE_PWM_DUTY_U16_NS (1) +#define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/rp2/machine_pwm.c" #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) diff --git a/py/py.mk b/py/py.mk index 609ba6cae3..be8296e5e8 100644 --- a/py/py.mk +++ b/py/py.mk @@ -189,6 +189,7 @@ PY_EXTMOD_O_BASENAME = \ extmod/machine_pinbase.o \ extmod/machine_signal.o \ extmod/machine_pulse.o \ + extmod/machine_pwm.o \ extmod/machine_i2c.o \ extmod/machine_spi.o \ extmod/modbluetooth.o \ From bbbdef4cc1d2cb3a3f6c2d067b6988534773b2a6 Mon Sep 17 00:00:00 2001 From: YoungJoon Chun Date: Sat, 4 Sep 2021 00:20:38 +0900 Subject: [PATCH 008/335] rp2/mpconfigport.h: Enable heapq module. Fixes issue #7746. --- ports/rp2/mpconfigport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index dea3775a85..bb2f505b6e 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -120,6 +120,7 @@ #define MICROPY_PY_URE_MATCH_GROUPS (1) #define MICROPY_PY_URE_MATCH_SPAN_START_END (1) #define MICROPY_PY_URE_SUB (1) +#define MICROPY_PY_UHEAPQ (1) #define MICROPY_PY_UHASHLIB (1) #define MICROPY_PY_UBINASCII (1) #define MICROPY_PY_UBINASCII_CRC32 (1) From 87f97e490c4fe12ab5f06e154dc76f0dd27091a9 Mon Sep 17 00:00:00 2001 From: Philipp Ebensberger Date: Sun, 1 Aug 2021 11:20:39 +0200 Subject: [PATCH 009/335] mimxrt/sdcard: Implement SDCard driver. - Configures `PLL2->PFD0` with **198MHz** as base clock of `USDHCx` peripheral. - Adds guards for SDCard related files via `MICROPY_PY_MACHINE_SDCARD` - Adds creation of pin defines for SDCard to make-pins.py - Adds new configuration option for SDCard peripheral pinout to mpconfigport.h - Adds interrupt handling support instead of polling - Adds support for `ADMA2` powered data transfer - Configures SDCard to run in HS (high-speed mode) with **50MHz** only! SDCard support is optional and requires `USDHC` peripheral. Thus this driver is not available on `MIMXRT1010_EVK`. SDCard support is enabled by setting `MICROPY_PY_MACHINE_SDCARD = 1` in mpconfigboard.mk. Signed-off-by: Philipp Ebensberger --- ports/mimxrt/Makefile | 77 +- ports/mimxrt/board_init.c | 6 +- .../boards/MIMXRT1010_EVK/mpconfigboard.mk | 1 + .../boards/MIMXRT1020_EVK/mpconfigboard.h | 12 + .../boards/MIMXRT1020_EVK/mpconfigboard.mk | 6 +- .../boards/MIMXRT1050_EVK/mpconfigboard.h | 12 + .../boards/MIMXRT1050_EVK/mpconfigboard.mk | 7 +- .../boards/MIMXRT1050_EVKB/mpconfigboard.h | 1 - .../boards/MIMXRT1050_EVKB/mpconfigboard.mk | 7 +- .../boards/MIMXRT1060_EVK/mpconfigboard.h | 12 + .../boards/MIMXRT1060_EVK/mpconfigboard.mk | 6 +- .../boards/MIMXRT1064_EVK/mpconfigboard.h | 12 + .../boards/MIMXRT1064_EVK/mpconfigboard.mk | 7 +- ports/mimxrt/boards/TEENSY40/mpconfigboard.h | 12 + ports/mimxrt/boards/TEENSY40/mpconfigboard.mk | 7 +- ports/mimxrt/boards/TEENSY40/pins.csv | 10 +- ports/mimxrt/boards/TEENSY41/mpconfigboard.h | 12 + ports/mimxrt/boards/TEENSY41/mpconfigboard.mk | 7 +- ports/mimxrt/boards/make-pins.py | 88 +- ports/mimxrt/boards/mimxrt_prefix.c | 5 +- ports/mimxrt/fatfs_port.c | 39 + ports/mimxrt/machine_sdcard.c | 222 ++++ ports/mimxrt/modmachine.c | 3 + ports/mimxrt/modmachine.h | 2 + ports/mimxrt/modules/_boot.py | 23 +- ports/mimxrt/moduos.c | 1 + ports/mimxrt/mpconfigport.h | 6 + ports/mimxrt/pin.h | 5 +- ports/mimxrt/sdcard.c | 1023 +++++++++++++++++ ports/mimxrt/sdcard.h | 111 ++ 30 files changed, 1672 insertions(+), 70 deletions(-) create mode 100644 ports/mimxrt/fatfs_port.c create mode 100644 ports/mimxrt/machine_sdcard.c create mode 100644 ports/mimxrt/sdcard.c create mode 100644 ports/mimxrt/sdcard.h diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 818a2a3c84..58fbe2df33 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -20,6 +20,7 @@ QSTR_GLOBAL_DEPENDENCIES = $(BOARD_DIR)/mpconfigboard.h # MicroPython feature configurations FROZEN_MANIFEST ?= boards/manifest.py MICROPY_VFS_LFS2 ?= 1 +MICROPY_VFS_FAT ?= 1 # Include py core make definitions include $(TOP)/py/py.mk @@ -44,27 +45,32 @@ GEN_PINS_AF_PY = $(BUILD)/pins_af.py CFLAGS += -Wno-error=unused-parameter INC += -I. -INC += -I$(TOP) -INC += -I$(BUILD) INC += -I$(BOARD_DIR) -INC += -I$(TOP)/lib/cmsis/inc +INC += -I$(BUILD) +INC += -I$(TOP) INC += -I$(TOP)/$(MCU_DIR) INC += -I$(TOP)/$(MCU_DIR)/drivers INC += -I$(TOP)/$(MCU_DIR)/project_template -INC += -I$(TOP)/lib/tinyusb/src +INC += -I$(TOP)/lib/cmsis/inc +INC += -I$(TOP)/lib/oofatfs INC += -I$(TOP)/lib/tinyusb/hw INC += -I$(TOP)/lib/tinyusb/hw/bsp/teensy_40 +INC += -I$(TOP)/lib/tinyusb/src CFLAGS_MCU = -mtune=cortex-m7 -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 CFLAGS += $(INC) -Wall -Werror -Wdouble-promotion -Wfloat-conversion -std=c99 -nostdlib -mthumb $(CFLAGS_MCU) CFLAGS += -DCPU_$(MCU_SERIES) -DCPU_$(MCU_VARIANT) CFLAGS += -DXIP_EXTERNAL_FLASH=1 \ -DXIP_BOOT_HEADER_ENABLE=1 \ + -DFSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1 \ -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX \ -D__STARTUP_CLEAR_BSS \ -D__STARTUP_INITIALIZE_RAMFUNCTION \ -D__START=main \ -DCPU_HEADER_H='<$(MCU_SERIES).h>' +ifeq ($(MICROPY_PY_MACHINE_SDCARD),1) +CFLAGS += -DMICROPY_PY_MACHINE_SDCARD=1 +endif CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA) # Configure floating point support @@ -98,64 +104,71 @@ endif # TinyUSB Stack source SRC_TINYUSB_C += \ - lib/tinyusb/src/tusb.c \ - lib/tinyusb/src/common/tusb_fifo.c \ - lib/tinyusb/src/device/usbd.c \ - lib/tinyusb/src/device/usbd_control.c \ - lib/tinyusb/src/class/msc/msc_device.c \ lib/tinyusb/src/class/cdc/cdc_device.c \ lib/tinyusb/src/class/dfu/dfu_rt_device.c \ lib/tinyusb/src/class/hid/hid_device.c \ lib/tinyusb/src/class/midi/midi_device.c \ + lib/tinyusb/src/class/msc/msc_device.c \ lib/tinyusb/src/class/usbtmc/usbtmc_device.c \ lib/tinyusb/src/class/vendor/vendor_device.c \ - lib/tinyusb/src/portable/nxp/transdimension/dcd_transdimension.c + lib/tinyusb/src/common/tusb_fifo.c \ + lib/tinyusb/src/device/usbd.c \ + lib/tinyusb/src/device/usbd_control.c \ + lib/tinyusb/src/portable/nxp/transdimension/dcd_transdimension.c \ + lib/tinyusb/src/tusb.c SRC_HAL_IMX_C += \ - $(MCU_DIR)/system_$(MCU_SERIES).c \ - $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ - $(MCU_DIR)/project_template/clock_config.c \ $(MCU_DIR)/drivers/fsl_adc.c \ $(MCU_DIR)/drivers/fsl_cache.c \ $(MCU_DIR)/drivers/fsl_clock.c \ + $(MCU_DIR)/drivers/fsl_common.c \ $(MCU_DIR)/drivers/fsl_dmamux.c \ $(MCU_DIR)/drivers/fsl_edma.c \ + $(MCU_DIR)/drivers/fsl_flexram.c \ + $(MCU_DIR)/drivers/fsl_flexspi.c \ $(MCU_DIR)/drivers/fsl_gpio.c \ $(MCU_DIR)/drivers/fsl_gpt.c \ - $(MCU_DIR)/drivers/fsl_common.c \ $(MCU_DIR)/drivers/fsl_lpi2c.c \ $(MCU_DIR)/drivers/fsl_lpspi.c \ $(MCU_DIR)/drivers/fsl_lpspi_edma.c \ $(MCU_DIR)/drivers/fsl_lpuart.c \ - $(MCU_DIR)/drivers/fsl_flexram.c \ - $(MCU_DIR)/drivers/fsl_flexspi.c \ $(MCU_DIR)/drivers/fsl_pit.c \ $(MCU_DIR)/drivers/fsl_snvs_lp.c \ $(MCU_DIR)/drivers/fsl_trng.c \ + $(MCU_DIR)/project_template/clock_config.c \ + $(MCU_DIR)/system_$(MCU_SERIES).c \ + $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ + +ifeq ($(MICROPY_PY_MACHINE_SDCARD),1) +SRC_HAL_IMX_C += $(MCU_DIR)/drivers/fsl_usdhc.c +endif SRC_C += \ - main.c \ - led.c \ - pin.c \ - ticks.c \ - tusb_port.c \ + $(BOARD_DIR)/flash_config.c \ board_init.c \ dma_channel.c \ - $(BOARD_DIR)/flash_config.c \ + drivers/bus/softspi.c \ + extmod/modonewire.c \ + fatfs_port.c \ + led.c \ machine_adc.c \ machine_i2c.c \ machine_led.c \ machine_pin.c \ machine_rtc.c \ + machine_sdcard.c \ machine_spi.c \ machine_timer.c \ machine_uart.c \ + main.c \ mimxrt_flash.c \ - modutime.c \ modmachine.c \ modmimxrt.c \ moduos.c \ + modutime.c \ mphalport.c \ + pin.c \ + sdcard.c \ shared/libc/printf.c \ shared/libc/string0.c \ shared/readline/readline.c \ @@ -165,8 +178,8 @@ SRC_C += \ shared/runtime/stdout_helpers.c \ shared/runtime/sys_stdio_mphal.c \ shared/timeutils/timeutils.c \ - drivers/bus/softspi.c \ - extmod/modonewire.c \ + ticks.c \ + tusb_port.c \ $(SRC_TINYUSB_C) \ $(SRC_HAL_IMX_C) \ @@ -188,9 +201,9 @@ LIBM_SRC_C += $(addprefix lib/libm_dbl/,\ atan2.c \ atanh.c \ ceil.c \ + copysign.c \ cos.c \ cosh.c \ - copysign.c \ erf.c \ exp.c \ expm1.c \ @@ -222,7 +235,6 @@ LIBM_SRC_C += lib/libm_dbl/sqrt.c endif else LIBM_SRC_C += $(addprefix lib/libm/,\ - math.c \ acoshf.c \ asinfacosf.c \ asinhf.c \ @@ -237,6 +249,7 @@ LIBM_SRC_C += $(addprefix lib/libm/,\ kf_sin.c \ kf_tan.c \ log1pf.c \ + math.c \ nearbyintf.c \ roundf.c \ sf_cos.c \ @@ -263,28 +276,29 @@ ifeq ($(MICROPY_FLOAT_IMPL),double) $(LIBM_O): CFLAGS := $(filter-out -Wdouble-promotion -Wfloat-conversion, $(CFLAGS)) endif -SRC_SS = $(MCU_DIR)/gcc/startup_$(MCU_SERIES).S +SRC_SS += $(MCU_DIR)/gcc/startup_$(MCU_SERIES).S -SRC_S = shared/runtime/gchelper_m3.s \ +SRC_S += shared/runtime/gchelper_m3.s \ # List of sources for qstr extraction SRC_QSTR += \ + extmod/modonewire.c \ machine_adc.c \ machine_led.c \ machine_pin.c \ machine_rtc.c \ + machine_sdcard.c \ machine_spi.c \ machine_timer.c \ machine_uart.c \ mimxrt_flash.c \ - modutime.c \ modmachine.c \ modmimxrt.c \ moduos.c \ + modutime.c \ pin.c \ shared/runtime/mpirq.c \ shared/runtime/sys_stdio_mphal.c \ - extmod/modonewire.c \ $(GEN_PINS_SRC) \ OBJ += $(PY_O) @@ -327,6 +341,7 @@ $(HEADER_BUILD)/qstrdefs.generated.h: $(BOARD_DIR)/mpconfigboard.h $(BUILD)/%_gen.c $(HEADER_BUILD)/%.h: $(BOARD_PINS) $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD) $(ECHO) "Create $@" $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE)\ + --iomux $(abspath $(TOP)/$(MCU_DIR)/drivers/fsl_iomuxc.h) \ --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) > $(GEN_PINS_SRC) $(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c diff --git a/ports/mimxrt/board_init.c b/ports/mimxrt/board_init.c index 65024ff3e2..091e23eb5d 100644 --- a/ports/mimxrt/board_init.c +++ b/ports/mimxrt/board_init.c @@ -40,7 +40,6 @@ #include "clock_config.h" #include "modmachine.h" -volatile uint32_t systick_ms = 0; const uint8_t dcd_data[] = { 0x00 }; @@ -85,6 +84,11 @@ void board_init(void) { // PIT machine_timer_init_PIT(); + + // SDCard + #if MICROPY_PY_MACHINE_SDCARD + machine_sdcard_init0(); + #endif } void USB_OTG1_IRQHandler(void) { diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk index ccc8ffeb41..f616d5afd4 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk @@ -2,6 +2,7 @@ MCU_SERIES = MIMXRT1011 MCU_VARIANT = MIMXRT1011DAE5A MICROPY_FLOAT_IMPL = single +MICROPY_PY_MACHINE_SDCARD = 0 SRC_C += \ hal/flexspi_nor_flash.c \ diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h index d2a2cbbdbd..d7fe575abc 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h @@ -64,3 +64,15 @@ { IOMUXC_GPIO_AD_B1_08_LPI2C2_SCL }, { IOMUXC_GPIO_AD_B1_09_LPI2C2_SDA }, \ { 0 }, { 0 }, \ { IOMUXC_GPIO_SD_B1_02_LPI2C4_SCL }, { IOMUXC_GPIO_SD_B1_03_LPI2C4_SDA }, + +#define USDHC_DUMMY_PIN NULL , 0 +#define MICROPY_USDHC1 \ + { \ + .cmd = {GPIO_SD_B0_02_USDHC1_CMD}, \ + .clk = { GPIO_SD_B0_03_USDHC1_CLK }, \ + .cd_b = { GPIO_SD_B0_06_USDHC1_CD_B },\ + .data0 = { GPIO_SD_B0_04_USDHC1_DATA0 },\ + .data1 = { GPIO_SD_B0_05_USDHC1_DATA1 },\ + .data2 = { GPIO_SD_B0_00_USDHC1_DATA2 },\ + .data3 = { GPIO_SD_B0_01_USDHC1_DATA3 },\ + } diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk index f8f66b0dff..6dd1686521 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk @@ -2,9 +2,7 @@ MCU_SERIES = MIMXRT1021 MCU_VARIANT = MIMXRT1021DAG5A MICROPY_FLOAT_IMPL = double - -SRC_C += \ - hal/flexspi_nor_flash.c \ +MICROPY_PY_MACHINE_SDCARD = 1 JLINK_PATH ?= /media/RT1020-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink @@ -16,6 +14,8 @@ else JLINK_CONNECTION_SETTINGS = endif +SRC_C += \ + hal/flexspi_nor_flash.c deploy_jlink: $(BUILD)/firmware.hex $(ECHO) "ExitOnError 1" > $(JLINK_COMMANDER_SCRIPT) diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h index af0975bc17..976de9c07d 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h @@ -54,3 +54,15 @@ { IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL }, { IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA }, \ { 0 }, { 0 }, \ { IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL }, { IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA }, + +#define USDHC_DUMMY_PIN NULL, 0 +#define MICROPY_USDHC1 \ + { \ + .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ + .clk = { GPIO_SD_B0_01_USDHC1_CLK }, \ + .cd_b = { GPIO_B1_12_USDHC1_CD_B },\ + .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 },\ + .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 },\ + .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 },\ + .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 },\ + } diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk index 61826b6f60..fdbf47f01e 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk @@ -2,11 +2,12 @@ MCU_SERIES = MIMXRT1052 MCU_VARIANT = MIMXRT1052DVL6B MICROPY_FLOAT_IMPL = double - -SRC_C += \ - hal/flexspi_nor_flash.c \ +MICROPY_PY_MACHINE_SDCARD = 1 JLINK_PATH ?= /media/RT1050-EVK/ deploy: $(BUILD)/firmware.bin cp $< $(JLINK_PATH) + +SRC_C += \ + hal/flexspi_nor_flash.c diff --git a/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.h index 518240b03f..963c42cb6a 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.h @@ -56,7 +56,6 @@ { IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL }, { IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA }, #define USDHC_DUMMY_PIN NULL , 0 - #define MICROPY_USDHC1 \ { \ .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.mk index c9e32612ca..e6cd1a63e8 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.mk @@ -2,11 +2,12 @@ MCU_SERIES = MIMXRT1052 MCU_VARIANT = MIMXRT1052DVL6B MICROPY_FLOAT_IMPL = double - -SRC_C += \ - hal/flexspi_hyper_flash.c \ +MICROPY_PY_MACHINE_SDCARD = 1 JLINK_PATH ?= /media/RT1050-EVKB/ +SRC_C += \ + hal/flexspi_hyper_flash.c + deploy: $(BUILD)/firmware.bin cp $< $(JLINK_PATH) diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h index c207da832e..c26364f265 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h @@ -54,3 +54,15 @@ { IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL }, { IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA }, \ { 0 }, { 0 }, \ { IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL }, { IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA }, + +#define USDHC_DUMMY_PIN NULL, 0 +#define MICROPY_USDHC1 \ + { \ + .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ + .clk = { GPIO_SD_B0_01_USDHC1_CLK }, \ + .cd_b = { GPIO_B1_12_USDHC1_CD_B },\ + .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 },\ + .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 },\ + .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 },\ + .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 },\ + } diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk index f5eaf3eab5..623e2617fd 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk @@ -2,9 +2,7 @@ MCU_SERIES = MIMXRT1062 MCU_VARIANT = MIMXRT1062DVJ6A MICROPY_FLOAT_IMPL = double - -SRC_C += \ - hal/flexspi_hyper_flash.c \ +MICROPY_PY_MACHINE_SDCARD = 1 JLINK_PATH ?= /media/RT1060-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink @@ -16,6 +14,8 @@ else JLINK_CONNECTION_SETTINGS = -USB endif +SRC_C += \ + hal/flexspi_hyper_flash.c deploy_jlink: $(BUILD)/firmware.hex $(Q)$(TOUCH) $(JLINK_COMMANDER_SCRIPT) diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h index 59f28b0e2a..4534caa296 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h @@ -52,3 +52,15 @@ { IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL }, { IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA }, \ { 0 }, { 0 }, \ { IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL }, { IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA }, + +#define USDHC_DUMMY_PIN NULL, 0 +#define MICROPY_USDHC1 \ + { \ + .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ + .clk = { GPIO_SD_B0_01_USDHC1_CLK }, \ + .cd_b = { GPIO_B1_12_USDHC1_CD_B },\ + .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 },\ + .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 },\ + .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 },\ + .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 },\ + } diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk index 444fe99672..fe3c442faa 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk @@ -2,9 +2,7 @@ MCU_SERIES = MIMXRT1064 MCU_VARIANT = MIMXRT1064DVL6A MICROPY_FLOAT_IMPL = double - -SRC_C += \ - hal/flexspi_hyper_flash.c \ +MICROPY_PY_MACHINE_SDCARD = 1 JLINK_PATH ?= /media/RT1064-EVK/ @@ -12,3 +10,6 @@ CFLAGS += -DBOARD_FLASH_SIZE=0x400000 deploy: $(BUILD)/firmware.bin cp $< $(JLINK_PATH) + +SRC_C += \ + hal/flexspi_hyper_flash.c diff --git a/ports/mimxrt/boards/TEENSY40/mpconfigboard.h b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h index aacee4623c..4a69303b56 100644 --- a/ports/mimxrt/boards/TEENSY40/mpconfigboard.h +++ b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h @@ -57,3 +57,15 @@ { 0 }, { 0 }, \ { IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL }, { IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA }, \ { IOMUXC_GPIO_AD_B0_12_LPI2C4_SCL }, { IOMUXC_GPIO_AD_B0_13_LPI2C4_SDA }, + +#define USDHC_DUMMY_PIN NULL, 0 +#define MICROPY_USDHC1 \ + { \ + .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ + .clk = { GPIO_SD_B0_01_USDHC1_CLK }, \ + .cd_b = { USDHC_DUMMY_PIN },\ + .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 },\ + .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 },\ + .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 },\ + .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 },\ + } diff --git a/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk b/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk index a15dd78128..bd70fd0925 100644 --- a/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk +++ b/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk @@ -2,9 +2,10 @@ MCU_SERIES = MIMXRT1062 MCU_VARIANT = MIMXRT1062DVJ6A MICROPY_FLOAT_IMPL = double - -SRC_C += \ - hal/flexspi_nor_flash.c \ +MICROPY_PY_MACHINE_SDCARD = 1 deploy: $(BUILD)/firmware.hex teensy_loader_cli --mcu=imxrt1062 -v -w $< + +SRC_C += \ + hal/flexspi_nor_flash.c diff --git a/ports/mimxrt/boards/TEENSY40/pins.csv b/ports/mimxrt/boards/TEENSY40/pins.csv index c9d7c9856d..0ea4f13731 100644 --- a/ports/mimxrt/boards/TEENSY40/pins.csv +++ b/ports/mimxrt/boards/TEENSY40/pins.csv @@ -32,12 +32,12 @@ D30,GPIO_EMC_37 D31,GPIO_EMC_36 D32,GPIO_B0_12 D33,GPIO_EMC_07 -DAT1,GPIO_AD_B0_03 -DAT0,GPIO_AD_B0_02 -CLK,GPIO_AD_B0_01 -CMD,GPIO_ASD_B0_00 -DAT3,GPIO_SD_B0_05 +CMD,GPIO_SD_B0_00 +CLK,GPIO_SD_B0_01 +DAT0,GPIO_SD_B0_02 +DAT1,GPIO_SD_B0_03 DAT2,GPIO_SD_B0_04 +DAT3,GPIO_SD_B0_05 A0,GPIO_AD_B1_02 A1,GPIO_AD_B1_03 A2,GPIO_AD_B1_07 diff --git a/ports/mimxrt/boards/TEENSY41/mpconfigboard.h b/ports/mimxrt/boards/TEENSY41/mpconfigboard.h index a72bd127b6..587bf9c620 100644 --- a/ports/mimxrt/boards/TEENSY41/mpconfigboard.h +++ b/ports/mimxrt/boards/TEENSY41/mpconfigboard.h @@ -57,3 +57,15 @@ { 0 }, { 0 }, \ { IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL }, { IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA }, \ { IOMUXC_GPIO_AD_B0_12_LPI2C4_SCL }, { IOMUXC_GPIO_AD_B0_13_LPI2C4_SDA }, + +#define USDHC_DUMMY_PIN NULL, 0 +#define MICROPY_USDHC1 \ + { \ + .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ + .clk = { GPIO_SD_B0_01_USDHC1_CLK }, \ + .cd_b = { USDHC_DUMMY_PIN },\ + .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 },\ + .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 },\ + .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 },\ + .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 },\ + } diff --git a/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk b/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk index a15dd78128..bd70fd0925 100755 --- a/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk +++ b/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk @@ -2,9 +2,10 @@ MCU_SERIES = MIMXRT1062 MCU_VARIANT = MIMXRT1062DVJ6A MICROPY_FLOAT_IMPL = double - -SRC_C += \ - hal/flexspi_nor_flash.c \ +MICROPY_PY_MACHINE_SDCARD = 1 deploy: $(BUILD)/firmware.hex teensy_loader_cli --mcu=imxrt1062 -v -w $< + +SRC_C += \ + hal/flexspi_nor_flash.c diff --git a/ports/mimxrt/boards/make-pins.py b/ports/mimxrt/boards/make-pins.py index e9e32a5047..d75592124a 100644 --- a/ports/mimxrt/boards/make-pins.py +++ b/ports/mimxrt/boards/make-pins.py @@ -8,11 +8,22 @@ import sys import csv import re -SUPPORTED_AFS = {"GPIO"} +SUPPORTED_AFS = {"GPIO", "USDHC"} MAX_AF = 10 # AF0 .. AF9 ADC_COL = 11 +regexes = [ + r"IOMUXC_(?PGPIO_SD_B\d_\d\d)_(?P\w+) (?P\w+), (?P\w+), (?P\w+), (?P\w+), (?P\w+)", + r"IOMUXC_(?PGPIO_AD_B\d_\d\d)_(?P\w+) (?P\w+), (?P\w+), (?P\w+), (?P\w+), (?P\w+)", + r"IOMUXC_(?PGPIO_EMC_\d\d)_(?P\w+) (?P\w+), (?P\w+), (?P\w+), (?P\w+), (?P\w+)", + r"IOMUXC_(?PGPIO_B\d_\d\d)_(?P\w+) (?P\w+), (?P\w+), (?P\w+), (?P\w+), (?P\w+)", + r"IOMUXC_(?PGPIO_\d\d)_(?P\w+) (?P\w+), (?P\w+), (?P\w+), (?P\w+), (?P\w+)", + r"IOMUXC_(?PGPIO_AD_\d\d)_(?P\w+) (?P\w+), (?P\w+), (?P\w+), (?P\w+), (?P\w+)", + r"IOMUXC_(?PGPIO_SD_\d\d)_(?P\w+) (?P\w+), (?P\w+), (?P\w+), (?P\w+), (?P\w+)", +] + + def parse_pad(pad_str): """Parses a string and returns a (port, gpio_bit) tuple.""" if len(pad_str) < 4: @@ -127,16 +138,18 @@ class AdcFunction(object): class AlternateFunction(object): """Holds the information associated with a pins alternate function.""" - def __init__(self, idx, af_str): + def __init__(self, idx, input_reg, input_daisy, af_str): self.idx = idx self.af_str = af_str + self.input_reg = input_reg + self.input_daisy = input_daisy self.instance = self.af_str.split("_")[0] def print(self): """Prints the C representation of this AF.""" print( - " PIN_AF({0}, PIN_AF_MODE_ALT{1}, {2}, {3}),".format( - self.af_str, self.idx, self.instance, "0x10B0U" + " PIN_AF({0}, PIN_AF_MODE_ALT{1}, {2}, {3}, {4}, {5}),".format( + self.af_str, self.idx, self.input_daisy, self.instance, self.input_reg, "0x10B0U" ) ) @@ -171,8 +184,26 @@ class Pins(object): if pin and row[0]: # Only add board pins that have a name self.board_pins.append(NamedPin(row[0], pin.pad, pin.idx)) - def parse_af_file(self, filename, pad_col, af_start_col): + def parse_af_file(self, filename, iomux_filename, pad_col, af_start_col): af_end_col = af_start_col + MAX_AF + + iomux_pin_config = dict() + + with open(iomux_filename, "r") as ipt: + input_str = ipt.read() + for regex in regexes: + matches = re.finditer(regex, input_str, re.MULTILINE) + + for match in matches: + if match.group("pin") not in iomux_pin_config: + iomux_pin_config[match.group("pin")] = { + int((match.groupdict()["muxMode"].strip("U")), 16): match.groupdict() + } + else: + iomux_pin_config[match.group("pin")][ + int((match.groupdict()["muxMode"].strip("U")), 16) + ] = match.groupdict() + with open(filename, "r") as csvfile: rows = csv.reader(csvfile) header = next(rows) @@ -187,7 +218,16 @@ class Pins(object): af_idx = 0 for af_idx, af in enumerate(row[af_start_col:af_end_col]): if af and af_supported(af): - pin.add_af(AlternateFunction(af_idx, af)) + pin.add_af( + AlternateFunction( + af_idx, + iomux_pin_config[pin.name][af_idx]["inputRegister"].strip("U"), + int( + iomux_pin_config[pin.name][af_idx]["inputDaisy"].strip("U"), 16 + ), + af, + ) + ) pin.parse_adc(row[ADC_COL]) @@ -235,6 +275,33 @@ class Pins(object): hdr_file.write("extern const mp_obj_dict_t machine_pin_cpu_pins_locals_dict;\n") hdr_file.write("extern const mp_obj_dict_t machine_pin_board_pins_locals_dict;\n") + hdr_file.write("\n// Defines\n") + usdhc_instance_factory(self.cpu_pins, hdr_file) + + +def usdhc_instance_factory(pins, output_file): + usdhc_pins = filter(lambda p: any([af for af in p.alt_fn if "USDHC" in af.af_str]), pins) + + usdhc_instances = dict() + for pin in usdhc_pins: + for idx, alt_fn in enumerate(pin.alt_fn): + if "USDHC" in alt_fn.instance: + format_string = "#define {0}_{1} &pin_{0}, {2}" + if alt_fn.instance not in usdhc_instances: + usdhc_instances[alt_fn.instance] = [ + format_string.format(pin.name, alt_fn.af_str, idx) + ] + else: + usdhc_instances[alt_fn.instance].append( + format_string.format(pin.name, alt_fn.af_str, idx) + ) + + for k, v in usdhc_instances.items(): + output_file.write(f"// {k}\n") + output_file.write(f"#define {k}_AVAIL (1)\n") + for i in v: + output_file.write(i + "\n") + def main(): parser = argparse.ArgumentParser( @@ -249,6 +316,13 @@ def main(): help="Specifies the alternate function file for the chip", default="mimxrt1021_af.csv", ) + parser.add_argument( + "-i", + "--iomux", + dest="iomux_filename", + help="Specifies the fsl_iomux.h file for the chip", + default="fsl_iomuxc.h", + ) parser.add_argument( "-b", "--board", @@ -279,7 +353,7 @@ def main(): if args.af_filename: print("// --af {:s}".format(args.af_filename)) - pins.parse_af_file(args.af_filename, 0, 1) + pins.parse_af_file(args.af_filename, args.iomux_filename, 0, 1) if args.board_filename: print("// --board {:s}".format(args.board_filename)) diff --git a/ports/mimxrt/boards/mimxrt_prefix.c b/ports/mimxrt/boards/mimxrt_prefix.c index 96ba6a0d5e..938efc8104 100644 --- a/ports/mimxrt/boards/mimxrt_prefix.c +++ b/ports/mimxrt/boards/mimxrt_prefix.c @@ -4,12 +4,14 @@ #include "py/mphal.h" #include "pin.h" -#define PIN_AF(_name, _af_mode, _instance, _pad_config) \ +#define PIN_AF(_name, _af_mode, _input_daisy, _instance, _input_register, _pad_config) \ { \ .base = { &machine_pin_af_type }, \ .name = MP_QSTR_##_name, \ .af_mode = (uint32_t)(_af_mode), \ + .input_daisy = (uint8_t)(_input_daisy), \ .instance = (void *)(_instance), \ + .input_register = (uint32_t)(_input_register), \ .pad_config = (uint32_t)(_pad_config), \ } \ @@ -32,3 +34,4 @@ .af_list = (_af_list), \ .adc_list = (_adc_list), \ } \ + diff --git a/ports/mimxrt/fatfs_port.c b/ports/mimxrt/fatfs_port.c new file mode 100644 index 0000000000..7b7008667f --- /dev/null +++ b/ports/mimxrt/fatfs_port.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2021 Robert Hammelrath + * + * 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 "lib/oofatfs/ff.h" +#include "fsl_snvs_lp.h" + + +MP_WEAK DWORD get_fattime(void) { + snvs_lp_srtc_datetime_t srtcDate; + + SNVS_LP_SRTC_GetDatetime(SNVS, &srtcDate); + + return ((srtcDate.year - 1980) << 25) | (srtcDate.month << 21) | (srtcDate.day << 16) | + (srtcDate.hour << 11) | ((srtcDate.minute << 5) | (srtcDate.second / 2)); +} diff --git a/ports/mimxrt/machine_sdcard.c b/ports/mimxrt/machine_sdcard.c new file mode 100644 index 0000000000..4a92aae00c --- /dev/null +++ b/ports/mimxrt/machine_sdcard.c @@ -0,0 +1,222 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Philipp Ebensberger + * + * 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. + */ + +#if MICROPY_PY_MACHINE_SDCARD + +#include "py/runtime.h" +#include "py/mperrno.h" +#include "extmod/vfs.h" +#include "ticks.h" +#include "fsl_cache.h" + +#include "sdcard.h" + + +enum { SDCARD_INIT_ARG_ID }; + + +STATIC const mp_arg_t sdcard_init_allowed_args[] = { + [SDCARD_INIT_ARG_ID] = { MP_QSTR_id, MP_ARG_INT, {.u_int = 1} }, +}; + + +STATIC void machine_sdcard_init_helper(mimxrt_sdcard_obj_t *self) { + sdcard_init(self, 198000000UL); // Initialize SDCard Host with 198MHz base clock + sdcard_init_pins(self); + + ticks_delay_us64(2ULL * 1000ULL); // Wait 2ms to allow USDHC signals to settle/debounce +} + +STATIC mp_obj_t sdcard_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args); + + // Parse args + mp_arg_val_t args[MP_ARRAY_SIZE(sdcard_init_allowed_args)]; + mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(sdcard_init_allowed_args), sdcard_init_allowed_args, args); + + // Extract arguments + mp_int_t sdcard_id = args[SDCARD_INIT_ARG_ID].u_int; + + if (!(1 <= sdcard_id && sdcard_id <= MP_ARRAY_SIZE(mimxrt_sdcard_objs))) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "SDCard(%d) doesn't exist", sdcard_id)); + } + + mimxrt_sdcard_obj_t *self = &mimxrt_sdcard_objs[(sdcard_id - 1)]; + + // Initialize SDCard Host + if (!sdcard_state_initialized(self)) { + machine_sdcard_init_helper(self); + } + return MP_OBJ_FROM_PTR(self); +} + +// init() +STATIC mp_obj_t machine_sdcard_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mimxrt_sdcard_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + if (!sdcard_state_initialized(self)) { + machine_sdcard_init_helper(self); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_sdcard_init_obj, 1, machine_sdcard_init); + +// deinit() +STATIC mp_obj_t machine_sdcard_deinit(mp_obj_t self_in) { + mimxrt_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + sdcard_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_sdcard_deinit_obj, machine_sdcard_deinit); + +// readblocks(block_num, buf) +STATIC mp_obj_t machine_sdcard_readblocks(mp_obj_t self_in, mp_obj_t block_num, mp_obj_t buf) { + mp_buffer_info_t bufinfo; + mimxrt_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE); + + if (sdcard_read(self, bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SDCARD_DEFAULT_BLOCK_SIZE)) { + return MP_OBJ_NEW_SMALL_INT(0); + } else { + return MP_OBJ_NEW_SMALL_INT(-MP_EIO); + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(machine_sdcard_readblocks_obj, machine_sdcard_readblocks); + +// present() +STATIC mp_obj_t machine_sdcard_present(mp_obj_t self_in) { + mimxrt_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(sdcard_detect(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_sdcard_present_obj, machine_sdcard_present); + +STATIC mp_obj_t machine_sdcard_info(mp_obj_t self_in) { + mimxrt_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (sdcard_detect(self) && sdcard_state_initialized(self)) { + uint32_t log_block_nbr = self->block_count; + uint32_t log_block_size = self->block_len; + + mp_obj_t tuple[2] = { + mp_obj_new_int_from_ull((uint64_t)log_block_nbr * (uint64_t)log_block_size), + mp_obj_new_int_from_uint(log_block_size), + }; + return mp_obj_new_tuple(2, tuple); + } else { + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_sdcard_info_obj, machine_sdcard_info); + +// writeblocks(block_num, buf) +STATIC mp_obj_t machine_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t block_num, mp_obj_t buf) { + mp_buffer_info_t bufinfo; + mimxrt_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE); + + if (sdcard_write(self, bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SDCARD_DEFAULT_BLOCK_SIZE)) { + return MP_OBJ_NEW_SMALL_INT(0); + } else { + return MP_OBJ_NEW_SMALL_INT(-MP_EIO); + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(machine_sdcard_writeblocks_obj, machine_sdcard_writeblocks); + +// ioctl(op, arg) +STATIC mp_obj_t machine_sdcard_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t arg_in) { + mimxrt_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_int_t cmd = mp_obj_get_int(cmd_in); + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_INIT: { + if (sdcard_detect(self)) { + if (sdcard_power_on(self)) { + return MP_OBJ_NEW_SMALL_INT(0); + } else { + sdcard_power_off(self); + return MP_OBJ_NEW_SMALL_INT(-MP_EIO); // Initialization failed + } + } else { + return MP_OBJ_NEW_SMALL_INT(-MP_EIO); // Initialization failed + } + } + case MP_BLOCKDEV_IOCTL_DEINIT: { + if (sdcard_power_off(self)) { + return MP_OBJ_NEW_SMALL_INT(0); + } else { + return MP_OBJ_NEW_SMALL_INT(-MP_EIO); // Deinitialization failed + } + } + case MP_BLOCKDEV_IOCTL_SYNC: { + return MP_OBJ_NEW_SMALL_INT(0); + } + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: { + if (sdcard_state_initialized(self)) { + return MP_OBJ_NEW_SMALL_INT(self->block_count); + } else { + return MP_OBJ_NEW_SMALL_INT(-MP_EIO); // Card not initialized + } + } + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: { + if (sdcard_state_initialized(self)) { + return MP_OBJ_NEW_SMALL_INT(self->block_len); + } else { + return MP_OBJ_NEW_SMALL_INT(-MP_EIO); // Card not initialized + } + } + default: // unknown command + { + return mp_const_none; + } + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(machine_sdcard_ioctl_obj, machine_sdcard_ioctl); + +STATIC const mp_rom_map_elem_t sdcard_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_sdcard_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_sdcard_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_present), MP_ROM_PTR(&machine_sdcard_present_obj) }, + { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&machine_sdcard_info_obj) }, + // block device protocol + { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&machine_sdcard_readblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&machine_sdcard_writeblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&machine_sdcard_ioctl_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(sdcard_locals_dict, sdcard_locals_dict_table); + +const mp_obj_type_t machine_sdcard_type = { + { &mp_type_type }, + .name = MP_QSTR_SDCard, + .make_new = sdcard_obj_make_new, + .locals_dict = (mp_obj_dict_t *)&sdcard_locals_dict, +}; + +void machine_sdcard_init0(void) { + return; +} + +#endif // MICROPY_PY_MACHINE_SDCARD diff --git a/ports/mimxrt/modmachine.c b/ports/mimxrt/modmachine.c index 150615ca03..a98d09bd0e 100644 --- a/ports/mimxrt/modmachine.c +++ b/ports/mimxrt/modmachine.c @@ -82,6 +82,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) }, { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) }, { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) }, + #if MICROPY_PY_MACHINE_SDCARD + { MP_ROM_QSTR(MP_QSTR_SDCard), MP_ROM_PTR(&machine_sdcard_type) }, + #endif { MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, diff --git a/ports/mimxrt/modmachine.h b/ports/mimxrt/modmachine.h index 9732093bd8..e1a7ce0b72 100644 --- a/ports/mimxrt/modmachine.h +++ b/ports/mimxrt/modmachine.h @@ -35,9 +35,11 @@ extern const mp_obj_type_t machine_rtc_type; extern const mp_obj_type_t machine_i2c_type; extern const mp_obj_type_t machine_spi_type; extern const mp_obj_type_t machine_uart_type; +extern const mp_obj_type_t machine_sdcard_type; void machine_adc_init(void); void machine_pin_irq_deinit(void); void machine_timer_init_PIT(void); +void machine_sdcard_init0(void); #endif // MICROPY_INCLUDED_MIMXRT_MODMACHINE_H diff --git a/ports/mimxrt/modules/_boot.py b/ports/mimxrt/modules/_boot.py index 892d004735..bc8d72224a 100644 --- a/ports/mimxrt/modules/_boot.py +++ b/ports/mimxrt/modules/_boot.py @@ -3,13 +3,32 @@ # Note: the flash requires the programming size to be aligned to 256 bytes. import os +import sys import mimxrt +from machine import Pin bdev = mimxrt.Flash() - try: vfs = os.VfsLfs2(bdev, progsize=256) except: os.VfsLfs2.mkfs(bdev, progsize=256) vfs = os.VfsLfs2(bdev, progsize=256) -os.mount(vfs, "/") +os.mount(vfs, "/flash") +os.chdir("/flash") +sys.path.append("/flash") + +# do not mount the SD card if SKIPSD exists. +try: + os.stat("SKIPSD") +except: + try: + from machine import SDCard + + sdcard = SDCard(1) + + fat = os.VfsFat(sdcard) + os.mount(fat, "/sdcard") + os.chdir("/sdcard") + sys.path.append("/sdcard") + except: + pass # Fail silently diff --git a/ports/mimxrt/moduos.c b/ports/mimxrt/moduos.c index 225cd4ddd2..ff0f0824c4 100644 --- a/ports/mimxrt/moduos.c +++ b/ports/mimxrt/moduos.c @@ -31,6 +31,7 @@ #include "py/objstr.h" #include "py/runtime.h" #include "extmod/vfs.h" +#include "extmod/vfs_fat.h" #include "extmod/vfs_lfs.h" #include "genhdr/mpversion.h" #include "fsl_trng.h" diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index be2b87e6a2..9775b29efa 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -132,6 +132,12 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_FRAMEBUF (1) #define MICROPY_PY_ONEWIRE (1) +// fatfs configuration used in ffconf.h +#define MICROPY_FATFS_ENABLE_LFN (1) +#define MICROPY_FATFS_RPATH (2) +#define MICROPY_FATFS_MAX_SS (4096) +#define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ + // Use VfsLfs2's types for fileio/textio #define mp_type_fileio mp_type_vfs_lfs2_fileio #define mp_type_textio mp_type_vfs_lfs2_textio diff --git a/ports/mimxrt/pin.h b/ports/mimxrt/pin.h index 8d80490d1c..3520ed0f4f 100644 --- a/ports/mimxrt/pin.h +++ b/ports/mimxrt/pin.h @@ -58,7 +58,8 @@ enum { }; enum { - PIN_AF_MODE_ALT1 = 1, + PIN_AF_MODE_ALT0 = 0, + PIN_AF_MODE_ALT1, PIN_AF_MODE_ALT2, PIN_AF_MODE_ALT3, PIN_AF_MODE_ALT4, @@ -97,7 +98,9 @@ typedef struct { mp_obj_base_t base; qstr name; // port name uint8_t af_mode; // alternate function + uint8_t input_daisy; void *instance; // pointer to peripheral instance for alternate function + uint32_t input_register; uint32_t pad_config; // pad configuration for alternate function } machine_pin_af_obj_t; diff --git a/ports/mimxrt/sdcard.c b/ports/mimxrt/sdcard.c new file mode 100644 index 0000000000..14a78e94a5 --- /dev/null +++ b/ports/mimxrt/sdcard.c @@ -0,0 +1,1023 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Philipp Ebensberger + * + * 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. + */ + +#if MICROPY_PY_MACHINE_SDCARD + +#include "sdcard.h" +#include "ticks.h" +#include "fsl_iomuxc.h" + +#define SDCARD_VOLTAGE_WINDOW_SD (0x80100000U) +#define SDCARD_HIGH_CAPACITY (0x40000000U) +#define SDCARD_SWITCH_1_8V_CAPACITY ((uint32_t)0x01000000U) +#define SDCARD_MAX_VOLT_TRIAL ((uint32_t)0x000000FFU) + +// Error +#define SDCARD_STATUS_OUT_OF_RANGE_SHIFT (31U) +#define SDCARD_STATUS_ADDRESS_ERROR_SHIFT (30U) +#define SDCARD_STATUS_BLOCK_LEN_ERROR_SHIFT (29U) +#define SDCARD_STATUS_ERASE_SEQ_ERROR_SHIFT (28U) +#define SDCARD_STATUS_ERASE_PARAM_SHIFT (27U) +#define SDCARD_STATUS_WP_VIOLATION_SHIFT (26U) +#define SDCARD_STATUS_LOCK_UNLOCK_FAILED_SHIFT (24U) +#define SDCARD_STATUS_COM_CRC_ERROR_SHIFT (23U) +#define SDCARD_STATUS_ILLEGAL_COMMAND_SHIFT (22U) +#define SDCARD_STATUS_CARD_ECC_FAILED_SHIFT (21U) +#define SDCARD_STATUS_CC_ERROR_SHIFT (20U) +#define SDCARD_STATUS_ERROR_SHIFT (19U) +#define SDCARD_STATUS_CSD_OVERWRITE_SHIFT (16U) +#define SDCARD_STATUS_WP_ERASE_SKIP_SHIFT (15U) +#define SDCARD_STATUS_AUTH_SEQ_ERR_SHIFT (3U) + +// Status Flags +#define SDCARD_STATUS_CARD_IS_LOCKED_SHIFT (25U) +#define SDCARD_STATUS_CARD_ECC_DISABLED_SHIFT (14U) +#define SDCARD_STATUS_ERASE_RESET_SHIFT (13U) +#define SDCARD_STATUS_READY_FOR_DATA_SHIFT (8U) +#define SDCARD_STATUS_FX_EVENT_SHIFT (6U) +#define SDCARD_STATUS_APP_CMD_SHIFT (5U) + +#define SDMMC_MASK(bit) (1U << (bit)) +#define SDMMC_R1_ALL_ERROR_FLAG \ + (SDMMC_MASK(SDCARD_STATUS_OUT_OF_RANGE_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_ADDRESS_ERROR_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_BLOCK_LEN_ERROR_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_ERASE_SEQ_ERROR_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_ERASE_PARAM_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_WP_VIOLATION_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_LOCK_UNLOCK_FAILED_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_COM_CRC_ERROR_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_ILLEGAL_COMMAND_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_CARD_ECC_FAILED_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_CC_ERROR_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_ERROR_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_CSD_OVERWRITE_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_WP_ERASE_SKIP_SHIFT)) | \ + (SDMMC_MASK(SDCARD_STATUS_AUTH_SEQ_ERR_SHIFT)) + +#define SDMMC_R1_CURRENT_STATE(x) (((x) & 0x00001E00U) >> 9U) + +// --- +// SD Card command identifiers +// --- +enum +{ + SDCARD_CMD_GO_IDLE_STATE = 0U, + SDCARD_CMD_ALL_SEND_CID = 2U, + SDCARD_CMD_SEND_REL_ADDR = 3U, + SDCARD_CMD_SET_DSR = 4U, + SDCARD_CMD_SELECT_CARD = 7U, + SDCARD_CMD_SEND_IF_COND = 8U, + SDCARD_CMD_SEND_CSD = 9U, + SDCARD_CMD_SEND_CID = 10U, + SDCARD_CMD_STOP_TRANSMISSION = 12U, + SDCARD_CMD_SEND_STATUS = 13U, + SDCARD_CMD_GO_INACTIVE_STATE = 15U, + SDCARD_CMD_SET_BLOCKLENGTH = 16U, + SDCARD_CMD_READ_SINGLE_BLOCK = 17U, + SDCARD_CMD_READ_MULTIPLE_BLOCK = 18U, + SDCARD_CMD_SET_BLOCK_COUNT = 23U, + SDCARD_CMD_WRITE_SINGLE_BLOCK = 24U, + SDCARD_CMD_WRITE_MULTIPLE_BLOCK = 25U, + SDCARD_CMD_PROGRAM_CSD = 27U, + SDCARD_CMD_SET_WRITE_PROTECT = 28U, + SDCARD_CMD_CLEAR_WRITE_PROTECT = 29U, + SDCARD_CMD_SEND_WRITE_PROTECT = 30U, + SDCARD_CMD_ERASE = 38U, + SDCARD_CMD_LOCK_UNLOCK = 42U, + SDCARD_CMD_APP_CMD = 55U, + SDCARD_CMD_GEN_CMD = 56U, + SDCARD_CMD_READ_OCR = 58U, +}; + +// --- +// SD Card application command identifiers +// --- +enum +{ + SDCARD_ACMD_SET_BUS_WIDTH = 6U, + SDCARD_ACMD_SD_SEND_OP_COND = 41U, +}; + +// --- +// SD Card state identifiers +// --- +enum +{ + SDCARD_STATE_IDLE = 0U, + SDCARD_STATE_READY = 1U, + SDCARD_STATE_IDENTIFY = 2U, + SDCARD_STATE_STANDBY = 3U, + SDCARD_STATE_TRANSFER = 4U, + SDCARD_STATE_SENDDATA = 5U, + SDCARD_STATE_RECEIVEDATA = 6U, + SDCARD_STATE_PROGRAM = 7U, + SDCARD_STATE_DISCONNECT = 8U, +}; + +// --- +// SD Card transfer status +// --- +typedef enum +{ + SDCARD_TRANSFER_SUCCESS = 0, + SDCARD_TRANSFER_ERROR, + SDCARD_TRANSFER_PENDING +} sdcard_transfer_status_t; + +// --- +// SD Card type definitions +// --- +typedef struct _cid_t { + uint8_t reserved_0; + uint16_t mdt : 12; + uint16_t reserved_1 : 4; + uint32_t psn; + uint8_t prv; + char pnm[6]; + uint16_t oid; + uint8_t mid; +} __attribute__((packed)) cid_t; + +typedef struct _csd_t { + uint32_t data[4]; +} __attribute__((packed)) csd_t; + +typedef struct _csr_t { + uint32_t data[2]; +} __attribute__((packed)) csr_t; + +#define DMA_DESCRIPTOR_BUFFER_SIZE (32U) +#define DMA_DESCRIPTOR_BUFFER_ALIGN_SIZE (4U) +AT_NONCACHEABLE_SECTION_ALIGN(static uint32_t sdcard_adma_descriptor_table[DMA_DESCRIPTOR_BUFFER_SIZE], DMA_DESCRIPTOR_BUFFER_ALIGN_SIZE); + +#if defined MICROPY_USDHC1 && USDHC1_AVAIL +const mimxrt_sdcard_obj_pins_t mimxrt_sdcard_1_obj_pins = MICROPY_USDHC1; +#endif + +#if defined MICROPY_USDHC2 && USDHC2_AVAIL +const mimxrt_sdcard_obj_pins_t mimxrt_sdcard_2_obj_pins = MICROPY_USDHC2; +#endif + +#if defined MICROPY_USDHC1 && USDHC1_AVAIL +mimxrt_sdcard_status_obj_t sdcard_usdhc1_state = {.initialized = false, .inserted = false}; +#endif +#if defined MICROPY_USDHC2 && USDHC2_AVAIL +mimxrt_sdcard_status_obj_t sdcard_usdhc2_state = {.initialized = false, .inserted = false}; +#endif + +mimxrt_sdcard_obj_t mimxrt_sdcard_objs[] = +{ + #if defined MICROPY_USDHC1 && USDHC1_AVAIL + { + .base.type = &machine_sdcard_type, + .usdhc_inst = USDHC1, + .state = &sdcard_usdhc1_state, + .rca = 0x0UL, + .block_len = SDCARD_DEFAULT_BLOCK_SIZE, + .block_count = 0UL, + .pins = &mimxrt_sdcard_1_obj_pins, + }, + #endif + #if defined MICROPY_USDHC2 && USDHC2_AVAIL + { + .base.type = &machine_sdcard_type, + .usdhc_inst = USDHC2, + .state = &sdcard_usdhc2_state, + .rca = 0x0UL, + .block_len = SDCARD_DEFAULT_BLOCK_SIZE, + .block_count = 0UL, + .pins = &mimxrt_sdcard_2_obj_pins, + }; + #endif +}; + +volatile status_t sdcard_transfer_status; +volatile bool sdcard_transfer_done; + +// --- +// Local function declarations +// --- +static status_t sdcard_transfer_blocking(USDHC_Type *base, + usdhc_handle_t *handle, + usdhc_transfer_t *transfer, + uint32_t timeout_ms); +static void sdcard_decode_csd(mimxrt_sdcard_obj_t *sdcard, csd_t *csd); +static bool sdcard_reset(mimxrt_sdcard_obj_t *card); +static inline void sdcard_init_pin(const machine_pin_obj_t *pin, uint8_t af_idx, uint32_t config_value); + +// SD Card interrupt callbacks +void sdcard_card_inserted_callback(USDHC_Type *base, void *userData); +void sdcard_card_removed_callback(USDHC_Type *base, void *userData); +void sdcard_transfer_complete_callback(USDHC_Type *base, usdhc_handle_t *handle, status_t status, void *userData); +void sdcard_dummy_callback(USDHC_Type *base, void *userData); + +// SD Card commmands +static bool sdcard_cmd_go_idle_state(mimxrt_sdcard_obj_t *card); +static bool sdcard_cmd_oper_cond(mimxrt_sdcard_obj_t *card); +static bool sdcard_cmd_app_cmd(mimxrt_sdcard_obj_t *card); +static bool sdcard_cmd_sd_app_op_cond(mimxrt_sdcard_obj_t *card, uint32_t argument); +static bool sdcard_cmd_all_send_cid(mimxrt_sdcard_obj_t *card, cid_t *cid); +static bool sdcard_cmd_send_cid(mimxrt_sdcard_obj_t *card, cid_t *cid); +static bool sdcard_cmd_set_rel_add(mimxrt_sdcard_obj_t *card); +static bool sdcard_cmd_send_csd(mimxrt_sdcard_obj_t *card, csd_t *csd); +static bool sdcard_cmd_select_card(mimxrt_sdcard_obj_t *sdcard); +static bool sdcard_cmd_set_blocklen(mimxrt_sdcard_obj_t *sdcard); +static bool sdcard_cmd_set_bus_width(mimxrt_sdcard_obj_t *sdcard, uint8_t bus_width); + +void sdcard_card_inserted_callback(USDHC_Type *base, void *userData) { + #if defined MICROPY_USDHC1 && USDHC1_AVAIL + if (base == USDHC1) { + sdcard_usdhc1_state.inserted = true; + } + #endif + #if defined MICROPY_USDHC2 && USDHC2_AVAIL + if (base == USDHC2) { + sdcard_usdhc2_state.inserted = true; + + } + #endif + + USDHC_ClearInterruptStatusFlags(base, kUSDHC_CardInsertionFlag); +} + +void sdcard_card_removed_callback(USDHC_Type *base, void *userData) { + #if defined MICROPY_USDHC1 && USDHC1_AVAIL + if (base == USDHC1) { + sdcard_usdhc1_state.inserted = false; + sdcard_usdhc1_state.initialized = false; + } + #endif + #if defined MICROPY_USDHC2 && USDHC2_AVAIL + if (base == USDHC2) { + sdcard_usdhc2_state.inserted = false; + sdcard_usdhc2_state.initialized = false; + } + #endif + + USDHC_ClearInterruptStatusFlags(base, kUSDHC_CardRemovalFlag); +} + +void sdcard_transfer_complete_callback(USDHC_Type *base, usdhc_handle_t *handle, status_t status, void *userData) { + sdcard_transfer_status = status; + sdcard_transfer_done = true; + USDHC_ClearInterruptStatusFlags(base, kUSDHC_CommandCompleteFlag | kUSDHC_DataCompleteFlag); +} + +void sdcard_dummy_callback(USDHC_Type *base, void *userData) { + return; +} + +static status_t sdcard_transfer_blocking(USDHC_Type *base, usdhc_handle_t *handle, usdhc_transfer_t *transfer, uint32_t timeout_ms) { + uint32_t retry_ctr = 0UL; + status_t status; + + usdhc_adma_config_t dma_config; + + (void)memset(&dma_config, 0, sizeof(usdhc_adma_config_t)); + dma_config.dmaMode = kUSDHC_DmaModeAdma2; + dma_config.burstLen = kUSDHC_EnBurstLenForINCR; + dma_config.admaTable = sdcard_adma_descriptor_table; + dma_config.admaTableWords = DMA_DESCRIPTOR_BUFFER_SIZE; + + do { + status = USDHC_TransferNonBlocking(base, handle, &dma_config, transfer); + retry_ctr++; + } while (!(status == kStatus_Success) && (retry_ctr < 1000000UL)); + + if (status == kStatus_Success) { + for (int i = 0; i < timeout_ms * 100; i++) { + if ((sdcard_transfer_done == true) && (sdcard_transfer_status == kStatus_Success)) { + sdcard_transfer_done = false; + return kStatus_Success; + } + ticks_delay_us64(10); + } + return kStatus_Timeout; + } else { + return status; + } +} + +static void sdcard_decode_csd(mimxrt_sdcard_obj_t *card, csd_t *csd) { + uint8_t csd_structure = 0x3 & (csd->data[3] >> 30); + uint8_t read_bl_len; + uint32_t c_size; + uint8_t c_size_mult; + + switch (csd_structure) + { + case 0: { + read_bl_len = 0xF & (csd->data[2] >> 16); + c_size = ((0x3FF & csd->data[2]) << 30) | (0x3 & (csd->data[1] >> 30)); + c_size_mult = 0x7 & (csd->data[1] >> 15); + + card->block_len = (1U << (read_bl_len)); + card->block_count = ((c_size + 1U) << (c_size_mult + 2U)); + + if (card->block_len != SDCARD_DEFAULT_BLOCK_SIZE) { + card->block_count = (card->block_count * card->block_len); + card->block_len = SDCARD_DEFAULT_BLOCK_SIZE; + card->block_count = (card->block_count / card->block_len); + } + break; + } + case 1: { + c_size = ((0x3F & csd->data[2]) << 16) | (0xFFFF & (csd->data[1] >> 16)); + + card->block_len = 512UL; + card->block_count = (uint32_t)(((uint64_t)(c_size + 1U) * (uint64_t)1024UL)); + break; + } + case 2: { + c_size = ((0xFF & csd->data[2]) << 16) | (0xFFFF & (csd->data[1] >> 16)); + + card->block_len = 512UL; + card->block_count = (uint32_t)(((uint64_t)(c_size + 1U) * (uint64_t)1024UL)); + break; + } + default: { + break; + } + } +} + +static bool sdcard_cmd_go_idle_state(mimxrt_sdcard_obj_t *card) { + status_t status; + usdhc_command_t command = { + .index = SDCARD_CMD_GO_IDLE_STATE, + .argument = 0UL, + .type = kCARD_CommandTypeNormal, + .responseType = kCARD_ResponseTypeNone, + }; + usdhc_transfer_t transfer = { + .data = NULL, + .command = &command, + }; + + status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 250); + + if (status == kStatus_Success) { + return true; + } else { + return false; + } +} + +static bool sdcard_cmd_oper_cond(mimxrt_sdcard_obj_t *card) { + status_t status; + usdhc_command_t command = { + .index = SDCARD_CMD_SEND_IF_COND, + .argument = 0x000001AAU, // 2.7-3.3V range and 0xAA check pattern + .type = kCARD_CommandTypeNormal, + .responseType = kCARD_ResponseTypeR7, + }; + usdhc_transfer_t transfer = { + .data = NULL, + .command = &command, + }; + + status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 250); + + if (status == kStatus_Success) { + card->oper_cond = command.response[0]; + return true; + } else { + return false; + } +} + +static bool sdcard_cmd_app_cmd(mimxrt_sdcard_obj_t *card) { + status_t status; + usdhc_command_t command = { + .index = SDCARD_CMD_APP_CMD, + .argument = (card->rca << 16), + .type = kCARD_CommandTypeNormal, + .responseType = kCARD_ResponseTypeR1, + }; + usdhc_transfer_t transfer = { + .data = NULL, + .command = &command, + }; + + status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 250); + + if (status == kStatus_Success) { + card->status = command.response[0]; + return true; + } else { + return false; + } +} + +static bool sdcard_cmd_sd_app_op_cond(mimxrt_sdcard_obj_t *card, uint32_t argument) { + if (!sdcard_cmd_app_cmd(card)) { + return false; + } + + status_t status; + usdhc_command_t command = { + .index = SDCARD_ACMD_SD_SEND_OP_COND, + .argument = argument, + .type = kCARD_CommandTypeNormal, + .responseType = kCARD_ResponseTypeR3, + }; + + usdhc_transfer_t transfer = { + .data = NULL, + .command = &command, + }; + + status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 250); + + if (status == kStatus_Success) { + card->oper_cond = command.response[0]; + return true; + } else { + return false; + } +} + +static bool sdcard_cmd_all_send_cid(mimxrt_sdcard_obj_t *card, cid_t *cid) { + status_t status; + usdhc_command_t command = { + .index = SDCARD_CMD_ALL_SEND_CID, + .argument = 0UL, + .type = kCARD_CommandTypeNormal, + .responseType = kCARD_ResponseTypeR2, + }; + usdhc_transfer_t transfer = { + .data = NULL, + .command = &command, + }; + + status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 250); + + if (status == kStatus_Success) { + cid->mdt = (uint16_t)((command.response[0] & 0xFFF00U) >> 8U); + cid->psn = (uint32_t)(((command.response[1] & 0xFFFFFFU) << 8U) | ((command.response[0] & 0xFF000000U) >> 24U)); + cid->prv = (uint8_t)((command.response[1] & 0xFF000000U) >> 24U); + cid->pnm[0] = (char)(command.response[2] & 0xFFU); + cid->pnm[1] = (char)((command.response[2] & 0xFF00U) >> 8U); + cid->pnm[2] = (char)((command.response[2] & 0xFF0000U) >> 16U); + cid->pnm[3] = (char)((command.response[2] & 0xFF000000U) >> 24U); + cid->pnm[4] = (char)(command.response[3] & 0xFFU); + cid->pnm[5] = '\0'; + cid->oid = (uint16_t)((command.response[3] & 0xFFFF00U) >> 8U); + cid->mid = (uint8_t)((command.response[3] & 0xFF000000U) >> 24U); + return true; + } else { + return false; + } +} + +static bool sdcard_cmd_send_cid(mimxrt_sdcard_obj_t *card, cid_t *cid) { + status_t status; + usdhc_command_t command = { + .index = SDCARD_CMD_SEND_CID, + .argument = (card->rca << 16), + .type = kCARD_CommandTypeNormal, + .responseType = kCARD_ResponseTypeR2, + }; + usdhc_transfer_t transfer = { + .data = NULL, + .command = &command, + }; + + status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 250); + + if (status == kStatus_Success) { + cid->mdt = (uint16_t)((command.response[0] & 0xFFF00U) >> 8U); + cid->psn = (uint32_t)(((command.response[1] & 0xFFFFFFU) << 8U) | ((command.response[0] & 0xFF000000U) >> 24U)); + cid->prv = (uint8_t)((command.response[1] & 0xFF000000U) >> 24U); + cid->pnm[0] = (char)(command.response[2] & 0xFFU); + cid->pnm[1] = (char)((command.response[2] & 0xFF00U) >> 8U); + cid->pnm[2] = (char)((command.response[2] & 0xFF0000U) >> 16U); + cid->pnm[3] = (char)((command.response[2] & 0xFF000000U) >> 24U); + cid->pnm[4] = (char)(command.response[3] & 0xFFU); + cid->pnm[5] = '\0'; + cid->oid = (uint16_t)((command.response[3] & 0xFFFF00U) >> 8U); + cid->mid = (uint8_t)((command.response[3] & 0xFF000000U) >> 24U); + return true; + } else { + return false; + } +} + +static bool sdcard_cmd_set_rel_add(mimxrt_sdcard_obj_t *card) { + status_t status; + usdhc_command_t command = { + .index = SDCARD_CMD_SEND_REL_ADDR, + .argument = 0UL, + .type = kCARD_CommandTypeNormal, + .responseType = kCARD_ResponseTypeR6, + }; + usdhc_transfer_t transfer = { + .data = NULL, + .command = &command, + }; + + status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 250); + + if (status == kStatus_Success) { + card->rca = 0xFFFFFFFF & (command.response[0] >> 16); + return true; + } else { + return false; + } +} + +static bool sdcard_cmd_send_csd(mimxrt_sdcard_obj_t *card, csd_t *csd) { + status_t status; + usdhc_command_t command = { + .index = SDCARD_CMD_SEND_CSD, + .argument = (card->rca << 16), + .type = kCARD_CommandTypeNormal, + .responseType = kCARD_ResponseTypeR2, + }; + usdhc_transfer_t transfer = { + .data = NULL, + .command = &command, + }; + + status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 250); + + if (status == kStatus_Success) { + csd->data[0] = command.response[0]; + csd->data[1] = command.response[1]; + csd->data[2] = command.response[2]; + csd->data[3] = command.response[3]; + return true; + } else { + return false; + } +} + +static bool sdcard_cmd_select_card(mimxrt_sdcard_obj_t *card) { + status_t status; + usdhc_command_t command = { + .index = SDCARD_CMD_SELECT_CARD, + .argument = (card->rca << 16), + .type = kCARD_CommandTypeNormal, + .responseType = kCARD_ResponseTypeR1b, + .responseErrorFlags = SDMMC_R1_ALL_ERROR_FLAG, + }; + usdhc_transfer_t transfer = { + .data = NULL, + .command = &command, + }; + + status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 250); + + if (status == kStatus_Success) { + card->status = command.response[0]; + return true; + } else { + return false; + } +} + +static bool sdcard_cmd_set_blocklen(mimxrt_sdcard_obj_t *card) { + status_t status; + usdhc_command_t command = { + .index = SDCARD_CMD_SET_BLOCKLENGTH, + .argument = card->block_len, + .type = kCARD_CommandTypeNormal, + .responseType = kCARD_ResponseTypeR1, + .responseErrorFlags = SDMMC_R1_ALL_ERROR_FLAG, + }; + usdhc_transfer_t transfer = { + .data = NULL, + .command = &command, + }; + + status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 250); + + if (status == kStatus_Success) { + card->status = command.response[0]; + return true; + } else { + return false; + } +} + +static bool sdcard_cmd_set_bus_width(mimxrt_sdcard_obj_t *card, usdhc_data_bus_width_t bus_width) { + if (!sdcard_cmd_app_cmd(card)) { + return false; + } + + status_t status; + usdhc_command_t command = { + .index = SDCARD_ACMD_SET_BUS_WIDTH, + .type = kCARD_CommandTypeNormal, + .responseType = kCARD_ResponseTypeR1, + }; + + if (bus_width == kUSDHC_DataBusWidth1Bit) { + command.argument = 0U; + } else if (bus_width == kUSDHC_DataBusWidth4Bit) { + command.argument = 2U; + } else { + return false; // Invalid argument + } + + usdhc_transfer_t transfer = { + .data = NULL, + .command = &command, + }; + + status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 250); + + if (status == kStatus_Success) { + card->status = command.response[0]; + return true; + } else { + return false; + } +} + +static bool sdcard_reset(mimxrt_sdcard_obj_t *card) { + card->block_len = SDCARD_DEFAULT_BLOCK_SIZE; + card->rca = 0UL; + card->block_count = 0UL; + card->status = 0UL; + card->oper_cond = 0UL; + card->state->initialized = false; + return USDHC_Reset(card->usdhc_inst, (USDHC_SYS_CTRL_RSTA_MASK | USDHC_SYS_CTRL_RSTC_MASK | USDHC_SYS_CTRL_RSTD_MASK), 2048); +} + +void sdcard_init(mimxrt_sdcard_obj_t *card, uint32_t base_clk) { + // Configure PFD0 of PLL2 (system PLL) fractional divider to 24 resulting in: + // with PFD0_clk = PLL2_clk * 18 / N + // PFD0_clk = 528MHz * 18 / 24 = 396MHz + CLOCK_InitSysPfd(kCLOCK_Pfd0, 24U); + + #if defined MICROPY_USDHC1 && USDHC1_AVAIL + // Configure USDHC clock source and divider + CLOCK_SetDiv(kCLOCK_Usdhc1Div, 1U); // USDHC_input_clk = PFD0_clk / 2 = 198MHZ + CLOCK_SetMux(kCLOCK_Usdhc1Mux, 1U); // Select PFD0 as clock input for USDHC + #endif + + #if defined MICROPY_USDHC2 && USDHC2_AVAIL + // Configure USDHC clock source and divider + CLOCK_SetDiv(kCLOCK_Usdhc2Div, 1U); // USDHC_input_clk = PFD0_clk / 2 = 198MHZ + CLOCK_SetMux(kCLOCK_Usdhc2Mux, 1U); // Select PFD0 as clock input for USDHC + #endif + + // Initialize USDHC + const usdhc_config_t config = { + .endianMode = kUSDHC_EndianModeLittle, + .dataTimeout = 0xFU, + .readWatermarkLevel = 128U, + .writeWatermarkLevel = 128U, + }; + USDHC_Init(card->usdhc_inst, &config); + + (void)sdcard_reset(card); + card->base_clk = base_clk; + + usdhc_transfer_callback_t callbacks = { + .CardInserted = sdcard_card_inserted_callback, + .CardRemoved = sdcard_card_removed_callback, + .SdioInterrupt = sdcard_dummy_callback, + .BlockGap = sdcard_dummy_callback, + .TransferComplete = sdcard_transfer_complete_callback, + .ReTuning = sdcard_dummy_callback, + }; + + USDHC_TransferCreateHandle(card->usdhc_inst, &card->handle, &callbacks, NULL); +} + +void sdcard_deinit(mimxrt_sdcard_obj_t *card) { + sdcard_power_off(card); + USDHC_Deinit(card->usdhc_inst); +} + +static inline void sdcard_init_pin(const machine_pin_obj_t *pin, uint8_t af_idx, uint32_t config_value) { + machine_pin_af_obj_t af = pin->af_list[af_idx]; + + IOMUXC_SetPinMux(pin->muxRegister, af.af_mode, af.input_register, af.input_daisy, pin->configRegister, 0U); + IOMUXC_SetPinConfig(pin->muxRegister, af.af_mode, af.input_register, af.input_daisy, pin->configRegister, config_value); +} + +void sdcard_init_pins(mimxrt_sdcard_obj_t *card) { + // speed and strength optimized for clock frequency < 100MHz + uint32_t speed = 1U; + uint32_t strength = 7U; + const mimxrt_sdcard_obj_pins_t *pins = card->pins; + + uint32_t default_config = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | + IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | + IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | + IOMUXC_SW_PAD_CTL_PAD_PUE_MASK | + IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | + IOMUXC_SW_PAD_CTL_PAD_PUS(1) | + IOMUXC_SW_PAD_CTL_PAD_DSE(strength); + uint32_t no_cd_config = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | + IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | + IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | + IOMUXC_SW_PAD_CTL_PAD_PUE_MASK | + IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | + IOMUXC_SW_PAD_CTL_PAD_PUS(0) | + IOMUXC_SW_PAD_CTL_PAD_DSE(strength); + + sdcard_init_pin(card->pins->clk.pin, card->pins->clk.af_idx, default_config); // USDHC1_CLK + sdcard_init_pin(card->pins->cmd.pin, card->pins->cmd.af_idx, default_config); // USDHC1_CMD + sdcard_init_pin(card->pins->data0.pin, card->pins->data0.af_idx, default_config); // USDHC1_DATA0 + sdcard_init_pin(card->pins->data1.pin, card->pins->data1.af_idx, default_config); // USDHC1_DATA1 + sdcard_init_pin(card->pins->data2.pin, card->pins->data2.af_idx, default_config); // USDHC1_DATA2 + + if (pins->cd_b.pin) { + sdcard_init_pin(card->pins->data3.pin, card->pins->data3.af_idx, default_config); // USDHC1_DATA3 + sdcard_init_pin(card->pins->cd_b.pin, card->pins->cd_b.af_idx, default_config); // USDHC1_CD_B + USDHC_CardDetectByData3(card->usdhc_inst, false); + } else { + sdcard_init_pin(card->pins->data3.pin, card->pins->data3.af_idx, no_cd_config); // USDHC1_DATA3 + USDHC_CardDetectByData3(card->usdhc_inst, true); + } +} + +bool sdcard_read(mimxrt_sdcard_obj_t *card, uint8_t *buffer, uint32_t block_num, uint32_t block_count) { + if (!card->state->initialized) { + return false; + } + + usdhc_data_t data = { + .enableAutoCommand12 = true, + .enableAutoCommand23 = false, + .enableIgnoreError = false, + .dataType = kUSDHC_TransferDataNormal, + .blockSize = card->block_len, + .blockCount = block_count, + .rxData = (uint32_t *)buffer, + .txData = NULL, + }; + + usdhc_command_t command = { + .index = (block_count == 1U) ? (uint32_t)SDCARD_CMD_READ_SINGLE_BLOCK : (uint32_t)SDCARD_CMD_READ_MULTIPLE_BLOCK, + .argument = block_num, + .type = kCARD_CommandTypeNormal, + .responseType = kCARD_ResponseTypeR1, + .responseErrorFlags = SDMMC_R1_ALL_ERROR_FLAG, + }; + + usdhc_transfer_t transfer = { + .data = &data, + .command = &command, + }; + + status_t status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 500); + + if (status == kStatus_Success) { + card->status = command.response[0]; + return true; + } else { + return false; + } +} + +bool sdcard_write(mimxrt_sdcard_obj_t *card, uint8_t *buffer, uint32_t block_num, uint32_t block_count) { + if (!card->state->initialized) { + return false; + } + + usdhc_data_t data = { + .enableAutoCommand12 = true, + .enableAutoCommand23 = false, + .enableIgnoreError = false, + .dataType = kUSDHC_TransferDataNormal, + .blockSize = card->block_len, + .blockCount = block_count, + .rxData = NULL, + .txData = (uint32_t *)buffer, + }; + + usdhc_command_t command = { + .index = (block_count == 1U) ? (uint32_t)SDCARD_CMD_WRITE_SINGLE_BLOCK : (uint32_t)SDCARD_CMD_WRITE_MULTIPLE_BLOCK, + .argument = block_num, + .type = kCARD_CommandTypeNormal, + .responseType = kCARD_ResponseTypeR1, + .responseErrorFlags = SDMMC_R1_ALL_ERROR_FLAG, + }; + + usdhc_transfer_t transfer = { + .data = &data, + .command = &command, + }; + + status_t status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 500); + + if (status == kStatus_Success) { + card->status = command.response[0]; + return true; + } else { + return false; + } +} + +bool sdcard_set_active(mimxrt_sdcard_obj_t *card) { + return USDHC_SetCardActive(card->usdhc_inst, 8192); +} + +bool sdcard_probe_bus_voltage(mimxrt_sdcard_obj_t *card) { + bool valid_voltage = false; + uint32_t count = 0UL; + bool status = false; + + // Perform voltage validation + while ((count < SDCARD_MAX_VOLT_TRIAL) && (valid_voltage == false)) { + status = sdcard_cmd_sd_app_op_cond(card, (uint32_t)(SDCARD_VOLTAGE_WINDOW_SD | + SDCARD_HIGH_CAPACITY | + SDCARD_SWITCH_1_8V_CAPACITY)); + if (status == false) { + return false; + } + + /* Get operating voltage*/ + valid_voltage = (((card->oper_cond >> 31U) == 1U) ? true : false); + count++; + ticks_delay_us64(1000); + } + + if (count >= SDCARD_MAX_VOLT_TRIAL) { + return false; + } else { + return true; + } +} + +bool sdcard_power_on(mimxrt_sdcard_obj_t *card) { + bool status = false; + + // Check if card is already initialized and powered on + if (card->state->initialized) { + return true; + } + + USDHC_SetDataBusWidth(card->usdhc_inst, kUSDHC_DataBusWidth1Bit); + card->bus_clk = USDHC_SetSdClock(card->usdhc_inst, card->base_clk, SDCARD_CLOCK_400KHZ); + + // Start initialization process + status = sdcard_reset(card); + if (!status) { + return false; + } + + status = sdcard_set_active(card); + if (!status) { + return false; + } + + status = sdcard_cmd_go_idle_state(card); + if (!status) { + return false; + } + + status = sdcard_cmd_oper_cond(card); + if (!status) { + return false; + } + + status = sdcard_probe_bus_voltage(card); + if (!status) { + return false; + } + + // === + // Ready State + // === + cid_t cid_all; + status = sdcard_cmd_all_send_cid(card, &cid_all); + if (!status) { + return false; + } + + // === + // Identification State + // === + status = sdcard_cmd_set_rel_add(card); + if (!status) { + return false; + } + + // === + // Standby State + // === + card->bus_clk = USDHC_SetSdClock(card->usdhc_inst, card->base_clk, SDCARD_CLOCK_50MHZ); + + csd_t csd; + status = sdcard_cmd_send_csd(card, &csd); + if (!status) { + return false; + } + sdcard_decode_csd(card, &csd); + + cid_t cid; + status = sdcard_cmd_send_cid(card, &cid); + if (!status) { + return false; + } + + // === + // Transfer State + // === + status = sdcard_cmd_select_card(card); + if (!status) { + return false; + } + + status = sdcard_cmd_set_blocklen(card); + if (!status) { + return false; + } + + status = sdcard_cmd_set_bus_width(card, kUSDHC_DataBusWidth4Bit); + if (!status) { + return false; + } + USDHC_SetDataBusWidth(card->usdhc_inst, kUSDHC_DataBusWidth4Bit); + + + status = sdcard_cmd_set_blocklen(card); + if (!status) { + return false; + } + + // Finialize initialization + card->state->initialized = true; + return true; +} + +bool sdcard_power_off(mimxrt_sdcard_obj_t *card) { + (void)sdcard_cmd_go_idle_state(card); + + // Reset card bus clock + USDHC_SetDataBusWidth(card->usdhc_inst, kUSDHC_DataBusWidth1Bit); + card->bus_clk = USDHC_SetSdClock(card->usdhc_inst, card->base_clk, SDCARD_CLOCK_400KHZ); + + (void)sdcard_reset(card); + return true; +} + +bool sdcard_detect(mimxrt_sdcard_obj_t *card) { + bool detect = false; + + #if defined MICROPY_USDHC1 && USDHC1_AVAIL + if ((card->usdhc_inst == USDHC1) && (sdcard_usdhc1_state.inserted == true)) { + return true; + } + #endif + #if defined MICROPY_USDHC2 && USDHC2_AVAIL + if ((card->usdhc_inst == USDHC2) && (sdcard_usdhc2_state.inserted == true)) { + return true; + } + #endif + + if (card->pins->cd_b.pin) { + detect = USDHC_DetectCardInsert(card->usdhc_inst); + } else { + USDHC_CardDetectByData3(card->usdhc_inst, true); + detect = (USDHC_GetPresentStatusFlags(card->usdhc_inst) & USDHC_PRES_STATE_DLSL(8)) != 0; + } + + // Update card state when detected via pin state + #if defined MICROPY_USDHC1 && USDHC1_AVAIL + if (card->usdhc_inst == USDHC1) { + sdcard_usdhc1_state.inserted = detect; + sdcard_usdhc1_state.initialized = detect ? sdcard_usdhc1_state.initialized : false; + } + #endif + #if defined MICROPY_USDHC2 && USDHC2_AVAIL + if (card->usdhc_inst == USDHC2) { + sdcard_usdhc2_state.inserted = detect; + sdcard_usdhc2_state.initialized = detect ? sdcard_usdhc1_state.initialized : false; + } + #endif + + return detect; +} + +#endif // MICROPY_PY_MACHINE_SDCARD diff --git a/ports/mimxrt/sdcard.h b/ports/mimxrt/sdcard.h new file mode 100644 index 0000000000..9219a42306 --- /dev/null +++ b/ports/mimxrt/sdcard.h @@ -0,0 +1,111 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Philipp Ebensberger + * + * 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_MIMXRT_SDCARD_H +#define MICROPY_INCLUDED_MIMXRT_SDCARD_H + +#include "modmachine.h" +#include "pin.h" +#include "fsl_usdhc.h" + +// --- +// SD Card public defines +// --- +#define SDCARD_DEFAULT_BLOCK_SIZE (512U) +#define SDCARD_CLOCK_400KHZ (400000U) +#define SDCARD_CLOCK_25MHZ (25000000U) +#define SDCARD_CLOCK_50MHZ (50000000U) + +typedef struct _mimxrt_sdcard_pin_t { + const machine_pin_obj_t *pin; + uint8_t af_idx; +} mimxrt_sdcard_pin_t; + +typedef struct _mimxrt_sdcard_obj_pins_t { + mimxrt_sdcard_pin_t cmd; + mimxrt_sdcard_pin_t clk; + mimxrt_sdcard_pin_t cd_b; + mimxrt_sdcard_pin_t data0; + mimxrt_sdcard_pin_t data1; + mimxrt_sdcard_pin_t data2; + mimxrt_sdcard_pin_t data3; +} mimxrt_sdcard_obj_pins_t; + +typedef volatile struct _mimxrt_sdcard_status_obj_t { + bool initialized; + bool inserted; +} mimxrt_sdcard_status_obj_t; + +typedef struct _mimxrt_sdcard_obj_t { + mp_obj_base_t base; + USDHC_Type *usdhc_inst; + usdhc_handle_t handle; + mimxrt_sdcard_status_obj_t *state; + uint16_t block_len; + uint32_t base_clk; + uint32_t bus_clk; + uint32_t rca; + uint32_t block_count; + uint32_t status; + uint32_t oper_cond; + const mimxrt_sdcard_obj_pins_t *pins; +} mimxrt_sdcard_obj_t; + +// --- +// SD Card object instances +// --- +#if MICROPY_PY_MACHINE_SDCARD && (defined MICROPY_USDHC1 || defined MICROPY_USDHC2) +enum { + #if defined MICROPY_USDHC1 && USDHC1_AVAIL + SDCARD_OBJ_USDHC1_IDX, + #endif + #if defined MICROPY_USDHC2 && USDHC2_AVAIL + SDCARD_OBJ_USDHC2_IDX, + #endif + SDCARD_OBJ_USDHC_N +}; +#endif +extern mimxrt_sdcard_obj_t mimxrt_sdcard_objs[SDCARD_OBJ_USDHC_N]; + +// --- +// SD Card functions +// --- +void sdcard_init(mimxrt_sdcard_obj_t *card, uint32_t base_clk); +void sdcard_deinit(mimxrt_sdcard_obj_t *card); +void sdcard_init_pins(mimxrt_sdcard_obj_t *card); +bool sdcard_read(mimxrt_sdcard_obj_t *card, uint8_t *buffer, uint32_t block_num, uint32_t block_count); +bool sdcard_write(mimxrt_sdcard_obj_t *card, uint8_t *buffer, uint32_t block_num, uint32_t block_count); +bool sdcard_set_active(mimxrt_sdcard_obj_t *card); +bool sdcard_volt_validation(mimxrt_sdcard_obj_t *card); +bool sdcard_power_on(mimxrt_sdcard_obj_t *self); +bool sdcard_power_off(mimxrt_sdcard_obj_t *self); +bool sdcard_detect(mimxrt_sdcard_obj_t *self); + +static inline bool sdcard_state_initialized(mimxrt_sdcard_obj_t *card) { + return card->state->initialized; +} + +#endif // MICROPY_INCLUDED_MIMXRT_SDCARD_H From 61b7c098b9a21311bbcec3b43c279ec9aada311b Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 19 Aug 2021 22:00:38 +0200 Subject: [PATCH 010/335] mimxrt/machine_bitstream: Add bitstream function to machine module. Following the code example for ESP32 of Jim Mussard. As a side effect: - mp_hal_ticks_cpu() was implemented, - mp_hal_get_cpu_freq() and mp_hal_ticks_cpu_init() were added and used. - mp_hal_pin_high() and mp_hal_pin_low() were changed for symmetry --- ports/mimxrt/Makefile | 1 + ports/mimxrt/machine_bitstream.c | 73 ++++++++++++++++++++++++++++++++ ports/mimxrt/modmachine.c | 6 ++- ports/mimxrt/mpconfigport.h | 1 + ports/mimxrt/mphalport.h | 15 +++++-- 5 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 ports/mimxrt/machine_bitstream.c diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 58fbe2df33..8b1bb2bfa7 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -152,6 +152,7 @@ SRC_C += \ fatfs_port.c \ led.c \ machine_adc.c \ + machine_bitstream.c \ machine_i2c.c \ machine_led.c \ machine_pin.c \ diff --git a/ports/mimxrt/machine_bitstream.c b/ports/mimxrt/machine_bitstream.c new file mode 100644 index 0000000000..c6ff469ea6 --- /dev/null +++ b/ports/mimxrt/machine_bitstream.c @@ -0,0 +1,73 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jim Mussared + * + * 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. + */ + +// This is a translation of the cycle counter implementation in ports/stm32/machine_bitstream.c. + +#include "py/mpconfig.h" +#include "py/mphal.h" + +#if MICROPY_PY_MACHINE_BITSTREAM + +#define NS_TICKS_OVERHEAD (6) + +void machine_bitstream_high_low(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const uint8_t *buf, size_t len) __attribute__((section(".ram_functions"))); +void machine_bitstream_high_low(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const uint8_t *buf, size_t len) { + uint32_t fcpu_mhz = mp_hal_get_cpu_freq() / 1000000; + // Convert ns to us ticks [high_time_0, period_0, high_time_1, period_1]. + for (size_t i = 0; i < 4; ++i) { + timing_ns[i] = fcpu_mhz * timing_ns[i] / 1000; + if (timing_ns[i] > NS_TICKS_OVERHEAD) { + timing_ns[i] -= NS_TICKS_OVERHEAD; + } + if (i % 2 == 1) { + // Convert low_time to period (i.e. add high_time). + timing_ns[i] += timing_ns[i - 1]; + } + } + // Enable the CPU cycle counter, which is not always enabled. + mp_hal_ticks_cpu_init(); + + uint32_t irq_state = mp_hal_quiet_timing_enter(); + + for (size_t i = 0; i < len; ++i) { + uint8_t b = buf[i]; + for (size_t j = 0; j < 8; ++j) { + uint32_t start_ticks = mp_hal_ticks_cpu(); + mp_hal_pin_high(pin); + uint32_t *t = &timing_ns[b >> 6 & 2]; + while ((mp_hal_ticks_cpu() - start_ticks) < t[0]) { + } + mp_hal_pin_low(pin); + b <<= 1; + while ((mp_hal_ticks_cpu() - start_ticks) < t[1]) { + } + } + } + + mp_hal_quiet_timing_exit(irq_state); +} + +#endif // MICROPY_PY_MACHINE_BITSTREAM diff --git a/ports/mimxrt/modmachine.c b/ports/mimxrt/modmachine.c index a98d09bd0e..2e8753df12 100644 --- a/ports/mimxrt/modmachine.c +++ b/ports/mimxrt/modmachine.c @@ -26,6 +26,7 @@ */ #include "py/runtime.h" +#include "extmod/machine_bitstream.h" #include "extmod/machine_mem.h" #include "extmod/machine_i2c.h" #include "extmod/machine_pulse.h" @@ -45,7 +46,7 @@ STATIC mp_obj_t machine_reset(void) { MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_obj, machine_reset); STATIC mp_obj_t machine_freq(void) { - return MP_OBJ_NEW_SMALL_INT(CLOCK_GetFreq(kCLOCK_CpuClk)); + return MP_OBJ_NEW_SMALL_INT(mp_hal_get_cpu_freq()); } MP_DEFINE_CONST_FUN_OBJ_0(machine_freq_obj, machine_freq); @@ -97,6 +98,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&machine_disable_irq_obj) }, { MP_ROM_QSTR(MP_QSTR_enable_irq), MP_ROM_PTR(&machine_enable_irq_obj) }, + #if MICROPY_PY_MACHINE_BITSTREAM + { MP_ROM_QSTR(MP_QSTR_bitstream), MP_ROM_PTR(&machine_bitstream_obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) }, }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 9775b29efa..0fe6cd1291 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -124,6 +124,7 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_USELECT (1) #define MICROPY_PY_MACHINE (1) #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new +#define MICROPY_PY_MACHINE_BITSTREAM (1) #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_SOFTI2C (1) diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index 94f43001d0..3f0ae51bb6 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -30,6 +30,7 @@ #include #include "ticks.h" #include "pin.h" +#include "fsl_clock.h" #define MP_HAL_PIN_FMT "%q" @@ -39,8 +40,8 @@ #define mp_hal_pin_input(p) machine_pin_set_mode(p, PIN_MODE_IN); #define mp_hal_pin_output(p) machine_pin_set_mode(p, PIN_MODE_OUT); #define mp_hal_pin_open_drain(p) machine_pin_set_mode(p, PIN_MODE_OPEN_DRAIN); -#define mp_hal_pin_high(p) (GPIO_PinWrite(p->gpio, p->pin, 1U)) -#define mp_hal_pin_low(p) (GPIO_PinWrite(p->gpio, p->pin, 0U)) +#define mp_hal_pin_high(p) (p->gpio->DR_SET = 1 << p->pin) +#define mp_hal_pin_low(p) (p->gpio->DR_CLEAR = 1 << p->pin) #define mp_hal_pin_write(p, value) (GPIO_PinWrite(p->gpio, p->pin, value)) #define mp_hal_pin_toggle(p) (GPIO_PortToggle(p->gpio, (1 << p->pin))) #define mp_hal_pin_read(p) (GPIO_PinReadPadStatus(p->gpio, p->pin)) @@ -72,8 +73,16 @@ static inline void mp_hal_delay_us(mp_uint_t us) { #define mp_hal_delay_us_fast(us) mp_hal_delay_us(us) +static inline void mp_hal_ticks_cpu_init(void) { + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; +} + static inline mp_uint_t mp_hal_ticks_cpu(void) { - return 0; + return DWT->CYCCNT; +} + +static inline mp_uint_t mp_hal_get_cpu_freq(void) { + return CLOCK_GetCpuClkFreq(); } From e6850838cdc1a0e0fe8e735a03e7df46d0dcdd0e Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 23 Mar 2021 12:48:35 +1100 Subject: [PATCH 011/335] py/parse: Simplify parse nodes representing a list. This commit simplifies and optimises the parse tree in-memory representation of lists of expressions, for tuples and lists, and when tuples are used on the left-hand-side of assignments and within del statements. This reduces memory usage of the parse tree when such code is compiled, and also reduces the size of the compiler. For example, (1,) was previously the following parse tree: expr_stmt(5) (n=2) atom_paren(45) (n=1) testlist_comp(146) (n=2) int(1) testlist_comp_3b(149) (n=1) NULL NULL and with this commit is now: expr_stmt(5) (n=2) atom_paren(45) (n=1) testlist_comp(146) (n=1) int(1) NULL Similarly, (1, 2, 3) was previously: expr_stmt(5) (n=2) atom_paren(45) (n=1) testlist_comp(146) (n=2) int(1) testlist_comp_3c(150) (n=2) int(2) int(3) NULL and is now: expr_stmt(5) (n=2) atom_paren(45) (n=1) testlist_comp(146) (n=3) int(1) int(2) int(3) NULL Signed-off-by: Damien George --- py/compile.c | 169 ++++++++++++--------------------------------------- py/parse.c | 38 +++++++++++- 2 files changed, 75 insertions(+), 132 deletions(-) diff --git a/py/compile.c b/py/compile.c index 0b02746a56..8ebcc2289f 100644 --- a/py/compile.c +++ b/py/compile.c @@ -59,6 +59,12 @@ typedef enum { #undef DEF_RULE_NC } pn_kind_t; +// Whether a mp_parse_node_struct_t that has pns->kind == PN_testlist_comp +// corresponds to a list comprehension or generator. +#define MP_PARSE_NODE_TESTLIST_COMP_HAS_COMP_FOR(pns) \ + (MP_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2 && \ + MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for)) + #define NEED_METHOD_TABLE MICROPY_EMIT_NATIVE #if NEED_METHOD_TABLE @@ -317,25 +323,13 @@ STATIC void compile_delete_id(compiler_t *comp, qstr qst) { } } -STATIC void c_tuple(compiler_t *comp, mp_parse_node_t pn, mp_parse_node_struct_t *pns_list) { - int total = 0; - if (!MP_PARSE_NODE_IS_NULL(pn)) { - compile_node(comp, pn); - total += 1; - } - if (pns_list != NULL) { - int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns_list); - for (int i = 0; i < n; i++) { - compile_node(comp, pns_list->nodes[i]); - } - total += n; - } - EMIT_ARG(build, total, MP_EMIT_BUILD_TUPLE); -} - STATIC void compile_generic_tuple(compiler_t *comp, mp_parse_node_struct_t *pns) { // a simple tuple expression - c_tuple(comp, MP_PARSE_NODE_NULL, pns); + size_t num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); + for (size_t i = 0; i < num_nodes; i++) { + compile_node(comp, pns->nodes[i]); + } + EMIT_ARG(build, num_nodes, MP_EMIT_BUILD_TUPLE); } STATIC void c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if, int label) { @@ -452,21 +446,14 @@ STATIC void c_assign_atom_expr(compiler_t *comp, mp_parse_node_struct_t *pns, as compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("can't assign to expression")); } -// we need to allow for a caller passing in 1 initial node (node_head) followed by an array of nodes (nodes_tail) -STATIC void c_assign_tuple(compiler_t *comp, mp_parse_node_t node_head, uint num_tail, mp_parse_node_t *nodes_tail) { - uint num_head = (node_head == MP_PARSE_NODE_NULL) ? 0 : 1; - +STATIC void c_assign_tuple(compiler_t *comp, uint num_tail, mp_parse_node_t *nodes_tail) { // look for star expression uint have_star_index = -1; - if (num_head != 0 && MP_PARSE_NODE_IS_STRUCT_KIND(node_head, PN_star_expr)) { - EMIT_ARG(unpack_ex, 0, num_tail); - have_star_index = 0; - } for (uint i = 0; i < num_tail; i++) { if (MP_PARSE_NODE_IS_STRUCT_KIND(nodes_tail[i], PN_star_expr)) { if (have_star_index == (uint)-1) { - EMIT_ARG(unpack_ex, num_head + i, num_tail - i - 1); - have_star_index = num_head + i; + EMIT_ARG(unpack_ex, i, num_tail - i - 1); + have_star_index = i; } else { compile_syntax_error(comp, nodes_tail[i], MP_ERROR_TEXT("multiple *x in assignment")); return; @@ -474,17 +461,10 @@ STATIC void c_assign_tuple(compiler_t *comp, mp_parse_node_t node_head, uint num } } if (have_star_index == (uint)-1) { - EMIT_ARG(unpack_sequence, num_head + num_tail); - } - if (num_head != 0) { - if (0 == have_star_index) { - c_assign(comp, ((mp_parse_node_struct_t *)node_head)->nodes[0], ASSIGN_STORE); - } else { - c_assign(comp, node_head, ASSIGN_STORE); - } + EMIT_ARG(unpack_sequence, num_tail); } for (uint i = 0; i < num_tail; i++) { - if (num_head + i == have_star_index) { + if (i == have_star_index) { c_assign(comp, ((mp_parse_node_struct_t *)nodes_tail[i])->nodes[0], ASSIGN_STORE); } else { c_assign(comp, nodes_tail[i], ASSIGN_STORE); @@ -526,7 +506,7 @@ STATIC void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_ if (assign_kind != ASSIGN_STORE) { goto cannot_assign; } - c_assign_tuple(comp, MP_PARSE_NODE_NULL, MP_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes); + c_assign_tuple(comp, MP_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes); break; case PN_atom_paren: @@ -551,13 +531,13 @@ STATIC void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_ } if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // empty list, assignment allowed - c_assign_tuple(comp, MP_PARSE_NODE_NULL, 0, NULL); + c_assign_tuple(comp, 0, NULL); } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) { pns = (mp_parse_node_struct_t *)pns->nodes[0]; goto testlist_comp; } else { // brackets around 1 item - c_assign_tuple(comp, pns->nodes[0], 0, NULL); + c_assign_tuple(comp, 1, pns->nodes); } break; @@ -568,27 +548,10 @@ STATIC void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_ testlist_comp: // lhs is a sequence - if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { - mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t *)pns->nodes[1]; - if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) { - // sequence of one item, with trailing comma - assert(MP_PARSE_NODE_IS_NULL(pns2->nodes[0])); - c_assign_tuple(comp, pns->nodes[0], 0, NULL); - } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) { - // sequence of many items - uint n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns2); - c_assign_tuple(comp, pns->nodes[0], n, pns2->nodes); - } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) { - goto cannot_assign; - } else { - // sequence with 2 items - goto sequence_with_2_items; - } - } else { - // sequence with 2 items - sequence_with_2_items: - c_assign_tuple(comp, MP_PARSE_NODE_NULL, 2, pns->nodes); + if (MP_PARSE_NODE_TESTLIST_COMP_HAS_COMP_FOR(pns)) { + goto cannot_assign; } + c_assign_tuple(comp, MP_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes); return; } return; @@ -983,32 +946,11 @@ STATIC void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) { } else { assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp)); mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)pn; - // TODO perhaps factorise testlist_comp code with other uses of PN_testlist_comp - - if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { - mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t *)pns->nodes[1]; - if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3b) { - // sequence of one item, with trailing comma - assert(MP_PARSE_NODE_IS_NULL(pns1->nodes[0])); - c_del_stmt(comp, pns->nodes[0]); - } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3c) { - // sequence of many items - int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns1); - c_del_stmt(comp, pns->nodes[0]); - for (int i = 0; i < n; i++) { - c_del_stmt(comp, pns1->nodes[i]); - } - } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) { - goto cannot_delete; - } else { - // sequence with 2 items - goto sequence_with_2_items; - } - } else { - // sequence with 2 items - sequence_with_2_items: - c_del_stmt(comp, pns->nodes[0]); - c_del_stmt(comp, pns->nodes[1]); + if (MP_PARSE_NODE_TESTLIST_COMP_HAS_COMP_FOR(pns)) { + goto cannot_delete; + } + for (size_t i = 0; i < MP_PARSE_NODE_STRUCT_NUM_NODES(pns); ++i) { + c_del_stmt(comp, pns->nodes[i]); } } } else { @@ -2490,31 +2432,16 @@ STATIC void compile_comprehension(compiler_t *comp, mp_parse_node_struct_t *pns, STATIC void compile_atom_paren(compiler_t *comp, mp_parse_node_struct_t *pns) { if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // an empty tuple - c_tuple(comp, MP_PARSE_NODE_NULL, NULL); + EMIT_ARG(build, 0, MP_EMIT_BUILD_TUPLE); } else { assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)); pns = (mp_parse_node_struct_t *)pns->nodes[0]; - assert(!MP_PARSE_NODE_IS_NULL(pns->nodes[1])); - if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { - mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t *)pns->nodes[1]; - if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) { - // tuple of one item, with trailing comma - assert(MP_PARSE_NODE_IS_NULL(pns2->nodes[0])); - c_tuple(comp, pns->nodes[0], NULL); - } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) { - // tuple of many items - c_tuple(comp, pns->nodes[0], pns2); - } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) { - // generator expression - compile_comprehension(comp, pns, SCOPE_GEN_EXPR); - } else { - // tuple with 2 items - goto tuple_with_2_items; - } + if (MP_PARSE_NODE_TESTLIST_COMP_HAS_COMP_FOR(pns)) { + // generator expression + compile_comprehension(comp, pns, SCOPE_GEN_EXPR); } else { - // tuple with 2 items - tuple_with_2_items: - c_tuple(comp, MP_PARSE_NODE_NULL, pns); + // tuple with N items + compile_generic_tuple(comp, pns); } } } @@ -2525,31 +2452,13 @@ STATIC void compile_atom_bracket(compiler_t *comp, mp_parse_node_struct_t *pns) EMIT_ARG(build, 0, MP_EMIT_BUILD_LIST); } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) { mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t *)pns->nodes[0]; - if (MP_PARSE_NODE_IS_STRUCT(pns2->nodes[1])) { - mp_parse_node_struct_t *pns3 = (mp_parse_node_struct_t *)pns2->nodes[1]; - if (MP_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3b) { - // list of one item, with trailing comma - assert(MP_PARSE_NODE_IS_NULL(pns3->nodes[0])); - compile_node(comp, pns2->nodes[0]); - EMIT_ARG(build, 1, MP_EMIT_BUILD_LIST); - } else if (MP_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3c) { - // list of many items - compile_node(comp, pns2->nodes[0]); - compile_generic_all_nodes(comp, pns3); - EMIT_ARG(build, 1 + MP_PARSE_NODE_STRUCT_NUM_NODES(pns3), MP_EMIT_BUILD_LIST); - } else if (MP_PARSE_NODE_STRUCT_KIND(pns3) == PN_comp_for) { - // list comprehension - compile_comprehension(comp, pns2, SCOPE_LIST_COMP); - } else { - // list with 2 items - goto list_with_2_items; - } + if (MP_PARSE_NODE_TESTLIST_COMP_HAS_COMP_FOR(pns2)) { + // list comprehension + compile_comprehension(comp, pns2, SCOPE_LIST_COMP); } else { - // list with 2 items - list_with_2_items: - compile_node(comp, pns2->nodes[0]); - compile_node(comp, pns2->nodes[1]); - EMIT_ARG(build, 2, MP_EMIT_BUILD_LIST); + // list with N items + compile_generic_all_nodes(comp, pns2); + EMIT_ARG(build, MP_PARSE_NODE_STRUCT_NUM_NODES(pns2), MP_EMIT_BUILD_LIST); } } else { // list with 1 item diff --git a/py/parse.c b/py/parse.c index ae3fa8ea6d..68c761734a 100644 --- a/py/parse.c +++ b/py/parse.c @@ -796,9 +796,11 @@ STATIC bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) { #endif STATIC void push_result_rule(parser_t *parser, size_t src_line, uint8_t rule_id, size_t num_args) { - // optimise away parenthesis around an expression if possible + // Simplify and optimise certain rules, to reduce memory usage and simplify the compiler. if (rule_id == RULE_atom_paren) { - // there should be just 1 arg for this rule + // Remove parenthesis around a single expression if possible. + // This atom_paren rule always has a single argument, and after this + // optimisation that argument is either NULL or testlist_comp. mp_parse_node_t pn = peek_result(parser, 0); if (MP_PARSE_NODE_IS_NULL(pn)) { // need to keep parenthesis for () @@ -808,6 +810,34 @@ STATIC void push_result_rule(parser_t *parser, size_t src_line, uint8_t rule_id, // parenthesis around a single expression, so it's just the expression return; } + } else if (rule_id == RULE_testlist_comp) { + // The testlist_comp rule can be the sole argument to either atom_parent + // or atom_bracket, for (...) and [...] respectively. + assert(num_args == 2); + mp_parse_node_t pn = peek_result(parser, 0); + if (MP_PARSE_NODE_IS_STRUCT(pn)) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)pn; + if (MP_PARSE_NODE_STRUCT_KIND(pns) == RULE_testlist_comp_3b) { + // tuple of one item, with trailing comma + pop_result(parser); + --num_args; + } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == RULE_testlist_comp_3c) { + // tuple of many items, convert testlist_comp_3c to testlist_comp + pop_result(parser); + assert(pn == peek_result(parser, 0)); + pns->kind_num_nodes = rule_id | MP_PARSE_NODE_STRUCT_NUM_NODES(pns) << 8; + return; + } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == RULE_comp_for) { + // generator expression + } else { + // tuple with 2 items + } + } else { + // tuple with 2 items + } + } else if (rule_id == RULE_testlist_comp_3c) { + // steal first arg of outer testlist_comp rule + ++num_args; } #if MICROPY_COMP_CONST_FOLDING @@ -827,6 +857,10 @@ STATIC void push_result_rule(parser_t *parser, size_t src_line, uint8_t rule_id, for (size_t i = num_args; i > 0; i--) { pn->nodes[i - 1] = pop_result(parser); } + if (rule_id == RULE_testlist_comp_3c) { + // need to push something non-null to replace stolen first arg of testlist_comp + push_result_node(parser, (mp_parse_node_t)pn); + } push_result_node(parser, (mp_parse_node_t)pn); } From 318c029d4569488df97661018fdce0e2c1443a79 Mon Sep 17 00:00:00 2001 From: stijn Date: Tue, 7 Sep 2021 11:36:58 +0200 Subject: [PATCH 012/335] windows/README: Remove unsupported Python instructions for Cygwin. It's not possible anymore to build MicroPython on Cygwin using a standard Windows installation of Python so don't advertise that. Specifically: preprocessing in makeqstrdefs.py fails on the subprocess call with 'gcc: fatal error: no input files' because one of the flags contains double quotes and that somehow messes up the commandline. --- ports/windows/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ports/windows/README.md b/ports/windows/README.md index 553e87513e..55e23de7bf 100644 --- a/ports/windows/README.md +++ b/ports/windows/README.md @@ -25,8 +25,7 @@ Install Cygwin, then install following packages using Cygwin's setup.exe: * mingw64-i686-gcc-core * mingw64-x86_64-gcc-core * make - -Also install the python3 package, or install Python globally for Windows (see below). +* python3 Build using: From cc0884bb4fe7ad5087030323cfae0bf800e432b5 Mon Sep 17 00:00:00 2001 From: Peter Hinch Date: Tue, 7 Sep 2021 07:56:26 +0100 Subject: [PATCH 013/335] docs/library/os.rst: Clarify littlefs requirements for block erase. --- docs/library/os.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/library/os.rst b/docs/library/os.rst index a1eae4f245..19652ee2bc 100644 --- a/docs/library/os.rst +++ b/docs/library/os.rst @@ -314,6 +314,12 @@ that the block device supports the extended interface. ``ioctl(6, ...)`` must also be intercepted. The need for others is hardware dependent. + Prior to any call to ``writeblocks(block, ...)`` littlefs issues + ``ioctl(6, block)``. This enables a device driver to erase the block + prior to a write if the hardware requires it. Alternatively a driver + might intercept ``ioctl(6, block)`` and return 0 (success). In this case + the driver assumes responsibility for detecting the need for erasure. + Unless otherwise stated ``ioctl(op, arg)`` can return ``None``. Consequently an implementation can ignore unused values of ``op``. Where ``op`` is intercepted, the return value for operations 4 and 5 are as From 60d3a3c3a0746312f4fd46c56d206ffad1c57796 Mon Sep 17 00:00:00 2001 From: Matt Trentini Date: Thu, 9 Sep 2021 12:52:32 +1000 Subject: [PATCH 014/335] docs/library/bluetooth.rst: Update incorrect link to gatts_write. --- docs/library/bluetooth.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/library/bluetooth.rst b/docs/library/bluetooth.rst index 7ab4d6e88c..6ebceeed58 100644 --- a/docs/library/bluetooth.rst +++ b/docs/library/bluetooth.rst @@ -49,7 +49,7 @@ Configuration - ``'mac'``: The current address in use, depending on the current address mode. This returns a tuple of ``(addr_type, addr)``. - See :meth:`gatts_write ` for details about address type. + See :meth:`gatts_write ` for details about address type. This may only be queried while the interface is currently active. From 9a7f77bfbc51f4dda5a9396d8bb4b57dcdfcdb90 Mon Sep 17 00:00:00 2001 From: Seon Rozenblum Date: Sat, 4 Sep 2021 10:41:25 +1000 Subject: [PATCH 015/335] esp32/boards: Add new FeatherS2-Neo board definition. --- .../esp32/boards/UM_FEATHERS2NEO/manifest.py | 2 + .../UM_FEATHERS2NEO/modules/feathers2neo.py | 90 +++++++++++++++++++ .../UM_FEATHERS2NEO/mpconfigboard.cmake | 8 ++ .../boards/UM_FEATHERS2NEO/mpconfigboard.h | 12 +++ .../boards/UM_FEATHERS2NEO/sdkconfig.board | 8 ++ tools/autobuild/build-esp32-latest.sh | 1 + 6 files changed, 121 insertions(+) create mode 100644 ports/esp32/boards/UM_FEATHERS2NEO/manifest.py create mode 100644 ports/esp32/boards/UM_FEATHERS2NEO/modules/feathers2neo.py create mode 100644 ports/esp32/boards/UM_FEATHERS2NEO/mpconfigboard.cmake create mode 100644 ports/esp32/boards/UM_FEATHERS2NEO/mpconfigboard.h create mode 100644 ports/esp32/boards/UM_FEATHERS2NEO/sdkconfig.board diff --git a/ports/esp32/boards/UM_FEATHERS2NEO/manifest.py b/ports/esp32/boards/UM_FEATHERS2NEO/manifest.py new file mode 100644 index 0000000000..7ae2ed15d9 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2NEO/manifest.py @@ -0,0 +1,2 @@ +include("$(PORT_DIR)/boards/manifest.py") +freeze("modules") diff --git a/ports/esp32/boards/UM_FEATHERS2NEO/modules/feathers2neo.py b/ports/esp32/boards/UM_FEATHERS2NEO/modules/feathers2neo.py new file mode 100644 index 0000000000..857c7559d1 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2NEO/modules/feathers2neo.py @@ -0,0 +1,90 @@ +# FeatherS2 Neo MicroPython Helper Library +# 2021 Seon Rozenblum - Unexpected Maker +# +# Project home: +# https://unexpectedmaker.com/feathers2-neo +# +# 2021-Sep-04 - v0.1 - Initial implementation + +# Import required libraries +from micropython import const +from machine import Pin, ADC +import machine, time + +# FeatherS2 Neo Hardware Pin Assignments + +# Sense Pins +VBUS_SENSE = const(34) +VBAT_SENSE = const(2) + +# RGB LED Pins +RGB_DATA = const(40) +RGB_PWR = const(39) + +# RGB MATRIX LED Pins +RGB_MATRIX_DATA = const(21) +RGB_MATRIX_PWR = const(4) + +# SPI +SPI_MOSI = const(35) +SPI_MISO = const(37) +SPI_CLK = const(36) + +# I2C +I2C_SDA = const(8) +I2C_SCL = const(9) + +# DAC +DAC1 = const(17) +DAC2 = const(18) + +# Helper functions +def set_pixel_power(state): + """Enable or Disable power to the onboard NeoPixel to either show colour, or to reduce power for deep sleep.""" + Pin(RGB_PWR, Pin.OUT).value(state) + + +def set_pixel_matrix_power(state): + """Enable or Disable power to the onboard NeoPixel RGB Matrix to either show colours, or to reduce power for deep sleep.""" + Pin(RGB_MATRIX_PWR, Pin.OUT).value(state) + + +def get_battery_voltage(): + """ + Returns the current battery voltage. If no battery is connected, returns 4.2V which is the charge voltage + This is an approximation only, but useful to detect if the charge state of the battery is getting low. + """ + adc = ADC(Pin(VBAT_SENSE)) # Assign the ADC pin to read + measuredvbat = adc.read() # Read the value + measuredvbat /= 8192 # divide by 8192 as we are using the default ADC voltage range of 0-1V + measuredvbat *= 4.2 # Multiply by 4.2V, our reference voltage + return round(measuredvbat, 2) + + +def get_vbus_present(): + """Detect if VBUS (5V) power source is present""" + return Pin(VBUS_SENSE, Pin.IN).value() == 1 + + +# NeoPixel rainbow colour wheel +def rgb_color_wheel(wheel_pos): + """Color wheel to allow for cycling through the rainbow of RGB colors.""" + wheel_pos = wheel_pos % 255 + + if wheel_pos < 85: + return 255 - wheel_pos * 3, 0, wheel_pos * 3 + elif wheel_pos < 170: + wheel_pos -= 85 + return 0, wheel_pos * 3, 255 - wheel_pos * 3 + else: + wheel_pos -= 170 + return wheel_pos * 3, 255 - wheel_pos * 3, 0 + + +# Go into deep sleep but shut down the RGB LED first to save power +# Use this if you want lowest deep sleep current +def go_deepsleep(t): + """Deep sleep helper that also powers down the on-board NeoPixel.""" + set_pixel_power(False) + set_pixel_matrix_power(False) + machine.deepsleep(t) diff --git a/ports/esp32/boards/UM_FEATHERS2NEO/mpconfigboard.cmake b/ports/esp32/boards/UM_FEATHERS2NEO/mpconfigboard.cmake new file mode 100644 index 0000000000..b0b3e3aa99 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2NEO/mpconfigboard.cmake @@ -0,0 +1,8 @@ +set(IDF_TARGET esp32s2) +set(SDKCONFIG_DEFAULTS + boards/sdkconfig.base + boards/sdkconfig.spiram_sx + boards/sdkconfig.usb +) + +set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) \ No newline at end of file diff --git a/ports/esp32/boards/UM_FEATHERS2NEO/mpconfigboard.h b/ports/esp32/boards/UM_FEATHERS2NEO/mpconfigboard.h new file mode 100644 index 0000000000..5ee6874b87 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2NEO/mpconfigboard.h @@ -0,0 +1,12 @@ +#define MICROPY_HW_BOARD_NAME "FeatherS2 Neo" +#define MICROPY_HW_MCU_NAME "ESP32-S2FN4R2" + +#define MICROPY_PY_BLUETOOTH (0) +#define MICROPY_HW_ENABLE_SDCARD (0) + +#define MICROPY_HW_I2C0_SCL (9) +#define MICROPY_HW_I2C0_SDA (8) + +#define MICROPY_HW_SPI1_MOSI (35) // SDO +#define MICROPY_HW_SPI1_MISO (37) // SDI +#define MICROPY_HW_SPI1_SCK (36) diff --git a/ports/esp32/boards/UM_FEATHERS2NEO/sdkconfig.board b/ports/esp32/boards/UM_FEATHERS2NEO/sdkconfig.board new file mode 100644 index 0000000000..87a92892d0 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2NEO/sdkconfig.board @@ -0,0 +1,8 @@ +CONFIG_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_USB_AND_UART=y +CONFIG_ESPTOOLPY_AFTER_NORESET=y + +# LWIP +CONFIG_LWIP_LOCAL_HOSTNAME="UMFeatherS2Neo" +# end of LWIP diff --git a/tools/autobuild/build-esp32-latest.sh b/tools/autobuild/build-esp32-latest.sh index 92a12b2d53..5445927ab0 100755 --- a/tools/autobuild/build-esp32-latest.sh +++ b/tools/autobuild/build-esp32-latest.sh @@ -49,4 +49,5 @@ else do_build esp32c3 GENERIC_C3 do_build tinys2 UM_TINYS2 do_build featherS2 UM_FEATHERS2 + do_build featherS2neo UM_FEATHERS2NEO fi From 0ec5052f622307429ab5dd74f1582bcd0a8e0aa1 Mon Sep 17 00:00:00 2001 From: Patrick Van Oosterwijck Date: Tue, 7 Sep 2021 21:33:16 -0600 Subject: [PATCH 016/335] tools/autobuild: Add auto build for GENERIC_C3_USB. --- tools/autobuild/build-esp32-latest.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/autobuild/build-esp32-latest.sh b/tools/autobuild/build-esp32-latest.sh index 5445927ab0..e0e932e026 100755 --- a/tools/autobuild/build-esp32-latest.sh +++ b/tools/autobuild/build-esp32-latest.sh @@ -47,6 +47,7 @@ if idf.py --version | grep -q v4.2; then do_build wesp32 SIL_WESP32 else do_build esp32c3 GENERIC_C3 + do_build esp32c3usb GENERIC_C3_USB do_build tinys2 UM_TINYS2 do_build featherS2 UM_FEATHERS2 do_build featherS2neo UM_FEATHERS2NEO From 97bbc0bb91a6215eecdeb39c37505fda96a1d74d Mon Sep 17 00:00:00 2001 From: Boris Vinogradov Date: Sat, 28 Aug 2021 23:19:55 +0300 Subject: [PATCH 017/335] stm32/boards/VCC_GND_H743VI: Add board definition for VCC_GND_H743VI. --- .../stm32/boards/VCC_GND_H743VI/board_init.c | 9 ++ .../boards/VCC_GND_H743VI/mpconfigboard.h | 103 ++++++++++++++++++ .../boards/VCC_GND_H743VI/mpconfigboard.mk | 21 ++++ ports/stm32/boards/VCC_GND_H743VI/pins.csv | 80 ++++++++++++++ .../VCC_GND_H743VI/stm32h7xx_hal_conf.h | 19 ++++ 5 files changed, 232 insertions(+) create mode 100644 ports/stm32/boards/VCC_GND_H743VI/board_init.c create mode 100644 ports/stm32/boards/VCC_GND_H743VI/mpconfigboard.h create mode 100644 ports/stm32/boards/VCC_GND_H743VI/mpconfigboard.mk create mode 100644 ports/stm32/boards/VCC_GND_H743VI/pins.csv create mode 100644 ports/stm32/boards/VCC_GND_H743VI/stm32h7xx_hal_conf.h diff --git a/ports/stm32/boards/VCC_GND_H743VI/board_init.c b/ports/stm32/boards/VCC_GND_H743VI/board_init.c new file mode 100644 index 0000000000..53b685ff92 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_H743VI/board_init.c @@ -0,0 +1,9 @@ +#include "py/mphal.h" + +void VCC_GND_STM32H743VI_board_early_init(void) { + // set SPI and QSPI flashes CS pin high + mp_hal_pin_output(pin_B10); + mp_hal_pin_write(pin_B10, 1); + mp_hal_pin_output(pin_B12); + mp_hal_pin_write(pin_B12, 1); +} diff --git a/ports/stm32/boards/VCC_GND_H743VI/mpconfigboard.h b/ports/stm32/boards/VCC_GND_H743VI/mpconfigboard.h new file mode 100644 index 0000000000..9ef5490fdb --- /dev/null +++ b/ports/stm32/boards/VCC_GND_H743VI/mpconfigboard.h @@ -0,0 +1,103 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * MIT License; Copyright (c) 2021 Damien P. George + */ + +// STM32H743VIT6 H7 core board by VCC-GND Studio +// http://vcc-gnd.com/ +// https://item.taobao.com/item.htm?ft=t&id=614466740679 +// https://www.aliexpress.com/wholesale?SearchText=STM32H743VIT6 + +#define MICROPY_HW_BOARD_NAME "VCC-GND STM32H743VI" +#define MICROPY_HW_MCU_NAME "STM32H743VI" +#define MICROPY_HW_FLASH_FS_LABEL "VCCGNDH743VI" + +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_ADC (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SDCARD (1) +#define MICROPY_HW_HAS_SWITCH (1) +#define MICROPY_HW_HAS_FLASH (1) + +#define MICROPY_BOARD_EARLY_INIT VCC_GND_STM32H743VI_board_early_init + +// The board has an 25MHz HSE, the following gives 480MHz CPU speed +#define MICROPY_HW_CLK_PLLM (5) +#define MICROPY_HW_CLK_PLLN (192) +#define MICROPY_HW_CLK_PLLP (2) +#define MICROPY_HW_CLK_PLLQ (4) +#define MICROPY_HW_CLK_PLLR (2) + +// The USB clock is set using PLL3 +#define MICROPY_HW_CLK_PLL3M (5) +#define MICROPY_HW_CLK_PLL3N (48) +#define MICROPY_HW_CLK_PLL3P (2) +#define MICROPY_HW_CLK_PLL3Q (5) +#define MICROPY_HW_CLK_PLL3R (2) + +// 5 wait states +#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_5 + +// UART config +#define MICROPY_HW_UART2_TX (pin_D5) +#define MICROPY_HW_UART2_RX (pin_D6) +#define MICROPY_HW_UART2_RTS (pin_D4) +#define MICROPY_HW_UART2_CTS (pin_D3) +#define MICROPY_HW_UART3_TX (pin_D8) +#define MICROPY_HW_UART3_RX (pin_D9) +#define MICROPY_HW_UART5_TX (pin_B6) +#define MICROPY_HW_UART5_RX (pin_B12) +#define MICROPY_HW_UART6_TX (pin_C6) +#define MICROPY_HW_UART6_RX (pin_C7) +#define MICROPY_HW_UART8_TX (pin_E1) +#define MICROPY_HW_UART8_RX (pin_E0) + +// I2C buses +#define MICROPY_HW_I2C1_SCL (pin_B6) +#define MICROPY_HW_I2C1_SDA (pin_B7) +#define MICROPY_HW_I2C2_SCL (pin_B10) +#define MICROPY_HW_I2C2_SDA (pin_B11) +#define MICROPY_HW_I2C3_SCL (pin_A8) +#define MICROPY_HW_I2C3_SDA (pin_C9) + +// SPI buses +#define MICROPY_HW_SPI1_NSS (pin_A4) +#define MICROPY_HW_SPI1_SCK (pin_A5) +#define MICROPY_HW_SPI1_MISO (pin_A6) +#define MICROPY_HW_SPI1_MOSI (pin_A7) +#define MICROPY_HW_SPI2_NSS (pin_B12) +#define MICROPY_HW_SPI2_SCK (pin_B13) +#define MICROPY_HW_SPI2_MISO (pin_B14) +#define MICROPY_HW_SPI2_MOSI (pin_B15) + +// USRSW is pulled low. Pressing the button makes the input go high. +#define MICROPY_HW_USRSW_PIN (pin_B3) +#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) +#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_RISING) +#define MICROPY_HW_USRSW_PRESSED (1) + +// LEDs +#define MICROPY_HW_LED1 (pin_A13) // red +#define MICROPY_HW_LED2 (pin_A14) // green +#define MICROPY_HW_LED3 (pin_A15) // yellow +#define MICROPY_HW_LED4 (pin_B4) // blue +#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) +#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) + +// USB config +#define MICROPY_HW_USB_FS (1) +#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) +#define MICROPY_HW_USB_OTG_ID_PIN (pin_A10) + +// FDCAN bus +#define MICROPY_HW_CAN1_NAME "FDCAN1" +#define MICROPY_HW_CAN1_TX (pin_D1) +#define MICROPY_HW_CAN1_RX (pin_D0) + +// SD card detect switch +#define MICROPY_HW_SDCARD_DETECT_PIN (pin_A8) +#define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP) +#define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) + +void VCC_GND_STM32H743VI_board_early_init(void); diff --git a/ports/stm32/boards/VCC_GND_H743VI/mpconfigboard.mk b/ports/stm32/boards/VCC_GND_H743VI/mpconfigboard.mk new file mode 100644 index 0000000000..1f5fa32a1b --- /dev/null +++ b/ports/stm32/boards/VCC_GND_H743VI/mpconfigboard.mk @@ -0,0 +1,21 @@ +USE_MBOOT ?= 0 + +# MCU settings +MCU_SERIES = h7 +CMSIS_MCU = STM32H743xx +MICROPY_FLOAT_IMPL = double +AF_FILE = boards/stm32h743_af.csv + +ifeq ($(USE_MBOOT),1) +# When using Mboot all the text goes together after the filesystem +LD_FILES = boards/stm32h743.ld boards/common_blifs.ld +TEXT0_ADDR = 0x08040000 +else +# When not using Mboot the ISR text goes first, then the rest after the filesystem +LD_FILES = boards/stm32h743.ld boards/common_ifs.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08040000 +endif + +# MicroPython settings +MICROPY_VFS_LFS2 = 1 diff --git a/ports/stm32/boards/VCC_GND_H743VI/pins.csv b/ports/stm32/boards/VCC_GND_H743VI/pins.csv new file mode 100644 index 0000000000..6668a92db6 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_H743VI/pins.csv @@ -0,0 +1,80 @@ +A0,PA0 +A1,PA1 +A2,PA2 +A3,PA3 +A4,PA4 +A5,PA5 +A6,PA6 +A7,PA7 +A8,PA8 +A9,PA9 +A10,PA10 +A11,PA11 +A12,PA12 +A13,PA13 +A14,PA14 +A15,PA15 +B0,PB0 +B1,PB1 +B2,PB2 +B3,PB3 +B4,PB4 +B5,PB5 +B6,PB6 +B7,PB7 +B8,PB8 +B9,PB9 +B10,PB10 +B11,PB11 +B12,PB12 +B13,PB13 +B14,PB14 +B15,PB15 +C0,PC0 +C1,PC1 +C2,PC2 +C3,PC3 +C4,PC4 +C5,PC5 +C6,PC6 +C7,PC7 +C8,PC8 +C9,PC9 +C10,PC10 +C11,PC11 +C12,PC12 +C13,PC13 +C14,PC14 +C15,PC15 +D0,PD0 +D1,PD1 +D2,PD2 +D3,PD3 +D4,PD4 +D5,PD5 +D6,PD6 +D7,PD7 +D8,PD8 +D9,PD9 +D10,PD10 +D11,PD11 +D12,PD12 +D13,PD13 +D14,PD14 +D15,PD15 +E0,PE0 +E1,PE1 +E2,PE2 +E3,PE3 +E4,PE4 +E5,PE5 +E6,PE6 +E7,PE7 +E8,PE8 +E9,PE9 +E10,PE10 +E11,PE11 +E12,PE12 +E13,PE13 +E14,PE14 +E15,PE15 diff --git a/ports/stm32/boards/VCC_GND_H743VI/stm32h7xx_hal_conf.h b/ports/stm32/boards/VCC_GND_H743VI/stm32h7xx_hal_conf.h new file mode 100644 index 0000000000..c4d148b0bb --- /dev/null +++ b/ports/stm32/boards/VCC_GND_H743VI/stm32h7xx_hal_conf.h @@ -0,0 +1,19 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2019 Damien P. George + */ +#ifndef MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H + +#include "boards/stm32h7xx_hal_conf_base.h" + +// Oscillator values in Hz +#define HSE_VALUE (25000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (5000) +#define LSE_STARTUP_TIMEOUT (5000) + +#endif // MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H From b71c621f468e50361c137f64b0241f3ecc944b7a Mon Sep 17 00:00:00 2001 From: Daniel Gorny Date: Tue, 7 Sep 2021 13:29:40 +0200 Subject: [PATCH 018/335] stm32/boards/OLIMEX_E407: Add Ethernet RMII support. --- ports/stm32/boards/OLIMEX_E407/mpconfigboard.h | 11 +++++++++++ ports/stm32/boards/OLIMEX_E407/mpconfigboard.mk | 5 +++++ ports/stm32/boards/OLIMEX_E407/pins.csv | 3 +++ 3 files changed, 19 insertions(+) diff --git a/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h b/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h index 999f97a708..b9c94b15be 100644 --- a/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h +++ b/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h @@ -78,3 +78,14 @@ #define MICROPY_HW_USB_FS (1) #define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) #define MICROPY_HW_USB_OTG_ID_PIN (pin_A10) + +// Ethernet via RMII +#define MICROPY_HW_ETH_MDC (pin_C1) +#define MICROPY_HW_ETH_MDIO (pin_A2) +#define MICROPY_HW_ETH_RMII_REF_CLK (pin_A1) +#define MICROPY_HW_ETH_RMII_CRS_DV (pin_A7) +#define MICROPY_HW_ETH_RMII_RXD0 (pin_C4) +#define MICROPY_HW_ETH_RMII_RXD1 (pin_C5) +#define MICROPY_HW_ETH_RMII_TX_EN (pin_G11) +#define MICROPY_HW_ETH_RMII_TXD0 (pin_G13) +#define MICROPY_HW_ETH_RMII_TXD1 (pin_G14) diff --git a/ports/stm32/boards/OLIMEX_E407/mpconfigboard.mk b/ports/stm32/boards/OLIMEX_E407/mpconfigboard.mk index b154dcfbac..0d3eee83be 100644 --- a/ports/stm32/boards/OLIMEX_E407/mpconfigboard.mk +++ b/ports/stm32/boards/OLIMEX_E407/mpconfigboard.mk @@ -4,3 +4,8 @@ AF_FILE = boards/stm32f405_af.csv LD_FILES = boards/stm32f405.ld boards/common_ifs.ld TEXT0_ADDR = 0x08000000 TEXT1_ADDR = 0x08020000 + +# MicroPython settings +MICROPY_PY_LWIP = 1 +MICROPY_PY_USSL = 1 +MICROPY_SSL_MBEDTLS = 1 diff --git a/ports/stm32/boards/OLIMEX_E407/pins.csv b/ports/stm32/boards/OLIMEX_E407/pins.csv index 81a9bcb853..cb0a49916e 100644 --- a/ports/stm32/boards/OLIMEX_E407/pins.csv +++ b/ports/stm32/boards/OLIMEX_E407/pins.csv @@ -84,3 +84,6 @@ PD15,PD15 PA0,PA0 USB_DM,PA11 USB_DP,PA12 +PG11,PG11 +PG13,PG13 +PG14,PG14 From 4c31d0ab60e7244a25e38f2a0bc640de6e87844f Mon Sep 17 00:00:00 2001 From: Tobias Thyrrestrup Date: Wed, 8 Sep 2021 12:22:35 +0200 Subject: [PATCH 019/335] stm32/boards/LEGO_HUB_NO6: Remove user paths from cc2564 init file. Signed-off-by: Tobias Thyrrestrup --- .../stm32/boards/LEGO_HUB_NO6/bluetooth_init_cc2564C_1.5.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/stm32/boards/LEGO_HUB_NO6/bluetooth_init_cc2564C_1.5.c b/ports/stm32/boards/LEGO_HUB_NO6/bluetooth_init_cc2564C_1.5.c index ec41fdfeef..b185b579f8 100644 --- a/ports/stm32/boards/LEGO_HUB_NO6/bluetooth_init_cc2564C_1.5.c +++ b/ports/stm32/boards/LEGO_HUB_NO6/bluetooth_init_cc2564C_1.5.c @@ -4,9 +4,9 @@ #if !BUILDING_MBOOT // init script created from -// - /Users/dktobthy/Downloads/cc256xc_bt_spv1.5/CC256XC_BT_SP/v1.5/initscripts-TIInit_6.12.26.bts +// - CC256XC_BT_SP/v1.5/initscripts-TIInit_6.12.26.bts // - AKA TIInit_6.12.26.bts -// - /Users/dktobthy/Downloads/cc256xc_bt_spv1.5/CC256XC_BT_SP/v1.5/initscripts-TIInit_6.12.26_ble_add-on.bts +// - CC256XC_BT_SP/v1.5/initscripts-TIInit_6.12.26_ble_add-on.bts #include #include "lib/btstack/chipset/cc256x/btstack_chipset_cc256x.h" @@ -613,4 +613,4 @@ const uint8_t cc256x_init_script[] = { const uint32_t cc256x_init_script_size = 6771; -#endif \ No newline at end of file +#endif From 0a510737248132430de4317d7fd4d47e76862182 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 10 Sep 2021 16:06:59 +1000 Subject: [PATCH 020/335] stm32/boards: Remove trailing spaces, and add newline at end of file. Signed-off-by: Damien George --- ports/stm32/boards/MIKROE_CLICKER2_STM32/pins.csv | 2 +- ports/stm32/boards/NUCLEO_F412ZG/pins.csv | 2 +- ports/stm32/boards/OLIMEX_E407/mpconfigboard.h | 2 +- ports/stm32/boards/STM32F4DISC/mpconfigboard.h | 2 +- ports/stm32/boards/STM32F769DISC/mpconfigboard.h | 2 +- ports/stm32/boards/stm32h743.ld | 2 +- ports/stm32/boards/stm32l432_af.csv | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ports/stm32/boards/MIKROE_CLICKER2_STM32/pins.csv b/ports/stm32/boards/MIKROE_CLICKER2_STM32/pins.csv index 09e1ccfb4b..c04d2b8c4a 100644 --- a/ports/stm32/boards/MIKROE_CLICKER2_STM32/pins.csv +++ b/ports/stm32/boards/MIKROE_CLICKER2_STM32/pins.csv @@ -85,4 +85,4 @@ T2,PE0 T3,PA10 USB_VBUS,PA9 USB_DM,PA11 -USB_DP,PA12 \ No newline at end of file +USB_DP,PA12 diff --git a/ports/stm32/boards/NUCLEO_F412ZG/pins.csv b/ports/stm32/boards/NUCLEO_F412ZG/pins.csv index 430d0972b3..31dcb99ed6 100644 --- a/ports/stm32/boards/NUCLEO_F412ZG/pins.csv +++ b/ports/stm32/boards/NUCLEO_F412ZG/pins.csv @@ -115,4 +115,4 @@ PH1,PH1 SW,C13 LED_RED,B14 LED_GREEN,B0 -LED_BLUE,B7 \ No newline at end of file +LED_BLUE,B7 diff --git a/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h b/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h index b9c94b15be..a3b23817d3 100644 --- a/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h +++ b/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h @@ -27,7 +27,7 @@ #define MICROPY_HW_UART3_RTS (pin_D12) #define MICROPY_HW_UART3_CTS (pin_D11) #if MICROPY_HW_HAS_SWITCH == 0 -// NOTE: A0 also connects to the user switch. To use UART4 you should +// NOTE: A0 also connects to the user switch. To use UART4 you should // set MICROPY_HW_HAS_SWITCH to 0, and also remove SB20 (on the back // of the board near the USER switch). #define MICROPY_HW_UART4_TX (pin_A0) diff --git a/ports/stm32/boards/STM32F4DISC/mpconfigboard.h b/ports/stm32/boards/STM32F4DISC/mpconfigboard.h index dbe52e6b10..3b291ad762 100644 --- a/ports/stm32/boards/STM32F4DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F4DISC/mpconfigboard.h @@ -31,7 +31,7 @@ #define MICROPY_HW_UART3_RTS (pin_D12) #define MICROPY_HW_UART3_CTS (pin_D11) #if MICROPY_HW_HAS_SWITCH == 0 -// NOTE: A0 also connects to the user switch. To use UART4 you should +// NOTE: A0 also connects to the user switch. To use UART4 you should // set MICROPY_HW_HAS_SWITCH to 0, and also remove SB20 (on the back // of the board near the USER switch). #define MICROPY_HW_UART4_TX (pin_A0) diff --git a/ports/stm32/boards/STM32F769DISC/mpconfigboard.h b/ports/stm32/boards/STM32F769DISC/mpconfigboard.h index 87cefb5017..981f17848f 100644 --- a/ports/stm32/boards/STM32F769DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F769DISC/mpconfigboard.h @@ -85,7 +85,7 @@ extern struct _spi_bdev_t spi_bdev; // LEDs #define MICROPY_HW_LED1 (pin_J13) // red -#define MICROPY_HW_LED2 (pin_J5) // green +#define MICROPY_HW_LED2 (pin_J5) // green #define MICROPY_HW_LED3 (pin_A12) // green #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) diff --git a/ports/stm32/boards/stm32h743.ld b/ports/stm32/boards/stm32h743.ld index 8cf8a4e591..72d915b2bb 100644 --- a/ports/stm32/boards/stm32h743.ld +++ b/ports/stm32/boards/stm32h743.ld @@ -10,7 +10,7 @@ MEMORY FLASH_FS (r) : ORIGIN = 0x08020000, LENGTH = 128K /* sector 1, 128K */ FLASH_TEXT (rx) : ORIGIN = 0x08040000, LENGTH = 1792K /* sectors 6*128 + 8*128 */ DTCM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for storage cache */ - RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 512K /* AXI SRAM */ + RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 512K /* AXI SRAM */ RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K } diff --git a/ports/stm32/boards/stm32l432_af.csv b/ports/stm32/boards/stm32l432_af.csv index e1d231c40a..debfcd7b35 100644 --- a/ports/stm32/boards/stm32l432_af.csv +++ b/ports/stm32/boards/stm32l432_af.csv @@ -25,4 +25,4 @@ PortB,PB6,,LPTIM1_ETR,,,I2C1_SCL,,,USART1_TX,,TSC_G2_IO3,,,,SAI1_FS_B,TIM16_CH1N PortB,PB7,,LPTIM1_IN2,,,I2C1_SDA,,,USART1_RX,,TSC_G2_IO4,,,,,,EVENTOUT,,COMP2_INM, PortC,PC14,,,,,,,,,,,,,,,,EVENTOUT,,, PortC,PC15,,,,,,,,,,,,,,,,EVENTOUT,,, -PortH,PH3,,,,,,,,,,,,,,,,EVENTOUT,,, \ No newline at end of file +PortH,PH3,,,,,,,,,,,,,,,,EVENTOUT,,, From c7842f479836e4aec449a83ddf2907d28dde6027 Mon Sep 17 00:00:00 2001 From: Ihor Nehrutsa Date: Fri, 10 Sep 2021 08:44:03 +0300 Subject: [PATCH 021/335] docs/make.bat: Change Windows output dir from '_build' to 'build'. To match the output file used by Makefile. --- docs/make.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/make.bat b/docs/make.bat index c09487fb74..2a9e670e4d 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -5,7 +5,7 @@ REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) -set BUILDDIR=_build +set BUILDDIR=build set SPHINXOPTS=-W --keep-going set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . From 4552f1816b194b22befb199d0adc3a67df2344b3 Mon Sep 17 00:00:00 2001 From: Peter Hinch Date: Fri, 10 Sep 2021 14:02:35 +0100 Subject: [PATCH 022/335] docs/library/machine.I2S.rst: Specify that I2S.shift args are kw-only. --- docs/library/machine.I2S.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/library/machine.I2S.rst b/docs/library/machine.I2S.rst index 45877a5ae0..d64fba33e4 100644 --- a/docs/library/machine.I2S.rst +++ b/docs/library/machine.I2S.rst @@ -134,7 +134,7 @@ Methods Setting a callback changes the ``write`` and ``readinto`` methods to non-blocking operation. ``handler`` is called in the context of the MicroPython scheduler. -.. staticmethod:: I2S.shift(buf, bits, shift) +.. staticmethod:: I2S.shift(*, buf, bits, shift) bitwise shift of all samples contained in ``buf``. ``bits`` specifies sample size in bits. ``shift`` specifies the number of bits to shift each sample. Positive for left shift, negative for right shift. From f690fd3a47d493e2c30829e06502ca7b3e787fff Mon Sep 17 00:00:00 2001 From: Seon Rozenblum Date: Sat, 11 Sep 2021 14:48:11 +1000 Subject: [PATCH 023/335] esp32/machine_timer: Use tx_update member for IDF 4.4 and above. --- ports/esp32/machine_timer.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ports/esp32/machine_timer.c b/ports/esp32/machine_timer.c index 3b14581498..803849e1be 100644 --- a/ports/esp32/machine_timer.c +++ b/ports/esp32/machine_timer.c @@ -137,8 +137,12 @@ STATIC void machine_timer_isr(void *self_in) { #if CONFIG_IDF_TARGET_ESP32 device->hw_timer[self->index].update = 1; #else + #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) + device->hw_timer[self->index].update.tx_update = 1; + #else device->hw_timer[self->index].update.update = 1; #endif + #endif timer_ll_clear_intr_status(device, self->index); timer_ll_set_alarm_enable(device, self->index, self->repeat); From c0761d28fc46072d73daf6bdd1c6abbbac0fc9c1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 13 Sep 2021 18:27:39 +1000 Subject: [PATCH 024/335] tests/perf_bench: Use math.log instead of math.log2. So MICROPY_PY_MATH_SPECIAL_FUNCTIONS is not needed for these performance tests. Signed-off-by: Damien George --- tests/perf_bench/bm_fft.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/perf_bench/bm_fft.py b/tests/perf_bench/bm_fft.py index fb79a9fd28..9a2d03d11b 100644 --- a/tests/perf_bench/bm_fft.py +++ b/tests/perf_bench/bm_fft.py @@ -15,7 +15,7 @@ def transform_radix2(vector, inverse): # Initialization n = len(vector) - levels = int(math.log2(n)) + levels = int(math.log(n) / math.log(2)) coef = (2 if inverse else -2) * cmath.pi / n exptable = [cmath.rect(1, i * coef) for i in range(n // 2)] vector = [vector[reverse(i, levels)] for i in range(n)] # Copy with bit-reversed permutation From 426785a19eeb12aef7383fbda4693575d8c4dddf Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 13 Sep 2021 22:30:24 +1000 Subject: [PATCH 025/335] py/emitnative: Ensure load_subscr does not clobber existing REG_RET. Fixes issue #7782, and part of issue #6314. Signed-off-by: Damien George --- py/emitnative.c | 2 ++ tests/micropython/viper_subscr_multi.py | 20 ++++++++++++++++++++ tests/micropython/viper_subscr_multi.py.exp | 2 ++ 3 files changed, 24 insertions(+) create mode 100644 tests/micropython/viper_subscr_multi.py create mode 100644 tests/micropython/viper_subscr_multi.py.exp diff --git a/py/emitnative.c b/py/emitnative.c index 7c7c342839..6504f37765 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -1560,6 +1560,7 @@ STATIC void emit_native_load_subscr(emit_t *emit) { int reg_base = REG_ARG_1; int reg_index = REG_ARG_2; emit_pre_pop_reg_flexible(emit, &vtype_base, ®_base, reg_index, reg_index); + need_reg_single(emit, REG_RET, 0); switch (vtype_base) { case VTYPE_PTR8: { // pointer to 8-bit memory @@ -1623,6 +1624,7 @@ STATIC void emit_native_load_subscr(emit_t *emit) { int reg_index = REG_ARG_2; emit_pre_pop_reg_flexible(emit, &vtype_index, ®_index, REG_ARG_1, REG_ARG_1); emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); + need_reg_single(emit, REG_RET, 0); if (vtype_index != VTYPE_INT && vtype_index != VTYPE_UINT) { EMIT_NATIVE_VIPER_TYPE_ERROR(emit, MP_ERROR_TEXT("can't load with '%q' index"), vtype_to_qstr(vtype_index)); diff --git a/tests/micropython/viper_subscr_multi.py b/tests/micropython/viper_subscr_multi.py new file mode 100644 index 0000000000..1561e5534d --- /dev/null +++ b/tests/micropython/viper_subscr_multi.py @@ -0,0 +1,20 @@ +# test viper with multiple subscripts in a single expression + + +@micropython.viper +def f1(b: ptr8): + b[0] += b[1] + + +@micropython.viper +def f2(b: ptr8, i: int): + b[0] += b[i] + + +b = bytearray(b"\x01\x02") +f1(b) +print(b) + +b = bytearray(b"\x01\x02") +f2(b, 1) +print(b) diff --git a/tests/micropython/viper_subscr_multi.py.exp b/tests/micropython/viper_subscr_multi.py.exp new file mode 100644 index 0000000000..a2c298bb16 --- /dev/null +++ b/tests/micropython/viper_subscr_multi.py.exp @@ -0,0 +1,2 @@ +bytearray(b'\x03\x02') +bytearray(b'\x03\x02') From 0d7366c9126f1b306d5cd4eaebe26c801f0e01d8 Mon Sep 17 00:00:00 2001 From: Philipp Ebensberger Date: Fri, 20 Aug 2021 21:41:58 +0200 Subject: [PATCH 026/335] mimxrt: Rework flash configuration. - Moves definition of BOARD_FLASH_SIZE and other header files related to flash configuration into the Makefile. - Adds board specific clock_config.h. - Adds board.h, pin_mux.h, and peripherals.h as they are required by NXP MCU SDK in order to use our own clock_config.h. - Renames board specific FlexSPI configuration files. - Updates flash frequency of MIMXRT1020_EVK - Creates separated flash_config files for QSPI NOR and QSPI Hyper flash. - Unifies VFS start address to be @ 1M for 1010 and 1020 boards. - Unifies 1050EVK boards - Adds support to both NOR and HyperFlash on boards with both capabilities. - Adds automatic FlexRAM initialization to start-up code based on linker script and NXP HAL. - Applies code formatting to all files in mimxrt port. With this change the flash configuration is restructured and organized. This simplifies the configuration process and provides a better overview of each board's settings. With the integration of clock_config.h, board.h, pin_mux.h, and peripherals.h we gain better control of the settings and clock configurations. Furthermore the implementation of an explicit FlexRAM setup improves the system performance and allows for performance tuning. Signed-off-by: Philipp Ebensberger --- ports/mimxrt/Makefile | 63 ++++- .../boards/MIMXRT1010_EVK/MIMXRT1010_EVK.ld | 1 - .../MIMXRT1010_EVK_flexspi_nor_config.h | 257 +++++++++++++++++ .../boards/MIMXRT1010_EVK/clock_config.h | 104 +++++++ .../evkmimxrt1010_flexspi_nor_config.h | 257 ----------------- .../boards/MIMXRT1010_EVK/flash_config.c | 124 -------- .../boards/MIMXRT1010_EVK/mpconfigboard.h | 6 +- .../boards/MIMXRT1010_EVK/mpconfigboard.mk | 9 +- .../MIMXRT1010_EVK/qspi_nor_flash_config.c | 124 ++++++++ ports/mimxrt/boards/MIMXRT1011.ld | 21 +- .../boards/MIMXRT1020_EVK/MIMXRT1020_EVK.ld | 1 - .../MIMXRT1020_EVK_flexspi_nor_config.h | 258 +++++++++++++++++ .../boards/MIMXRT1020_EVK/clock_config.h | 114 ++++++++ .../evkmimxrt1020_flexspi_nor_config.h | 258 ----------------- .../boards/MIMXRT1020_EVK/flash_config.c | 136 --------- .../boards/MIMXRT1020_EVK/mpconfigboard.h | 22 +- .../boards/MIMXRT1020_EVK/mpconfigboard.mk | 9 +- .../MIMXRT1020_EVK/qspi_nor_flash_config.c | 136 +++++++++ ports/mimxrt/boards/MIMXRT1021.ld | 23 +- .../boards/MIMXRT1050_EVK/MIMXRT1050_EVK.ld | 1 - .../MIMXRT1050_EVK_flexspi_nor_config.h | 263 +++++++++++++++++ .../boards/MIMXRT1050_EVK/clock_config.h | 119 ++++++++ .../evkmimxrt1050_flexspi_nor_config.h | 255 ----------------- .../boards/MIMXRT1050_EVK/flash_config.c | 129 --------- .../boards/MIMXRT1050_EVK/mpconfigboard.h | 21 +- .../boards/MIMXRT1050_EVK/mpconfigboard.mk | 7 +- .../MIMXRT1050_EVK/qspi_hyper_flash_config.c | 186 ++++++++++++ .../MIMXRT1050_EVK/qspi_nor_flash_config.c | 129 +++++++++ .../boards/MIMXRT1050_EVKB/MIMXRT1050_EVKB.ld | 1 - .../evkbmimxrt1050_flexspi_nor_config.h | 263 ----------------- .../boards/MIMXRT1050_EVKB/flash_config.c | 186 ------------ .../boards/MIMXRT1050_EVKB/mpconfigboard.h | 68 ----- .../boards/MIMXRT1050_EVKB/mpconfigboard.mk | 13 - ports/mimxrt/boards/MIMXRT1050_EVKB/pins.csv | 31 -- ports/mimxrt/boards/MIMXRT1052.ld | 19 +- .../boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld | 1 - .../MIMXRT1060_EVK_flexspi_nor_config.h | 264 ++++++++++++++++++ .../boards/MIMXRT1060_EVK/clock_config.h | 122 ++++++++ .../evkmimxrt1060_flexspi_nor_config.h | 264 ------------------ .../boards/MIMXRT1060_EVK/flash_config.c | 186 ------------ .../boards/MIMXRT1060_EVK/mpconfigboard.h | 18 +- .../boards/MIMXRT1060_EVK/mpconfigboard.mk | 6 +- .../MIMXRT1060_EVK/qspi_hyper_flash_config.c | 186 ++++++++++++ .../MIMXRT1060_EVK/qspi_nor_flash_config.c | 129 +++++++++ ports/mimxrt/boards/MIMXRT1062.ld | 19 +- ports/mimxrt/boards/MIMXRT1064.ld | 21 +- .../boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld | 1 - .../MIMXRT1064_EVK_flexspi_nor_config.h | 264 ++++++++++++++++++ .../boards/MIMXRT1064_EVK/clock_config.h | 122 ++++++++ .../evkmimxrt1064_flexspi_nor_config.h | 264 ------------------ .../boards/MIMXRT1064_EVK/flash_config.c | 186 ------------ .../boards/MIMXRT1064_EVK/mpconfigboard.h | 16 +- .../boards/MIMXRT1064_EVK/mpconfigboard.mk | 7 +- .../MIMXRT1064_EVK/qspi_hyper_flash_config.c | 186 ++++++++++++ .../MIMXRT1064_EVK/qspi_nor_flash_config.c | 129 +++++++++ ports/mimxrt/boards/TEENSY40/TEENSY40.ld | 2 - .../TEENSY40/TEENSY40_flexspi_nor_config.h | 259 +++++++++++++++++ ports/mimxrt/boards/TEENSY40/clock_config.h | 122 ++++++++ ports/mimxrt/boards/TEENSY40/flash_config.c | 144 ---------- ports/mimxrt/boards/TEENSY40/mpconfigboard.h | 18 +- ports/mimxrt/boards/TEENSY40/mpconfigboard.mk | 6 +- .../boards/TEENSY40/qspi_nor_flash_config.c | 144 ++++++++++ .../TEENSY40/teensy40_flexspi_nor_config.h | 259 ----------------- ports/mimxrt/boards/TEENSY41/TEENSY41.ld | 2 - .../TEENSY41/TEENSY41_flexspi_nor_config.h | 259 +++++++++++++++++ ports/mimxrt/boards/TEENSY41/clock_config.h | 122 ++++++++ ports/mimxrt/boards/TEENSY41/flash_config.c | 144 ---------- ports/mimxrt/boards/TEENSY41/mpconfigboard.h | 18 +- ports/mimxrt/boards/TEENSY41/mpconfigboard.mk | 6 +- .../boards/TEENSY41/qspi_nor_flash_config.c | 144 ++++++++++ .../TEENSY41/teensy41_flexspi_nor_config.h | 259 ----------------- ports/mimxrt/boards/make-flexram-config.py | 219 +++++++++++++++ ports/mimxrt/hal/board.h | 33 +++ ports/mimxrt/hal/flexspi_hyper_flash.c | 99 +++---- ports/mimxrt/hal/flexspi_hyper_flash.h | 3 +- ports/mimxrt/hal/flexspi_nor_flash.c | 15 +- ports/mimxrt/hal/flexspi_nor_flash.h | 1 - ports/mimxrt/hal/peripherals.h | 1 + ports/mimxrt/hal/pin_mux.h | 1 + ports/mimxrt/hal/resethandler_MIMXRT10xx.S | 175 ++++++++++++ tools/autobuild/build-mimxrt-latest.sh | 2 +- tools/codeformat.py | 1 + 82 files changed, 4830 insertions(+), 3633 deletions(-) delete mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK.ld create mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK_flexspi_nor_config.h create mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/clock_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/evkmimxrt1010_flexspi_nor_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/flash_config.c create mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/qspi_nor_flash_config.c delete mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK.ld create mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK_flexspi_nor_config.h create mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/clock_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/evkmimxrt1020_flexspi_nor_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/flash_config.c create mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/qspi_nor_flash_config.c delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK.ld create mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK_flexspi_nor_config.h create mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/clock_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/evkmimxrt1050_flexspi_nor_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/flash_config.c create mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/qspi_hyper_flash_config.c create mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/qspi_nor_flash_config.c delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVKB/MIMXRT1050_EVKB.ld delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVKB/evkbmimxrt1050_flexspi_nor_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVKB/flash_config.c delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.h delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.mk delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVKB/pins.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld create mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK_flexspi_nor_config.h create mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/clock_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/evkmimxrt1060_flexspi_nor_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/flash_config.c create mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/qspi_hyper_flash_config.c create mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/qspi_nor_flash_config.c delete mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld create mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK_flexspi_nor_config.h create mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/clock_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/evkmimxrt1064_flexspi_nor_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/flash_config.c create mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/qspi_hyper_flash_config.c create mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/qspi_nor_flash_config.c delete mode 100644 ports/mimxrt/boards/TEENSY40/TEENSY40.ld create mode 100644 ports/mimxrt/boards/TEENSY40/TEENSY40_flexspi_nor_config.h create mode 100644 ports/mimxrt/boards/TEENSY40/clock_config.h delete mode 100644 ports/mimxrt/boards/TEENSY40/flash_config.c create mode 100644 ports/mimxrt/boards/TEENSY40/qspi_nor_flash_config.c delete mode 100644 ports/mimxrt/boards/TEENSY40/teensy40_flexspi_nor_config.h delete mode 100755 ports/mimxrt/boards/TEENSY41/TEENSY41.ld create mode 100644 ports/mimxrt/boards/TEENSY41/TEENSY41_flexspi_nor_config.h create mode 100644 ports/mimxrt/boards/TEENSY41/clock_config.h delete mode 100755 ports/mimxrt/boards/TEENSY41/flash_config.c create mode 100644 ports/mimxrt/boards/TEENSY41/qspi_nor_flash_config.c delete mode 100755 ports/mimxrt/boards/TEENSY41/teensy41_flexspi_nor_config.h create mode 100644 ports/mimxrt/boards/make-flexram-config.py create mode 100644 ports/mimxrt/hal/board.h create mode 100644 ports/mimxrt/hal/peripherals.h create mode 100644 ports/mimxrt/hal/pin_mux.h create mode 100644 ports/mimxrt/hal/resethandler_MIMXRT10xx.S diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 8b1bb2bfa7..fcbd97b20c 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -13,6 +13,17 @@ endif include ../../py/mkenv.mk include $(BOARD_DIR)/mpconfigboard.mk +# Set optional flash configuration variables +BOARD_FLASH_RESERVED ?= + +LD_MEMORY_CONFIG_DEFINES += \ + BOARD_FLASH_TYPE=$(BOARD_FLASH_TYPE) \ + BOARD_FLASH_SIZE=$(BOARD_FLASH_SIZE) + +ifdef $(BOARD_FLASH_RESERVED) +LD_MEMORY_CONFIG_DEFINES += BOARD_FLASH_RESERVED=$(BOARD_FLASH_RESERVED) +endif + # Qstr definitions (must come before including py.mk) QSTR_DEFS = qstrdefsport.h QSTR_GLOBAL_DEPENDENCIES = $(BOARD_DIR)/mpconfigboard.h @@ -28,9 +39,10 @@ include $(TOP)/py/py.mk GIT_SUBMODULES = lib/tinyusb lib/nxp_driver MCU_DIR = lib/nxp_driver/sdk/devices/$(MCU_SERIES) -LD_FILES = boards/$(BOARD)/$(BOARD).ld boards/$(MCU_SERIES).ld boards/common.ld +LD_FILES = boards/$(MCU_SERIES).ld boards/common.ld MAKE_PINS = boards/make-pins.py +MAKE_FLEXRAM_LD = boards/make-flexram-config.py BOARD_PINS = $(BOARD_DIR)/pins.csv AF_FILE = boards/$(MCU_SERIES)_af.csv PREFIX_FILE = boards/mimxrt_prefix.c @@ -39,18 +51,19 @@ GEN_PINS_HDR = $(HEADER_BUILD)/pins.h GEN_PINS_QSTR = $(BUILD)/pins_qstr.h GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h GEN_PINS_AF_PY = $(BUILD)/pins_af.py +GEN_FLEXRAM_CONFIG_SRC = $(BUILD)/flexram_config.s # mcu driver cause following warnings #CFLAGS += -Wno-error=float-equal -Wno-error=nested-externs CFLAGS += -Wno-error=unused-parameter INC += -I. +INC += -Ihal INC += -I$(BOARD_DIR) INC += -I$(BUILD) INC += -I$(TOP) INC += -I$(TOP)/$(MCU_DIR) INC += -I$(TOP)/$(MCU_DIR)/drivers -INC += -I$(TOP)/$(MCU_DIR)/project_template INC += -I$(TOP)/lib/cmsis/inc INC += -I$(TOP)/lib/oofatfs INC += -I$(TOP)/lib/tinyusb/hw @@ -67,10 +80,20 @@ CFLAGS += -DXIP_EXTERNAL_FLASH=1 \ -D__STARTUP_CLEAR_BSS \ -D__STARTUP_INITIALIZE_RAMFUNCTION \ -D__START=main \ - -DCPU_HEADER_H='<$(MCU_SERIES).h>' + -DCPU_HEADER_H='<$(MCU_SERIES).h>' \ + -DBOARD_FLASH_SIZE=$(BOARD_FLASH_SIZE) \ + -DBOARD_FLASH_CONFIG_HEADER_H=\"$(BOARD)_flexspi_nor_config.h\" + +ifeq ($(BOARD_FLASH_TYPE), qspi_nor) +CFLAGS += -DBOARD_FLASH_OPS_HEADER_H=\"hal/flexspi_nor_flash.h\" +else ifeq ($(BOARD_FLASH_TYPE), hyperflash) +CFLAGS += -DBOARD_FLASH_OPS_HEADER_H=\"hal/flexspi_hyper_flash.h\" +endif + ifeq ($(MICROPY_PY_MACHINE_SDCARD),1) CFLAGS += -DMICROPY_PY_MACHINE_SDCARD=1 endif + CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA) # Configure floating point support @@ -88,7 +111,8 @@ endif SUPPORTS_HARDWARE_FP_SINGLE = 0 SUPPORTS_HARDWARE_FP_DOUBLE = 0 -LDFLAGS = $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref --print-memory-usage +LDFLAGS = -Map=$@.map --cref --print-memory-usage +LDDEFINES = $(addprefix -D, $(LD_MEMORY_CONFIG_DEFINES)) LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) # Tune for Debugging or Optimization @@ -144,7 +168,6 @@ SRC_HAL_IMX_C += $(MCU_DIR)/drivers/fsl_usdhc.c endif SRC_C += \ - $(BOARD_DIR)/flash_config.c \ board_init.c \ dma_channel.c \ drivers/bus/softspi.c \ @@ -184,6 +207,18 @@ SRC_C += \ $(SRC_TINYUSB_C) \ $(SRC_HAL_IMX_C) \ +ifeq ($(BOARD_FLASH_TYPE), qspi_nor) +SRC_C += \ + hal/flexspi_nor_flash.c \ + $(BOARD_DIR)/qspi_nor_flash_config.c +else ifeq ($(BOARD_FLASH_TYPE), hyperflash) +SRC_C += \ + hal/flexspi_hyper_flash.c \ + $(BOARD_DIR)/qspi_hyper_flash_config.c +else +$(error Error: Unknown board flash type $(BOARD_FLASH_TYPE)) +endif + ifeq ($(MICROPY_FLOAT_IMPL),double) LIBM_SRC_C += $(addprefix lib/libm_dbl/,\ __cos.c \ @@ -277,7 +312,9 @@ ifeq ($(MICROPY_FLOAT_IMPL),double) $(LIBM_O): CFLAGS := $(filter-out -Wdouble-promotion -Wfloat-conversion, $(CFLAGS)) endif -SRC_SS += $(MCU_DIR)/gcc/startup_$(MCU_SERIES).S +SRC_SS = \ + $(MCU_DIR)/gcc/startup_$(MCU_SERIES).S \ + hal/resethandler_MIMXRT10xx.S SRC_S += shared/runtime/gchelper_m3.s \ @@ -316,8 +353,10 @@ $(BUILD)/lib/tinyusb/src/device/usbd.o: CFLAGS += -Wno-missing-braces all: $(BUILD)/firmware.hex $(BUILD)/firmware.bin $(BUILD)/firmware.elf: $(OBJ) + $(ECHO) "PREPROCESS LINK $@" + $(Q)$(CC) -E -x c $(LDDEFINES) $(LD_FILES) | grep -v '^#' > $(BUILD)/link.ld $(ECHO) "LINK $@" - $(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS) + $(Q)$(LD) -T$(BUILD)/link.ld $(LDFLAGS) -o $@ $^ $(LIBS) $(Q)$(SIZE) $@ $(BUILD)/firmware.bin: $(BUILD)/firmware.elf @@ -326,17 +365,23 @@ $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(BUILD)/firmware.hex: $(BUILD)/firmware.elf $(Q)$(OBJCOPY) -O ihex -R .eeprom $< $@ -# Making OBJ use an order-only depenedency on the generated pins.h file +# Making OBJ use an order-only dependency on the generated pins.h file # has the side effect of making the pins.h file before we actually compile # any of the objects. The normal dependency generation will deal with the # case when pins.h is modified. But when it doesn't exist, we don't know # which source files might need it. -$(OBJ): | $(GEN_PINS_HDR) +$(OBJ): | $(GEN_PINS_HDR) $(GEN_FLEXRAM_CONFIG_SRC) # With conditional pins, we may need to regenerate qstrdefs.h when config # options change. $(HEADER_BUILD)/qstrdefs.generated.h: $(BOARD_DIR)/mpconfigboard.h +$(GEN_FLEXRAM_CONFIG_SRC): + $(ECHO) "Create $@" + $(Q)$(PYTHON) $(MAKE_FLEXRAM_LD) -d $(TOP)/$(MCU_DIR)/$(MCU_SERIES).h \ + -f $(TOP)/$(MCU_DIR)/$(MCU_SERIES)_features.h -l boards/$(MCU_SERIES).ld -c $(MCU_SERIES) > $(GEN_FLEXRAM_CONFIG_SRC) + + # Use a pattern rule here so that make will only call make-pins.py once to make # both pins_gen.c and pins.h $(BUILD)/%_gen.c $(HEADER_BUILD)/%.h: $(BOARD_PINS) $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD) diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK.ld b/ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK.ld deleted file mode 100644 index 83da7ec73c..0000000000 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK.ld +++ /dev/null @@ -1 +0,0 @@ -flash_size = 16M; \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK_flexspi_nor_config.h new file mode 100644 index 0000000000..aeb5f356ea --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK_flexspi_nor_config.h @@ -0,0 +1,257 @@ +/* + * Copyright 2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1010_flexspi_nor_config.h + +#ifndef __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ +#define __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define 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)) + +// !@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_120MHz = 7, + kFlexSpiSerialClk_133MHz = 8, +} flexspi_serial_clk_freq_t; + +// !@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, // !< Clock configure for SDR mode + kFlexSpiClk_DDR, // !< Clock configurat for DDR mode +}; + +// !@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +// !@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. +}; + +// !@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +// !@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +// !@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; // !< Sequence Number, valid number: 1-16 + uint8_t seqId; // !< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +// !@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, // !< Reset device command +}; + +// !@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + // ! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + // ! Generic configuration, etc. + uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + // ! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + // ! sequence number, [31:16] Reserved + uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + // ! details + uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + // ! Chapter for more details + uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + // ! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI + uint32_t pageSize; // !< Page size of Serial NOR + uint32_t sectorSize; // !< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command + uint8_t isUniformBlockSize; // !< Sector/Block size is the same + uint8_t reserved0[2]; // !< Reserved for future use + uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; // !< Block size + uint32_t reserve2[11]; // !< Reserved for future use +} flexspi_nor_config_t; + +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/clock_config.h b/ports/mimxrt/boards/MIMXRT1010_EVK/clock_config.h new file mode 100644 index 0000000000..76f3df422f --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/clock_config.h @@ -0,0 +1,104 @@ +/* + * Copyright 2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ + +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 500000000U /*!< Core clock frequency: 500000000Hz */ + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKRUN_ADC_ALT_CLK 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_CORE_CLK_ROOT 500000000UL +#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_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_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_USBPHY_CLK 0UL + +/*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; +/*! @brief Sys PLL for BOARD_BootClockRUN configuration. + */ +extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; +/*! @brief Enet PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/evkmimxrt1010_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1010_EVK/evkmimxrt1010_flexspi_nor_config.h deleted file mode 100644 index 2cb4535edc..0000000000 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/evkmimxrt1010_flexspi_nor_config.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1010_flexspi_nor_config.h - -#ifndef __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ -#define __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_common.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related defintions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -//!@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_120MHz = 7, - kFlexSpiSerialClk_133MHz = 8, -} flexspi_serial_clk_freq_t; - -//!@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, //!< Clock configure for SDR mode - kFlexSpiClk_DDR, //!< Clock configurat for DDR mode -}; - -//!@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -//!@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. -}; - -//!@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -//!@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -//!@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; //!< Sequence Number, valid number: 1-16 - uint8_t seqId; //!< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -//!@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, //!< Reset device command -}; - -//!@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - //! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - //! Generic configuration, etc. - uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - //! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - //! sequence number, [31:16] Reserved - uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - //! details - uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - //! Chapter for more details - uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - //! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI - uint32_t pageSize; //!< Page size of Serial NOR - uint32_t sectorSize; //!< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command - uint8_t isUniformBlockSize; //!< Sector/Block size is the same - uint8_t reserved0[2]; //!< Reserved for future use - uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; //!< Block size - uint32_t reserve2[11]; //!< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/flash_config.c b/ports/mimxrt/boards/MIMXRT1010_EVK/flash_config.c deleted file mode 100644 index 5e7e5dcf15..0000000000 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/flash_config.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1010_flexspi_nor_config.c - -#include "evkmimxrt1010_flexspi_nor_config.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_100MHz, - .sflashA1Size = 16u * 1024u * 1024u, - .lookupTable = - { - // 0 Read LUTs 0 -> 0 - 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), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 1 Read status register -> 1 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 2 Fast read quad mode - SDR - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 3 Write Enable -> 3 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 4 Read extend parameters - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 5 Erase Sector -> 5 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 6 Write Status Reg - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 7 Page Program - quad mode (-> 9) - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 8 Read ID - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 9 Page Program - single mode -> 9 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 10 Enter QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 11 Erase Chip - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 12 Exit QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - }, - }, - .pageSize = 256u, - .sectorSize = 4u * 1024u, - .blockSize = 256u * 1024u, - .isUniformBlockSize = false, -}; -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h index 2cdb433e18..918513b230 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h @@ -1,14 +1,10 @@ #define MICROPY_HW_BOARD_NAME "i.MX RT1010 EVK" #define MICROPY_HW_MCU_NAME "MIMXRT1011DAE5A" -#define BOARD_FLASH_SIZE (16 * 1024 * 1024) - // i.MX RT1010 EVK has 1 board LED #define MICROPY_HW_LED1_PIN (pin_GPIO_11) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) -#define BOARD_FLASH_CONFIG_HEADER_H "evkmimxrt1010_flexspi_nor_config.h" -#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_nor_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (2 * 32) @@ -33,7 +29,7 @@ { IOMUXC_GPIO_AD_04_LPSPI1_SDO }, { IOMUXC_GPIO_AD_03_LPSPI1_SDI }, #define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx } -#define DMA_REQ_SRC_TX { 0, kDmaRequestMuxLPSPI1Tx, kDmaRequestMuxLPSPI2Tx } +#define DMA_REQ_SRC_TX { 0, kDmaRequestMuxLPSPI1Tx, kDmaRequestMuxLPSPI2Tx } // Define mapping hardware I2C # to logical I2C # // SDA/SCL HW-I2C Logical I2C diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk index f616d5afd4..c4c911d7db 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk @@ -3,21 +3,18 @@ MCU_VARIANT = MIMXRT1011DAE5A MICROPY_FLOAT_IMPL = single MICROPY_PY_MACHINE_SDCARD = 0 +BOARD_FLASH_TYPE ?= qspi_nor +BOARD_FLASH_SIZE ?= 0x1000000 # 16MB -SRC_C += \ - hal/flexspi_nor_flash.c \ - -JLINK_PATH = /media/RT1010-EVK/ +JLINK_PATH ?= /media/RT1010-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink - ifdef JLINK_IP JLINK_CONNECTION_SETTINGS = -IP $(JLINK_IP) else JLINK_CONNECTION_SETTINGS = -USB endif - deploy_jlink: $(BUILD)/firmware.hex $(Q)$(TOUCH) $(JLINK_COMMANDER_SCRIPT) $(ECHO) "ExitOnError 1" > $(JLINK_COMMANDER_SCRIPT) diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1010_EVK/qspi_nor_flash_config.c new file mode 100644 index 0000000000..83a45159c0 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/qspi_nor_flash_config.c @@ -0,0 +1,124 @@ +/* + * Copyright 2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1010_flexspi_nor_config.c + +#include BOARD_FLASH_CONFIG_HEADER_H + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_100MHz, + .sflashA1Size = BOARD_FLASH_SIZE, + .lookupTable = + { + // 0 Read LUTs 0 -> 0 + 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), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = false, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1011.ld b/ports/mimxrt/boards/MIMXRT1011.ld index d9a4956856..22d5da3199 100644 --- a/ports/mimxrt/boards/MIMXRT1011.ld +++ b/ports/mimxrt/boards/MIMXRT1011.ld @@ -1,15 +1,24 @@ /* Memory configuration */ +#if BOARD_FLASH_RESERVED +reserved_size = BOARD_FLASH_RESERVED; +#endif + +#if BOARD_FLASH_TYPE==qspi_nor flash_start = 0x60000000; +#else +#error Unknown BOARD_FLASH_TYPE +#endif +flash_size = BOARD_FLASH_SIZE; flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); -flash_config_start = 0x60000400; +flash_config_start = flash_start + 0x00000400; flash_config_size = 0x00000C00; -ivt_start = 0x60001000; +ivt_start = flash_start + 0x00001000; ivt_size = 0x00001000; -interrupts_start = 0x60002000; +interrupts_start = flash_start + 0x00002000; interrupts_size = 0x00000400; -text_start = 0x60002400; -text_size = ((((text_start) + 1M) + (4k - 1)) & ~(4k - 1)) - (text_start); /* reserve 1M for code but align on 4k boundary */ -vfs_start = (text_start) + (text_size); +text_start = flash_start + 0x00002400; +vfs_start = flash_start + 0x00100000; +text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); itcm_start = 0x00000000; itcm_size = 0x00008000; diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK.ld b/ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK.ld deleted file mode 100644 index fd1bf32ede..0000000000 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK.ld +++ /dev/null @@ -1 +0,0 @@ -flash_size = 8M; \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK_flexspi_nor_config.h new file mode 100644 index 0000000000..26ed3de36f --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK_flexspi_nor_config.h @@ -0,0 +1,258 @@ +/* + * Copyright 2019 NXP. + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1020_flexspi_nor_config.h + +#ifndef __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ +#define __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define 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)) + +// !@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_133MHz = 7, + kFlexSpiSerialClk_166MHz = 8, + kFlexSpiSerialClk_200MHz = 9, +} flexspi_serial_clk_freq_t; + +// !@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, // !< Clock configure for SDR mode + kFlexSpiClk_DDR, // !< Clock configurat for DDR mode +}; + +// !@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +// !@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. +}; + +// !@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +// !@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +// !@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; // !< Sequence Number, valid number: 1-16 + uint8_t seqId; // !< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +// !@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, // !< Reset device command +}; + +// !@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + // ! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + // ! Generic configuration, etc. + uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + // ! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + // ! sequence number, [31:16] Reserved + uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + // ! details + uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + // ! Chapter for more details + uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + // ! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI + uint32_t pageSize; // !< Page size of Serial NOR + uint32_t sectorSize; // !< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command + uint8_t isUniformBlockSize; // !< Sector/Block size is the same + uint8_t reserved0[2]; // !< Reserved for future use + uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; // !< Block size + uint32_t reserve2[11]; // !< Reserved for future use +} flexspi_nor_config_t; + +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/clock_config.h b/ports/mimxrt/boards/MIMXRT1020_EVK/clock_config.h new file mode 100644 index 0000000000..21d4e630ae --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/clock_config.h @@ -0,0 +1,114 @@ +/* + * Copyright 2018-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ + +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#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 + +/*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; +/*! @brief Sys PLL for BOARD_BootClockRUN configuration. + */ +extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; +/*! @brief Enet PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/evkmimxrt1020_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1020_EVK/evkmimxrt1020_flexspi_nor_config.h deleted file mode 100644 index 195c0c225e..0000000000 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/evkmimxrt1020_flexspi_nor_config.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2019 NXP. - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1020_flexspi_nor_config.h - -#ifndef __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ -#define __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_common.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related defintions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -//!@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_133MHz = 7, - kFlexSpiSerialClk_166MHz = 8, - kFlexSpiSerialClk_200MHz = 9, -} flexspi_serial_clk_freq_t; - -//!@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, //!< Clock configure for SDR mode - kFlexSpiClk_DDR, //!< Clock configurat for DDR mode -}; - -//!@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -//!@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. -}; - -//!@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -//!@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -//!@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; //!< Sequence Number, valid number: 1-16 - uint8_t seqId; //!< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -//!@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, //!< Reset device command -}; - -//!@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - //! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - //! Generic configuration, etc. - uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - //! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - //! sequence number, [31:16] Reserved - uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - //! details - uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - //! Chapter for more details - uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - //! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI - uint32_t pageSize; //!< Page size of Serial NOR - uint32_t sectorSize; //!< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command - uint8_t isUniformBlockSize; //!< Sector/Block size is the same - uint8_t reserved0[2]; //!< Reserved for future use - uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; //!< Block size - uint32_t reserve2[11]; //!< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/flash_config.c b/ports/mimxrt/boards/MIMXRT1020_EVK/flash_config.c deleted file mode 100644 index 5377cc1b25..0000000000 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/flash_config.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2019 NXP. - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1010_flexspi_nor_config.c - -#include "evkmimxrt1020_flexspi_nor_config.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - .busyOffset = FLASH_BUSY_STATUS_OFFSET, // Status bit 0 indicates busy. - .busyBitPolarity = FLASH_BUSY_STATUS_POL, // Busy when the bit is 1. - .deviceModeCfgEnable = 1u, - .deviceModeType = kDeviceConfigCmdType_QuadEnable, - .deviceModeSeq = { - .seqId = 4u, - .seqNum = 1u, - }, - .deviceModeArg = 0x40, - // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock - .deviceType = kFlexSpiDeviceType_SerialNOR, - .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_30MHz, - .sflashA1Size = 8u * 1024u * 1024u, - .lookupTable = - { - // 0 Read LUTs 0 -> 0 - 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), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 1 Read status register -> 1 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 2 Fast read quad mode - SDR - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 3 Write Enable -> 3 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 4 Read extend parameters - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 5 Erase Sector -> 5 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 6 Write Status Reg - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 7 Page Program - quad mode (-> 9) - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 8 Read ID - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 9 Page Program - single mode -> 9 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 10 Enter QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 11 Erase Chip - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 12 Exit QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - }, - }, - .pageSize = 256u, - .sectorSize = 4u * 1024u, - .blockSize = 256u * 1024u, - .isUniformBlockSize = false, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, -}; -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h index d7fe575abc..35c24b3d47 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h @@ -1,15 +1,11 @@ #define MICROPY_HW_BOARD_NAME "i.MX RT1020 EVK" #define MICROPY_HW_MCU_NAME "MIMXRT1021DAG5A" -#define BOARD_FLASH_SIZE (8 * 1024 * 1024) - // i.MX RT1020 EVK has 1 board LED // Todo: think about replacing the define with searching in the generated pins? #define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_05) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) -#define BOARD_FLASH_CONFIG_HEADER_H "evkmimxrt1020_flexspi_nor_config.h" -#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_nor_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (3 * 32) @@ -43,13 +39,13 @@ { 0 }, { 0 }, \ { 0 }, { 0 }, \ { IOMUXC_GPIO_AD_B1_12_LPSPI3_SCK }, { IOMUXC_GPIO_AD_B1_13_LPSPI3_PCS0 }, \ - { IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO }, { IOMUXC_GPIO_AD_B1_15_LPSPI3_SDI }, + { IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO }, { IOMUXC_GPIO_AD_B1_15_LPSPI3_SDI }, #define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \ - kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } + kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } #define DMA_REQ_SRC_TX { 0, kDmaRequestMuxLPSPI1Tx, kDmaRequestMuxLPSPI2Tx, \ - kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } + kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } // Define mapping hardware I2C # to logical I2C # // SDA/SCL HW-I2C Logical I2C @@ -65,14 +61,14 @@ { 0 }, { 0 }, \ { IOMUXC_GPIO_SD_B1_02_LPI2C4_SCL }, { IOMUXC_GPIO_SD_B1_03_LPI2C4_SDA }, -#define USDHC_DUMMY_PIN NULL , 0 +#define USDHC_DUMMY_PIN NULL, 0 #define MICROPY_USDHC1 \ { \ .cmd = {GPIO_SD_B0_02_USDHC1_CMD}, \ .clk = { GPIO_SD_B0_03_USDHC1_CLK }, \ - .cd_b = { GPIO_SD_B0_06_USDHC1_CD_B },\ - .data0 = { GPIO_SD_B0_04_USDHC1_DATA0 },\ - .data1 = { GPIO_SD_B0_05_USDHC1_DATA1 },\ - .data2 = { GPIO_SD_B0_00_USDHC1_DATA2 },\ - .data3 = { GPIO_SD_B0_01_USDHC1_DATA3 },\ + .cd_b = { GPIO_SD_B0_06_USDHC1_CD_B }, \ + .data0 = { GPIO_SD_B0_04_USDHC1_DATA0 }, \ + .data1 = { GPIO_SD_B0_05_USDHC1_DATA1 }, \ + .data2 = { GPIO_SD_B0_00_USDHC1_DATA2 }, \ + .data3 = { GPIO_SD_B0_01_USDHC1_DATA3 }, \ } diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk index 6dd1686521..34b714e623 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk @@ -3,21 +3,20 @@ MCU_VARIANT = MIMXRT1021DAG5A MICROPY_FLOAT_IMPL = double MICROPY_PY_MACHINE_SDCARD = 1 +BOARD_FLASH_TYPE ?= qspi_nor +BOARD_FLASH_SIZE ?= 0x800000 # 8MB JLINK_PATH ?= /media/RT1020-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink - ifdef JLINK_IP JLINK_CONNECTION_SETTINGS = -IP $(JLINK_IP) else -JLINK_CONNECTION_SETTINGS = +JLINK_CONNECTION_SETTINGS = -USB endif -SRC_C += \ - hal/flexspi_nor_flash.c - deploy_jlink: $(BUILD)/firmware.hex + $(Q)$(TOUCH) $(JLINK_COMMANDER_SCRIPT) $(ECHO) "ExitOnError 1" > $(JLINK_COMMANDER_SCRIPT) $(ECHO) "speed auto" >> $(JLINK_COMMANDER_SCRIPT) $(ECHO) "r" >> $(JLINK_COMMANDER_SCRIPT) diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1020_EVK/qspi_nor_flash_config.c new file mode 100644 index 0000000000..7b2584d3de --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/qspi_nor_flash_config.c @@ -0,0 +1,136 @@ +/* + * Copyright 2019 NXP. + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1010_flexspi_nor_config.c + +#include BOARD_FLASH_CONFIG_HEADER_H + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .busyOffset = FLASH_BUSY_STATUS_OFFSET, // Status bit 0 indicates busy. + .busyBitPolarity = FLASH_BUSY_STATUS_POL, // Busy when the bit is 1. + .deviceModeCfgEnable = 1u, + .deviceModeType = kDeviceConfigCmdType_QuadEnable, + .deviceModeSeq = { + .seqId = 4u, + .seqNum = 1u, + }, + .deviceModeArg = 0x40, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .deviceType = kFlexSpiDeviceType_SerialNOR, + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_100MHz, + .sflashA1Size = BOARD_FLASH_SIZE, + .lookupTable = + { + // 0 Read LUTs 0 -> 0 + 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), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = false, + // .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1021.ld b/ports/mimxrt/boards/MIMXRT1021.ld index de0f259dcc..92cd59d668 100644 --- a/ports/mimxrt/boards/MIMXRT1021.ld +++ b/ports/mimxrt/boards/MIMXRT1021.ld @@ -1,20 +1,29 @@ /* Memory configuration */ +#if defined BOARD_FLASH_RESERVED +reserved_size = BOARD_FLASH_RESERVED; +#endif + +#if BOARD_FLASH_TYPE == qspi_nor flash_start = 0x60000000; +#else +#error Unknown BOARD_FLASH_TYPE +#endif +flash_size = BOARD_FLASH_SIZE; flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); flash_config_start = flash_start; flash_config_size = 0x00001000; -ivt_start = 0x60001000; +ivt_start = flash_start + 0x00001000; ivt_size = 0x00001000; -interrupts_start = 0x60002000; +interrupts_start = flash_start + 0x00002000; interrupts_size = 0x00000400; -text_start = 0x60002400; -text_size = ((((text_start) + 1M) + (4k - 1)) & ~(4k - 1)) - (text_start); /* reserve 1M for code but align on 4k boundary */ -vfs_start = (text_start) + (text_size); +text_start = flash_start + 0x00002400; +vfs_start = flash_start + 0x00100000; +text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); itcm_start = 0x00000000; -itcm_size = 0x00010000; +itcm_size = 0x00008000; dtcm_start = 0x20000000; -dtcm_size = 0x00010000; +dtcm_size = 0x00018000; ocrm_start = 0x20200000; ocrm_size = 0x00020000; diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK.ld b/ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK.ld deleted file mode 100644 index fd1bf32ede..0000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK.ld +++ /dev/null @@ -1 +0,0 @@ -flash_size = 8M; \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK_flexspi_nor_config.h new file mode 100644 index 0000000000..b4e9217416 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK_flexspi_nor_config.h @@ -0,0 +1,263 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __EVKMIMXRT1050_FLEXSPI_NOR_CONFIG__ +#define __EVKMIMXRT1050_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_flexspi.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define 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)) + +// !@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_133MHz = 7, + kFlexSpiSerialClk_166MHz = 8, +} flexspi_serial_clk_freq_t; + +// !@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, // !< Clock configure for SDR mode + kFlexSpiClk_DDR, // !< Clock configurat for DDR mode +}; + +// !@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +// !@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. +}; + +// !@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +// !@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +// !@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; // !< Sequence Number, valid number: 1-16 + uint8_t seqId; // !< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +// !@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, // !< Reset device command +}; + +// !@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + // ! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + // ! Generic configuration, etc. + uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + // ! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + // ! sequence number, [31:16] Reserved + uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + // ! details + uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + // ! Chapter for more details + uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + // ! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 + +#define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP 12 + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI + uint32_t pageSize; // !< Page size of Serial NOR + uint32_t sectorSize; // !< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command + uint8_t isUniformBlockSize; // !< Sector/Block size is the same + uint8_t reserved0[2]; // !< Reserved for future use + uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; // !< Block size + uint32_t reserve2[11]; // !< Reserved for future use +} flexspi_nor_config_t; + +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1050_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/clock_config.h b/ports/mimxrt/boards/MIMXRT1050_EVK/clock_config.h new file mode 100644 index 0000000000..f213ac7e23 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/clock_config.h @@ -0,0 +1,119 @@ +/* + * Copyright 2017-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ + +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */ + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 600000000UL +#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_CSI_CLK_ROOT 12000000UL +#define BOARD_BOOTCLOCKRUN_ENET1_TX_CLK 2400000UL +#define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 2400000UL +#define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 160000000UL +#define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 150000000UL +#define BOARD_BOOTCLOCKRUN_LCDIF_CLK_ROOT 9642857UL +#define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL +#define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL +#define BOARD_BOOTCLOCKRUN_LVDS1_CLK 1200000000UL +#define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL +#define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 75000000UL +#define BOARD_BOOTCLOCKRUN_PLL7_MAIN_CLK 24000000UL +#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 75000000UL +#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_USBPHY2_CLK 0UL +#define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 198000000UL +#define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 198000000UL + +/*! @brief Arm PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN; +/*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; +/*! @brief Sys PLL for BOARD_BootClockRUN configuration. + */ +extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/evkmimxrt1050_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1050_EVK/evkmimxrt1050_flexspi_nor_config.h deleted file mode 100644 index e038967e17..0000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/evkmimxrt1050_flexspi_nor_config.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __EVKMIMXRT1050_FLEXSPI_NOR_CONFIG__ -#define __EVKMIMXRT1050_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_common.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related defintions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -//!@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_133MHz = 7, - kFlexSpiSerialClk_166MHz = 8, -} flexspi_serial_clk_freq_t; - -//!@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, //!< Clock configure for SDR mode - kFlexSpiClk_DDR, //!< Clock configurat for DDR mode -}; - -//!@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -//!@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. -}; - -//!@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -//!@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -//!@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; //!< Sequence Number, valid number: 1-16 - uint8_t seqId; //!< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -//!@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, //!< Reset device command -}; - -//!@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - //! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - //! Generic configuration, etc. - uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - //! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - //! sequence number, [31:16] Reserved - uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - //! details - uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - //! Chapter for more details - uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - //! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI - uint32_t pageSize; //!< Page size of Serial NOR - uint32_t sectorSize; //!< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command - uint8_t isUniformBlockSize; //!< Sector/Block size is the same - uint8_t reserved0[2]; //!< Reserved for future use - uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; //!< Block size - uint32_t reserve2[11]; //!< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1050_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/flash_config.c b/ports/mimxrt/boards/MIMXRT1050_EVK/flash_config.c deleted file mode 100644 index 2a9303fc98..0000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/flash_config.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "evkmimxrt1050_flexspi_nor_config.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - .columnAddressWidth = 3u, - // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock - .controllerMiscOption = - (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | - (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), - .sflashPadType = kSerialFlash_8Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = 64u * 1024u * 1024u, - .dataValidTime = {16u, 16u}, - .lookupTable = - { - // 0 Read LUTs 0 -> 0 - 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), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 1 Read status register -> 1 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 2 Fast read quad mode - SDR - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 3 Write Enable -> 3 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 4 Read extend parameters - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 5 Erase Sector -> 5 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 6 Write Status Reg - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 7 Page Program - quad mode (-> 9) - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 8 Read ID - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 9 Page Program - single mode -> 9 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 10 Enter QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 11 Erase Chip - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 12 Exit QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - }, - }, - .pageSize = 512u, - .sectorSize = 256u * 1024u, - .blockSize = 256u * 1024u, - .isUniformBlockSize = true, -}; - -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h index 976de9c07d..b6b70be058 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h @@ -1,14 +1,10 @@ #define MICROPY_HW_BOARD_NAME "i.MX RT1050 EVK" #define MICROPY_HW_MCU_NAME "MIMXRT1052DVL6B" -#define BOARD_FLASH_SIZE (64 * 1024 * 1024) - -// MIMXRT1050_EVK has 1 user LED +// MIMXRT1050_EVKB has 1 user LED #define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) -#define BOARD_FLASH_CONFIG_HEADER_H "evkmimxrt1050_flexspi_nor_config.h" -#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_nor_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) @@ -38,10 +34,10 @@ { IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO }, { IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI }, #define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \ - kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } + kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } #define DMA_REQ_SRC_TX { 0, kDmaRequestMuxLPSPI1Tx, kDmaRequestMuxLPSPI2Tx, \ - kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } + kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } // Define the mapping hardware I2C # to logical I2C # // SDA/SCL HW-I2C Logical I2C @@ -56,13 +52,14 @@ { IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL }, { IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA }, #define USDHC_DUMMY_PIN NULL, 0 + #define MICROPY_USDHC1 \ { \ .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ .clk = { GPIO_SD_B0_01_USDHC1_CLK }, \ - .cd_b = { GPIO_B1_12_USDHC1_CD_B },\ - .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 },\ - .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 },\ - .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 },\ - .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 },\ + .cd_b = { GPIO_B1_12_USDHC1_CD_B }, \ + .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 }, \ + .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 }, \ + .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 }, \ + .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 }, \ } diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk index fdbf47f01e..1ea85b7b4f 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk @@ -3,11 +3,10 @@ MCU_VARIANT = MIMXRT1052DVL6B MICROPY_FLOAT_IMPL = double MICROPY_PY_MACHINE_SDCARD = 1 +BOARD_FLASH_TYPE ?= hyperflash +BOARD_FLASH_SIZE ?= 0x4000000 # 64MB -JLINK_PATH ?= /media/RT1050-EVK/ +JLINK_PATH ?= /media/RT1050-EVKB/ deploy: $(BUILD)/firmware.bin cp $< $(JLINK_PATH) - -SRC_C += \ - hal/flexspi_nor_flash.c diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_hyper_flash_config.c b/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_hyper_flash_config.c new file mode 100644 index 0000000000..1b3349f911 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_hyper_flash_config.c @@ -0,0 +1,186 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include BOARD_FLASH_CONFIG_HEADER_H + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .columnAddressWidth = 3u, + // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock + .controllerMiscOption = + (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | + (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), + .sflashPadType = kSerialFlash_8Pads, + .serialClkFreq = kFlexSpiSerialClk_133MHz, + .sflashA1Size = BOARD_FLASH_SIZE, + .dataValidTime = {16u, 16u}, + .lookupTable = + { + /* 0 Read Data */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04), + + /* 1 Write Data */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02), + + /* 2 Read Status */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x70), // DATA 0x70 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 5] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x0B), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0), + + /* 4 Write Enable */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // DATA 0xAA + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 7] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + + /* 6 Erase Sector */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), // DATA 0x80 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 7] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + // +2 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 8] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 9] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 10] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 11] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + // +3 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 12] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 13] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 14] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x30, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), + + /* 10 program page with word program command sequence */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0), // DATA 0xA0 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 5] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x80), + + /* 12 Erase chip */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 1] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 3] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 7] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + // +2 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 8] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 9] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 10] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 11] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + // +3 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 12] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 13] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 14] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 15] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10), + }, + }, + .pageSize = 512u, + .sectorSize = 256u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = true, +}; + +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_nor_flash_config.c new file mode 100644 index 0000000000..290c6bc152 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_nor_flash_config.c @@ -0,0 +1,129 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include BOARD_FLASH_CONFIG_HEADER_H + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .columnAddressWidth = 3u, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .controllerMiscOption = + (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | + (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), + .sflashPadType = kSerialFlash_8Pads, + .serialClkFreq = kFlexSpiSerialClk_133MHz, + .sflashA1Size = BOARD_FLASH_SIZE, + .dataValidTime = {16u, 16u}, + .lookupTable = + { + // 0 Read LUTs 0 -> 0 + 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), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + }, + }, + .pageSize = 512u, + .sectorSize = 256u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = true, +}; + +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVKB/MIMXRT1050_EVKB.ld b/ports/mimxrt/boards/MIMXRT1050_EVKB/MIMXRT1050_EVKB.ld deleted file mode 100644 index f616178a9b..0000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVKB/MIMXRT1050_EVKB.ld +++ /dev/null @@ -1 +0,0 @@ -flash_size = 64M; \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1050_EVKB/evkbmimxrt1050_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1050_EVKB/evkbmimxrt1050_flexspi_nor_config.h deleted file mode 100644 index 02ac394e95..0000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVKB/evkbmimxrt1050_flexspi_nor_config.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __EVKMIMXRT1050_FLEXSPI_NOR_CONFIG__ -#define __EVKMIMXRT1050_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_flexspi.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related defintions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -//!@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_133MHz = 7, - kFlexSpiSerialClk_166MHz = 8, -} flexspi_serial_clk_freq_t; - -//!@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, //!< Clock configure for SDR mode - kFlexSpiClk_DDR, //!< Clock configurat for DDR mode -}; - -//!@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -//!@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. -}; - -//!@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -//!@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -//!@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; //!< Sequence Number, valid number: 1-16 - uint8_t seqId; //!< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -//!@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, //!< Reset device command -}; - -//!@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - //! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - //! Generic configuration, etc. - uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - //! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - //! sequence number, [31:16] Reserved - uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - //! details - uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - //! Chapter for more details - uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - //! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -#define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI - uint32_t pageSize; //!< Page size of Serial NOR - uint32_t sectorSize; //!< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command - uint8_t isUniformBlockSize; //!< Sector/Block size is the same - uint8_t reserved0[2]; //!< Reserved for future use - uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; //!< Block size - uint32_t reserve2[11]; //!< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1050_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVKB/flash_config.c b/ports/mimxrt/boards/MIMXRT1050_EVKB/flash_config.c deleted file mode 100644 index e8190bcb6c..0000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVKB/flash_config.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "evkbmimxrt1050_flexspi_nor_config.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - .columnAddressWidth = 3u, - // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock - .controllerMiscOption = - (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | - (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), - .sflashPadType = kSerialFlash_8Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = 64u * 1024u * 1024u, - .dataValidTime = {16u, 16u}, - .lookupTable = - { - /* 0 Read Data */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04), - - /* 1 Write Data */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02), - - /* 2 Read Status */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x70), // DATA 0x70 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 5] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x0B), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0), - - /* 4 Write Enable */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // DATA 0xAA - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 7] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - - /* 6 Erase Sector */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), // DATA 0x80 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 7] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - // +2 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 8] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 9] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 10] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 11] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - // +3 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 12] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 13] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 14] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x30, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), - - /* 10 program page with word program command sequence */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0), // DATA 0xA0 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 5] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x80), - - /* 12 Erase chip */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 1] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 3] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 7] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - // +2 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 8] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 9] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 10] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 11] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - // +3 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 12] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 13] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 14] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 15] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10), - }, - }, - .pageSize = 512u, - .sectorSize = 256u * 1024u, - .blockSize = 256u * 1024u, - .isUniformBlockSize = true, -}; - -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.h deleted file mode 100644 index 963c42cb6a..0000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.h +++ /dev/null @@ -1,68 +0,0 @@ -#define MICROPY_HW_BOARD_NAME "i.MX RT1050 EVKB" -#define MICROPY_HW_MCU_NAME "MIMXRT1052DVL6B" - -#define BOARD_FLASH_SIZE (64 * 1024 * 1024) - -// MIMXRT1050_EVKB has 1 user LED -#define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) -#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) -#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) -#define BOARD_FLASH_CONFIG_HEADER_H "evkbmimxrt1050_flexspi_nor_config.h" -#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_hyper_flash.h" - -#define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) - -// Define mapping logical UART # to hardware UART # -// LPUART3 on D0/D1 -> 1 -// LPUART2 on D7/D6 -> 2 -// LPUART6 on D8/D9 -> 3 -// LPUART8 on A1/A0 -> 4 - -#define MICROPY_HW_UART_NUM (sizeof(uart_index_table) / sizeof(uart_index_table)[0]) -#define MICROPY_HW_UART_INDEX { 0, 3, 2, 6, 8 } - -#define IOMUX_TABLE_UART \ - { 0 }, { 0 }, \ - { IOMUXC_GPIO_AD_B1_02_LPUART2_TX }, { IOMUXC_GPIO_AD_B1_03_LPUART2_RX }, \ - { IOMUXC_GPIO_AD_B1_06_LPUART3_TX }, { IOMUXC_GPIO_AD_B1_07_LPUART3_RX }, \ - { 0 }, { 0 }, \ - { 0 }, { 0 }, \ - { IOMUXC_GPIO_AD_B0_02_LPUART6_TX }, { IOMUXC_GPIO_AD_B0_03_LPUART6_RX }, \ - { 0 }, { 0 }, \ - { IOMUXC_GPIO_AD_B1_10_LPUART8_TX }, { IOMUXC_GPIO_AD_B1_11_LPUART8_RX }, - -#define MICROPY_HW_SPI_INDEX { 1 } - -#define IOMUX_TABLE_SPI \ - { IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK }, { IOMUXC_GPIO_SD_B0_01_LPSPI1_PCS0 }, \ - { IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO }, { IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI }, - -#define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \ - kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } - -#define DMA_REQ_SRC_TX { 0, kDmaRequestMuxLPSPI1Tx, kDmaRequestMuxLPSPI2Tx, \ - kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } - -// Define the mapping hardware I2C # to logical I2C # -// SDA/SCL HW-I2C Logical I2C -// D14/D15 LPI2C1 -> 0 -// D1/D0 LPI2C3 -> 1 - -#define MICROPY_HW_I2C_INDEX { 1, 3 } - -#define IOMUX_TABLE_I2C \ - { IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL }, { IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA }, \ - { 0 }, { 0 }, \ - { IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL }, { IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA }, - -#define USDHC_DUMMY_PIN NULL , 0 -#define MICROPY_USDHC1 \ - { \ - .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ - .clk = { GPIO_SD_B0_01_USDHC1_CLK }, \ - .cd_b = { GPIO_B1_12_USDHC1_CD_B },\ - .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 },\ - .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 },\ - .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 },\ - .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 },\ - } diff --git a/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.mk deleted file mode 100644 index e6cd1a63e8..0000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVKB/mpconfigboard.mk +++ /dev/null @@ -1,13 +0,0 @@ -MCU_SERIES = MIMXRT1052 -MCU_VARIANT = MIMXRT1052DVL6B - -MICROPY_FLOAT_IMPL = double -MICROPY_PY_MACHINE_SDCARD = 1 - -JLINK_PATH ?= /media/RT1050-EVKB/ - -SRC_C += \ - hal/flexspi_hyper_flash.c - -deploy: $(BUILD)/firmware.bin - cp $< $(JLINK_PATH) diff --git a/ports/mimxrt/boards/MIMXRT1050_EVKB/pins.csv b/ports/mimxrt/boards/MIMXRT1050_EVKB/pins.csv deleted file mode 100644 index 366a141ff8..0000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVKB/pins.csv +++ /dev/null @@ -1,31 +0,0 @@ -D0,GPIO_AD_B1_07 -D1,GPIO_AD_B1_06 -D2,GPIO_AD_B0_11 -D3,GPIO_AD_B1_08 -D4,GPIO_AD_B0_09 -D5,GPIO_AD_B0_10 -D6,GPIO_AD_B1_02 -D7,GPIO_AD_B1_03 -D8,GPIO_AD_B0_03 -D9,GPIO_AD_B0_02 -D10,GPIO_SD_B0_01 -D11,GPIO_SD_B0_02 -D12,GPIO_SD_B0_03 -D13,GPIO_SD_B0_00 -D14,GPIO_AD_B1_01 -D15,GPIO_AD_B1_00 -A0,GPIO_AD_B1_10 -A1,GPIO_AD_B1_11 -A2,GPIO_AD_B1_04 -A3,GPIO_AD_B1_05 -A4,GPIO_AD_B1_01 -A5,GPIO_AD_B1_00 -RX,GPIO_AD_B1_07 -TX,GPIO_AD_B1_06 -SCL,GPIO_AD_B1_00 -SDA,GPIO_AD_B1_01 -SCK,GPIO_SD_B0_00 -SDI,GPIO_SD_B0_03 -SDO,GPIO_SD_B0_02 -CS,GPIO_SD_B0_01 -LED_GREEN,GPIO_AD_B0_09 diff --git a/ports/mimxrt/boards/MIMXRT1052.ld b/ports/mimxrt/boards/MIMXRT1052.ld index 7519297940..d8c51d530a 100644 --- a/ports/mimxrt/boards/MIMXRT1052.ld +++ b/ports/mimxrt/boards/MIMXRT1052.ld @@ -1,14 +1,25 @@ /* Memory configuration */ +#if BOARD_FLASH_RESERVED +reserved_size = BOARD_FLASH_RESERVED; +#endif + +#if BOARD_FLASH_TYPE==qspi_nor flash_start = 0x60000000; +#elif BOARD_FLASH_TYPE==hyperflash +flash_start = 0x60000000; +#else +#error Unknown BOARD_FLASH_TYPE +#endif +flash_size = BOARD_FLASH_SIZE; flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); flash_config_start = flash_start; flash_config_size = 0x00001000; -ivt_start = 0x60001000; +ivt_start = flash_start + 0x00001000; ivt_size = 0x00001000; -interrupts_start = 0x60002000; +interrupts_start = flash_start + 0x00002000; interrupts_size = 0x00000400; -text_start = 0x60002400; -vfs_start = 0x60100000; +text_start = flash_start + 0x00002400; +vfs_start = flash_start + 0x00100000; text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); itcm_start = 0x00000000; diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld b/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld deleted file mode 100644 index f616178a9b..0000000000 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld +++ /dev/null @@ -1 +0,0 @@ -flash_size = 64M; \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK_flexspi_nor_config.h new file mode 100644 index 0000000000..e447733f06 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK_flexspi_nor_config.h @@ -0,0 +1,264 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ +#define __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_flexspi.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define 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)) + +// !@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_120MHz = 7, + kFlexSpiSerialClk_133MHz = 8, + kFlexSpiSerialClk_166MHz = 9, +} flexspi_serial_clk_freq_t; + +// !@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, // !< Clock configure for SDR mode + kFlexSpiClk_DDR, // !< Clock configurat for DDR mode +}; + +// !@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +// !@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. +}; + +// !@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +// !@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +// !@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; // !< Sequence Number, valid number: 1-16 + uint8_t seqId; // !< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +// !@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, // !< Reset device command +}; + +// !@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + // ! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + // ! Generic configuration, etc. + uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + // ! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + // ! sequence number, [31:16] Reserved + uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + // ! details + uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + // ! Chapter for more details + uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + // ! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 + +#define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP 12 + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI + uint32_t pageSize; // !< Page size of Serial NOR + uint32_t sectorSize; // !< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command + uint8_t isUniformBlockSize; // !< Sector/Block size is the same + uint8_t reserved0[2]; // !< Reserved for future use + uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; // !< Block size + uint32_t reserve2[11]; // !< Reserved for future use +} flexspi_nor_config_t; + +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/clock_config.h b/ports/mimxrt/boards/MIMXRT1060_EVK/clock_config.h new file mode 100644 index 0000000000..0822024847 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/clock_config.h @@ -0,0 +1,122 @@ +/* + * Copyright 2018-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ + +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */ + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 600000000UL +#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_CSI_CLK_ROOT 12000000UL +#define BOARD_BOOTCLOCKRUN_ENET1_TX_CLK 2400000UL +#define BOARD_BOOTCLOCKRUN_ENET2_125M_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_ENET2_TX_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 2400000UL +#define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXSPI2_CLK_ROOT 130909090UL +#define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 130909090UL +#define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 150000000UL +#define BOARD_BOOTCLOCKRUN_LCDIF_CLK_ROOT 9642857UL +#define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL +#define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL +#define BOARD_BOOTCLOCKRUN_LVDS1_CLK 1200000000UL +#define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL +#define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 75000000UL +#define BOARD_BOOTCLOCKRUN_PLL7_MAIN_CLK 24000000UL +#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 75000000UL +#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_USBPHY2_CLK 0UL +#define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 198000000UL +#define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 198000000UL + +/*! @brief Arm PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN; +/*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; +/*! @brief Sys PLL for BOARD_BootClockRUN configuration. + */ +extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/evkmimxrt1060_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1060_EVK/evkmimxrt1060_flexspi_nor_config.h deleted file mode 100644 index cff520e0e2..0000000000 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/evkmimxrt1060_flexspi_nor_config.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ -#define __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_flexspi.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related defintions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -//!@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_120MHz = 7, - kFlexSpiSerialClk_133MHz = 8, - kFlexSpiSerialClk_166MHz = 9, -} flexspi_serial_clk_freq_t; - -//!@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, //!< Clock configure for SDR mode - kFlexSpiClk_DDR, //!< Clock configurat for DDR mode -}; - -//!@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -//!@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. -}; - -//!@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -//!@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -//!@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; //!< Sequence Number, valid number: 1-16 - uint8_t seqId; //!< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -//!@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, //!< Reset device command -}; - -//!@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - //! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - //! Generic configuration, etc. - uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - //! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - //! sequence number, [31:16] Reserved - uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - //! details - uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - //! Chapter for more details - uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - //! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -#define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI - uint32_t pageSize; //!< Page size of Serial NOR - uint32_t sectorSize; //!< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command - uint8_t isUniformBlockSize; //!< Sector/Block size is the same - uint8_t reserved0[2]; //!< Reserved for future use - uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; //!< Block size - uint32_t reserve2[11]; //!< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/flash_config.c b/ports/mimxrt/boards/MIMXRT1060_EVK/flash_config.c deleted file mode 100644 index e28f581547..0000000000 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/flash_config.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "evkmimxrt1060_flexspi_nor_config.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - .columnAddressWidth = 3u, - // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock - .controllerMiscOption = - (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | - (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), - .sflashPadType = kSerialFlash_8Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = 64u * 1024u * 1024u, - .dataValidTime = {16u, 16u}, - .lookupTable = - { - /* 0 Read Data */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04), - - /* 1 Write Data */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02), - - /* 2 Read Status */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x70), // DATA 0x70 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 5] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x0B), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0), - - /* 4 Write Enable */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // DATA 0xAA - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 7] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - - /* 6 Erase Sector */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), // DATA 0x80 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 7] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - // +2 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 8] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 9] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 10] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 11] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - // +3 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 12] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 13] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 14] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x30, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), - - /* 10 program page with word program command sequence */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0), // DATA 0xA0 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 5] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x80), - - /* 12 Erase chip */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 1] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 3] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 7] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - // +2 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 8] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 9] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 10] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 11] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - // +3 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 12] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 13] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 14] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 15] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10), - }, - }, - .pageSize = 512u, - .sectorSize = 256u * 1024u, - .blockSize = 256u * 1024u, - .isUniformBlockSize = true, -}; - -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h index c26364f265..5cf31aa25a 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h @@ -1,14 +1,10 @@ #define MICROPY_HW_BOARD_NAME "i.MX RT1060 EVK" #define MICROPY_HW_MCU_NAME "MIMXRT1062DVJ6A" -#define BOARD_FLASH_SIZE (8 * 1024 * 1024) - // MIMXRT1060_EVK has 1 user LED #define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) -#define BOARD_FLASH_CONFIG_HEADER_H "evkmimxrt1060_flexspi_nor_config.h" -#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_hyper_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) @@ -38,10 +34,10 @@ { IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO }, { IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI }, #define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \ - kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } + kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } #define DMA_REQ_SRC_TX { 0, kDmaRequestMuxLPSPI1Tx, kDmaRequestMuxLPSPI2Tx, \ - kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } + kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } // Define the mapping hardware I2C # to logical I2C # // SDA/SCL HW-I2C Logical I2C @@ -60,9 +56,9 @@ { \ .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ .clk = { GPIO_SD_B0_01_USDHC1_CLK }, \ - .cd_b = { GPIO_B1_12_USDHC1_CD_B },\ - .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 },\ - .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 },\ - .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 },\ - .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 },\ + .cd_b = { GPIO_B1_12_USDHC1_CD_B }, \ + .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 }, \ + .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 }, \ + .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 }, \ + .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 }, \ } diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk index 623e2617fd..1e041c8eb5 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk @@ -3,20 +3,18 @@ MCU_VARIANT = MIMXRT1062DVJ6A MICROPY_FLOAT_IMPL = double MICROPY_PY_MACHINE_SDCARD = 1 +BOARD_FLASH_TYPE ?= qspi_nor +BOARD_FLASH_SIZE ?= 0x800000 # 8MB JLINK_PATH ?= /media/RT1060-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink - ifdef JLINK_IP JLINK_CONNECTION_SETTINGS = -IP $(JLINK_IP) else JLINK_CONNECTION_SETTINGS = -USB endif -SRC_C += \ - hal/flexspi_hyper_flash.c - deploy_jlink: $(BUILD)/firmware.hex $(Q)$(TOUCH) $(JLINK_COMMANDER_SCRIPT) $(ECHO) "ExitOnError 1" > $(JLINK_COMMANDER_SCRIPT) diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_hyper_flash_config.c b/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_hyper_flash_config.c new file mode 100644 index 0000000000..1b3349f911 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_hyper_flash_config.c @@ -0,0 +1,186 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include BOARD_FLASH_CONFIG_HEADER_H + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .columnAddressWidth = 3u, + // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock + .controllerMiscOption = + (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | + (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), + .sflashPadType = kSerialFlash_8Pads, + .serialClkFreq = kFlexSpiSerialClk_133MHz, + .sflashA1Size = BOARD_FLASH_SIZE, + .dataValidTime = {16u, 16u}, + .lookupTable = + { + /* 0 Read Data */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04), + + /* 1 Write Data */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02), + + /* 2 Read Status */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x70), // DATA 0x70 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 5] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x0B), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0), + + /* 4 Write Enable */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // DATA 0xAA + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 7] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + + /* 6 Erase Sector */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), // DATA 0x80 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 7] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + // +2 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 8] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 9] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 10] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 11] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + // +3 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 12] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 13] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 14] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x30, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), + + /* 10 program page with word program command sequence */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0), // DATA 0xA0 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 5] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x80), + + /* 12 Erase chip */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 1] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 3] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 7] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + // +2 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 8] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 9] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 10] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 11] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + // +3 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 12] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 13] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 14] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 15] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10), + }, + }, + .pageSize = 512u, + .sectorSize = 256u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = true, +}; + +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_nor_flash_config.c new file mode 100644 index 0000000000..290c6bc152 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_nor_flash_config.c @@ -0,0 +1,129 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include BOARD_FLASH_CONFIG_HEADER_H + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .columnAddressWidth = 3u, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .controllerMiscOption = + (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | + (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), + .sflashPadType = kSerialFlash_8Pads, + .serialClkFreq = kFlexSpiSerialClk_133MHz, + .sflashA1Size = BOARD_FLASH_SIZE, + .dataValidTime = {16u, 16u}, + .lookupTable = + { + // 0 Read LUTs 0 -> 0 + 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), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + }, + }, + .pageSize = 512u, + .sectorSize = 256u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = true, +}; + +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1062.ld b/ports/mimxrt/boards/MIMXRT1062.ld index 5edf70ee46..03c1193344 100644 --- a/ports/mimxrt/boards/MIMXRT1062.ld +++ b/ports/mimxrt/boards/MIMXRT1062.ld @@ -1,14 +1,25 @@ /* Memory configuration */ +#if BOARD_FLASH_RESERVED +reserved_size = BOARD_FLASH_RESERVED; +#endif + +#if BOARD_FLASH_TYPE==qspi_nor flash_start = 0x60000000; +#elif BOARD_FLASH_TYPE==hyperflash +flash_start = 0x60000000; +#else +#error Unknown BOARD_FLASH_TYPE +#endif +flash_size = BOARD_FLASH_SIZE; flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); flash_config_start = flash_start; flash_config_size = 0x00001000; -ivt_start = 0x60001000; +ivt_start = flash_start + 0x00001000; ivt_size = 0x00001000; -interrupts_start = 0x60002000; +interrupts_start = flash_start + 0x00002000; interrupts_size = 0x00000400; -text_start = 0x60002400; -vfs_start = 0x60100000; +text_start = flash_start + 0x00002400; +vfs_start = flash_start + 0x00100000; text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); itcm_start = 0x00000000; diff --git a/ports/mimxrt/boards/MIMXRT1064.ld b/ports/mimxrt/boards/MIMXRT1064.ld index 8203930017..88720896f4 100644 --- a/ports/mimxrt/boards/MIMXRT1064.ld +++ b/ports/mimxrt/boards/MIMXRT1064.ld @@ -1,14 +1,27 @@ /* Memory configuration */ +#if BOARD_FLASH_RESERVED +reserved_size = BOARD_FLASH_RESERVED; +#endif + +#if BOARD_FLASH_TYPE==qspi_nor flash_start = 0x60000000; +#elif BOARD_FLASH_TYPE==hyperflash +flash_start = 0x60000000; +#elif BOARD_FLASH_TYPE==internal +flash_start = 0x70000000; +#else +#error Unknown BOARD_FLASH_TYPE +#endif +flash_size = BOARD_FLASH_SIZE; flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); flash_config_start = flash_start; flash_config_size = 0x00001000; -ivt_start = 0x60001000; +ivt_start = flash_start + 0x00001000; ivt_size = 0x00001000; -interrupts_start = 0x60002000; +interrupts_start = flash_start + 0x00002000; interrupts_size = 0x00000400; -text_start = 0x60002400; -vfs_start = 0x60100000; +text_start = flash_start + 0x00002400; +vfs_start = flash_start + 0x00100000; text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); itcm_start = 0x00000000; diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld b/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld deleted file mode 100644 index f616178a9b..0000000000 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld +++ /dev/null @@ -1 +0,0 @@ -flash_size = 64M; \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK_flexspi_nor_config.h new file mode 100644 index 0000000000..01b3194e31 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK_flexspi_nor_config.h @@ -0,0 +1,264 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ +#define __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_flexspi.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define 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)) + +// !@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_120MHz = 7, + kFlexSpiSerialClk_133MHz = 8, + kFlexSpiSerialClk_166MHz = 9, +} flexspi_serial_clk_freq_t; + +// !@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, // !< Clock configure for SDR mode + kFlexSpiClk_DDR, // !< Clock configurat for DDR mode +}; + +// !@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +// !@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. +}; + +// !@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +// !@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +// !@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; // !< Sequence Number, valid number: 1-16 + uint8_t seqId; // !< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +// !@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, // !< Reset device command +}; + +// !@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + // ! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + // ! Generic configuration, etc. + uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + // ! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + // ! sequence number, [31:16] Reserved + uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + // ! details + uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + // ! Chapter for more details + uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + // ! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 + +#define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP 12 + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI + uint32_t pageSize; // !< Page size of Serial NOR + uint32_t sectorSize; // !< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command + uint8_t isUniformBlockSize; // !< Sector/Block size is the same + uint8_t reserved0[2]; // !< Reserved for future use + uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; // !< Block size + uint32_t reserve2[11]; // !< Reserved for future use +} flexspi_nor_config_t; + +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/clock_config.h b/ports/mimxrt/boards/MIMXRT1064_EVK/clock_config.h new file mode 100644 index 0000000000..13bc925a10 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/clock_config.h @@ -0,0 +1,122 @@ +/* + * Copyright 2018-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ + +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */ + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 600000000UL +#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_CSI_CLK_ROOT 12000000UL +#define BOARD_BOOTCLOCKRUN_ENET1_TX_CLK 2400000UL +#define BOARD_BOOTCLOCKRUN_ENET2_125M_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_ENET2_TX_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 2400000UL +#define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXSPI2_CLK_ROOT 130909090UL +#define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 130909090UL +#define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 150000000UL +#define BOARD_BOOTCLOCKRUN_LCDIF_CLK_ROOT 67500000UL +#define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL +#define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL +#define BOARD_BOOTCLOCKRUN_LVDS1_CLK 1200000000UL +#define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL +#define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 75000000UL +#define BOARD_BOOTCLOCKRUN_PLL7_MAIN_CLK 24000000UL +#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 75000000UL +#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_USBPHY2_CLK 0UL +#define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 198000000UL +#define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 198000000UL + +/*! @brief Arm PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN; +/*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; +/*! @brief Sys PLL for BOARD_BootClockRUN configuration. + */ +extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/evkmimxrt1064_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1064_EVK/evkmimxrt1064_flexspi_nor_config.h deleted file mode 100644 index 7560f24836..0000000000 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/evkmimxrt1064_flexspi_nor_config.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ -#define __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_flexspi.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related defintions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -//!@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_120MHz = 7, - kFlexSpiSerialClk_133MHz = 8, - kFlexSpiSerialClk_166MHz = 9, -} flexspi_serial_clk_freq_t; - -//!@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, //!< Clock configure for SDR mode - kFlexSpiClk_DDR, //!< Clock configurat for DDR mode -}; - -//!@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -//!@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. -}; - -//!@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -//!@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -//!@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; //!< Sequence Number, valid number: 1-16 - uint8_t seqId; //!< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -//!@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, //!< Reset device command -}; - -//!@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - //! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - //! Generic configuration, etc. - uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - //! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - //! sequence number, [31:16] Reserved - uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - //! details - uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - //! Chapter for more details - uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - //! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -#define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI - uint32_t pageSize; //!< Page size of Serial NOR - uint32_t sectorSize; //!< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command - uint8_t isUniformBlockSize; //!< Sector/Block size is the same - uint8_t reserved0[2]; //!< Reserved for future use - uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; //!< Block size - uint32_t reserve2[11]; //!< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/flash_config.c b/ports/mimxrt/boards/MIMXRT1064_EVK/flash_config.c deleted file mode 100644 index f308b7f8ad..0000000000 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/flash_config.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "evkmimxrt1064_flexspi_nor_config.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - .columnAddressWidth = 3u, - // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock - .controllerMiscOption = - (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | - (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), - .sflashPadType = kSerialFlash_8Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = 64u * 1024u * 1024u, - .dataValidTime = {16u, 16u}, - .lookupTable = - { - /* 0 Read Data */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04), - - /* 1 Write Data */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02), - - /* 2 Read Status */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x70), // DATA 0x70 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 5] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x0B), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0), - - /* 4 Write Enable */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // DATA 0xAA - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 7] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - - /* 6 Erase Sector */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), // DATA 0x80 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 7] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - // +2 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 8] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 9] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 10] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 11] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - // +3 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 12] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 13] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 14] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x30, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), - - /* 10 program page with word program command sequence */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0), // DATA 0xA0 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 5] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x80), - - /* 12 Erase chip */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 1] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 3] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 7] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - // +2 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 8] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 9] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 10] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 11] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - // +3 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 12] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 13] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 14] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 15] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10), - }, - }, - .pageSize = 512u, - .sectorSize = 256u * 1024u, - .blockSize = 256u * 1024u, - .isUniformBlockSize = true, -}; - -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h index 4534caa296..ab8a80a3a4 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h @@ -5,8 +5,6 @@ #define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) -#define BOARD_FLASH_CONFIG_HEADER_H "evkmimxrt1064_flexspi_nor_config.h" -#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_hyper_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) @@ -36,10 +34,10 @@ { IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO }, { IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI }, #define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \ - kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } + kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } #define DMA_REQ_SRC_TX { 0, kDmaRequestMuxLPSPI1Tx, kDmaRequestMuxLPSPI2Tx, \ - kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } + kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } // Define the mapping hardware I2C # to logical I2C # // SDA/SCL HW-I2C Logical I2C @@ -58,9 +56,9 @@ { \ .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ .clk = { GPIO_SD_B0_01_USDHC1_CLK }, \ - .cd_b = { GPIO_B1_12_USDHC1_CD_B },\ - .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 },\ - .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 },\ - .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 },\ - .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 },\ + .cd_b = { GPIO_B1_12_USDHC1_CD_B }, \ + .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 }, \ + .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 }, \ + .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 }, \ + .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 }, \ } diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk index fe3c442faa..19655da616 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk @@ -3,13 +3,10 @@ MCU_VARIANT = MIMXRT1064DVL6A MICROPY_FLOAT_IMPL = double MICROPY_PY_MACHINE_SDCARD = 1 +BOARD_FLASH_TYPE ?= hyperflash +BOARD_FLASH_SIZE ?= 0x4000000 # 64MB JLINK_PATH ?= /media/RT1064-EVK/ -CFLAGS += -DBOARD_FLASH_SIZE=0x400000 - deploy: $(BUILD)/firmware.bin cp $< $(JLINK_PATH) - -SRC_C += \ - hal/flexspi_hyper_flash.c diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_hyper_flash_config.c b/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_hyper_flash_config.c new file mode 100644 index 0000000000..1b3349f911 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_hyper_flash_config.c @@ -0,0 +1,186 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include BOARD_FLASH_CONFIG_HEADER_H + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .columnAddressWidth = 3u, + // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock + .controllerMiscOption = + (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | + (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), + .sflashPadType = kSerialFlash_8Pads, + .serialClkFreq = kFlexSpiSerialClk_133MHz, + .sflashA1Size = BOARD_FLASH_SIZE, + .dataValidTime = {16u, 16u}, + .lookupTable = + { + /* 0 Read Data */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04), + + /* 1 Write Data */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02), + + /* 2 Read Status */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x70), // DATA 0x70 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 5] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x0B), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0), + + /* 4 Write Enable */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // DATA 0xAA + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 7] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + + /* 6 Erase Sector */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), // DATA 0x80 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 7] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + // +2 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 8] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 9] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 10] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 11] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + // +3 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 12] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 13] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 14] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x30, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), + + /* 10 program page with word program command sequence */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0), // DATA 0xA0 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 5] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x80), + + /* 12 Erase chip */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 1] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 3] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 7] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + // +2 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 8] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 9] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 10] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 11] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + // +3 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 12] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 13] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 14] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 15] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10), + }, + }, + .pageSize = 512u, + .sectorSize = 256u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = true, +}; + +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_nor_flash_config.c new file mode 100644 index 0000000000..290c6bc152 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_nor_flash_config.c @@ -0,0 +1,129 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include BOARD_FLASH_CONFIG_HEADER_H + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .columnAddressWidth = 3u, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .controllerMiscOption = + (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | + (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), + .sflashPadType = kSerialFlash_8Pads, + .serialClkFreq = kFlexSpiSerialClk_133MHz, + .sflashA1Size = BOARD_FLASH_SIZE, + .dataValidTime = {16u, 16u}, + .lookupTable = + { + // 0 Read LUTs 0 -> 0 + 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), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + }, + }, + .pageSize = 512u, + .sectorSize = 256u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = true, +}; + +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/TEENSY40/TEENSY40.ld b/ports/mimxrt/boards/TEENSY40/TEENSY40.ld deleted file mode 100644 index a3b696db66..0000000000 --- a/ports/mimxrt/boards/TEENSY40/TEENSY40.ld +++ /dev/null @@ -1,2 +0,0 @@ -flash_size = 2M; -reserved_size = 4K; \ No newline at end of file diff --git a/ports/mimxrt/boards/TEENSY40/TEENSY40_flexspi_nor_config.h b/ports/mimxrt/boards/TEENSY40/TEENSY40_flexspi_nor_config.h new file mode 100644 index 0000000000..b06def76c0 --- /dev/null +++ b/ports/mimxrt/boards/TEENSY40/TEENSY40_flexspi_nor_config.h @@ -0,0 +1,259 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.h + +#ifndef __TEENSY40_FLEXSPI_NOR_CONFIG__ +#define __TEENSY40_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related definitions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_ERASE 5 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define 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)) + +// !@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_120MHz = 7, + kFlexSpiSerialClk_133MHz = 8, + kFlexSpiSerialClk_166MHz = 9, +} flexspi_serial_clk_freq_t; + +// !@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, // !< Clock configure for SDR mode + kFlexSpiClk_DDR, // !< Clock configurat for DDR mode +}; + +// !@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +// !@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. +}; + +// !@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +// !@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +// !@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; // !< Sequence Number, valid number: 1-16 + uint8_t seqId; // !< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +// !@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, // !< Reset device command +}; + +// !@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + // ! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + // ! Generic configuration, etc. + uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + // ! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + // ! sequence number, [31:16] Reserved + uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + // ! details + uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + // ! Chapter for more details + uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + // ! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI + uint32_t pageSize; // !< Page size of Serial NOR + uint32_t sectorSize; // !< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command + uint8_t isUniformBlockSize; // !< Sector/Block size is the same + uint8_t reserved0[2]; // !< Reserved for future use + uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; // !< Block size + uint32_t reserve2[11]; // !< Reserved for future use +} flexspi_nor_config_t; + +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/TEENSY40/clock_config.h b/ports/mimxrt/boards/TEENSY40/clock_config.h new file mode 100644 index 0000000000..0822024847 --- /dev/null +++ b/ports/mimxrt/boards/TEENSY40/clock_config.h @@ -0,0 +1,122 @@ +/* + * Copyright 2018-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ + +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */ + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 600000000UL +#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_CSI_CLK_ROOT 12000000UL +#define BOARD_BOOTCLOCKRUN_ENET1_TX_CLK 2400000UL +#define BOARD_BOOTCLOCKRUN_ENET2_125M_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_ENET2_TX_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 2400000UL +#define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXSPI2_CLK_ROOT 130909090UL +#define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 130909090UL +#define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 150000000UL +#define BOARD_BOOTCLOCKRUN_LCDIF_CLK_ROOT 9642857UL +#define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL +#define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL +#define BOARD_BOOTCLOCKRUN_LVDS1_CLK 1200000000UL +#define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL +#define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 75000000UL +#define BOARD_BOOTCLOCKRUN_PLL7_MAIN_CLK 24000000UL +#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 75000000UL +#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_USBPHY2_CLK 0UL +#define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 198000000UL +#define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 198000000UL + +/*! @brief Arm PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN; +/*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; +/*! @brief Sys PLL for BOARD_BootClockRUN configuration. + */ +extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/ports/mimxrt/boards/TEENSY40/flash_config.c b/ports/mimxrt/boards/TEENSY40/flash_config.c deleted file mode 100644 index 7a63cf825d..0000000000 --- a/ports/mimxrt/boards/TEENSY40/flash_config.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.c - -#include "teensy40_flexspi_nor_config.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - - .busyOffset = FLASH_BUSY_STATUS_OFFSET, // Status bit 0 indicates busy. - .busyBitPolarity = FLASH_BUSY_STATUS_POL, // Busy when the bit is 1. - - .deviceModeCfgEnable = 1u, - .deviceModeType = kDeviceConfigCmdType_QuadEnable, - .deviceModeSeq = { - .seqId = 4u, - .seqNum = 1u, - }, - .deviceModeArg = 0x0200, - .configCmdEnable = 1u, - .configModeType[0] = kDeviceConfigCmdType_Generic, - .configCmdSeqs[0] = { - .seqId = 2u, - .seqNum = 1u, - }, - .deviceType = kFlexSpiDeviceType_SerialNOR, - // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock - .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, - .sflashA1Size = 2u * 1024u * 1024u, - .lookupTable = - { - // 0 Read LUTs 0 -> 0 - 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), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 1 Read status register -> 1 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 2 Fast read quad mode - SDR - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 3 Write Enable -> 3 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 4 Read extend parameters - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 5 Erase Sector -> 5 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 6 Write Status Reg - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 7 Page Program - quad mode (-> 9) - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 8 Read ID - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 9 Page Program - single mode -> 9 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 10 Enter QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 11 Erase Chip - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 12 Exit QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - }, - }, - .pageSize = 256u, - .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, - .blockSize = 0x00010000, - .isUniformBlockSize = false, -}; -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/TEENSY40/mpconfigboard.h b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h index 4a69303b56..ae0a234629 100644 --- a/ports/mimxrt/boards/TEENSY40/mpconfigboard.h +++ b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h @@ -1,14 +1,10 @@ #define MICROPY_HW_BOARD_NAME "Teensy 4.0" #define MICROPY_HW_MCU_NAME "MIMXRT1062DVJ6A" -#define BOARD_FLASH_SIZE (2 * 1024 * 1024) - // Teensy 4.0 has 1 board LED #define MICROPY_HW_LED1_PIN (pin_GPIO_B0_03) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) -#define BOARD_FLASH_CONFIG_HEADER_H "teensy40_flexspi_nor_config.h" -#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_nor_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) @@ -39,10 +35,10 @@ { IOMUXC_GPIO_B0_02_LPSPI4_SDO }, { IOMUXC_GPIO_B0_01_LPSPI4_SDI }, #define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \ - kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } + kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } #define DMA_REQ_SRC_TX { 0, kDmaRequestMuxLPSPI1Tx, kDmaRequestMuxLPSPI2Tx, \ - kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } + kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } // Define mapping hardware I2C # to logical I2C # // SDA/SCL HW-I2C Logical I2C @@ -63,9 +59,9 @@ { \ .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ .clk = { GPIO_SD_B0_01_USDHC1_CLK }, \ - .cd_b = { USDHC_DUMMY_PIN },\ - .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 },\ - .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 },\ - .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 },\ - .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 },\ + .cd_b = { USDHC_DUMMY_PIN }, \ + .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 }, \ + .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 }, \ + .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 }, \ + .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 }, \ } diff --git a/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk b/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk index bd70fd0925..170f93dcf8 100644 --- a/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk +++ b/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk @@ -3,9 +3,9 @@ MCU_VARIANT = MIMXRT1062DVJ6A MICROPY_FLOAT_IMPL = double MICROPY_PY_MACHINE_SDCARD = 1 +BOARD_FLASH_TYPE ?= qspi_nor +BOARD_FLASH_SIZE ?= 0x200000 # 2MB +BOARD_FLASH_RESERVED ?= 0x1000 # 4KB deploy: $(BUILD)/firmware.hex teensy_loader_cli --mcu=imxrt1062 -v -w $< - -SRC_C += \ - hal/flexspi_nor_flash.c diff --git a/ports/mimxrt/boards/TEENSY40/qspi_nor_flash_config.c b/ports/mimxrt/boards/TEENSY40/qspi_nor_flash_config.c new file mode 100644 index 0000000000..71d871b751 --- /dev/null +++ b/ports/mimxrt/boards/TEENSY40/qspi_nor_flash_config.c @@ -0,0 +1,144 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.c + +#include BOARD_FLASH_CONFIG_HEADER_H + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + + .busyOffset = FLASH_BUSY_STATUS_OFFSET, // Status bit 0 indicates busy. + .busyBitPolarity = FLASH_BUSY_STATUS_POL, // Busy when the bit is 1. + + .deviceModeCfgEnable = 1u, + .deviceModeType = kDeviceConfigCmdType_QuadEnable, + .deviceModeSeq = { + .seqId = 4u, + .seqNum = 1u, + }, + .deviceModeArg = 0x0200, + .configCmdEnable = 1u, + .configModeType[0] = kDeviceConfigCmdType_Generic, + .configCmdSeqs[0] = { + .seqId = 2u, + .seqNum = 1u, + }, + .deviceType = kFlexSpiDeviceType_SerialNOR, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_60MHz, + .sflashA1Size = BOARD_FLASH_SIZE, + .lookupTable = + { + // 0 Read LUTs 0 -> 0 + 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), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .blockSize = 0x00010000, + .isUniformBlockSize = false, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/TEENSY40/teensy40_flexspi_nor_config.h b/ports/mimxrt/boards/TEENSY40/teensy40_flexspi_nor_config.h deleted file mode 100644 index 445a0baccc..0000000000 --- a/ports/mimxrt/boards/TEENSY40/teensy40_flexspi_nor_config.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.h - -#ifndef __TEENSY40_FLEXSPI_NOR_CONFIG__ -#define __TEENSY40_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_common.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related definitions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_ERASE 5 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -//!@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_120MHz = 7, - kFlexSpiSerialClk_133MHz = 8, - kFlexSpiSerialClk_166MHz = 9, -} flexspi_serial_clk_freq_t; - -//!@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, //!< Clock configure for SDR mode - kFlexSpiClk_DDR, //!< Clock configurat for DDR mode -}; - -//!@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -//!@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. -}; - -//!@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -//!@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -//!@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; //!< Sequence Number, valid number: 1-16 - uint8_t seqId; //!< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -//!@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, //!< Reset device command -}; - -//!@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - //! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - //! Generic configuration, etc. - uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - //! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - //! sequence number, [31:16] Reserved - uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - //! details - uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - //! Chapter for more details - uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - //! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI - uint32_t pageSize; //!< Page size of Serial NOR - uint32_t sectorSize; //!< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command - uint8_t isUniformBlockSize; //!< Sector/Block size is the same - uint8_t reserved0[2]; //!< Reserved for future use - uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; //!< Block size - uint32_t reserve2[11]; //!< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/TEENSY41/TEENSY41.ld b/ports/mimxrt/boards/TEENSY41/TEENSY41.ld deleted file mode 100755 index 7f3cfc302a..0000000000 --- a/ports/mimxrt/boards/TEENSY41/TEENSY41.ld +++ /dev/null @@ -1,2 +0,0 @@ -flash_size = 8M; -reserved_size = 4K; diff --git a/ports/mimxrt/boards/TEENSY41/TEENSY41_flexspi_nor_config.h b/ports/mimxrt/boards/TEENSY41/TEENSY41_flexspi_nor_config.h new file mode 100644 index 0000000000..b06def76c0 --- /dev/null +++ b/ports/mimxrt/boards/TEENSY41/TEENSY41_flexspi_nor_config.h @@ -0,0 +1,259 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.h + +#ifndef __TEENSY40_FLEXSPI_NOR_CONFIG__ +#define __TEENSY40_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related definitions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_ERASE 5 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define 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)) + +// !@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_120MHz = 7, + kFlexSpiSerialClk_133MHz = 8, + kFlexSpiSerialClk_166MHz = 9, +} flexspi_serial_clk_freq_t; + +// !@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, // !< Clock configure for SDR mode + kFlexSpiClk_DDR, // !< Clock configurat for DDR mode +}; + +// !@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +// !@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. +}; + +// !@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +// !@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +// !@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; // !< Sequence Number, valid number: 1-16 + uint8_t seqId; // !< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +// !@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, // !< Reset device command +}; + +// !@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + // ! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + // ! Generic configuration, etc. + uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + // ! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + // ! sequence number, [31:16] Reserved + uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + // ! details + uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + // ! Chapter for more details + uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + // ! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI + uint32_t pageSize; // !< Page size of Serial NOR + uint32_t sectorSize; // !< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command + uint8_t isUniformBlockSize; // !< Sector/Block size is the same + uint8_t reserved0[2]; // !< Reserved for future use + uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; // !< Block size + uint32_t reserve2[11]; // !< Reserved for future use +} flexspi_nor_config_t; + +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/TEENSY41/clock_config.h b/ports/mimxrt/boards/TEENSY41/clock_config.h new file mode 100644 index 0000000000..0822024847 --- /dev/null +++ b/ports/mimxrt/boards/TEENSY41/clock_config.h @@ -0,0 +1,122 @@ +/* + * Copyright 2018-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ + +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */ + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 600000000UL +#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_CSI_CLK_ROOT 12000000UL +#define BOARD_BOOTCLOCKRUN_ENET1_TX_CLK 2400000UL +#define BOARD_BOOTCLOCKRUN_ENET2_125M_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_ENET2_TX_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 2400000UL +#define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXSPI2_CLK_ROOT 130909090UL +#define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 130909090UL +#define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 150000000UL +#define BOARD_BOOTCLOCKRUN_LCDIF_CLK_ROOT 9642857UL +#define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL +#define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL +#define BOARD_BOOTCLOCKRUN_LVDS1_CLK 1200000000UL +#define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL +#define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 75000000UL +#define BOARD_BOOTCLOCKRUN_PLL7_MAIN_CLK 24000000UL +#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 75000000UL +#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_USBPHY2_CLK 0UL +#define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 198000000UL +#define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 198000000UL + +/*! @brief Arm PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN; +/*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; +/*! @brief Sys PLL for BOARD_BootClockRUN configuration. + */ +extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/ports/mimxrt/boards/TEENSY41/flash_config.c b/ports/mimxrt/boards/TEENSY41/flash_config.c deleted file mode 100755 index f5066216d1..0000000000 --- a/ports/mimxrt/boards/TEENSY41/flash_config.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.c - -#include "teensy41_flexspi_nor_config.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - - .busyOffset = FLASH_BUSY_STATUS_OFFSET, // Status bit 0 indicates busy. - .busyBitPolarity = FLASH_BUSY_STATUS_POL, // Busy when the bit is 1. - - .deviceModeCfgEnable = 1u, - .deviceModeType = kDeviceConfigCmdType_QuadEnable, - .deviceModeSeq = { - .seqId = 4u, - .seqNum = 1u, - }, - .deviceModeArg = 0x0200, - .configCmdEnable = 1u, - .configModeType[0] = kDeviceConfigCmdType_Generic, - .configCmdSeqs[0] = { - .seqId = 2u, - .seqNum = 1u, - }, - .deviceType = kFlexSpiDeviceType_SerialNOR, - // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock - .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, - .sflashA1Size = 8u * 1024u * 1024u, - .lookupTable = - { - // 0 Read LUTs 0 -> 0 - 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), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 1 Read status register -> 1 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 2 Fast read quad mode - SDR - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 3 Write Enable -> 3 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 4 Read extend parameters - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 5 Erase Sector -> 5 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 6 Write Status Reg - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 7 Page Program - quad mode (-> 9) - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 8 Read ID - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 9 Page Program - single mode -> 9 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 10 Enter QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 11 Erase Chip - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 12 Exit QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - }, - }, - .pageSize = 256u, - .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, - .blockSize = 0x00010000, - .isUniformBlockSize = false, -}; -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/TEENSY41/mpconfigboard.h b/ports/mimxrt/boards/TEENSY41/mpconfigboard.h index 587bf9c620..7890ba762c 100644 --- a/ports/mimxrt/boards/TEENSY41/mpconfigboard.h +++ b/ports/mimxrt/boards/TEENSY41/mpconfigboard.h @@ -1,14 +1,10 @@ #define MICROPY_HW_BOARD_NAME "Teensy 4.1" #define MICROPY_HW_MCU_NAME "MIMXRT1062DVJ6A" -#define BOARD_FLASH_SIZE (8 * 1024 * 1024) - // Teensy 4.1 has 1 board LED #define MICROPY_HW_LED1_PIN (pin_GPIO_B0_03) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) -#define BOARD_FLASH_CONFIG_HEADER_H "teensy41_flexspi_nor_config.h" -#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_nor_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) @@ -39,10 +35,10 @@ { IOMUXC_GPIO_B0_02_LPSPI4_SDO }, { IOMUXC_GPIO_B0_01_LPSPI4_SDI }, #define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \ - kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } + kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } #define DMA_REQ_SRC_TX { 0, kDmaRequestMuxLPSPI1Tx, kDmaRequestMuxLPSPI2Tx, \ - kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } + kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } // Define mapping hardware I2C # to logical I2C # // SDA/SCL HW-I2C Logical I2C @@ -63,9 +59,9 @@ { \ .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ .clk = { GPIO_SD_B0_01_USDHC1_CLK }, \ - .cd_b = { USDHC_DUMMY_PIN },\ - .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 },\ - .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 },\ - .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 },\ - .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 },\ + .cd_b = { USDHC_DUMMY_PIN }, \ + .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 }, \ + .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 }, \ + .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 }, \ + .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 }, \ } diff --git a/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk b/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk index bd70fd0925..9a29a9b75d 100755 --- a/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk +++ b/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk @@ -3,9 +3,9 @@ MCU_VARIANT = MIMXRT1062DVJ6A MICROPY_FLOAT_IMPL = double MICROPY_PY_MACHINE_SDCARD = 1 +BOARD_FLASH_TYPE ?= qspi_nor +BOARD_FLASH_SIZE ?= 0x800000 # 8MB +BOARD_FLASH_RESERVED ?= 0x1000 # 4KB deploy: $(BUILD)/firmware.hex teensy_loader_cli --mcu=imxrt1062 -v -w $< - -SRC_C += \ - hal/flexspi_nor_flash.c diff --git a/ports/mimxrt/boards/TEENSY41/qspi_nor_flash_config.c b/ports/mimxrt/boards/TEENSY41/qspi_nor_flash_config.c new file mode 100644 index 0000000000..71d871b751 --- /dev/null +++ b/ports/mimxrt/boards/TEENSY41/qspi_nor_flash_config.c @@ -0,0 +1,144 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.c + +#include BOARD_FLASH_CONFIG_HEADER_H + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + + .busyOffset = FLASH_BUSY_STATUS_OFFSET, // Status bit 0 indicates busy. + .busyBitPolarity = FLASH_BUSY_STATUS_POL, // Busy when the bit is 1. + + .deviceModeCfgEnable = 1u, + .deviceModeType = kDeviceConfigCmdType_QuadEnable, + .deviceModeSeq = { + .seqId = 4u, + .seqNum = 1u, + }, + .deviceModeArg = 0x0200, + .configCmdEnable = 1u, + .configModeType[0] = kDeviceConfigCmdType_Generic, + .configCmdSeqs[0] = { + .seqId = 2u, + .seqNum = 1u, + }, + .deviceType = kFlexSpiDeviceType_SerialNOR, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_60MHz, + .sflashA1Size = BOARD_FLASH_SIZE, + .lookupTable = + { + // 0 Read LUTs 0 -> 0 + 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), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .blockSize = 0x00010000, + .isUniformBlockSize = false, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/TEENSY41/teensy41_flexspi_nor_config.h b/ports/mimxrt/boards/TEENSY41/teensy41_flexspi_nor_config.h deleted file mode 100755 index 445a0baccc..0000000000 --- a/ports/mimxrt/boards/TEENSY41/teensy41_flexspi_nor_config.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.h - -#ifndef __TEENSY40_FLEXSPI_NOR_CONFIG__ -#define __TEENSY40_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_common.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related definitions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_ERASE 5 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -//!@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_120MHz = 7, - kFlexSpiSerialClk_133MHz = 8, - kFlexSpiSerialClk_166MHz = 9, -} flexspi_serial_clk_freq_t; - -//!@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, //!< Clock configure for SDR mode - kFlexSpiClk_DDR, //!< Clock configurat for DDR mode -}; - -//!@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -//!@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. -}; - -//!@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -//!@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -//!@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; //!< Sequence Number, valid number: 1-16 - uint8_t seqId; //!< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -//!@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, //!< Reset device command -}; - -//!@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - //! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - //! Generic configuration, etc. - uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - //! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - //! sequence number, [31:16] Reserved - uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - //! details - uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - //! Chapter for more details - uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - //! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI - uint32_t pageSize; //!< Page size of Serial NOR - uint32_t sectorSize; //!< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command - uint8_t isUniformBlockSize; //!< Sector/Block size is the same - uint8_t reserved0[2]; //!< Reserved for future use - uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; //!< Block size - uint32_t reserve2[11]; //!< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/make-flexram-config.py b/ports/mimxrt/boards/make-flexram-config.py new file mode 100644 index 0000000000..0a667ff5b7 --- /dev/null +++ b/ports/mimxrt/boards/make-flexram-config.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python3 +# +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2021 Philipp Ebensberger +# +# 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. + +"""Evaluate FlexRAM configuration and generate startup code.""" + +import re +import argparse + +# Regex for linker script configuration +ocram_regex = r"^\s*ocrm_size\s*=\s*(?P.*);" +dtcm_regex = r"^\s*dtcm_size\s*=\s*(?P.*);" +itcm_regex = r"^\s*itcm_size\s*=\s*(?P.*);" + +# Regex for GPR register base define in NXL hal +gpr_base_regex = r"^.*IOMUXC_GPR_BASE\s*\((?P\w*)u\)" + +# Regex for FlexRAM parameters in NXP HAL +fsl_ram_bank_size_regex = r"^.*FSL_FEATURE_FLEXRAM_INTERNAL_RAM_BANK_SIZE\s*\((?P\w*)\)" +fsl_bank_nbr_regex = ( + r"^.*FSL_FEATURE_FLEXRAM_INTERNAL_RAM_TOTAL_BANK_NUMBERS\s*\((?P\w*)\)" +) + + +""" +According to AN12077: + The minimum configuration of OCRAM is 64 KB. This is required + due to ROM code requires at least 64 KB of RAM for its execution. + + 2.1.1.1. Static configuration - Page 4 +""" +ocram_min_size = 0x00010000 # 64 KB + +# Value parser +def mimxrt_default_parser(defines_file, features_file, ld_script): + with open(ld_script, "r") as input_file: + input_str = input_file.read() + # + ocram_match = re.search(ocram_regex, input_str, re.MULTILINE) + dtcm_match = re.search(dtcm_regex, input_str, re.MULTILINE) + itcm_match = re.search(itcm_regex, input_str, re.MULTILINE) + + with open(defines_file, "r") as input_file: + input_str = input_file.read() + mcu_define_file_match = re.search(gpr_base_regex, input_str, re.MULTILINE) + + with open(features_file, "r") as input_file: + input_str = input_file.read() + fsl_ram_bank_size_match = re.search(fsl_ram_bank_size_regex, input_str, re.MULTILINE) + fsl_bank_nbr_match = re.search(fsl_bank_nbr_regex, input_str, re.MULTILINE) + # + extract = { + "ocram_size": int(ocram_match.group("size"), 16), + "dtcm_size": int(dtcm_match.group("size"), 16), + "itcm_size": int(itcm_match.group("size"), 16), + "gpr_base_addr": int(mcu_define_file_match.group("base_addr"), 16), + "fsl_ram_bank_size": int(fsl_ram_bank_size_match.group("size")), + "fsl_bank_nbr": int(fsl_bank_nbr_match.group("number")), + } + # Evaluate configuration + if extract["ocram_size"] < ocram_min_size: + raise ValueError("OCRAM size must be at least {:08X}!".format(ocram_min_size)) + + if (extract["ocram_size"] % extract["fsl_ram_bank_size"]) != 0: + raise ValueError("Configuration invalid!") + + # Check if DTCM and ITCM size is either multiple of 32k or 4k,8k or 16k + if extract["dtcm_size"] != 0x0: + if extract["dtcm_size"] % extract["fsl_ram_bank_size"] != 0: + if extract["dtcm_size"] not in (0x00000000, 0x00001000, 0x00002000, 0x00004000): + raise ValueError("Configuration invalid!") + + if extract["itcm_size"] != 0x0: + if extract["itcm_size"] % extract["fsl_ram_bank_size"] != 0: + if extract["itcm_size"] not in (0x00000000, 0x00001000, 0x00002000, 0x00004000): + raise ValueError("Configuration invalid!") + # + return extract + + +# Code generators +def mimxrt_default_gen_code(extract_dict): + flexram_bank_cfg = "0b" + avail_flexram = extract_dict["fsl_ram_bank_size"] * extract_dict["fsl_bank_nbr"] + + if ( + extract_dict["ocram_size"] + extract_dict["dtcm_size"] + extract_dict["itcm_size"] + ) > avail_flexram: + raise ValueError("Configuration exceeds available FlexRAM!") + + bit_patterns = ( + (extract_dict["ocram_size"], "01"), + (extract_dict["dtcm_size"], "10"), + (extract_dict["itcm_size"], "11"), + ) + + for size, pattern in bit_patterns: + for _ in range(0, size, extract_dict["fsl_ram_bank_size"]): + flexram_bank_cfg += pattern + + # Generate GPR Register config + print(".equ __iomux_gpr14_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x38)) + print(".equ __iomux_gpr16_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x40)) + print(".equ __iomux_gpr17_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x44)) + print( + ".equ __iomux_gpr17_value, 0x{:08X} /* {}k OCRAM, {}k DTCM, {}k ITCM */".format( + int(flexram_bank_cfg, 2), + extract_dict["ocram_size"] // 1024, + extract_dict["dtcm_size"] // 1024, + extract_dict["itcm_size"] // 1024, + ) + ) + + +def mimxrt_106x_gen_code(extract_dict): + flexram_bank_cfg = "0b" + avail_flexram = extract_dict["fsl_ram_bank_size"] * extract_dict["fsl_bank_nbr"] + flexram_configurable_ocram = ( + extract_dict["ocram_size"] % 524288 + ) # 512kB OCRAM are not part of FlexRAM configurable memory + + if ( + flexram_configurable_ocram + extract_dict["dtcm_size"] + extract_dict["itcm_size"] + ) > avail_flexram: + raise ValueError("Configuration exceeds available FlexRAM!") + + for size, pattern in ( + (flexram_configurable_ocram, "01"), + (extract_dict["dtcm_size"], "10"), + (extract_dict["itcm_size"], "11"), + ): + for _ in range(0, size, extract_dict["fsl_ram_bank_size"]): + flexram_bank_cfg += pattern + + # Generate GPR Register config + print(".equ __iomux_gpr14_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x38)) + print(".equ __iomux_gpr16_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x40)) + print(".equ __iomux_gpr17_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x44)) + print( + ".equ __iomux_gpr17_value, 0x{:08X} /* {}k OCRAM (512k OCRAM, {}k from FlexRAM), {}k DTCM, {}k ITCM */".format( + int(flexram_bank_cfg, 2), + extract_dict["ocram_size"] // 1024, + flexram_configurable_ocram // 1024, + extract_dict["dtcm_size"] // 1024, + extract_dict["itcm_size"] // 1024, + ) + ) + + +def main(defines_file, features_file, ld_script, controller): + dispatcher = { + "MIMXRT1011": (mimxrt_default_parser, mimxrt_default_gen_code), + "MIMXRT1021": (mimxrt_default_parser, mimxrt_default_gen_code), + "MIMXRT1052": (mimxrt_default_parser, mimxrt_default_gen_code), + "MIMXRT1062": (mimxrt_default_parser, mimxrt_106x_gen_code), + "MIMXRT1064": (mimxrt_default_parser, mimxrt_106x_gen_code), + } + + extractor, code_generator = dispatcher[controller] + + extract_dict = extractor(defines_file, features_file, ld_script) + code_generator(extract_dict) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + prog="make-flexram-ld.py", + usage="%(prog)s [options] [command]", + description="Evaluate FlexRAM configuration and generate startup code.", + ) + parser.add_argument( + "-d", + "--defines_file", + dest="defines_file", + help="Path to MCU defines file", + default="../../../lib/nxp_driver/sdk/devices/MIMXRT1021/MIMXRT1021.h", + ) + parser.add_argument( + "-f", + "--features_file", + dest="features_file", + help="Path to MCU features file", + default="../../../lib/nxp_driver/sdk/devices/MIMXRT1021/MIMXRT1021_features.h", + ) + parser.add_argument( + "-l", + "--ld_file", + dest="linker_file", + help="Path to the aggregated linker-script", + default="MIMXRT1021.ld", + ) + parser.add_argument( + "-c", "--controller", dest="controller", help="Controller name", default="MIMXRT1021" + ) + # + args = parser.parse_args() + main(args.defines_file, args.features_file, args.linker_file, args.controller) diff --git a/ports/mimxrt/hal/board.h b/ports/mimxrt/hal/board.h new file mode 100644 index 0000000000..ce5e047976 --- /dev/null +++ b/ports/mimxrt/hal/board.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Philipp Ebensberger + * + * 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_MIMXRT_BOARD_H +#define MICROPY_INCLUDED_MIMXRT_BOARD_H + +#include "clock_config.h" +#include "fsl_common.h" + +#endif /* MICROPY_INCLUDED_MIMXRT_BOARD_H */ diff --git a/ports/mimxrt/hal/flexspi_hyper_flash.c b/ports/mimxrt/hal/flexspi_hyper_flash.c index fb71d4d941..c7b41658a4 100644 --- a/ports/mimxrt/hal/flexspi_hyper_flash.c +++ b/ports/mimxrt/hal/flexspi_hyper_flash.c @@ -16,14 +16,15 @@ __attribute__((always_inline)) static inline void clock_set_div(clock_div_t divider, uint32_t value) { uint32_t busyShift; - busyShift = CCM_TUPLE_BUSY_SHIFT(divider); + busyShift = CCM_TUPLE_BUSY_SHIFT(divider); CCM_TUPLE_REG(CCM, divider) = (CCM_TUPLE_REG(CCM, divider) & (~CCM_TUPLE_MASK(divider))) | - (((uint32_t)((value) << CCM_TUPLE_SHIFT(divider))) & CCM_TUPLE_MASK(divider)); + (((uint32_t)((value) << CCM_TUPLE_SHIFT(divider))) & CCM_TUPLE_MASK(divider)); /* Clock switch need Handshake? */ if (CCM_NO_BUSY_WAIT != busyShift) { /* Wait until CCM internal handshake finish. */ - while (CCM->CDHIPR & (1U << busyShift)) {} + while (CCM->CDHIPR & (1U << busyShift)) { + } } } @@ -32,7 +33,7 @@ __attribute__((always_inline)) static inline void clock_control_gate(clock_ip_na uint32_t shift = ((uint32_t)name) & 0x1FU; volatile uint32_t *reg; - reg = ((volatile uint32_t *)&CCM->CCGR0) + index; + reg = ((volatile uint32_t *)&CCM->CCGR0) + index; *reg = ((*reg) & ~(3U << shift)) | (((uint32_t)value) << shift); } @@ -44,9 +45,9 @@ __attribute__((always_inline)) static inline void clock_disable_clock(clock_ip_n clock_control_gate(name, kCLOCK_ClockNotNeeded); } -#define DIV_PAGE_PGM 4 -#define DIV_ERASE_PGM 4 -#define DIV_READ 0 +#define DIV_PAGE_PGM 4 +#define DIV_ERASE_PGM 4 +#define DIV_READ 0 static void SetFlexSPIDiv(uint32_t div) __attribute__((section(".ram_functions"))); static void SetFlexSPIDiv(uint32_t div) { @@ -54,7 +55,7 @@ static void SetFlexSPIDiv(uint32_t div) { clock_disable_clock(kCLOCK_FlexSpi); clock_set_div(kCLOCK_FlexspiDiv, div); /* flexspi clock 332M, DDR mode, internal clock 166M. */ clock_enable_clock(kCLOCK_FlexSpi); - FLEXSPI_Enable(FLEXSPI, true); + FLEXSPI_Enable(FLEXSPI, true); } status_t flexspi_nor_hyperbus_read(FLEXSPI_Type *base, uint32_t addr, uint32_t *buffer, uint32_t bytes) __attribute__((section(".ram_functions"))); @@ -63,13 +64,13 @@ status_t flexspi_nor_hyperbus_read(FLEXSPI_Type *base, uint32_t addr, uint32_t * status_t status; flashXfer.deviceAddress = addr * 2; - flashXfer.port = kFLEXSPI_PortA1; - flashXfer.cmdType = kFLEXSPI_Read; - flashXfer.SeqNumber = 1; - flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA; - flashXfer.data = buffer; - flashXfer.dataSize = bytes; - status = FLEXSPI_TransferBlocking(base, &flashXfer); + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Read; + flashXfer.SeqNumber = 1; + flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA; + flashXfer.data = buffer; + flashXfer.dataSize = bytes; + status = FLEXSPI_TransferBlocking(base, &flashXfer); return status; } @@ -80,13 +81,13 @@ status_t flexspi_nor_hyperbus_write(FLEXSPI_Type *base, uint32_t addr, uint32_t status_t status; flashXfer.deviceAddress = addr * 2; - flashXfer.port = kFLEXSPI_PortA1; - flashXfer.cmdType = kFLEXSPI_Write; - flashXfer.SeqNumber = 1; - flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA; - flashXfer.data = buffer; - flashXfer.dataSize = bytes; - status = FLEXSPI_TransferBlocking(base, &flashXfer); + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Write; + flashXfer.SeqNumber = 1; + flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA; + flashXfer.data = buffer; + flashXfer.dataSize = bytes; + status = FLEXSPI_TransferBlocking(base, &flashXfer); return status; } @@ -98,10 +99,10 @@ status_t flexspi_nor_write_enable(FLEXSPI_Type *base, uint32_t baseAddr) { /* Write enable */ flashXfer.deviceAddress = baseAddr; - flashXfer.port = kFLEXSPI_PortA1; - flashXfer.cmdType = kFLEXSPI_Command; - flashXfer.SeqNumber = 2; - flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE; + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Command; + flashXfer.SeqNumber = 2; + flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE; status = FLEXSPI_TransferBlocking(base, &flashXfer); @@ -117,12 +118,12 @@ status_t flexspi_nor_wait_bus_busy(FLEXSPI_Type *base) { flexspi_transfer_t flashXfer; flashXfer.deviceAddress = 0; - flashXfer.port = kFLEXSPI_PortA1; - flashXfer.cmdType = kFLEXSPI_Read; - flashXfer.SeqNumber = 2; - flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS; - flashXfer.data = &readValue; - flashXfer.dataSize = 2; + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Read; + flashXfer.SeqNumber = 2; + flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS; + flashXfer.data = &readValue; + flashXfer.dataSize = 2; do { status = FLEXSPI_TransferBlocking(base, &flashXfer); @@ -159,11 +160,11 @@ status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address) { } flashXfer.deviceAddress = address; - flashXfer.port = kFLEXSPI_PortA1; - flashXfer.cmdType = kFLEXSPI_Command; - flashXfer.SeqNumber = 4; - flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR; - status = FLEXSPI_TransferBlocking(base, &flashXfer); + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Command; + flashXfer.SeqNumber = 4; + flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR; + status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { return status; @@ -174,13 +175,13 @@ status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address) { return status; } -status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src, uint32_t size ) __attribute__((section(".ram_functions"))); +status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src, uint32_t size) __attribute__((section(".ram_functions"))); status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src, uint32_t size) { status_t status; flexspi_transfer_t flashXfer; /* Speed down flexspi clock */ - SetFlexSPIDiv(DIV_PAGE_PGM); + SetFlexSPIDiv(DIV_PAGE_PGM); /* Write enable */ status = flexspi_nor_write_enable(base, address); @@ -191,13 +192,13 @@ status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, co /* Prepare page program command */ flashXfer.deviceAddress = address; - flashXfer.port = kFLEXSPI_PortA1; - flashXfer.cmdType = kFLEXSPI_Write; - flashXfer.SeqNumber = 2; - flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM; - flashXfer.data = (uint32_t *)src; - flashXfer.dataSize = size; - status = FLEXSPI_TransferBlocking(base, &flashXfer); + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Write; + flashXfer.SeqNumber = 2; + flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM; + flashXfer.data = (uint32_t *)src; + flashXfer.dataSize = size; + status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { return status; @@ -205,7 +206,7 @@ status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, co status = flexspi_nor_wait_bus_busy(base); - SetFlexSPIDiv(DIV_READ); + SetFlexSPIDiv(DIV_READ); return status; } @@ -219,7 +220,7 @@ status_t flexspi_nor_hyperflash_cfi(FLEXSPI_Type *base) { status_t status; uint32_t buffer[2]; uint8_t data[4] = {0x00, 0x98}; - status = flexspi_nor_hyperbus_write(base, 0x555, (uint32_t *)data, 2); + status = flexspi_nor_hyperbus_write(base, 0x555, (uint32_t *)data, 2); if (status != kStatus_Success) { return status; } @@ -238,7 +239,7 @@ status_t flexspi_nor_hyperflash_cfi(FLEXSPI_Type *base) { } // ASO Exit 0xF000 data[1] = 0xF0; - status = flexspi_nor_hyperbus_write(base, 0x0, (uint32_t *)data, 2); + status = flexspi_nor_hyperbus_write(base, 0x0, (uint32_t *)data, 2); if (status != kStatus_Success) { return status; } diff --git a/ports/mimxrt/hal/flexspi_hyper_flash.h b/ports/mimxrt/hal/flexspi_hyper_flash.h index bba76c1324..d51ca3073d 100644 --- a/ports/mimxrt/hal/flexspi_hyper_flash.h +++ b/ports/mimxrt/hal/flexspi_hyper_flash.h @@ -26,15 +26,14 @@ #ifndef MICROPY_INCLUDED_MIMXRT_HAL_FLEXSPI_HYPER_FLASH_H #define MICROPY_INCLUDED_MIMXRT_HAL_FLEXSPI_HYPER_FLASH_H -#include "mpconfigboard.h" #include "fsl_flexspi.h" +#include "mpconfigboard.h" #include BOARD_FLASH_CONFIG_HEADER_H // Defined in boards flash_config.c extern flexspi_nor_config_t qspiflash_config; status_t flexspi_nor_hyperflash_cfi(FLEXSPI_Type *base); -void flexspi_hyper_flash_init(void); void flexspi_nor_update_lut(void); status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address); status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src, uint32_t size); diff --git a/ports/mimxrt/hal/flexspi_nor_flash.c b/ports/mimxrt/hal/flexspi_nor_flash.c index a70d234d6e..8c04150d12 100644 --- a/ports/mimxrt/hal/flexspi_nor_flash.c +++ b/ports/mimxrt/hal/flexspi_nor_flash.c @@ -41,8 +41,7 @@ void flexspi_nor_reset(FLEXSPI_Type *base) __attribute__((section(".ram_function void flexspi_nor_reset(FLEXSPI_Type *base) { // Using content of FLEXSPI_SoftwareReset directly to prevent issues when compiler does not inline function base->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK; - while (base->MCR0 & FLEXSPI_MCR0_SWRESET_MASK) - { + while (base->MCR0 & FLEXSPI_MCR0_SWRESET_MASK) { } } @@ -63,7 +62,7 @@ status_t flexspi_nor_write_enable(FLEXSPI_Type *base, uint32_t baseAddr) { return status; } -status_t flexspi_nor_wait_bus_busy(FLEXSPI_Type *base) __attribute__((section(".ram_functions"))) ; +status_t flexspi_nor_wait_bus_busy(FLEXSPI_Type *base) __attribute__((section(".ram_functions"))); status_t flexspi_nor_wait_bus_busy(FLEXSPI_Type *base) { /* Wait status ready. */ bool isBusy; @@ -103,7 +102,7 @@ status_t flexspi_nor_wait_bus_busy(FLEXSPI_Type *base) { return status; } -status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base) __attribute__((section(".ram_functions"))) ; +status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base) __attribute__((section(".ram_functions"))); status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base) { flexspi_transfer_t flashXfer; status_t status; @@ -135,7 +134,7 @@ status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base) { return status; } -status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address) __attribute__((section(".ram_functions"))) ; +status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address) __attribute__((section(".ram_functions"))); status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address) { status_t status; flexspi_transfer_t flashXfer; @@ -166,7 +165,7 @@ status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address) { return status; } -status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src, uint32_t size) __attribute__((section(".ram_functions"))) ; +status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src, uint32_t size) __attribute__((section(".ram_functions"))); status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src, uint32_t size) { status_t status; flexspi_transfer_t flashXfer; @@ -184,7 +183,7 @@ status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, co flashXfer.cmdType = kFLEXSPI_Write; flashXfer.SeqNumber = 1; flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD; - flashXfer.data = (uint32_t *) src; + flashXfer.data = (uint32_t *)src; flashXfer.dataSize = size; status = FLEXSPI_TransferBlocking(base, &flashXfer); @@ -199,7 +198,7 @@ status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, co return status; } -status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId) __attribute__((section(".ram_functions"))) ; +status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId) __attribute__((section(".ram_functions"))); status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId) { uint32_t temp; flexspi_transfer_t flashXfer; diff --git a/ports/mimxrt/hal/flexspi_nor_flash.h b/ports/mimxrt/hal/flexspi_nor_flash.h index c34df74168..f8c31488a9 100644 --- a/ports/mimxrt/hal/flexspi_nor_flash.h +++ b/ports/mimxrt/hal/flexspi_nor_flash.h @@ -34,7 +34,6 @@ extern flexspi_nor_config_t qspiflash_config; status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId); -status_t flexspi_nor_init(void); void flexspi_nor_update_lut(void); status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address); status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src, uint32_t size); diff --git a/ports/mimxrt/hal/peripherals.h b/ports/mimxrt/hal/peripherals.h new file mode 100644 index 0000000000..81036b0a2c --- /dev/null +++ b/ports/mimxrt/hal/peripherals.h @@ -0,0 +1 @@ +// Empty file, necessary for compilation with NXP MCU SDK diff --git a/ports/mimxrt/hal/pin_mux.h b/ports/mimxrt/hal/pin_mux.h new file mode 100644 index 0000000000..81036b0a2c --- /dev/null +++ b/ports/mimxrt/hal/pin_mux.h @@ -0,0 +1 @@ +// Empty file, necessary for compilation with NXP MCU SDK diff --git a/ports/mimxrt/hal/resethandler_MIMXRT10xx.S b/ports/mimxrt/hal/resethandler_MIMXRT10xx.S new file mode 100644 index 0000000000..8fe0611033 --- /dev/null +++ b/ports/mimxrt/hal/resethandler_MIMXRT10xx.S @@ -0,0 +1,175 @@ +/* ------------------------------------------------------------------------- */ +/* */ +/* Copyright 1997-2016 Freescale Semiconductor, Inc. */ +/* Copyright 2016-2019 NXP */ +/* All rights reserved. */ +/* */ +/* SPDX-License-Identifier: BSD-3-Clause */ +/*****************************************************************************/ +/* Version: GCC for ARM Embedded Processors */ +/*****************************************************************************/ + .syntax unified + .arch armv7-m + +#include"flexram_config.s" + + +/* Reset Handler */ + + .thumb_func + .align 2 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + cpsid i /* Mask interrupts */ + .equ VTOR, 0xE000ED08 + ldr r0, =VTOR + ldr r1, =__isr_vector + str r1, [r0] + ldr r2, [r1] + msr msp, r2 + +/* Reconfigure the memory map, which must match the setting of the linker script */ + dsb + isb + ldr r0, =__iomux_gpr17_adr /* load IOMUXC_GPR17 register address to R0 */ + ldr r1, =__iomux_gpr17_value /* move FlexRAM configuration value to R1 */ + str r1,[r0] /* store FLEXRAM configuration value to IOMUXC_GPR17 */ + dsb + isb + ldr r0, =__iomux_gpr16_adr /* load IOMUXC_GPR16 register address to R0 */ + ldr r1,[r0] /* load IOMUXC_GPR16 register value to R1 */ + orr r1, r1, #4 /* set corresponding FLEXRAM_BANK_CFG_SEL bit */ + str r1,[r0] /* store the value to IOMUXC_GPR16 (FLEXRAM_BANK_CFG_SEL = '1') */ + dsb + isb + +#ifndef __NO_SYSTEM_INIT + ldr r0,=SystemInit + blx r0 +#endif +/* Loop to copy data from read only memory to RAM. The ranges + * of copy from/to are specified by following symbols evaluated in + * linker script. + * __etext: End of code section, i.e., begin of data sections to copy from. + * __data_start__/__data_end__: RAM address range that data should be + * __noncachedata_start__/__noncachedata_end__ : none cachable region + * __ram_function_start__/__ram_function_end__ : ramfunction region + * copied to. Both must be aligned to 4 bytes boundary. */ + + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__data_end__ + +#ifdef __PERFORMANCE_IMPLEMENTATION +/* Here are two copies of loop implementations. First one favors performance + * and the second one favors code size. Default uses the second one. + * Define macro "__PERFORMANCE_IMPLEMENTATION" in project to use the first one */ + subs r3, r2 + ble .LC1 +.LC0: + subs r3, #4 + ldr r0, [r1, r3] + str r0, [r2, r3] + bgt .LC0 +.LC1: +#else /* code size implemenation */ +.LC0: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .LC0 +#endif +#ifdef __STARTUP_INITIALIZE_RAMFUNCTION + ldr r2, =__ram_function_start__ + ldr r3, =__ram_function_end__ +#ifdef __PERFORMANCE_IMPLEMENTATION +/* Here are two copies of loop implementations. First one favors performance + * and the second one favors code size. Default uses the second one. + * Define macro "__PERFORMANCE_IMPLEMENTATION" in project to use the first one */ + subs r3, r2 + ble .LC_ramfunc_copy_end +.LC_ramfunc_copy_start: + subs r3, #4 + ldr r0, [r1, r3] + str r0, [r2, r3] + bgt .LC_ramfunc_copy_start +.LC_ramfunc_copy_end: +#else /* code size implemenation */ +.LC_ramfunc_copy_start: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .LC_ramfunc_copy_start +#endif +#endif /* __STARTUP_INITIALIZE_RAMFUNCTION */ +#ifdef __STARTUP_INITIALIZE_NONCACHEDATA + ldr r2, =__noncachedata_start__ + ldr r3, =__noncachedata_init_end__ +#ifdef __PERFORMANCE_IMPLEMENTATION +/* Here are two copies of loop implementations. First one favors performance + * and the second one favors code size. Default uses the second one. + * Define macro "__PERFORMANCE_IMPLEMENTATION" in project to use the first one */ + subs r3, r2 + ble .LC3 +.LC2: + subs r3, #4 + ldr r0, [r1, r3] + str r0, [r2, r3] + bgt .LC2 +.LC3: +#else /* code size implemenation */ +.LC2: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .LC2 +#endif +/* zero inited ncache section initialization */ + ldr r3, =__noncachedata_end__ + movs r0,0 +.LC4: + cmp r2,r3 + itt lt + strlt r0,[r2],#4 + blt .LC4 +#endif /* __STARTUP_INITIALIZE_NONCACHEDATA */ + +#ifdef __STARTUP_CLEAR_BSS +/* This part of work usually is done in C library startup code. Otherwise, + * define this macro to enable it in this startup. + * + * Loop to zero out BSS section, which uses following symbols + * in linker script: + * __bss_start__: start of BSS section. Must align to 4 + * __bss_end__: end of BSS section. Must align to 4 + */ + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 +.LC5: + cmp r1, r2 + itt lt + strlt r0, [r1], #4 + blt .LC5 +#endif /* __STARTUP_CLEAR_BSS */ + + cpsie i /* Unmask interrupts */ +#ifndef __START +#define __START _start +#endif +#ifndef __ATOLLIC__ + ldr r0,=__START + blx r0 +#else + ldr r0,=__libc_init_array + blx r0 + ldr r0,=main + bx r0 +#endif + .pool + .size Reset_Handler, . - Reset_Handler diff --git a/tools/autobuild/build-mimxrt-latest.sh b/tools/autobuild/build-mimxrt-latest.sh index 4db65c0916..f5bc1397a5 100755 --- a/tools/autobuild/build-mimxrt-latest.sh +++ b/tools/autobuild/build-mimxrt-latest.sh @@ -34,4 +34,4 @@ fi do_build TEENSY40 TEENSY40 hex do_build TEENSY41 TEENSY41 hex do_build MIMXRT1020_EVK MIMXRT1020_EVK bin -do_build MIMXRT1050_EVKB MIMXRT1050_EVKB bin +do_build MIMXRT1050_EVK MIMXRT1050_EVK bin diff --git a/tools/codeformat.py b/tools/codeformat.py index a5d64739aa..ab12745fa5 100755 --- a/tools/codeformat.py +++ b/tools/codeformat.py @@ -52,6 +52,7 @@ PATHS = [ "examples/**/*.py", "extmod/**/*.py", "ports/**/*.py", + "ports/mimxrt/**/*.[ch]", "py/**/*.py", "tools/**/*.py", "tests/**/*.py", From 7aab0dc5d81506de2020b7305cf2ee51894d29eb Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 22 Aug 2021 17:26:13 +0200 Subject: [PATCH 027/335] extmod: Move modnetwork and modusocket from stm32 to extmod. So they can be used by other ports. --- {ports/stm32 => extmod}/modnetwork.c | 35 ------------ {ports/stm32 => extmod}/modnetwork.h | 0 {ports/stm32 => extmod}/modusocket.c | 0 ports/stm32/Makefile | 7 +-- ports/stm32/eth.c | 2 +- ports/stm32/main.c | 2 +- ports/stm32/modnwcc3k.c | 2 +- ports/stm32/modnwwiznet5k.c | 2 +- ports/stm32/mpnetworkport.c | 81 ++++++++++++++++++++++++++++ ports/stm32/network_lan.c | 2 +- ports/stm32/network_wiznet5k.c | 2 +- 11 files changed, 91 insertions(+), 44 deletions(-) rename {ports/stm32 => extmod}/modnetwork.c (88%) rename {ports/stm32 => extmod}/modnetwork.h (100%) rename {ports/stm32 => extmod}/modusocket.c (100%) create mode 100644 ports/stm32/mpnetworkport.c diff --git a/ports/stm32/modnetwork.c b/extmod/modnetwork.c similarity index 88% rename from ports/stm32/modnetwork.c rename to extmod/modnetwork.c index 06c4eb05db..600f1346bc 100644 --- a/ports/stm32/modnetwork.c +++ b/extmod/modnetwork.c @@ -39,7 +39,6 @@ #if MICROPY_PY_NETWORK #if MICROPY_PY_LWIP - #include "lwip/netif.h" #include "lwip/timeouts.h" #include "lwip/dns.h" @@ -47,40 +46,6 @@ #include "lwip/apps/mdns.h" #include "extmod/network_cyw43.h" #include "drivers/cyw43/cyw43.h" - -// Poll lwIP every 128ms -#define LWIP_TICK(tick) (((tick) & ~(SYSTICK_DISPATCH_NUM_SLOTS - 1) & 0x7f) == 0) - -u32_t sys_now(void) { - return mp_hal_ticks_ms(); -} - -STATIC void pyb_lwip_poll(void) { - #if MICROPY_PY_WIZNET5K - // Poll the NIC for incoming data - wiznet5k_poll(); - #endif - - // Run the lwIP internal updates - sys_check_timeouts(); -} - -void mod_network_lwip_poll_wrapper(uint32_t ticks_ms) { - if (LWIP_TICK(ticks_ms)) { - pendsv_schedule_dispatch(PENDSV_DISPATCH_LWIP, pyb_lwip_poll); - } - - #if MICROPY_PY_NETWORK_CYW43 - if (cyw43_poll) { - if (cyw43_sleep != 0) { - if (--cyw43_sleep == 0) { - pendsv_schedule_dispatch(PENDSV_DISPATCH_CYW43, cyw43_poll); - } - } - } - #endif -} - #endif /// \module network - network configuration diff --git a/ports/stm32/modnetwork.h b/extmod/modnetwork.h similarity index 100% rename from ports/stm32/modnetwork.h rename to extmod/modnetwork.h diff --git a/ports/stm32/modusocket.c b/extmod/modusocket.c similarity index 100% rename from ports/stm32/modusocket.c rename to extmod/modusocket.c diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index a6804ee616..d0a4d69a6f 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -267,7 +267,9 @@ endif EXTMOD_SRC_C += $(addprefix extmod/,\ modonewire.c \ - ) + modnetwork.c \ + modusocket.c \ + ) DRIVERS_SRC_C += $(addprefix drivers/,\ bus/softspi.c \ @@ -286,6 +288,7 @@ SRC_C += \ usbd_hid_interface.c \ usbd_msc_interface.c \ mphalport.c \ + mpnetworkport.c \ mpthreadport.c \ irq.c \ pendsv.c \ @@ -329,9 +332,7 @@ SRC_C += \ modstm.c \ moduos.c \ modutime.c \ - modusocket.c \ network_lan.c \ - modnetwork.c \ extint.c \ usrsw.c \ rng.c \ diff --git a/ports/stm32/eth.c b/ports/stm32/eth.c index f174b6af0d..be418235e1 100644 --- a/ports/stm32/eth.c +++ b/ports/stm32/eth.c @@ -29,7 +29,7 @@ #include "py/mperrno.h" #include "shared/netutils/netutils.h" #include "pin_static_af.h" -#include "modnetwork.h" +#include "extmod/modnetwork.h" #include "mpu.h" #include "eth.h" diff --git a/ports/stm32/main.c b/ports/stm32/main.c index ccc8fd1ae7..e506cc5713 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -39,6 +39,7 @@ #include "lib/littlefs/lfs1_util.h" #include "lib/littlefs/lfs2.h" #include "lib/littlefs/lfs2_util.h" +#include "extmod/modnetwork.h" #include "extmod/vfs.h" #include "extmod/vfs_fat.h" #include "extmod/vfs_lfs.h" @@ -83,7 +84,6 @@ #include "servo.h" #include "dac.h" #include "can.h" -#include "modnetwork.h" #if MICROPY_PY_THREAD STATIC pyb_thread_t pyb_thread_main; diff --git a/ports/stm32/modnwcc3k.c b/ports/stm32/modnwcc3k.c index 07178b65c7..5dae9d6407 100644 --- a/ports/stm32/modnwcc3k.c +++ b/ports/stm32/modnwcc3k.c @@ -37,7 +37,7 @@ #include "py/mperrno.h" #include "py/mphal.h" #include "shared/netutils/netutils.h" -#include "modnetwork.h" +#include "extmod/modnetwork.h" #include "pin.h" #include "spi.h" diff --git a/ports/stm32/modnwwiznet5k.c b/ports/stm32/modnwwiznet5k.c index 1e18d03ca1..d3c2c516c3 100644 --- a/ports/stm32/modnwwiznet5k.c +++ b/ports/stm32/modnwwiznet5k.c @@ -34,7 +34,7 @@ #include "py/mperrno.h" #include "py/mphal.h" #include "shared/netutils/netutils.h" -#include "modnetwork.h" +#include "extmod/modnetwork.h" #include "pin.h" #include "spi.h" diff --git a/ports/stm32/mpnetworkport.c b/ports/stm32/mpnetworkport.c new file mode 100644 index 0000000000..a5ee15bc67 --- /dev/null +++ b/ports/stm32/mpnetworkport.c @@ -0,0 +1,81 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * + * 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 +#include +#include + +#include "py/objlist.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "shared/netutils/netutils.h" +#include "systick.h" +#include "pendsv.h" +#include "extmod/modnetwork.h" + +#if MICROPY_PY_LWIP +#include "lwip/netif.h" +#include "lwip/timeouts.h" +#include "lwip/dns.h" +#include "lwip/dhcp.h" +#include "lwip/apps/mdns.h" +#include "extmod/network_cyw43.h" +#include "drivers/cyw43/cyw43.h" + +// Poll lwIP every 128ms +#define LWIP_TICK(tick) (((tick) & ~(SYSTICK_DISPATCH_NUM_SLOTS - 1) & 0x7f) == 0) + +u32_t sys_now(void) { + return mp_hal_ticks_ms(); +} + +STATIC void pyb_lwip_poll(void) { + #if MICROPY_PY_WIZNET5K + // Poll the NIC for incoming data + wiznet5k_poll(); + #endif + + // Run the lwIP internal updates + sys_check_timeouts(); +} + +void mod_network_lwip_poll_wrapper(uint32_t ticks_ms) { + if (LWIP_TICK(ticks_ms)) { + pendsv_schedule_dispatch(PENDSV_DISPATCH_LWIP, pyb_lwip_poll); + } + + #if MICROPY_PY_NETWORK_CYW43 + if (cyw43_poll) { + if (cyw43_sleep != 0) { + if (--cyw43_sleep == 0) { + pendsv_schedule_dispatch(PENDSV_DISPATCH_CYW43, cyw43_poll); + } + } + } + #endif +} + +#endif // MICROPY_PY_LWIP diff --git a/ports/stm32/network_lan.c b/ports/stm32/network_lan.c index 6dd9aadb65..f19916a1df 100644 --- a/ports/stm32/network_lan.c +++ b/ports/stm32/network_lan.c @@ -26,7 +26,7 @@ #include "py/runtime.h" #include "py/mphal.h" -#include "modnetwork.h" +#include "extmod/modnetwork.h" #include "eth.h" #if defined(MICROPY_HW_ETH_MDC) diff --git a/ports/stm32/network_wiznet5k.c b/ports/stm32/network_wiznet5k.c index bd4c02cb05..b6f1498eff 100644 --- a/ports/stm32/network_wiznet5k.c +++ b/ports/stm32/network_wiznet5k.c @@ -29,8 +29,8 @@ #include "py/runtime.h" #include "py/mphal.h" +#include "extmod/modnetwork.h" #include "spi.h" -#include "modnetwork.h" #if MICROPY_PY_WIZNET5K && MICROPY_PY_LWIP From d889f672da7d34550eb1613d25d7d51ad8503263 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 22 Aug 2021 17:27:38 +0200 Subject: [PATCH 028/335] extmod/modnetwork: Add STA_IF and AP_IF constants. --- extmod/modnetwork.c | 4 ++++ extmod/modnetwork.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/extmod/modnetwork.c b/extmod/modnetwork.c index 600f1346bc..043d1967a3 100644 --- a/extmod/modnetwork.c +++ b/extmod/modnetwork.c @@ -110,6 +110,10 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { #if MICROPY_PY_NETWORK_CYW43 { MP_ROM_QSTR(MP_QSTR_STA_IF), MP_ROM_INT(CYW43_ITF_STA)}, { MP_ROM_QSTR(MP_QSTR_AP_IF), MP_ROM_INT(CYW43_ITF_AP)}, + #else + // Station/AP mode. + { MP_ROM_QSTR(MP_QSTR_STA_IF), MP_ROM_INT(MOD_NETWORK_STA_IF) }, + { MP_ROM_QSTR(MP_QSTR_AP_IF), MP_ROM_INT(MOD_NETWORK_AP_IF) }, #endif }; diff --git a/extmod/modnetwork.h b/extmod/modnetwork.h index 0b6d0c4a7f..9017625cf0 100644 --- a/extmod/modnetwork.h +++ b/extmod/modnetwork.h @@ -35,6 +35,9 @@ #define MOD_NETWORK_SOCK_DGRAM (2) #define MOD_NETWORK_SOCK_RAW (3) +#define MOD_NETWORK_STA_IF (0) +#define MOD_NETWORK_AP_IF (1) + #if MICROPY_PY_LWIP struct netif; From e7429389a6a6322ebf88c30bf417279dc36ecda1 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 22 Aug 2021 17:29:35 +0200 Subject: [PATCH 029/335] extmod/modnetwork: Add extended socket state. --- extmod/modnetwork.h | 6 ++++++ extmod/modusocket.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/extmod/modnetwork.h b/extmod/modnetwork.h index 9017625cf0..50c8bc4b06 100644 --- a/extmod/modnetwork.h +++ b/extmod/modnetwork.h @@ -85,9 +85,15 @@ typedef struct _mod_network_socket_obj_t { uint8_t domain; uint8_t type; int8_t fileno; + uint8_t bound; } u_param; mp_uint_t u_state; }; + #if MICROPY_PY_USOCKET_EXTENDED_STATE + // Extended socket state for NICs/ports that need it. + int32_t timeout; + void *state; + #endif } mod_network_socket_obj_t; extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; diff --git a/extmod/modusocket.c b/extmod/modusocket.c index c59fc85226..143470a96a 100644 --- a/extmod/modusocket.c +++ b/extmod/modusocket.c @@ -54,6 +54,7 @@ STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t s->u_param.domain = MOD_NETWORK_AF_INET; s->u_param.type = MOD_NETWORK_SOCK_STREAM; s->u_param.fileno = -1; + s->u_param.bound = false; if (n_args >= 1) { s->u_param.domain = mp_obj_get_int(args[0]); if (n_args >= 2) { @@ -64,6 +65,11 @@ STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t } } + #if MICROPY_PY_USOCKET_EXTENDED_STATE + s->timeout = 0; + s->state = NULL; + #endif + return MP_OBJ_FROM_PTR(s); } From c13e25c329ae65c6a7ccbb35b95406a5939bea4e Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 22 Aug 2021 17:57:52 +0200 Subject: [PATCH 030/335] extmod/modusocket: Add read/write stream methods to socket object. Following other socket implementations. --- extmod/modusocket.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/extmod/modusocket.c b/extmod/modusocket.c index 143470a96a..fea81077c5 100644 --- a/extmod/modusocket.c +++ b/extmod/modusocket.c @@ -362,10 +362,41 @@ STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socket_setsockopt_obj) }, { MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socket_settimeout_obj) }, { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, + + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, }; STATIC MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table); +mp_uint_t socket_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->nic == MP_OBJ_NULL) { + return MP_STREAM_ERROR; + } + mp_int_t ret = self->nic_type->recv(self, (byte *)buf, size, errcode); + if (ret < 0) { + ret = MP_STREAM_ERROR; + *errcode = -(*errcode); // expects a positive error code + } + return ret; +} + +mp_uint_t socket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->nic == MP_OBJ_NULL) { + return MP_STREAM_ERROR; + } + mp_int_t ret = self->nic_type->send(self, buf, size, errcode); + if (ret < 0) { + ret = MP_STREAM_ERROR; + *errcode = -(*errcode); // expects a positive error code + } + return ret; +} + mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (request == MP_STREAM_CLOSE) { @@ -386,6 +417,8 @@ mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int * } STATIC const mp_stream_p_t socket_stream_p = { + .read = socket_read, + .write = socket_write, .ioctl = socket_ioctl, .is_text = false, }; From 4dba04a50fea01f6f8fec83d64f958f8d14e285a Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 24 Aug 2021 16:59:32 +0200 Subject: [PATCH 031/335] extmod/modnetwork: Define network interfaces in port config files. So this network implementation becomes more generic. --- extmod/modnetwork.c | 26 +++----------------------- extmod/modnetwork.h | 13 +------------ ports/stm32/mpconfigport.h | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/extmod/modnetwork.c b/extmod/modnetwork.c index 043d1967a3..a6a37ccb7e 100644 --- a/extmod/modnetwork.c +++ b/extmod/modnetwork.c @@ -44,8 +44,6 @@ #include "lwip/dns.h" #include "lwip/dhcp.h" #include "lwip/apps/mdns.h" -#include "extmod/network_cyw43.h" -#include "drivers/cyw43/cyw43.h" #endif /// \module network - network configuration @@ -89,32 +87,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_route_obj, network_route); STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) }, - - #if defined(MICROPY_HW_ETH_MDC) - { MP_ROM_QSTR(MP_QSTR_LAN), MP_ROM_PTR(&network_lan_type) }, - #endif - #if MICROPY_PY_NETWORK_CYW43 - { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mp_network_cyw43_type) }, - #endif - - #if MICROPY_PY_WIZNET5K - { MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) }, - #endif - #if MICROPY_PY_CC3K - { MP_ROM_QSTR(MP_QSTR_CC3K), MP_ROM_PTR(&mod_network_nic_type_cc3k) }, - #endif - { MP_ROM_QSTR(MP_QSTR_route), MP_ROM_PTR(&network_route_obj) }, + // Defined per port in mpconfigport.h + MICROPY_PORT_NETWORK_INTERFACES + // Constants - #if MICROPY_PY_NETWORK_CYW43 - { MP_ROM_QSTR(MP_QSTR_STA_IF), MP_ROM_INT(CYW43_ITF_STA)}, - { MP_ROM_QSTR(MP_QSTR_AP_IF), MP_ROM_INT(CYW43_ITF_AP)}, - #else - // Station/AP mode. { MP_ROM_QSTR(MP_QSTR_STA_IF), MP_ROM_INT(MOD_NETWORK_STA_IF) }, { MP_ROM_QSTR(MP_QSTR_AP_IF), MP_ROM_INT(MOD_NETWORK_AP_IF) }, - #endif }; STATIC MP_DEFINE_CONST_DICT(mp_module_network_globals, mp_module_network_globals_table); diff --git a/extmod/modnetwork.h b/extmod/modnetwork.h index 50c8bc4b06..0f49350980 100644 --- a/extmod/modnetwork.h +++ b/extmod/modnetwork.h @@ -39,17 +39,9 @@ #define MOD_NETWORK_AP_IF (1) #if MICROPY_PY_LWIP - struct netif; - -extern const mp_obj_type_t network_lan_type; -extern const mp_obj_type_t mod_network_nic_type_wiznet5k; - void mod_network_lwip_poll_wrapper(uint32_t ticks_ms); mp_obj_t mod_network_nic_ifconfig(struct netif *netif, size_t n_args, const mp_obj_t *args); - -void wiznet5k_poll(void); - #else struct _mod_network_socket_obj_t; @@ -96,10 +88,7 @@ typedef struct _mod_network_socket_obj_t { #endif } mod_network_socket_obj_t; -extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; -extern const mod_network_nic_type_t mod_network_nic_type_cc3k; - -#endif +#endif // MICROPY_PY_LWIP void mod_network_init(void); void mod_network_deinit(void); diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index eff90cb25f..3147e28681 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -323,6 +323,34 @@ extern const struct _mp_obj_module_t mp_module_onewire; #define ONEWIRE_BUILTIN_MODULE #endif +#if defined(MICROPY_HW_ETH_MDC) +extern const struct _mp_obj_type_t network_lan_type; +#define MICROPY_HW_NIC_ETH { MP_ROM_QSTR(MP_QSTR_LAN), MP_ROM_PTR(&network_lan_type) }, +#else +#define MICROPY_HW_NIC_ETH +#endif + +#if MICROPY_PY_NETWORK_CYW43 +extern const struct _mp_obj_type_t mp_network_cyw43_type; +#define MICROPY_HW_NIC_CYW43 { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mp_network_cyw43_type) }, +#else +#define MICROPY_HW_NIC_CYW43 +#endif + +#if MICROPY_PY_WIZNET5K +extern const struct _mod_network_nic_type_t mod_network_nic_type_wiznet5k; +#define MICROPY_HW_NIC_WIZNET5K { MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) }, +#else +#define MICROPY_HW_NIC_WIZNET5K +#endif + +#if MICROPY_PY_CC3K +extern const struct _mod_network_nic_type_t mod_network_nic_type_cc3k; +#define MICROPY_HW_NIC_CC3K { MP_ROM_QSTR(MP_QSTR_CC3K), MP_ROM_PTR(&mod_network_nic_type_cc3k) }, +#else +#define MICROPY_HW_NIC_CC3K +#endif + #define MICROPY_PORT_BUILTIN_MODULES \ MACHINE_BUILTIN_MODULE \ PYB_BUILTIN_MODULE \ @@ -340,6 +368,12 @@ extern const struct _mp_obj_module_t mp_module_onewire; PYB_BUILTIN_MODULE \ STM_BUILTIN_MODULE \ +#define MICROPY_PORT_NETWORK_INTERFACES \ + MICROPY_HW_NIC_ETH \ + MICROPY_HW_NIC_CYW43 \ + MICROPY_HW_NIC_WIZNET5K \ + MICROPY_HW_NIC_CC3K \ + #define MP_STATE_PORT MP_STATE_VM #if MICROPY_SSL_MBEDTLS From a34d43b2b7a0651e52eeab52298a02556ed2c23c Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 15 Sep 2021 01:36:39 +1000 Subject: [PATCH 032/335] extmod/network_cyw43: Make consistent use of STA and AP constants. The network.STA_IF and network.AP_IF constants are now independent to the CYW43_ITF_STA and CYW43_ITF_AP constants. Signed-off-by: Damien George --- extmod/network_cyw43.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/extmod/network_cyw43.c b/extmod/network_cyw43.c index a5ed5d5b8e..d2383c7187 100644 --- a/extmod/network_cyw43.c +++ b/extmod/network_cyw43.c @@ -43,8 +43,8 @@ typedef struct _network_cyw43_obj_t { int itf; } network_cyw43_obj_t; -STATIC const network_cyw43_obj_t network_cyw43_wl0 = { { &mp_network_cyw43_type }, &cyw43_state, 0 }; -STATIC const network_cyw43_obj_t network_cyw43_wl1 = { { &mp_network_cyw43_type }, &cyw43_state, 1 }; +STATIC const network_cyw43_obj_t network_cyw43_wl_sta = { { &mp_network_cyw43_type }, &cyw43_state, CYW43_ITF_STA }; +STATIC const network_cyw43_obj_t network_cyw43_wl_ap = { { &mp_network_cyw43_type }, &cyw43_state, CYW43_ITF_AP }; STATIC void network_cyw43_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { network_cyw43_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -65,7 +65,7 @@ STATIC void network_cyw43_print(const mp_print_t *print, mp_obj_t self_in, mp_pr status_str = "fail"; } mp_printf(print, "", - self->itf == 0 ? "STA" : "AP", + self->itf == CYW43_ITF_STA ? "STA" : "AP", status_str, netif->ip_addr.addr & 0xff, netif->ip_addr.addr >> 8 & 0xff, @@ -76,10 +76,10 @@ STATIC void network_cyw43_print(const mp_print_t *print, mp_obj_t self_in, mp_pr STATIC mp_obj_t network_cyw43_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); - if (n_args == 0 || mp_obj_get_int(args[0]) == 0) { - return MP_OBJ_FROM_PTR(&network_cyw43_wl0); + if (n_args == 0 || mp_obj_get_int(args[0]) == MOD_NETWORK_STA_IF) { + return MP_OBJ_FROM_PTR(&network_cyw43_wl_sta); } else { - return MP_OBJ_FROM_PTR(&network_cyw43_wl1); + return MP_OBJ_FROM_PTR(&network_cyw43_wl_ap); } } From d451dc008680bfb27786b6f1d84ceac5da640050 Mon Sep 17 00:00:00 2001 From: Jan Hrudka Date: Thu, 9 Sep 2021 23:39:09 +0200 Subject: [PATCH 033/335] stm32: Add basic support for STM32H750. --- ports/stm32/Makefile | 4 ++-- ports/stm32/adc.c | 3 ++- ports/stm32/mboot/main.c | 2 ++ ports/stm32/powerctrl.c | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index d0a4d69a6f..1614db2358 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -77,7 +77,7 @@ CFLAGS_CORTEX_M = -mthumb # Select hardware floating-point support SUPPORTS_HARDWARE_FP_SINGLE = 0 SUPPORTS_HARDWARE_FP_DOUBLE = 0 -ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32F765xx STM32F767xx STM32F769xx STM32H743xx)) +ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32F765xx STM32F767xx STM32F769xx STM32H743xx STM32H750xx)) CFLAGS_CORTEX_M += -mfpu=fpv5-d16 -mfloat-abi=hard SUPPORTS_HARDWARE_FP_SINGLE = 1 SUPPORTS_HARDWARE_FP_DOUBLE = 1 @@ -424,7 +424,7 @@ HAL_SRC_C += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\ ) endif -ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32H743xx)) +ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32H743xx STM32H750xx)) HAL_SRC_C += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_, hal_fdcan.c) else ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 f4 f7 h7 l4)) diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c index 09cd3306bb..dd2702d6f9 100644 --- a/ports/stm32/adc.c +++ b/ports/stm32/adc.c @@ -136,7 +136,8 @@ defined(STM32F746xx) || defined(STM32F765xx) || \ defined(STM32F767xx) || defined(STM32F769xx) #define VBAT_DIV (4) -#elif defined(STM32H743xx) || defined(STM32H747xx) +#elif defined(STM32H743xx) || defined(STM32H747xx) || \ + defined(STM32H750xx) #define VBAT_DIV (4) #elif defined(STM32L432xx) || \ defined(STM32L451xx) || defined(STM32L452xx) || \ diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index 6c7d2c7714..278c07fb4a 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -501,6 +501,8 @@ void led0_update() { #define FLASH_LAYOUT_STR "@Internal Flash /0x08000000/04*032Kg,01*128Kg,07*256Kg" MBOOT_SPIFLASH_LAYOUT MBOOT_SPIFLASH2_LAYOUT #elif defined(STM32H743xx) #define FLASH_LAYOUT_STR "@Internal Flash /0x08000000/16*128Kg" MBOOT_SPIFLASH_LAYOUT MBOOT_SPIFLASH2_LAYOUT +#elif defined(STM32H750xx) +#define FLASH_LAYOUT_STR "@Internal Flash /0x08000000/01*128Kg" MBOOT_SPIFLASH_LAYOUT MBOOT_SPIFLASH2_LAYOUT #elif defined(STM32WB) #define FLASH_LAYOUT_STR "@Internal Flash /0x08000000/256*04Kg" MBOOT_SPIFLASH_LAYOUT MBOOT_SPIFLASH2_LAYOUT #endif diff --git a/ports/stm32/powerctrl.c b/ports/stm32/powerctrl.c index 137312ade8..9d9cc7f51b 100644 --- a/ports/stm32/powerctrl.c +++ b/ports/stm32/powerctrl.c @@ -32,7 +32,7 @@ #if defined(STM32H7) #define RCC_SR RSR -#if defined(STM32H743xx) +#if defined(STM32H743xx) || defined(STM32H750xx) #define RCC_SR_SFTRSTF RCC_RSR_SFTRSTF #elif defined(STM32H747xx) #define RCC_SR_SFTRSTF RCC_RSR_SFT2RSTF From f9d573a4ace66b6b8991f304f4a895906fb4ad61 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 14 Sep 2021 20:33:53 +0200 Subject: [PATCH 034/335] extmod/modnetwork: Remove STM32 references. --- extmod/modnetwork.c | 2 -- extmod/modnetwork.h | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/extmod/modnetwork.c b/extmod/modnetwork.c index a6a37ccb7e..1f242de869 100644 --- a/extmod/modnetwork.c +++ b/extmod/modnetwork.c @@ -32,8 +32,6 @@ #include "py/runtime.h" #include "py/mphal.h" #include "shared/netutils/netutils.h" -#include "systick.h" -#include "pendsv.h" #include "modnetwork.h" #if MICROPY_PY_NETWORK diff --git a/extmod/modnetwork.h b/extmod/modnetwork.h index 0f49350980..39e4d06d69 100644 --- a/extmod/modnetwork.h +++ b/extmod/modnetwork.h @@ -23,8 +23,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_STM32_MODNETWORK_H -#define MICROPY_INCLUDED_STM32_MODNETWORK_H +#ifndef MICROPY_INCLUDED_MODNETWORK_H +#define MICROPY_INCLUDED_MODNETWORK_H #define MOD_NETWORK_IPADDR_BUF_SIZE (4) @@ -95,4 +95,4 @@ void mod_network_deinit(void); void mod_network_register_nic(mp_obj_t nic); mp_obj_t mod_network_find_nic(const uint8_t *ip); -#endif // MICROPY_INCLUDED_STM32_MODNETWORK_H +#endif // MICROPY_INCLUDED_MODNETWORK_H From d9749f90ad6aecbebffe09a9e252a81624750ceb Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 14 Sep 2021 21:21:09 +0200 Subject: [PATCH 035/335] extmod/modnetwork: Remove modnetwork socket u_state member. To simplify the socket state. The CC3K driver (see drivers/cc3000/inc/socket.h and src/socket.c) has socket() returning an INT16 so there is now enough room to store it directly in the fileno member. --- extmod/modnetwork.h | 14 ++++------ extmod/modusocket.c | 15 +++++----- ports/stm32/modnwcc3k.c | 52 +++++++++++++++++----------------- ports/stm32/modnwwiznet5k.c | 56 +++++++++++++++++++------------------ 4 files changed, 68 insertions(+), 69 deletions(-) diff --git a/extmod/modnetwork.h b/extmod/modnetwork.h index 39e4d06d69..bbf80bc474 100644 --- a/extmod/modnetwork.h +++ b/extmod/modnetwork.h @@ -72,15 +72,11 @@ typedef struct _mod_network_socket_obj_t { mp_obj_base_t base; mp_obj_t nic; mod_network_nic_type_t *nic_type; - union { - struct { - uint8_t domain; - uint8_t type; - int8_t fileno; - uint8_t bound; - } u_param; - mp_uint_t u_state; - }; + uint32_t domain : 5; + uint32_t type : 5; + uint32_t proto : 5; + uint32_t bound : 1; + int32_t fileno : 16; #if MICROPY_PY_USOCKET_EXTENDED_STATE // Extended socket state for NICs/ports that need it. int32_t timeout; diff --git a/extmod/modusocket.c b/extmod/modusocket.c index fea81077c5..e08f8134fd 100644 --- a/extmod/modusocket.c +++ b/extmod/modusocket.c @@ -51,16 +51,17 @@ STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t s->base.type = &socket_type; s->nic = MP_OBJ_NULL; s->nic_type = NULL; - s->u_param.domain = MOD_NETWORK_AF_INET; - s->u_param.type = MOD_NETWORK_SOCK_STREAM; - s->u_param.fileno = -1; - s->u_param.bound = false; + s->domain = MOD_NETWORK_AF_INET; + s->type = MOD_NETWORK_SOCK_STREAM; + s->proto = 0; + s->bound = false; + s->fileno = -1; if (n_args >= 1) { - s->u_param.domain = mp_obj_get_int(args[0]); + s->domain = mp_obj_get_int(args[0]); if (n_args >= 2) { - s->u_param.type = mp_obj_get_int(args[1]); + s->type = mp_obj_get_int(args[1]); if (n_args >= 4) { - s->u_param.fileno = mp_obj_get_int(args[3]); + s->fileno = mp_obj_get_int(args[3]); } } } diff --git a/ports/stm32/modnwcc3k.c b/ports/stm32/modnwcc3k.c index 5dae9d6407..952e535c2d 100644 --- a/ports/stm32/modnwcc3k.c +++ b/ports/stm32/modnwcc3k.c @@ -136,13 +136,13 @@ STATIC int cc3k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uin } STATIC int cc3k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) { - if (socket->u_param.domain != MOD_NETWORK_AF_INET) { + if (socket->domain != MOD_NETWORK_AF_INET) { *_errno = MP_EAFNOSUPPORT; return -1; } mp_uint_t type; - switch (socket->u_param.type) { + switch (socket->type) { case MOD_NETWORK_SOCK_STREAM: type = SOCK_STREAM; break; @@ -168,23 +168,23 @@ STATIC int cc3k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) { cc3k_reset_fd_closed_state(fd); // store state of this socket - socket->u_state = fd; + socket->fileno = fd; // make accept blocking by default int optval = SOCK_OFF; socklen_t optlen = sizeof(optval); - CC3000_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen); + CC3000_EXPORT(setsockopt)(socket->fileno, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen); return 0; } STATIC void cc3k_socket_close(mod_network_socket_obj_t *socket) { - CC3000_EXPORT(closesocket)(socket->u_state); + CC3000_EXPORT(closesocket)(socket->fileno); } STATIC int cc3k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { MAKE_SOCKADDR(addr, ip, port) - int ret = CC3000_EXPORT(bind)(socket->u_state, &addr, sizeof(addr)); + int ret = CC3000_EXPORT(bind)(socket->fileno, &addr, sizeof(addr)); if (ret != 0) { *_errno = ret; return -1; @@ -193,7 +193,7 @@ STATIC int cc3k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_ } STATIC int cc3k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) { - int ret = CC3000_EXPORT(listen)(socket->u_state, backlog); + int ret = CC3000_EXPORT(listen)(socket->fileno, backlog); if (ret != 0) { *_errno = ret; return -1; @@ -206,7 +206,7 @@ STATIC int cc3k_socket_accept(mod_network_socket_obj_t *socket, mod_network_sock int fd; sockaddr addr; socklen_t addr_len = sizeof(addr); - if ((fd = CC3000_EXPORT(accept)(socket->u_state, &addr, &addr_len)) < 0) { + if ((fd = CC3000_EXPORT(accept)(socket->fileno, &addr, &addr_len)) < 0) { if (fd == SOC_IN_PROGRESS) { *_errno = MP_EAGAIN; } else { @@ -219,7 +219,7 @@ STATIC int cc3k_socket_accept(mod_network_socket_obj_t *socket, mod_network_sock cc3k_reset_fd_closed_state(fd); // store state in new socket object - socket2->u_state = fd; + socket2->fileno = fd; // return ip and port // it seems CC3000 returns little endian for accept?? @@ -235,7 +235,7 @@ STATIC int cc3k_socket_accept(mod_network_socket_obj_t *socket, mod_network_sock STATIC int cc3k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { MAKE_SOCKADDR(addr, ip, port) - int ret = CC3000_EXPORT(connect)(socket->u_state, &addr, sizeof(addr)); + int ret = CC3000_EXPORT(connect)(socket->fileno, &addr, sizeof(addr)); if (ret != 0) { *_errno = CC3000_EXPORT(errno); return -1; @@ -244,8 +244,8 @@ STATIC int cc3k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_ui } STATIC mp_uint_t cc3k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) { - if (cc3k_get_fd_closed_state(socket->u_state)) { - CC3000_EXPORT(closesocket)(socket->u_state); + if (cc3k_get_fd_closed_state(socket->fileno)) { + CC3000_EXPORT(closesocket)(socket->fileno); *_errno = MP_EPIPE; return -1; } @@ -255,7 +255,7 @@ STATIC mp_uint_t cc3k_socket_send(mod_network_socket_obj_t *socket, const byte * mp_int_t bytes = 0; while (bytes < len) { int n = MIN((len - bytes), MAX_TX_PACKET); - n = CC3000_EXPORT(send)(socket->u_state, (uint8_t *)buf + bytes, n, 0); + n = CC3000_EXPORT(send)(socket->fileno, (uint8_t *)buf + bytes, n, 0); if (n <= 0) { *_errno = CC3000_EXPORT(errno); return -1; @@ -268,18 +268,18 @@ STATIC mp_uint_t cc3k_socket_send(mod_network_socket_obj_t *socket, const byte * STATIC mp_uint_t cc3k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) { // check the socket is open - if (cc3k_get_fd_closed_state(socket->u_state)) { + if (cc3k_get_fd_closed_state(socket->fileno)) { // socket is closed, but CC3000 may have some data remaining in buffer, so check fd_set rfds; FD_ZERO(&rfds); - FD_SET(socket->u_state, &rfds); + FD_SET(socket->fileno, &rfds); cc3000_timeval tv; tv.tv_sec = 0; tv.tv_usec = 1; - int nfds = CC3000_EXPORT(select)(socket->u_state + 1, &rfds, NULL, NULL, &tv); - if (nfds == -1 || !FD_ISSET(socket->u_state, &rfds)) { + int nfds = CC3000_EXPORT(select)(socket->fileno + 1, &rfds, NULL, NULL, &tv); + if (nfds == -1 || !FD_ISSET(socket->fileno, &rfds)) { // no data waiting, so close socket and return 0 data - CC3000_EXPORT(closesocket)(socket->u_state); + CC3000_EXPORT(closesocket)(socket->fileno); return 0; } } @@ -288,7 +288,7 @@ STATIC mp_uint_t cc3k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, m len = MIN(len, MAX_RX_PACKET); // do the recv - int ret = CC3000_EXPORT(recv)(socket->u_state, buf, len, 0); + int ret = CC3000_EXPORT(recv)(socket->fileno, buf, len, 0); if (ret < 0) { *_errno = CC3000_EXPORT(errno); return -1; @@ -299,7 +299,7 @@ STATIC mp_uint_t cc3k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, m STATIC mp_uint_t cc3k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) { MAKE_SOCKADDR(addr, ip, port) - int ret = CC3000_EXPORT(sendto)(socket->u_state, (byte *)buf, len, 0, (sockaddr *)&addr, sizeof(addr)); + int ret = CC3000_EXPORT(sendto)(socket->fileno, (byte *)buf, len, 0, (sockaddr *)&addr, sizeof(addr)); if (ret < 0) { *_errno = CC3000_EXPORT(errno); return -1; @@ -310,7 +310,7 @@ STATIC mp_uint_t cc3k_socket_sendto(mod_network_socket_obj_t *socket, const byte STATIC mp_uint_t cc3k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) { sockaddr addr; socklen_t addr_len = sizeof(addr); - mp_int_t ret = CC3000_EXPORT(recvfrom)(socket->u_state, buf, len, 0, &addr, &addr_len); + mp_int_t ret = CC3000_EXPORT(recvfrom)(socket->fileno, buf, len, 0, &addr, &addr_len); if (ret < 0) { *_errno = CC3000_EXPORT(errno); return -1; @@ -320,7 +320,7 @@ STATIC mp_uint_t cc3k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *bu } STATIC int cc3k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) { - int ret = CC3000_EXPORT(setsockopt)(socket->u_state, level, opt, optval, optlen); + int ret = CC3000_EXPORT(setsockopt)(socket->fileno, level, opt, optval, optlen); if (ret < 0) { *_errno = CC3000_EXPORT(errno); return -1; @@ -340,14 +340,14 @@ STATIC int cc3k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t ti // set blocking mode optval = SOCK_OFF; } - ret = CC3000_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_RECV_NONBLOCK, &optval, optlen); + ret = CC3000_EXPORT(setsockopt)(socket->fileno, SOL_SOCKET, SOCKOPT_RECV_NONBLOCK, &optval, optlen); if (ret == 0) { - ret = CC3000_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen); + ret = CC3000_EXPORT(setsockopt)(socket->fileno, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen); } } else { // set timeout socklen_t optlen = sizeof(timeout_ms); - ret = CC3000_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_RECV_TIMEOUT, &timeout_ms, optlen); + ret = CC3000_EXPORT(setsockopt)(socket->fileno, SOL_SOCKET, SOCKOPT_RECV_TIMEOUT, &timeout_ms, optlen); } if (ret != 0) { @@ -363,7 +363,7 @@ STATIC int cc3k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request if (request == MP_STREAM_POLL) { mp_uint_t flags = arg; ret = 0; - int fd = socket->u_state; + int fd = socket->fileno; // init fds fd_set rfds, wfds, xfds; diff --git a/ports/stm32/modnwwiznet5k.c b/ports/stm32/modnwwiznet5k.c index d3c2c516c3..f7adad3f31 100644 --- a/ports/stm32/modnwwiznet5k.c +++ b/ports/stm32/modnwwiznet5k.c @@ -99,33 +99,33 @@ STATIC int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, } STATIC int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) { - if (socket->u_param.domain != MOD_NETWORK_AF_INET) { + if (socket->domain != MOD_NETWORK_AF_INET) { *_errno = MP_EAFNOSUPPORT; return -1; } - switch (socket->u_param.type) { + switch (socket->type) { case MOD_NETWORK_SOCK_STREAM: - socket->u_param.type = Sn_MR_TCP; + socket->type = Sn_MR_TCP; break; case MOD_NETWORK_SOCK_DGRAM: - socket->u_param.type = Sn_MR_UDP; + socket->type = Sn_MR_UDP; break; default: *_errno = MP_EINVAL; return -1; } - if (socket->u_param.fileno == -1) { + if (socket->fileno == -1) { // get first unused socket number for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) { if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) { wiznet5k_obj.socket_used |= (1 << sn); - socket->u_param.fileno = sn; + socket->fileno = sn; break; } } - if (socket->u_param.fileno == -1) { + if (socket->fileno == -1) { // too many open sockets *_errno = MP_EMFILE; return -1; @@ -137,13 +137,13 @@ STATIC int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) // So, we defer the open until we know what kind of socket we want. // use "domain" to indicate that this socket has not yet been opened - socket->u_param.domain = 0; + socket->domain = 0; return 0; } STATIC void wiznet5k_socket_close(mod_network_socket_obj_t *socket) { - uint8_t sn = (uint8_t)socket->u_param.fileno; + uint8_t sn = (uint8_t)socket->fileno; if (sn < _WIZCHIP_SOCK_NUM_) { wiznet5k_obj.socket_used &= ~(1 << sn); WIZCHIP_EXPORT(close)(sn); @@ -152,7 +152,7 @@ STATIC void wiznet5k_socket_close(mod_network_socket_obj_t *socket) { STATIC int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { // open the socket in server mode (if port != 0) - mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->u_param.fileno, socket->u_param.type, port, 0); + mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->fileno, socket->type, port, 0); if (ret < 0) { wiznet5k_socket_close(socket); *_errno = -ret; @@ -160,14 +160,14 @@ STATIC int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_u } // indicate that this socket has been opened - socket->u_param.domain = 1; + socket->domain = 1; // success return 0; } STATIC int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) { - mp_int_t ret = WIZCHIP_EXPORT(listen)(socket->u_param.fileno); + mp_int_t ret = WIZCHIP_EXPORT(listen)(socket->fileno); if (ret < 0) { wiznet5k_socket_close(socket); *_errno = -ret; @@ -178,17 +178,19 @@ STATIC int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t bac STATIC int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno) { for (;;) { - int sr = getSn_SR((uint8_t)socket->u_param.fileno); + int sr = getSn_SR((uint8_t)socket->fileno); if (sr == SOCK_ESTABLISHED) { - socket2->u_param = socket->u_param; - getSn_DIPR((uint8_t)socket2->u_param.fileno, ip); - *port = getSn_PORT(socket2->u_param.fileno); + socket2->domain = socket->domain; + socket2->type = socket->type; + socket2->fileno = socket->fileno; + getSn_DIPR((uint8_t)socket2->fileno, ip); + *port = getSn_PORT(socket2->fileno); // WIZnet turns the listening socket into the client socket, so we // need to re-bind and re-listen on another socket for the server. // TODO handle errors, especially no-more-sockets error - socket->u_param.domain = MOD_NETWORK_AF_INET; - socket->u_param.fileno = -1; + socket->domain = MOD_NETWORK_AF_INET; + socket->fileno = -1; int _errno2; if (wiznet5k_socket_socket(socket, &_errno2) != 0) { // printf("(bad resocket %d)\n", _errno2); @@ -217,7 +219,7 @@ STATIC int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, m // now connect MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->u_param.fileno, ip, port); + mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->fileno, ip, port); MP_THREAD_GIL_ENTER(); if (ret < 0) { @@ -232,7 +234,7 @@ STATIC int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, m STATIC mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) { MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(send)(socket->u_param.fileno, (byte *)buf, len); + mp_int_t ret = WIZCHIP_EXPORT(send)(socket->fileno, (byte *)buf, len); MP_THREAD_GIL_ENTER(); // TODO convert Wiz errno's to POSIX ones @@ -246,7 +248,7 @@ STATIC mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const by STATIC mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) { MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(recv)(socket->u_param.fileno, buf, len); + mp_int_t ret = WIZCHIP_EXPORT(recv)(socket->fileno, buf, len); MP_THREAD_GIL_ENTER(); // TODO convert Wiz errno's to POSIX ones @@ -259,7 +261,7 @@ STATIC mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *bu } STATIC mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) { - if (socket->u_param.domain == 0) { + if (socket->domain == 0) { // socket not opened; use "bind" function to open the socket in client mode if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { return -1; @@ -267,7 +269,7 @@ STATIC mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const } MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(sendto)(socket->u_param.fileno, (byte *)buf, len, ip, port); + mp_int_t ret = WIZCHIP_EXPORT(sendto)(socket->fileno, (byte *)buf, len, ip, port); MP_THREAD_GIL_ENTER(); if (ret < 0) { @@ -281,7 +283,7 @@ STATIC mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const STATIC mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) { uint16_t port2; MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(recvfrom)(socket->u_param.fileno, buf, len, ip, &port2); + mp_int_t ret = WIZCHIP_EXPORT(recvfrom)(socket->fileno, buf, len, ip, &port2); MP_THREAD_GIL_ENTER(); *port = port2; if (ret < 0) { @@ -307,7 +309,7 @@ STATIC int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_ if (timeout_ms == 0) { // set non-blocking mode uint8_t arg = SOCK_IO_NONBLOCK; - WIZCHIP_EXPORT(ctlsocket)(socket->u_param.fileno, CS_SET_IOMODE, &arg); + WIZCHIP_EXPORT(ctlsocket)(socket->fileno, CS_SET_IOMODE, &arg); } */ } @@ -315,10 +317,10 @@ STATIC int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_ STATIC int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) { if (request == MP_STREAM_POLL) { int ret = 0; - if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->u_param.fileno) != 0) { + if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->fileno) != 0) { ret |= MP_STREAM_POLL_RD; } - if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->u_param.fileno) != 0) { + if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->fileno) != 0) { ret |= MP_STREAM_POLL_WR; } return ret; From 9e2423e730ae32cd82e5c06099e6a847a2020f6a Mon Sep 17 00:00:00 2001 From: Jan Staal Date: Wed, 15 Sep 2021 15:08:16 +0200 Subject: [PATCH 036/335] stm32: Add support for H7A3(Q)/H7B3(Q), and STM32H73B3I_DK board defn. This commit is based upon prior work of @dpgeorge and @koendv. MCU support for the STM32H7A3 and B3 families MCUs: - STM32H7A3xx - STM32H7A3xxQ (SMPS) - STM32H7B3xx - STM32H7B3xxQ (SMPS) Support has been added for the STM32H7B3I_DK board. Signed-off-by: Jan Staal --- ports/stm32/Makefile | 4 +- ports/stm32/adc.c | 11 +- ports/stm32/adc.h | 2 + .../boards/STM32H7B3I_DK/mpconfigboard.h | 86 ++++++++ .../boards/STM32H7B3I_DK/mpconfigboard.mk | 18 ++ ports/stm32/boards/STM32H7B3I_DK/pins.csv | 191 ++++++++++++++++++ .../boards/STM32H7B3I_DK/stm32h7xx_hal_conf.h | 19 ++ ports/stm32/boards/stm32h7b3.ld | 30 +++ ports/stm32/boards/stm32h7b3_af.csv | 175 ++++++++++++++++ ports/stm32/extint.c | 4 + ports/stm32/flash.c | 4 + ports/stm32/machine_adc.c | 9 +- ports/stm32/main.c | 3 + ports/stm32/mpconfigboard_common.h | 11 + ports/stm32/powerctrl.c | 24 +++ ports/stm32/rtc.c | 17 +- ports/stm32/stm32_it.c | 4 + ports/stm32/system_stm32.c | 6 +- ports/stm32/timer.c | 5 + ports/stm32/uart.c | 27 +++ ports/stm32/usbd_conf.c | 17 +- 21 files changed, 655 insertions(+), 12 deletions(-) create mode 100644 ports/stm32/boards/STM32H7B3I_DK/mpconfigboard.h create mode 100644 ports/stm32/boards/STM32H7B3I_DK/mpconfigboard.mk create mode 100644 ports/stm32/boards/STM32H7B3I_DK/pins.csv create mode 100644 ports/stm32/boards/STM32H7B3I_DK/stm32h7xx_hal_conf.h create mode 100644 ports/stm32/boards/stm32h7b3.ld create mode 100644 ports/stm32/boards/stm32h7b3_af.csv diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 1614db2358..7a869d3c04 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -77,7 +77,7 @@ CFLAGS_CORTEX_M = -mthumb # Select hardware floating-point support SUPPORTS_HARDWARE_FP_SINGLE = 0 SUPPORTS_HARDWARE_FP_DOUBLE = 0 -ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32F765xx STM32F767xx STM32F769xx STM32H743xx STM32H750xx)) +ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32F765xx STM32F767xx STM32F769xx STM32H743xx STM32H750xx STM32H7A3xx STM32H7A3xxQ STM32H7B3xx STM32H7B3xxQ)) CFLAGS_CORTEX_M += -mfpu=fpv5-d16 -mfloat-abi=hard SUPPORTS_HARDWARE_FP_SINGLE = 1 SUPPORTS_HARDWARE_FP_DOUBLE = 1 @@ -424,7 +424,7 @@ HAL_SRC_C += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\ ) endif -ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32H743xx STM32H750xx)) +ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32H743xx STM32H750xx STM32H7A3xx STM32H7A3xxQ STM32H7B3xx STM32H7B3xxQ)) HAL_SRC_C += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_, hal_fdcan.c) else ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 f4 f7 h7 l4)) diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c index dd2702d6f9..ceb6584d03 100644 --- a/ports/stm32/adc.c +++ b/ports/stm32/adc.c @@ -55,7 +55,11 @@ #define PIN_ADC_MASK PIN_ADC1 #define pin_adc_table pin_adc1 -#if defined(STM32H7) +#if defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || \ + defined(STM32H7B3xx) || defined(STM32H7B3xxQ) +#define ADCALLx (ADC2) +#define pin_adcall_table pin_adc2 +#elif defined(STM32H7) // On the H7 ADC3 is used for ADCAll to be able to read internal // channels. For all other GPIO channels, ADC12 is used instead. #define ADCALLx (ADC3) @@ -137,6 +141,8 @@ defined(STM32F767xx) || defined(STM32F769xx) #define VBAT_DIV (4) #elif defined(STM32H743xx) || defined(STM32H747xx) || \ + defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || \ + defined(STM32H7B3xx) || defined(STM32H7B3xxQ) || \ defined(STM32H750xx) #define VBAT_DIV (4) #elif defined(STM32L432xx) || \ @@ -227,6 +233,9 @@ STATIC void adc_wait_for_eoc_or_timeout(ADC_HandleTypeDef *adcHandle, int32_t ti STATIC void adcx_clock_enable(ADC_HandleTypeDef *adch) { #if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) ADCx_CLK_ENABLE(); + #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + __HAL_RCC_ADC12_CLK_ENABLE(); + __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP); #elif defined(STM32H7) if (adch->Instance == ADC3) { __HAL_RCC_ADC3_CLK_ENABLE(); diff --git a/ports/stm32/adc.h b/ports/stm32/adc.h index 64864b1967..5821eb9d67 100644 --- a/ports/stm32/adc.h +++ b/ports/stm32/adc.h @@ -48,6 +48,8 @@ static inline void adc_deselect_vbat(ADC_TypeDef *adc, uint32_t channel) { adc_common = ADC_COMMON_REGISTER(0); #elif defined(STM32F7) adc_common = ADC123_COMMON; + #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + adc_common = ADC12_COMMON; #elif defined(STM32H7) adc_common = adc == ADC3 ? ADC3_COMMON : ADC12_COMMON; #endif diff --git a/ports/stm32/boards/STM32H7B3I_DK/mpconfigboard.h b/ports/stm32/boards/STM32H7B3I_DK/mpconfigboard.h new file mode 100644 index 0000000000..02f5fcac20 --- /dev/null +++ b/ports/stm32/boards/STM32H7B3I_DK/mpconfigboard.h @@ -0,0 +1,86 @@ +#define MICROPY_HW_BOARD_NAME "STM32H7B3I-DK" +#define MICROPY_HW_MCU_NAME "STM32H7B3LIH6Q" + +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_ADC (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SDCARD (1) +#define MICROPY_HW_HAS_SWITCH (1) +#define MICROPY_HW_HAS_FLASH (0) + +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (0) + +// The board has a 24MHz HSE, the following gives 280MHz CPU speed +#define MICROPY_HW_CLK_PLLM (12) +#define MICROPY_HW_CLK_PLLN (280) +#define MICROPY_HW_CLK_PLLP (2) +#define MICROPY_HW_CLK_PLLQ (2) +#define MICROPY_HW_CLK_PLLR (2) + +// The USB clock is set using PLL3 (48Mhz usb clock) +#define MICROPY_HW_CLK_PLL3M (12) +#define MICROPY_HW_CLK_PLL3N (192) +#define MICROPY_HW_CLK_PLL3P (17) +#define MICROPY_HW_CLK_PLL3Q (8) +#define MICROPY_HW_CLK_PLL3R (2) + +// 6 wait states when running at 280MHz (VOS0 range) +#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_6 + +#if 0 +// 512MBit external OSPI flash, used for either the filesystem or XIP memory mapped +#define MICROPY_HW_OSPIFLASH_SIZE_BITS_LOG2 (29) +#define MICROPY_HW_OSPIFLASH_CS (pin_G6) +#define MICROPY_HW_OSPIFLASH_CLK (pin_B2) +#define MICROPY_HW_OSPIFLASH_DQS (pin_C5) +#define MICROPY_HW_OSPIFLASH_IO0 (pin_P8) +#define MICROPY_HW_OSPIFLASH_IO1 (pin_F9) +#define MICROPY_HW_OSPIFLASH_IO2 (pin_F7) +#define MICROPY_HW_OSPIFLASH_IO3 (pin_F6) +#define MICROPY_HW_OSPIFLASH_IO4 (pin_C1) +#define MICROPY_HW_OSPIFLASH_IO5 (pin_H3) +#define MICROPY_HW_OSPIFLASH_IO6 (pin_D6) +#define MICROPY_HW_OSPIFLASH_IO7 (pin_G14) +#endif + +// UART buses +#define MICROPY_HW_UART1_TX (pin_A9) +#define MICROPY_HW_UART1_RX (pin_A10) +#define MICROPY_HW_UART4_TX (pin_H13) // Arduino Connector CN11-Pin1 +#define MICROPY_HW_UART4_RX (pin_H14) // Arduino Connector CN11-Pin2 +#define MICROPY_HW_UART_REPL PYB_UART_1 +#define MICROPY_HW_UART_REPL_BAUD 115200 + +// USRSW is pulled low. Pressing the button makes the input go high. +#define MICROPY_HW_USRSW_PIN (pin_C13) +#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) +#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_RISING) +#define MICROPY_HW_USRSW_PRESSED (1) + +// LEDs +#define MICROPY_HW_LED1 (pin_G11) // red +#define MICROPY_HW_LED2 (pin_G2) // blue +#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) +#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) + +// USB config +#define MICROPY_HW_USB_FS (0) +#define MICROPY_HW_USB_HS (1) +#define MICROPY_HW_USB_HS_IN_FS (1) +#define MICROPY_HW_USB_MAIN_DEV (USB_PHY_HS_ID) +#define MICROPY_HW_USB_CDC_NUM (2) +#define MICROPY_HW_USB_MSC (0) + +// SD card detect switch +#define MICROPY_HW_SDCARD_DETECT_PIN (pin_I8) +#define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP) +#define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) + +#define MICROPY_HW_SDMMC_D0 (pin_C8) +#define MICROPY_HW_SDMMC_D1 (pin_C9) +#define MICROPY_HW_SDMMC_D2 (pin_C10) +#define MICROPY_HW_SDMMC_D3 (pin_C11) +#define MICROPY_HW_SDMMC_CK (pin_C12) +#define MICROPY_HW_SDMMC_CMD (pin_D2) diff --git a/ports/stm32/boards/STM32H7B3I_DK/mpconfigboard.mk b/ports/stm32/boards/STM32H7B3I_DK/mpconfigboard.mk new file mode 100644 index 0000000000..380ade8d02 --- /dev/null +++ b/ports/stm32/boards/STM32H7B3I_DK/mpconfigboard.mk @@ -0,0 +1,18 @@ +USE_MBOOT ?= 0 + +# MCU settings +MCU_SERIES = h7 +CMSIS_MCU = STM32H7B3xxQ +MICROPY_FLOAT_IMPL = double +AF_FILE = boards/stm32h7b3_af.csv + +ifeq ($(USE_MBOOT),1) +# When using Mboot all the text goes together after the filesystem +LD_FILES = boards/stm32h743.ld boards/common_blifs.ld +TEXT0_ADDR = 0x08040000 +else +# When not using Mboot the ISR text goes first, then the rest after the filesystem +LD_FILES = boards/stm32h7b3.ld boards/common_ifs.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08040000 +endif diff --git a/ports/stm32/boards/STM32H7B3I_DK/pins.csv b/ports/stm32/boards/STM32H7B3I_DK/pins.csv new file mode 100644 index 0000000000..e005e38af7 --- /dev/null +++ b/ports/stm32/boards/STM32H7B3I_DK/pins.csv @@ -0,0 +1,191 @@ +,PA0 +,PA1 +,PA2 +,PA3 +,PA4 +,PA5 +,PA6 +,PA7 +,PA8 +,PA9 +,PA10 +,PA11 +,PA12 +,PA13 +,PA14 +,PA15 +,PB0 +,PB1 +,PB2 +,PB3 +,PB4 +,PB5 +,PB6 +,PB7 +,PB8 +,PB9 +,PB10 +,PB11 +,PB12 +,PB13 +,PB14 +,PB15 +,PC0 +,PC1 +,PC2 +,PC3 +,PC4 +,PC5 +,PC6 +,PC7 +,PC8 +,PC9 +,PC10 +,PC11 +,PC12 +,PC13 +,PC14 +,PC15 +,PD0 +,PD1 +,PD2 +,PD3 +,PD4 +,PD5 +,PD6 +,PD7 +,PD8 +,PD9 +,PD10 +,PD11 +,PD12 +,PD13 +,PD14 +,PD15 +,PE0 +,PE1 +,PE2 +,PE3 +,PE4 +,PE5 +,PE6 +,PE7 +,PE8 +,PE9 +,PE10 +,PE11 +,PE12 +,PE13 +,PE14 +,PE15 +,PF0 +,PF1 +,PF2 +,PF3 +,PF4 +,PF5 +,PF6 +,PF7 +,PF8 +,PF9 +,PF10 +,PF11 +,PF12 +,PF13 +,PF14 +,PF15 +,PG0 +,PG1 +,PG2 +,PG3 +,PG4 +,PG5 +,PG6 +,PG7 +,PG8 +,PG9 +,PG10 +,PG11 +,PG12 +,PG13 +,PG14 +,PG15 +,PH0 +,PH1 +,PH2 +,PH3 +,PH4 +,PH5 +,PH6 +,PH7 +,PH8 +,PH9 +,PH10 +,PH11 +,PH12 +,PH13 +,PH14 +,PH15 +,PI0 +,PI1 +,PI2 +,PI3 +,PI4 +,PI5 +,PI6 +,PI7 +,PI8 +,PI9 +,PI10 +,PI11 +,PI12 +,PI13 +,PI14 +,PI15 +DAC1,PA4 +DAC2,PA5 +LED1,G11 +LED2,G2 +SW,PC13 +I2C1_SDA,PB9 +I2C1_SCL,PB8 +I2C2_SDA,PF0 +I2C2_SCL,PF1 +I2C4_SCL,PF14 +I2C4_SDA,PF15 +SD_D0,PC8 +SD_D1,PC9 +SD_D2,PC10 +SD_D3,PC11 +SD_CMD,PD2 +SD_CK,PC12 +SD_SW,PG2 +OTG_FS_POWER,PG6 +OTG_FS_OVER_CURRENT,PG7 +USB_VBUS,PA9 +USB_ID,PA10 +USB_DM,PA11 +USB_DP,PA12 +UART2_TX,PD5 +UART2_RX,PD6 +UART2_RTS,PD4 +UART2_CTS,PD3 +UART3_TX,PD8 +UART3_RX,PD9 +UART5_TX,PB6 +UART5_RX,PB12 +UART6_TX,PC6 +UART6_RX,PC7 +UART7_TX,PF7 +UART7_RX,PF6 +UART8_TX,PE1 +UART8_RX,PE0 +ETH_MDC,PC1 +ETH_MDIO,PA2 +ETH_RMII_REF_CLK,PA1 +ETH_RMII_CRS_DV,PA7 +ETH_RMII_RXD0,PC4 +ETH_RMII_RXD1,PC5 +ETH_RMII_TX_EN,PG11 +ETH_RMII_TXD0,PG13 +ETH_RMII_TXD1,PB13 diff --git a/ports/stm32/boards/STM32H7B3I_DK/stm32h7xx_hal_conf.h b/ports/stm32/boards/STM32H7B3I_DK/stm32h7xx_hal_conf.h new file mode 100644 index 0000000000..70c3246a89 --- /dev/null +++ b/ports/stm32/boards/STM32H7B3I_DK/stm32h7xx_hal_conf.h @@ -0,0 +1,19 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2019 Damien P. George + */ +#ifndef MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H + +#include "boards/stm32h7xx_hal_conf_base.h" + +// Oscillator values in Hz +#define HSE_VALUE (24000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (5000) +#define LSE_STARTUP_TIMEOUT (5000) + +#endif // MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H diff --git a/ports/stm32/boards/stm32h7b3.ld b/ports/stm32/boards/stm32h7b3.ld new file mode 100644 index 0000000000..cccea983fa --- /dev/null +++ b/ports/stm32/boards/stm32h7b3.ld @@ -0,0 +1,30 @@ +/* + GNU linker script for STM32H7B3 +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 128K /* sector 0, 128K */ + FLASH_FS (r) : ORIGIN = 0x08020000, LENGTH = 128K /* sector 1, 128K */ + FLASH_TEXT (rx) : ORIGIN = 0x08040000, LENGTH = 1792K /* sectors 6*128 + 8*128 */ + DTCM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for storage cache */ + RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 512K /* AXI SRAM */ + RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K +} + +/* 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 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) - _estack_reserve; +_sstack = _estack - 16K; /* tunable */ + +/* RAM extents for the garbage collector */ +_ram_start = ORIGIN(RAM); +_ram_end = ORIGIN(RAM) + LENGTH(RAM); +_heap_start = _ebss; /* heap starts just after statically allocated memory */ +_heap_end = _sstack; diff --git a/ports/stm32/boards/stm32h7b3_af.csv b/ports/stm32/boards/stm32h7b3_af.csv new file mode 100644 index 0000000000..0e1747161f --- /dev/null +++ b/ports/stm32/boards/stm32h7b3_af.csv @@ -0,0 +1,175 @@ +Port,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15, +,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15,ADC +PortA,PA0,,TIM2_CH1/TIM2_ETR,TIM5_CH1,TIM8_ETR,TIM15_BKIN,I2S6_WS/SPI6_NSS,,USART2_CTS/USART2_NSS,UART4_TX,SDMMC2_CMD,SAI2_SD_B,,,,,EVENTOUT/EVENTOUT,ADC1_INP16, +PortA,PA0_C,,TIM2_CH1/TIM2_ETR,TIM5_CH1,TIM8_ETR,TIM15_BKIN,I2S6_WS/SPI6_NSS,,USART2_CTS/USART2_NSS,UART4_TX,SDMMC2_CMD,SAI2_SD_B,,,,,EVENTOUT/EVENTOUT,ADC1_INP16, +PortA,PA1,,TIM2_CH2,TIM5_CH2,LPTIM3_OUT,TIM15_CH1N,,,USART2_DE/USART2_RTS,UART4_RX,OCTOSPIM_P1_IO3,SAI2_MCLK_B,OCTOSPIM_P1_DQS,,,LTDC_R2,EVENTOUT/EVENTOUT,ADC1_INN16/ADC1_INP17, +PortA,PA10,,TIM1_CH3,,LPUART1_RX,,,,USART1_RX,,,USB_OTG_HS_ID,MDIOS_MDIO,LTDC_B4,DCMI_D1/PSSI_D1,LTDC_B1,EVENTOUT/EVENTOUT,, +PortA,PA11,,TIM1_CH4,,LPUART1_CTS,,I2S2_WS/SPI2_NSS,UART4_RX,USART1_CTS/USART1_NSS,,FDCAN1_RX,,,,,LTDC_R4,EVENTOUT/EVENTOUT,, +PortA,PA12,,TIM1_ETR,,LPUART1_DE/LPUART1_RTS,,I2S2_CK/SPI2_SCK,UART4_TX,USART1_DE/USART1_RTS,SAI2_FS_B,FDCAN1_TX,,,,,LTDC_R5,EVENTOUT/EVENTOUT,, +PortA,PA13,DEBUG_JTMS/SWDIO,,,,,,,,,,,,,,,EVENTOUT/EVENTOUT,, +PortA,PA14,DEBUG_JTCK/SWCLK,,,,,,,,,,,,,,,EVENTOUT/EVENTOUT,, +PortA,PA15,DEBUG_JTDI,TIM2_CH1/TIM2_ETR,,,CEC,I2S1_WS/SPI1_NSS,I2S3_WS/SPI3_NSS,I2S6_WS/SPI6_NSS,UART4_DE/UART4_RTS,LTDC_R3,,UART7_TX,,,LTDC_B6,EVENTOUT/EVENTOUT,, +PortA,PA1_C,,TIM2_CH2,TIM5_CH2,LPTIM3_OUT,TIM15_CH1N,,,USART2_DE/USART2_RTS,UART4_RX,OCTOSPIM_P1_IO3,SAI2_MCLK_B,OCTOSPIM_P1_DQS,,,LTDC_R2,EVENTOUT/EVENTOUT,ADC1_INN16/ADC1_INP17, +PortA,PA2,,TIM2_CH3,TIM5_CH3,,TIM15_CH1,,DFSDM2_CKIN1,USART2_TX,SAI2_SCK_B,,,,MDIOS_MDIO,,LTDC_R1,EVENTOUT/EVENTOUT,ADC1_INP14, +PortA,PA3,,TIM2_CH4,TIM5_CH4,OCTOSPIM_P1_CLK,TIM15_CH2,I2S6_MCK,,USART2_RX,,LTDC_B2,USB_OTG_HS_ULPI_D0,,,,LTDC_B5,EVENTOUT/EVENTOUT,ADC1_INP15, +PortA,PA4,,,TIM5_ETR,,,I2S1_WS/SPI1_NSS,I2S3_WS/SPI3_NSS,USART2_CK,I2S6_WS/SPI6_NSS,,,,,DCMI_HSYNC/PSSI_DE,LTDC_VSYNC,EVENTOUT/EVENTOUT,ADC1_INP18, +PortA,PA5,PWR_NDSTOP2,TIM2_CH1/TIM2_ETR,,TIM8_CH1N,,I2S1_CK/SPI1_SCK,,,I2S6_CK/SPI6_SCK,,USB_OTG_HS_ULPI_CK,,,PSSI_D14,LTDC_R4,EVENTOUT/EVENTOUT,ADC1_INN18/ADC1_INP19, +PortA,PA6,,TIM1_BKIN,TIM3_CH1,TIM8_BKIN,,I2S1_SDI/SPI1_MISO,OCTOSPIM_P1_IO3,,I2S6_SDI/SPI6_MISO,TIM13_CH1,TIM8_BKIN_COMP1/TIM8_BKIN_COMP2,MDIOS_MDC,TIM1_BKIN_COMP1/TIM1_BKIN_COMP2,DCMI_PIXCLK/PSSI_PDCK,LTDC_G2,EVENTOUT/EVENTOUT,ADC1_INP3/ADC2_INP3, +PortA,PA7,,TIM1_CH1N,TIM3_CH2,TIM8_CH1N,DFSDM2_DATIN1,I2S1_SDO/SPI1_MOSI,,,I2S6_SDO/SPI6_MOSI,TIM14_CH1,OCTOSPIM_P1_IO2,,FMC_SDNWE,,LTDC_VSYNC,EVENTOUT/EVENTOUT,ADC1_INN3/ADC1_INP7/ADC2_INN3/ADC2_INP7, +PortA,PA8,RCC_MCO_1,TIM1_CH1,,TIM8_BKIN2,I2C3_SCL,,,USART1_CK,,,USB_OTG_HS_SOF,UART7_RX,TIM8_BKIN2_COMP1/TIM8_BKIN2_COMP2,LTDC_B3,LTDC_R6,EVENTOUT/EVENTOUT,, +PortA,PA9,,TIM1_CH2,,LPUART1_TX,I2C3_SMBA,I2S2_CK/SPI2_SCK,,USART1_TX,,,,,,DCMI_D0/PSSI_D0,LTDC_R5,EVENTOUT/EVENTOUT,, +PortB,PB0,,TIM1_CH2N,TIM3_CH3,TIM8_CH2N,DFSDM2_CKOUT,,DFSDM1_CKOUT,,UART4_CTS,LTDC_R3,USB_OTG_HS_ULPI_D1,OCTOSPIM_P1_IO1,,,LTDC_G1,EVENTOUT/EVENTOUT,ADC1_INN5/ADC1_INP9/ADC2_INN5/ADC2_INP9, +PortB,PB1,,TIM1_CH3N,TIM3_CH4,TIM8_CH3N,,,DFSDM1_DATIN1,,,LTDC_R6,USB_OTG_HS_ULPI_D2,OCTOSPIM_P1_IO0,,,LTDC_G0,EVENTOUT/EVENTOUT,ADC1_INP5/ADC2_INP5, +PortB,PB10,,TIM2_CH3,,LPTIM2_IN1,I2C2_SCL,I2S2_CK/SPI2_SCK,DFSDM1_DATIN7,USART3_TX,,OCTOSPIM_P1_NCS,USB_OTG_HS_ULPI_D3,,,,LTDC_G4,EVENTOUT/EVENTOUT,, +PortB,PB11,,TIM2_CH4,,LPTIM2_ETR,I2C2_SDA,,DFSDM1_CKIN7,USART3_RX,,,USB_OTG_HS_ULPI_D4,,,,LTDC_G5,EVENTOUT/EVENTOUT,, +PortB,PB12,,TIM1_BKIN,,OCTOSPIM_P1_NCLK,I2C2_SMBA,I2S2_WS/SPI2_NSS,DFSDM1_DATIN1,USART3_CK,,FDCAN2_RX,USB_OTG_HS_ULPI_D5,DFSDM2_DATIN1,,TIM1_BKIN_COMP1/TIM1_BKIN_COMP2,UART5_RX,EVENTOUT/EVENTOUT,, +PortB,PB13,,TIM1_CH1N,,LPTIM2_OUT,DFSDM2_CKIN1,I2S2_CK/SPI2_SCK,DFSDM1_CKIN1,USART3_CTS/USART3_NSS,,FDCAN2_TX,USB_OTG_HS_ULPI_D6,,SDMMC1_D0,DCMI_D2/PSSI_D2,UART5_TX,EVENTOUT/EVENTOUT,, +PortB,PB14,,TIM1_CH2N,TIM12_CH1,TIM8_CH2N,USART1_TX,I2S2_SDI/SPI2_MISO,DFSDM1_DATIN2,USART3_DE/USART3_RTS,UART4_DE/UART4_RTS,SDMMC2_D0,,,,,LTDC_CLK,EVENTOUT/EVENTOUT,, +PortB,PB15,RTC_REFIN,TIM1_CH3N,TIM12_CH2,TIM8_CH3N,USART1_RX,I2S2_SDO/SPI2_MOSI,DFSDM1_CKIN2,,UART4_CTS,SDMMC2_D1,,,,,LTDC_G7,EVENTOUT/EVENTOUT,, +PortB,PB2,RTC_OUT_ALARM,,SAI1_D1,,DFSDM1_CKIN1,,SAI1_SD_A,I2S3_SDO/SPI3_MOSI,,OCTOSPIM_P1_CLK,OCTOSPIM_P1_DQS,,,,,EVENTOUT/EVENTOUT,, +PortB,PB3,DEBUG_JTDO/SWO,TIM2_CH2,,,,I2S1_CK/SPI1_SCK,I2S3_CK/SPI3_SCK,,I2S6_CK/SPI6_SCK,SDMMC2_D2,CRS_SYNC,UART7_RX,,,,EVENTOUT/EVENTOUT,, +PortB,PB4,,TIM16_BKIN,TIM3_CH1,,,I2S1_SDI/SPI1_MISO,I2S3_SDI/SPI3_MISO,I2S2_WS/SPI2_NSS,I2S6_SDI/SPI6_MISO,SDMMC2_D3,,UART7_TX,,,,EVENTOUT/EVENTOUT,, +PortB,PB5,,TIM17_BKIN,TIM3_CH2,,I2C1_SMBA,I2S1_SDO/SPI1_MOSI,I2C4_SMBA,I2S3_SDO/SPI3_MOSI,I2S6_SDO/SPI6_MOSI,FDCAN2_RX,USB_OTG_HS_ULPI_D7,LTDC_B5,FMC_SDCKE1,DCMI_D10/PSSI_D10,UART5_RX,EVENTOUT/EVENTOUT,, +PortB,PB6,,TIM16_CH1N,TIM4_CH1,,I2C1_SCL,CEC,I2C4_SCL,USART1_TX,LPUART1_TX,FDCAN2_TX,OCTOSPIM_P1_NCS,DFSDM1_DATIN5,FMC_SDNE1,DCMI_D5/PSSI_D5,UART5_TX,EVENTOUT/EVENTOUT,, +PortB,PB7,,TIM17_CH1N,TIM4_CH2,,I2C1_SDA,,I2C4_SDA,USART1_RX,LPUART1_RX,,,DFSDM1_CKIN5,FMC_NL,DCMI_VSYNC/PSSI_RDY,,EVENTOUT/EVENTOUT,, +PortB,PB8,,TIM16_CH1,TIM4_CH3,DFSDM1_CKIN7,I2C1_SCL,,I2C4_SCL,SDMMC1_CKIN,UART4_RX,FDCAN1_RX,SDMMC2_D4,,SDMMC1_D4,DCMI_D6/PSSI_D6,LTDC_B6,EVENTOUT/EVENTOUT,, +PortB,PB9,,TIM17_CH1,TIM4_CH4,DFSDM1_DATIN7,I2C1_SDA,I2S2_WS/SPI2_NSS,I2C4_SDA,SDMMC1_CDIR,UART4_TX,FDCAN1_TX,SDMMC2_D5,I2C4_SMBA,SDMMC1_D5,DCMI_D7/PSSI_D7,LTDC_B7,EVENTOUT/EVENTOUT,, +PortC,PC0,,,,DFSDM1_CKIN0,,,DFSDM1_DATIN4,,SAI2_FS_B,FMC_A25,USB_OTG_HS_ULPI_STP,LTDC_G2,FMC_SDNWE,,LTDC_R5,EVENTOUT/EVENTOUT,ADC1_INP10/ADC2_INP10, +PortC,PC1,DEBUG_TRACED0,,SAI1_D1,DFSDM1_DATIN0,DFSDM1_CKIN4,I2S2_SDO/SPI2_MOSI,SAI1_SD_A,,,SDMMC2_CK,OCTOSPIM_P1_IO4,,MDIOS_MDC,,LTDC_G5,EVENTOUT/EVENTOUT,ADC1_INN10/ADC1_INP11/ADC2_INN10/ADC2_INP11, +PortC,PC10,,,,DFSDM1_CKIN5,DFSDM2_CKIN0,,I2S3_CK/SPI3_SCK,USART3_TX,UART4_TX,OCTOSPIM_P1_IO1,LTDC_B1,SWPMI1_RX,SDMMC1_D2,DCMI_D8/PSSI_D8,LTDC_R2,EVENTOUT/EVENTOUT,, +PortC,PC11,,,,DFSDM1_DATIN5,DFSDM2_DATIN0,,I2S3_SDI/SPI3_MISO,USART3_RX,UART4_RX,OCTOSPIM_P1_NCS,,,SDMMC1_D3,DCMI_D4/PSSI_D4,LTDC_B4,EVENTOUT/EVENTOUT,, +PortC,PC12,DEBUG_TRACED3,,TIM15_CH1,,DFSDM2_CKOUT,I2S6_CK/SPI6_SCK,I2S3_SDO/SPI3_MOSI,USART3_CK,UART5_TX,,,,SDMMC1_CK,DCMI_D9/PSSI_D9,LTDC_R6,EVENTOUT/EVENTOUT,, +PortC,PC13,,,,,,,,,,,,,,,,EVENTOUT/EVENTOUT,, +PortC,PC14-OSC32_IN,,,,,,,,,,,,,,,,EVENTOUT/EVENTOUT,, +PortC,PC15-OSC32_OUT,,,,,,,,,,,,,,,,EVENTOUT/EVENTOUT,, +PortC,PC2,PWR_CSTOP,,,DFSDM1_CKIN1,,I2S2_SDI/SPI2_MISO,DFSDM1_CKOUT,,,OCTOSPIM_P1_IO2,USB_OTG_HS_ULPI_DIR,OCTOSPIM_P1_IO5,FMC_SDNE0,,,EVENTOUT/EVENTOUT,ADC1_INN11/ADC1_INP12/ADC2_INN11/ADC2_INP12, +PortC,PC2_C,PWR_CSTOP,,,DFSDM1_CKIN1,,I2S2_SDI/SPI2_MISO,DFSDM1_CKOUT,,,OCTOSPIM_P1_IO2,USB_OTG_HS_ULPI_DIR,OCTOSPIM_P1_IO5,FMC_SDNE0,,,EVENTOUT/EVENTOUT,ADC1_INN11/ADC1_INP12/ADC2_INN11/ADC2_INP12, +PortC,PC3,PWR_CSLEEP,,,DFSDM1_DATIN1,,I2S2_SDO/SPI2_MOSI,,,,OCTOSPIM_P1_IO0,USB_OTG_HS_ULPI_NXT,OCTOSPIM_P1_IO6,FMC_SDCKE0,,,EVENTOUT/EVENTOUT,ADC2_INP1, +PortC,PC3_C,PWR_CSLEEP,,,DFSDM1_DATIN1,,I2S2_SDO/SPI2_MOSI,,,,OCTOSPIM_P1_IO0,USB_OTG_HS_ULPI_NXT,OCTOSPIM_P1_IO6,FMC_SDCKE0,,,EVENTOUT/EVENTOUT,ADC2_INP1, +PortC,PC4,,,,DFSDM1_CKIN2,,I2S1_MCK,,,,SPDIFRX_IN3,,,FMC_SDNE0,,LTDC_R7,EVENTOUT/EVENTOUT,ADC1_INP4/ADC2_INP4, +PortC,PC5,,,SAI1_D3,DFSDM1_DATIN2,PSSI_D15,,,,,SPDIFRX_IN4,OCTOSPIM_P1_DQS,,FMC_SDCKE0,COMP1_OUT,LTDC_DE,EVENTOUT/EVENTOUT,ADC1_INN4/ADC1_INP8/ADC2_INN4/ADC2_INP8, +PortC,PC6,,,TIM3_CH1,TIM8_CH1,DFSDM1_CKIN3,I2S2_MCK,,USART6_TX,SDMMC1_D0DIR,FMC_NWAIT,SDMMC2_D6,,SDMMC1_D6,DCMI_D0/PSSI_D0,LTDC_HSYNC,EVENTOUT/EVENTOUT,, +PortC,PC7,DEBUG_TRGIO,,TIM3_CH2,TIM8_CH2,DFSDM1_DATIN3,,I2S3_MCK,USART6_RX,SDMMC1_D123DIR,FMC_NE1,SDMMC2_D7,SWPMI1_TX,SDMMC1_D7,DCMI_D1/PSSI_D1,LTDC_G6,EVENTOUT/EVENTOUT,, +PortC,PC8,DEBUG_TRACED1,,TIM3_CH3,TIM8_CH3,,,,USART6_CK,UART5_DE/UART5_RTS,FMC_NCE/FMC_NE2,FMC_INT,SWPMI1_RX,SDMMC1_D0,DCMI_D2/PSSI_D2,,EVENTOUT/EVENTOUT,, +PortC,PC9,RCC_MCO_2,,TIM3_CH4,TIM8_CH4,I2C3_SDA,I2S_CKIN,,,UART5_CTS,OCTOSPIM_P1_IO0,LTDC_G3,SWPMI1_SUSPEND,SDMMC1_D1,DCMI_D3/PSSI_D3,LTDC_B2,EVENTOUT/EVENTOUT,, +PortD,PD0,,,,DFSDM1_CKIN6,,,,,UART4_RX,FDCAN1_RX,,UART9_CTS,FMC_D2/FMC_DA2,,LTDC_B1,EVENTOUT/EVENTOUT,, +PortD,PD1,,,,DFSDM1_DATIN6,,,,,UART4_TX,FDCAN1_TX,,,FMC_D3/FMC_DA3,,,EVENTOUT/EVENTOUT,, +PortD,PD10,,,,DFSDM1_CKOUT,DFSDM2_CKOUT,,,USART3_CK,,,,,FMC_D15/FMC_DA15,,LTDC_B3,EVENTOUT/EVENTOUT,, +PortD,PD11,,,,LPTIM2_IN2,I2C4_SMBA,,,USART3_CTS/USART3_NSS,,OCTOSPIM_P1_IO0,SAI2_SD_A,,FMC_A16/FMC_CLE,,,EVENTOUT/EVENTOUT,, +PortD,PD12,,LPTIM1_IN1,TIM4_CH1,LPTIM2_IN1,I2C4_SCL,,,USART3_DE/USART3_RTS,,OCTOSPIM_P1_IO1,SAI2_FS_A,,FMC_A17/FMC_ALE,DCMI_D12/PSSI_D12,,EVENTOUT/EVENTOUT,, +PortD,PD13,,LPTIM1_OUT,TIM4_CH2,,I2C4_SDA,,,,,OCTOSPIM_P1_IO3,SAI2_SCK_A,UART9_DE/UART9_RTS,FMC_A18,DCMI_D13/PSSI_D13,,EVENTOUT/EVENTOUT,, +PortD,PD14,,,TIM4_CH3,,,,,,UART8_CTS,,,UART9_RX,FMC_D0/FMC_DA0,,,EVENTOUT/EVENTOUT,, +PortD,PD15,,,TIM4_CH4,,,,,,UART8_DE/UART8_RTS,,,UART9_TX,FMC_D1/FMC_DA1,,,EVENTOUT/EVENTOUT,, +PortD,PD2,DEBUG_TRACED2,,TIM3_ETR,,TIM15_BKIN,,,,UART5_RX,LTDC_B7,,,SDMMC1_CMD,DCMI_D11/PSSI_D11,LTDC_B2,EVENTOUT/EVENTOUT,, +PortD,PD3,,,,DFSDM1_CKOUT,,I2S2_CK/SPI2_SCK,,USART2_CTS/USART2_NSS,,,,,FMC_CLK,DCMI_D5/PSSI_D5,LTDC_G7,EVENTOUT/EVENTOUT,, +PortD,PD4,,,,,,,,USART2_DE/USART2_RTS,,,OCTOSPIM_P1_IO4,,FMC_NOE,,,EVENTOUT/EVENTOUT,, +PortD,PD5,,,,,,,,USART2_TX,,,OCTOSPIM_P1_IO5,,FMC_NWE,,,EVENTOUT/EVENTOUT,, +PortD,PD6,,,SAI1_D1,DFSDM1_CKIN4,DFSDM1_DATIN1,I2S3_SDO/SPI3_MOSI,SAI1_SD_A,USART2_RX,,,OCTOSPIM_P1_IO6,SDMMC2_CK,FMC_NWAIT,DCMI_D10/PSSI_D10,LTDC_B2,EVENTOUT/EVENTOUT,, +PortD,PD7,,,,DFSDM1_DATIN4,,I2S1_SDO/SPI1_MOSI,DFSDM1_CKIN1,USART2_CK,,SPDIFRX_IN1,OCTOSPIM_P1_IO7,SDMMC2_CMD,FMC_NE1,,,EVENTOUT/EVENTOUT,, +PortD,PD8,,,,DFSDM1_CKIN3,,,,USART3_TX,,SPDIFRX_IN2,,,FMC_D13/FMC_DA13,,,EVENTOUT/EVENTOUT,, +PortD,PD9,,,,DFSDM1_DATIN3,,,,USART3_RX,,,,,FMC_D14/FMC_DA14,,,EVENTOUT/EVENTOUT,, +PortD,PDR_ON,,,,,,,,,,,,,,,,EVENTOUT,, +PortE,PE0,,LPTIM1_ETR,TIM4_ETR,,LPTIM2_ETR,,,,UART8_RX,,SAI2_MCLK_A,,FMC_NBL0,DCMI_D2/PSSI_D2,LTDC_R0,EVENTOUT/EVENTOUT,, +PortE,PE1,,LPTIM1_IN2,,,,,,,UART8_TX,,,,FMC_NBL1,DCMI_D3/PSSI_D3,LTDC_R6,EVENTOUT/EVENTOUT,, +PortE,PE10,,TIM1_CH2N,,DFSDM1_DATIN4,,,,UART7_CTS,,,OCTOSPIM_P1_IO7,,FMC_D7/FMC_DA7,,,EVENTOUT/EVENTOUT,, +PortE,PE11,,TIM1_CH2,,DFSDM1_CKIN4,,SPI4_NSS,,,,,SAI2_SD_B,OCTOSPIM_P1_NCS,FMC_D8/FMC_DA8,,LTDC_G3,EVENTOUT/EVENTOUT,, +PortE,PE12,,TIM1_CH3N,,DFSDM1_DATIN5,,SPI4_SCK,,,,,SAI2_SCK_B,,FMC_D9/FMC_DA9,COMP1_OUT,LTDC_B4,EVENTOUT/EVENTOUT,, +PortE,PE13,,TIM1_CH3,,DFSDM1_CKIN5,,SPI4_MISO,,,,,SAI2_FS_B,,FMC_D10/FMC_DA10,COMP2_OUT,LTDC_DE,EVENTOUT/EVENTOUT,, +PortE,PE14,,TIM1_CH4,,,,SPI4_MOSI,,,,,SAI2_MCLK_B,,FMC_D11/FMC_DA11,,LTDC_CLK,EVENTOUT/EVENTOUT,, +PortE,PE15,,TIM1_BKIN,,,,,,,,,,USART10_CK,FMC_D12/FMC_DA12,TIM1_BKIN_COMP1/TIM1_BKIN_COMP2,LTDC_R7,EVENTOUT/EVENTOUT,, +PortE,PE2,DEBUG_TRACECLK,,SAI1_CK1,,,SPI4_SCK,SAI1_MCLK_A,,,OCTOSPIM_P1_IO2,,USART10_RX,FMC_A23,,,EVENTOUT/EVENTOUT,, +PortE,PE3,DEBUG_TRACED0,,,,TIM15_BKIN,,SAI1_SD_B,,,,,USART10_TX,FMC_A19,,,EVENTOUT/EVENTOUT,, +PortE,PE4,DEBUG_TRACED1,,SAI1_D2,DFSDM1_DATIN3,TIM15_CH1N,SPI4_NSS,SAI1_FS_A,,,,,,FMC_A20,DCMI_D4/PSSI_D4,LTDC_B0,EVENTOUT/EVENTOUT,, +PortE,PE5,DEBUG_TRACED2,,SAI1_CK2,DFSDM1_CKIN3,TIM15_CH1,SPI4_MISO,SAI1_SCK_A,,,,,,FMC_A21,DCMI_D6/PSSI_D6,LTDC_G0,EVENTOUT/EVENTOUT,, +PortE,PE6,DEBUG_TRACED3,TIM1_BKIN2,SAI1_D1,,TIM15_CH2,SPI4_MOSI,SAI1_SD_A,,,,SAI2_MCLK_B,TIM1_BKIN2_COMP1/TIM1_BKIN2_COMP2,FMC_A22,DCMI_D7/PSSI_D7,LTDC_G1,EVENTOUT/EVENTOUT,, +PortE,PE7,,TIM1_ETR,,DFSDM1_DATIN2,,,,UART7_RX,,,OCTOSPIM_P1_IO4,,FMC_D4/FMC_DA4,,,EVENTOUT/EVENTOUT,, +PortE,PE8,,TIM1_CH1N,,DFSDM1_CKIN2,,,,UART7_TX,,,OCTOSPIM_P1_IO5,,FMC_D5/FMC_DA5,COMP2_OUT,,EVENTOUT/EVENTOUT,, +PortE,PE9,,TIM1_CH1,,DFSDM1_CKOUT,,,,UART7_DE/UART7_RTS,,,OCTOSPIM_P1_IO6,,FMC_D6/FMC_DA6,,,EVENTOUT/EVENTOUT,, +PortF,PF0,,,,,I2C2_SDA,,,,,OCTOSPIM_P2_IO0,,,FMC_A0,,,EVENTOUT/EVENTOUT,, +PortF,PF1,,,,,I2C2_SCL,,,,,OCTOSPIM_P2_IO1,,,FMC_A1,,,EVENTOUT/EVENTOUT,, +PortF,PF10,,TIM16_BKIN,SAI1_D3,,PSSI_D15,,,,,OCTOSPIM_P1_CLK,,,,DCMI_D11/PSSI_D11,LTDC_DE,EVENTOUT/EVENTOUT,, +PortF,PF11,,,,,,SPI5_MOSI,,,,OCTOSPIM_P1_NCLK,SAI2_SD_B,,FMC_SDNRAS,DCMI_D12/PSSI_D12,,EVENTOUT/EVENTOUT,ADC1_INP2, +PortF,PF12,,,,,,,,,,OCTOSPIM_P2_DQS,,,FMC_A6,,,EVENTOUT/EVENTOUT,ADC1_INN2/ADC1_INP6, +PortF,PF13,,,,DFSDM1_DATIN6,I2C4_SMBA,,,,,,,,FMC_A7,,,EVENTOUT/EVENTOUT,ADC2_INP2, +PortF,PF14,,,,DFSDM1_CKIN6,I2C4_SCL,,,,,,,,FMC_A8,,,EVENTOUT/EVENTOUT,ADC2_INN2/ADC2_INP6, +PortF,PF15,,,,,I2C4_SDA,,,,,,,,FMC_A9,,,EVENTOUT/EVENTOUT,, +PortF,PF2,,,,,I2C2_SMBA,,,,,OCTOSPIM_P2_IO2,,,FMC_A2,,,EVENTOUT/EVENTOUT,, +PortF,PF3,,,,,,,,,,OCTOSPIM_P2_IO3,,,FMC_A3,,,EVENTOUT/EVENTOUT,, +PortF,PF4,,,,,,,,,,OCTOSPIM_P2_CLK,,,FMC_A4,,,EVENTOUT/EVENTOUT,, +PortF,PF5,,,,,,,,,,OCTOSPIM_P2_NCLK,,,FMC_A5,,,EVENTOUT/EVENTOUT,, +PortF,PF6,,TIM16_CH1,,,,SPI5_NSS,SAI1_SD_B,UART7_RX,,,OCTOSPIM_P1_IO3,,,,,EVENTOUT/EVENTOUT,, +PortF,PF7,,TIM17_CH1,,,,SPI5_SCK,SAI1_MCLK_B,UART7_TX,,,OCTOSPIM_P1_IO2,,,,,EVENTOUT/EVENTOUT,, +PortF,PF8,,TIM16_CH1N,,,,SPI5_MISO,SAI1_SCK_B,UART7_DE/UART7_RTS,,TIM13_CH1,OCTOSPIM_P1_IO0,,,,,EVENTOUT/EVENTOUT,, +PortF,PF9,,TIM17_CH1N,,,,SPI5_MOSI,SAI1_FS_B,UART7_CTS,,TIM14_CH1,OCTOSPIM_P1_IO1,,,,,EVENTOUT/EVENTOUT,, +PortG,PG0,,,,,,,,,,OCTOSPIM_P2_IO4,,UART9_RX,FMC_A10,,,EVENTOUT/EVENTOUT,, +PortG,PG1,,,,,,,,,,OCTOSPIM_P2_IO5,,UART9_TX,FMC_A11,,,EVENTOUT/EVENTOUT,, +PortG,PG10,,,,OCTOSPIM_P2_IO6,,I2S1_WS/SPI1_NSS,,,,LTDC_G3,SAI2_SD_B,SDMMC2_D1,FMC_NE3,DCMI_D2/PSSI_D2,LTDC_B2,EVENTOUT/EVENTOUT,, +PortG,PG11,,LPTIM1_IN2,,,,I2S1_CK/SPI1_SCK,,,SPDIFRX_IN1,OCTOSPIM_P2_IO7,SDMMC2_D2,USART10_RX,,DCMI_D3/PSSI_D3,LTDC_B3,EVENTOUT/EVENTOUT,, +PortG,PG12,,LPTIM1_IN1,,OCTOSPIM_P2_NCS,,I2S6_SDI/SPI6_MISO,,USART6_DE/USART6_RTS,SPDIFRX_IN2,LTDC_B4,SDMMC2_D3,USART10_TX,FMC_NE4,,LTDC_B1,EVENTOUT/EVENTOUT,, +PortG,PG13,DEBUG_TRACED0,LPTIM1_OUT,,,,I2S6_CK/SPI6_SCK,,USART6_CTS/USART6_NSS,,,SDMMC2_D6,USART10_CTS/USART10_NSS,FMC_A24,,LTDC_R0,EVENTOUT/EVENTOUT,, +PortG,PG14,DEBUG_TRACED1,LPTIM1_ETR,,,,I2S6_SDO/SPI6_MOSI,,USART6_TX,,OCTOSPIM_P1_IO7,SDMMC2_D7,USART10_DE/USART10_RTS,FMC_A25,,LTDC_B0,EVENTOUT/EVENTOUT,, +PortG,PG15,,,,,,,,USART6_CTS/USART6_NSS,,OCTOSPIM_P2_DQS,,USART10_CK,FMC_SDNCAS,DCMI_D13/PSSI_D13,,EVENTOUT/EVENTOUT,, +PortG,PG2,,,,TIM8_BKIN,,,,,,,,TIM8_BKIN_COMP1/TIM8_BKIN_COMP2,FMC_A12,,,EVENTOUT/EVENTOUT,, +PortG,PG3,,,,TIM8_BKIN2,,,,,,,,TIM8_BKIN2_COMP1/TIM8_BKIN2_COMP2,FMC_A13,,,EVENTOUT/EVENTOUT,, +PortG,PG4,,TIM1_BKIN2,,,,,,,,,,TIM1_BKIN2_COMP1/TIM1_BKIN2_COMP2,FMC_A14/FMC_BA0,,,EVENTOUT/EVENTOUT,, +PortG,PG5,,TIM1_ETR,,,,,,,,,,,FMC_A15/FMC_BA1,,,EVENTOUT/EVENTOUT,, +PortG,PG6,,TIM17_BKIN,,,,,,,,,OCTOSPIM_P1_NCS,,FMC_NE3,DCMI_D12/PSSI_D12,LTDC_R7,EVENTOUT/EVENTOUT,, +PortG,PG7,,,,,,,SAI1_MCLK_A,USART6_CK,,OCTOSPIM_P2_DQS,,,FMC_INT,DCMI_D13/PSSI_D13,LTDC_CLK,EVENTOUT/EVENTOUT,, +PortG,PG8,,,,TIM8_ETR,,I2S6_WS/SPI6_NSS,,USART6_DE/USART6_RTS,SPDIFRX_IN3,,,,FMC_SDCLK,,LTDC_G7,EVENTOUT/EVENTOUT,, +PortG,PG9,,,,,,I2S1_SDI/SPI1_MISO,,USART6_RX,SPDIFRX_IN4,OCTOSPIM_P1_IO6,SAI2_FS_B,SDMMC2_D0,FMC_NCE/FMC_NE2,DCMI_VSYNC/PSSI_RDY,,EVENTOUT/EVENTOUT,, +PortH,PH0-OSC_IN,,,,,,,,,,,,,,,,EVENTOUT/EVENTOUT,, +PortH,PH1-OSC_OUT,,,,,,,,,,,,,,,,EVENTOUT/EVENTOUT,, +PortH,PH10,,,TIM5_CH1,,I2C4_SMBA,,,,,,,,FMC_D18,DCMI_D1/PSSI_D1,LTDC_R4,EVENTOUT/EVENTOUT,, +PortH,PH11,,,TIM5_CH2,,I2C4_SCL,,,,,,,,FMC_D19,DCMI_D2/PSSI_D2,LTDC_R5,EVENTOUT/EVENTOUT,, +PortH,PH12,,,TIM5_CH3,,I2C4_SDA,,,,,,,,FMC_D20,DCMI_D3/PSSI_D3,LTDC_R6,EVENTOUT/EVENTOUT,, +PortH,PH13,,,,TIM8_CH1N,,,,,UART4_TX,FDCAN1_TX,,,FMC_D21,,LTDC_G2,EVENTOUT/EVENTOUT,, +PortH,PH14,,,,TIM8_CH2N,,,,,UART4_RX,FDCAN1_RX,,,FMC_D22,DCMI_D4/PSSI_D4,LTDC_G3,EVENTOUT/EVENTOUT,, +PortH,PH15,,,,TIM8_CH3N,,,,,,,,,FMC_D23,DCMI_D11/PSSI_D11,LTDC_G4,EVENTOUT/EVENTOUT,, +PortH,PH2,,LPTIM1_IN2,,,,,,,,OCTOSPIM_P1_IO4,SAI2_SCK_B,,FMC_SDCKE0,,LTDC_R0,EVENTOUT/EVENTOUT,, +PortH,PH3,,,,,,,,,,OCTOSPIM_P1_IO5,SAI2_MCLK_B,,FMC_SDNE0,,LTDC_R1,EVENTOUT/EVENTOUT,, +PortH,PH4,,,,,I2C2_SCL,,,,,LTDC_G5,USB_OTG_HS_ULPI_NXT,,,PSSI_D14,LTDC_G4,EVENTOUT/EVENTOUT,, +PortH,PH5,,,,,I2C2_SDA,SPI5_NSS,,,,,,,FMC_SDNWE,,,EVENTOUT/EVENTOUT,, +PortH,PH6,,,TIM12_CH1,,I2C2_SMBA,SPI5_SCK,,,,,,,FMC_SDNE1,DCMI_D8/PSSI_D8,,EVENTOUT/EVENTOUT,, +PortH,PH7,,,,,I2C3_SCL,SPI5_MISO,,,,,,,FMC_SDCKE1,DCMI_D9/PSSI_D9,,EVENTOUT/EVENTOUT,, +PortH,PH8,,,TIM5_ETR,,I2C3_SDA,,,,,,,,FMC_D16,DCMI_HSYNC/PSSI_DE,LTDC_R2,EVENTOUT/EVENTOUT,, +PortH,PH9,,,TIM12_CH2,,I2C3_SMBA,,,,,,,,FMC_D17,DCMI_D0/PSSI_D0,LTDC_R3,EVENTOUT/EVENTOUT,, +PortI,PI0,,,TIM5_CH4,,,I2S2_WS/SPI2_NSS,,,,,,,FMC_D24,DCMI_D13/PSSI_D13,LTDC_G5,EVENTOUT/EVENTOUT,, +PortI,PI1,,,,TIM8_BKIN2,,I2S2_CK/SPI2_SCK,,,,,,TIM8_BKIN2_COMP1/TIM8_BKIN2_COMP2,FMC_D25,DCMI_D8/PSSI_D8,LTDC_G6,EVENTOUT/EVENTOUT,, +PortI,PI10,,,,OCTOSPIM_P2_IO1,,,,,,,,,FMC_D31,PSSI_D14,LTDC_HSYNC,EVENTOUT/EVENTOUT,, +PortI,PI11,,,,OCTOSPIM_P2_IO2,,,,,,LTDC_G6,USB_OTG_HS_ULPI_DIR,,,PSSI_D15,,EVENTOUT/EVENTOUT,, +PortI,PI12,,,,OCTOSPIM_P2_IO3,,,,,,,,,,,LTDC_HSYNC,EVENTOUT/EVENTOUT,, +PortI,PI13,,,,OCTOSPIM_P2_CLK,,,,,,,,,,,LTDC_VSYNC,EVENTOUT/EVENTOUT,, +PortI,PI14,,,,OCTOSPIM_P2_NCLK,,,,,,,,,,,LTDC_CLK,EVENTOUT/EVENTOUT,, +PortI,PI15,,,,,,,,,,LTDC_G2,,,,,LTDC_R0,EVENTOUT/EVENTOUT,, +PortI,PI2,,,,TIM8_CH4,,I2S2_SDI/SPI2_MISO,,,,,,,FMC_D26,DCMI_D9/PSSI_D9,LTDC_G7,EVENTOUT/EVENTOUT,, +PortI,PI3,,,,TIM8_ETR,,I2S2_SDO/SPI2_MOSI,,,,,,,FMC_D27,DCMI_D10/PSSI_D10,,EVENTOUT/EVENTOUT,, +PortI,PI4,,,,TIM8_BKIN,,,,,,,SAI2_MCLK_A,TIM8_BKIN_COMP1/TIM8_BKIN_COMP2,FMC_NBL2,DCMI_D5/PSSI_D5,LTDC_B4,EVENTOUT/EVENTOUT,, +PortI,PI5,,,,TIM8_CH1,,,,,,,SAI2_SCK_A,,FMC_NBL3,DCMI_VSYNC/PSSI_RDY,LTDC_B5,EVENTOUT/EVENTOUT,, +PortI,PI6,,,,TIM8_CH2,,,,,,,SAI2_SD_A,,FMC_D28,DCMI_D6/PSSI_D6,LTDC_B6,EVENTOUT/EVENTOUT,, +PortI,PI7,,,,TIM8_CH3,,,,,,,SAI2_FS_A,,FMC_D29,DCMI_D7/PSSI_D7,LTDC_B7,EVENTOUT/EVENTOUT,, +PortI,PI8,,,,,,,,,,,,,,,,EVENTOUT/EVENTOUT,, +PortI,PI9,,,,OCTOSPIM_P2_IO0,,,,,UART4_RX,FDCAN1_RX,,,FMC_D30,,LTDC_VSYNC,EVENTOUT/EVENTOUT,, +PortJ,PJ0,,,,,,,,,,LTDC_R7,,,,,LTDC_R1,EVENTOUT/EVENTOUT,, +PortJ,PJ1,,,,OCTOSPIM_P2_IO4,,,,,,,,,,,LTDC_R2,EVENTOUT/EVENTOUT,, +PortJ,PJ10,,TIM1_CH2N,,TIM8_CH2,,SPI5_MOSI,,,,,,,,,LTDC_G3,EVENTOUT/EVENTOUT,, +PortJ,PJ11,,TIM1_CH2,,TIM8_CH2N,,SPI5_MISO,,,,,,,,,LTDC_G4,EVENTOUT/EVENTOUT,, +PortJ,PJ12,DEBUG_TRGOUT,,,,,,,,,LTDC_G3,,,,,LTDC_B0,EVENTOUT/EVENTOUT,, +PortJ,PJ13,,,,,,,,,,LTDC_B4,,,,,LTDC_B1,EVENTOUT/EVENTOUT,, +PortJ,PJ14,,,,,,,,,,,,,,,LTDC_B2,EVENTOUT/EVENTOUT,, +PortJ,PJ15,,,,,,,,,,,,,,,LTDC_B3,EVENTOUT/EVENTOUT,, +PortJ,PJ2,,,,OCTOSPIM_P2_IO5,,,,,,,,,,,LTDC_R3,EVENTOUT/EVENTOUT,, +PortJ,PJ3,,,,,,,,,,,,UART9_DE/UART9_RTS,,,LTDC_R4,EVENTOUT/EVENTOUT,, +PortJ,PJ4,,,,,,,,,,,,UART9_CTS,,,LTDC_R5,EVENTOUT/EVENTOUT,, +PortJ,PJ5,,,,,,,,,,,,,,,LTDC_R6,EVENTOUT/EVENTOUT,, +PortJ,PJ6,,,,TIM8_CH2,,,,,,,,,,,LTDC_R7,EVENTOUT/EVENTOUT,, +PortJ,PJ7,DEBUG_TRGIN,,,TIM8_CH2N,,,,,,,,,,,LTDC_G0,EVENTOUT/EVENTOUT,, +PortJ,PJ8,,TIM1_CH3N,,TIM8_CH1,,,,,UART8_TX,,,,,,LTDC_G1,EVENTOUT/EVENTOUT,, +PortJ,PJ9,,TIM1_CH3,,TIM8_CH1N,,,,,UART8_RX,,,,,,LTDC_G2,EVENTOUT/EVENTOUT,, +PortK,PK0,,TIM1_CH1N,,TIM8_CH3,,SPI5_SCK,,,,,,,,,LTDC_G5,EVENTOUT/EVENTOUT,, +PortK,PK1,,TIM1_CH1,,TIM8_CH3N,,SPI5_NSS,,,,,,,,,LTDC_G6,EVENTOUT/EVENTOUT,, +PortK,PK2,,TIM1_BKIN,,TIM8_BKIN,,,,,,,TIM8_BKIN_COMP1/TIM8_BKIN_COMP2,TIM1_BKIN_COMP1/TIM1_BKIN_COMP2,,,LTDC_G7,EVENTOUT/EVENTOUT,, +PortK,PK3,,,,OCTOSPIM_P2_IO6,,,,,,,,,,,LTDC_B4,EVENTOUT/EVENTOUT,, +PortK,PK4,,,,OCTOSPIM_P2_IO7,,,,,,,,,,,LTDC_B5,EVENTOUT/EVENTOUT,, +PortK,PK5,,,,OCTOSPIM_P2_NCS,,,,,,,,,,,LTDC_B6,EVENTOUT/EVENTOUT,, +PortK,PK6,,,,OCTOSPIM_P2_DQS,,,,,,,,,,,LTDC_B7,EVENTOUT/EVENTOUT,, +PortK,PK7,,,,,,,,,,,,,,,LTDC_DE,EVENTOUT/EVENTOUT,, diff --git a/ports/stm32/extint.c b/ports/stm32/extint.c index 695655f09f..699bc60040 100644 --- a/ports/stm32/extint.c +++ b/ports/stm32/extint.c @@ -166,7 +166,11 @@ STATIC const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = { #if defined(STM32H7) PVD_AVD_IRQn, RTC_Alarm_IRQn, + #if defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + RTC_TAMP_STAMP_CSS_LSE_IRQn, + #else TAMP_STAMP_IRQn, + #endif RTC_WKUP_IRQn, #elif defined(STM32WB) PVD_PVM_IRQn, diff --git a/ports/stm32/flash.c b/ports/stm32/flash.c index d399ece866..b926679f9f 100644 --- a/ports/stm32/flash.c +++ b/ports/stm32/flash.c @@ -253,7 +253,11 @@ int flash_erase(uint32_t flash_dest, uint32_t num_word32) { #endif EraseInitStruct.TypeErase = TYPEERASE_SECTORS; + #if defined(FLASH_CR_PSIZE) EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V + #else + EraseInitStruct.VoltageRange = 0; // unused parameter on STM32H7A3/B3 + #endif #if defined(STM32H7) EraseInitStruct.Banks = get_bank(flash_dest); #endif diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c index f28bd5b398..a114a9ad1a 100644 --- a/ports/stm32/machine_adc.c +++ b/ports/stm32/machine_adc.c @@ -130,6 +130,8 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) { adc->CFGR2 = 2 << ADC_CFGR2_CKMODE_Pos; // PCLK/4 (synchronous clock mode) #elif defined(STM32F4) || defined(STM32F7) || defined(STM32L4) ADCx_COMMON->CCR = 0; // ADCPR=PCLK/2 + #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + ADC12_COMMON->CCR = 3 << ADC_CCR_CKMODE_Pos; #elif defined(STM32H7) ADC12_COMMON->CCR = 3 << ADC_CCR_CKMODE_Pos; ADC3_COMMON->CCR = 3 << ADC_CCR_CKMODE_Pos; @@ -290,8 +292,9 @@ STATIC void adc_config_channel(ADC_TypeDef *adc, uint32_t channel, uint32_t samp *smpr = (*smpr & ~(7 << (channel * 3))) | sample_time << (channel * 3); // select sample time #elif defined(STM32H7) || defined(STM32L4) || defined(STM32WB) - - #if defined(STM32H7) + #if defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + ADC_Common_TypeDef *adc_common = ADC12_COMMON; + #elif defined(STM32H7) adc->PCSEL |= 1 << channel; ADC_Common_TypeDef *adc_common = adc == ADC3 ? ADC3_COMMON : ADC12_COMMON; #elif defined(STM32L4) @@ -413,7 +416,7 @@ STATIC mp_obj_t machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, s } else if (pin->adc_num & PIN_ADC2) { adc = ADC2; #endif - #if defined(ADC2) + #if defined(ADC3) } else if (pin->adc_num & PIN_ADC3) { adc = ADC3; #endif diff --git a/ports/stm32/main.c b/ports/stm32/main.c index e506cc5713..5d1ff2dcf5 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -378,6 +378,9 @@ void stm32_main(uint32_t reset_mode) { // enable the CCM RAM __HAL_RCC_CCMDATARAMEN_CLK_ENABLE(); #endif + #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + // Enable SRAM clock. + __HAL_RCC_SRDSRAM_CLK_ENABLE(); #elif defined(STM32H7) // Enable D2 SRAM1/2/3 clocks. __HAL_RCC_D2SRAM1_CLK_ENABLE(); diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h index 0cf6adce33..bd00bae9c3 100644 --- a/ports/stm32/mpconfigboard_common.h +++ b/ports/stm32/mpconfigboard_common.h @@ -314,6 +314,17 @@ #define MICROPY_HW_MAX_UART (8) #define MICROPY_HW_MAX_LPUART (0) +// Configuration for STM32H7A3/B3 series +#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || \ + defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + +#define MP_HAL_UNIQUE_ID_ADDRESS (0x08fff800) +#define PYB_EXTI_NUM_VECTORS (24) +#define MICROPY_HW_MAX_I2C (4) +#define MICROPY_HW_MAX_TIMER (17) +#define MICROPY_HW_MAX_UART (10) +#define MICROPY_HW_MAX_LPUART (1) + // Configuration for STM32H7 series #elif defined(STM32H7) diff --git a/ports/stm32/powerctrl.c b/ports/stm32/powerctrl.c index 9d9cc7f51b..406325581b 100644 --- a/ports/stm32/powerctrl.c +++ b/ports/stm32/powerctrl.c @@ -36,14 +36,22 @@ #define RCC_SR_SFTRSTF RCC_RSR_SFTRSTF #elif defined(STM32H747xx) #define RCC_SR_SFTRSTF RCC_RSR_SFT2RSTF +#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) +#define RCC_SR_SFTRSTF RCC_RSR_SFTRSTF #endif #define RCC_SR_RMVF RCC_RSR_RMVF // This macro returns the actual voltage scaling level factoring in the power overdrive bit. // If the current voltage scale is VOLTAGE_SCALE1 and PWER_ODEN bit is set return VOLTAGE_SCALE0 // otherwise the current voltage scaling (level VOS1 to VOS3) set in PWER_CSR is returned instead. +#if defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || \ + defined(STM32H7B3xx) || defined(STM32H7B3xxQ) +// TODO +#define POWERCTRL_GET_VOLTAGE_SCALING() PWR_REGULATOR_VOLTAGE_SCALE0 +#else #define POWERCTRL_GET_VOLTAGE_SCALING() \ (((PWR->CSR1 & PWR_CSR1_ACTVOS) && (SYSCFG->PWRCR & SYSCFG_PWRCR_ODEN)) ? \ PWR_REGULATOR_VOLTAGE_SCALE0 : (PWR->CSR1 & PWR_CSR1_ACTVOS)) +#endif #else #define RCC_SR CSR #define RCC_SR_SFTRSTF RCC_CSR_SFTRSTF @@ -148,6 +156,15 @@ STATIC const sysclk_scaling_table_entry_t volt_scale_table[] = { { 180, PWR_REGULATOR_VOLTAGE_SCALE2 }, // Above 180MHz uses default PWR_REGULATOR_VOLTAGE_SCALE1 }; +#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || \ + defined(STM32H7B3xx) || defined(STM32H7B3xxQ) +STATIC const sysclk_scaling_table_entry_t volt_scale_table[] = { + // See table 15 "FLASH recommended number of wait states and programming delay" of RM0455. + {88, PWR_REGULATOR_VOLTAGE_SCALE3}, + {160, PWR_REGULATOR_VOLTAGE_SCALE2}, + {225, PWR_REGULATOR_VOLTAGE_SCALE1}, + {280, PWR_REGULATOR_VOLTAGE_SCALE0}, +}; #elif defined(STM32H7) STATIC const sysclk_scaling_table_entry_t volt_scale_table[] = { // See table 55 "Kernel clock distribution overview" of RM0433. @@ -836,6 +853,9 @@ void powerctrl_enter_standby_mode(void) { #if defined(STM32F0) || defined(STM32L0) #define CR_BITS (RTC_CR_ALRAIE | RTC_CR_WUTIE | RTC_CR_TSIE) #define ISR_BITS (RTC_ISR_ALRAF | RTC_ISR_WUTF | RTC_ISR_TSF) + #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + #define CR_BITS (RTC_CR_ALRAIE | RTC_CR_ALRBIE | RTC_CR_WUTIE | RTC_CR_TSIE) + #define SR_BITS (RTC_SR_ALRAF | RTC_SR_ALRBF | RTC_SR_WUTF | RTC_SR_TSF) #else #define CR_BITS (RTC_CR_ALRAIE | RTC_CR_ALRBIE | RTC_CR_WUTIE | RTC_CR_TSIE) #define ISR_BITS (RTC_ISR_ALRAF | RTC_ISR_ALRBF | RTC_ISR_WUTF | RTC_ISR_TSF) @@ -852,7 +872,11 @@ void powerctrl_enter_standby_mode(void) { RTC->CR &= ~CR_BITS; // clear RTC wake-up flags + #if defined(SR_BITS) + RTC->SR &= ~SR_BITS; + #else RTC->ISR &= ~ISR_BITS; + #endif #if defined(STM32F7) // Save EWUP state diff --git a/ports/stm32/rtc.c b/ports/stm32/rtc.c index ab8b49e188..a5553b8a0a 100644 --- a/ports/stm32/rtc.c +++ b/ports/stm32/rtc.c @@ -339,9 +339,15 @@ STATIC HAL_StatusTypeDef PYB_RTC_Init(RTC_HandleTypeDef *hrtc) { hrtc->Instance->PRER |= (uint32_t)(hrtc->Init.AsynchPrediv << 16); // Exit Initialization mode + #if defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + hrtc->Instance->ICSR &= (uint32_t) ~RTC_ICSR_INIT; + #else hrtc->Instance->ISR &= (uint32_t) ~RTC_ISR_INIT; + #endif - #if defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) + #if defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + // do nothing + #elif defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) hrtc->Instance->OR &= (uint32_t) ~RTC_OR_ALARMOUTTYPE; hrtc->Instance->OR |= (uint32_t)(hrtc->Init.OutPutType); #elif defined(STM32F7) @@ -693,8 +699,13 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) { RTC->CR &= ~RTC_CR_WUTE; // wait until WUTWF is set + #if defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + while (!(RTC->ICSR & RTC_ICSR_WUTWF)) { + } + #else while (!(RTC->ISR & RTC_ISR_WUTWF)) { } + #endif if (enable) { // program WUT @@ -721,7 +732,11 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) { #endif // clear interrupt flags + #if defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + RTC->SR &= ~RTC_SR_WUTF; + #else RTC->ISR &= ~RTC_ISR_WUTF; + #endif #if defined(STM32L4) || defined(STM32WB) EXTI->PR1 = 1 << EXTI_RTC_WAKEUP; #elif defined(STM32H7) diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c index 4dde201a2f..ed97c4fe0b 100644 --- a/ports/stm32/stm32_it.c +++ b/ports/stm32/stm32_it.c @@ -527,7 +527,11 @@ void TAMP_STAMP_IRQHandler(void) { void RTC_WKUP_IRQHandler(void) { IRQ_ENTER(RTC_WKUP_IRQn); + #if defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + RTC->SR &= ~RTC_SR_WUTF; // clear wakeup interrupt flag + #else RTC->ISR &= ~RTC_ISR_WUTF; // clear wakeup interrupt flag + #endif Handle_EXTI_Irq(EXTI_RTC_WAKEUP); // clear EXTI flag and execute optional callback IRQ_EXIT(RTC_WKUP_IRQn); } diff --git a/ports/stm32/system_stm32.c b/ports/stm32/system_stm32.c index 4e89204bf6..8142fd0a5c 100644 --- a/ports/stm32/system_stm32.c +++ b/ports/stm32/system_stm32.c @@ -180,7 +180,9 @@ void SystemClock_Config(void) { #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) /* Enable Power Control clock */ - #if defined(STM32H7) + #if defined(STM32H7A3xxQ) || defined(STM32H7B3xxQ) + MODIFY_REG(PWR->CR3, PWR_SUPPLY_CONFIG_MASK, PWR_CR3_SMPSEN); + #elif defined(STM32H7) MODIFY_REG(PWR->CR3, PWR_CR3_SCUEN, 0); #else __PWR_CLK_ENABLE(); @@ -197,7 +199,7 @@ void SystemClock_Config(void) { #if defined(STM32H7) // Wait for PWR_FLAG_VOSRDY - while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) { + while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) { } #endif diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c index a34d2984da..c23e7e02d4 100644 --- a/ports/stm32/timer.c +++ b/ports/stm32/timer.c @@ -239,6 +239,9 @@ uint32_t timer_get_source_freq(uint32_t tim_id) { #if defined(STM32F0) source = HAL_RCC_GetPCLK1Freq(); clk_div = RCC->CFGR & RCC_CFGR_PPRE; + #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + source = HAL_RCC_GetPCLK2Freq(); + clk_div = RCC->CDCFGR2 & RCC_CDCFGR2_CDPPRE2; #elif defined(STM32H7) source = HAL_RCC_GetPCLK2Freq(); clk_div = RCC->D2CFGR & RCC_D2CFGR_D2PPRE2; @@ -251,6 +254,8 @@ uint32_t timer_get_source_freq(uint32_t tim_id) { source = HAL_RCC_GetPCLK1Freq(); #if defined(STM32F0) clk_div = RCC->CFGR & RCC_CFGR_PPRE; + #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + clk_div = RCC->CDCFGR1 & RCC_CDCFGR2_CDPPRE1; #elif defined(STM32H7) clk_div = RCC->D2CFGR & RCC_D2CFGR_D2PPRE1; #else diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c index d2953b2646..627c33397d 100644 --- a/ports/stm32/uart.c +++ b/ports/stm32/uart.c @@ -717,6 +717,33 @@ uint32_t uart_get_source_freq(pyb_uart_obj_t *self) { uart_clk = LSE_VALUE; break; } + #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + uint32_t csel; + if (self->uart_id == 1 || self->uart_id == 6 || self->uart_id == 9 || self->uart_id == 10) { + csel = RCC->CDCCIP2R >> 3; + } else { + csel = RCC->CDCCIP2R; + } + switch (csel & 3) { + case 0: + if (self->uart_id == 1 || self->uart_id == 6 || self->uart_id == 9 || self->uart_id == 10) { + uart_clk = HAL_RCC_GetPCLK2Freq(); + } else { + uart_clk = HAL_RCC_GetPCLK1Freq(); + } + break; + case 3: + uart_clk = HSI_VALUE; + break; + case 4: + uart_clk = CSI_VALUE; + break; + case 5: + uart_clk = LSE_VALUE; + break; + default: + break; + } #elif defined(STM32H7) uint32_t csel; if (self->uart_id == 1 || self->uart_id == 6) { diff --git a/ports/stm32/usbd_conf.c b/ports/stm32/usbd_conf.c index d24881d202..50e10ba178 100644 --- a/ports/stm32/usbd_conf.c +++ b/ports/stm32/usbd_conf.c @@ -59,6 +59,7 @@ PCD_HandleTypeDef pcd_hs_handle; * @retval None */ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) { + #if MICROPY_HW_USB_FS if (hpcd->Instance == USB_OTG_FS) { #if defined(STM32H7) const uint32_t otg_alt = GPIO_AF10_OTG1_FS; @@ -125,12 +126,18 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) { NVIC_SetPriority(OTG_FS_IRQn, IRQ_PRI_OTG_FS); HAL_NVIC_EnableIRQ(OTG_FS_IRQn); #endif + + return; } + #endif + #if MICROPY_HW_USB_HS - else if (hpcd->Instance == USB_OTG_HS) { + if (hpcd->Instance == USB_OTG_HS) { #if MICROPY_HW_USB_HS_IN_FS - #if defined(STM32H7) + #if defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + const uint32_t otg_alt = GPIO_AF10_OTG1_FS; + #elif defined(STM32H7) const uint32_t otg_alt = GPIO_AF12_OTG2_FS; #else const uint32_t otg_alt = GPIO_AF12_OTG_HS_FS; @@ -204,13 +211,17 @@ void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) { __HAL_RCC_USB_CLK_DISABLE(); #else + #if MICROPY_HW_USB_FS if (hpcd->Instance == USB_OTG_FS) { /* Disable USB FS Clocks */ __USB_OTG_FS_CLK_DISABLE(); __SYSCFG_CLK_DISABLE(); + return; } + #endif + #if MICROPY_HW_USB_HS - else if (hpcd->Instance == USB_OTG_HS) { + if (hpcd->Instance == USB_OTG_HS) { /* Disable USB FS Clocks */ __USB_OTG_HS_CLK_DISABLE(); __SYSCFG_CLK_DISABLE(); From e3eebc329f06983dd1fe304e1ceddbafb814f1e6 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 15 Sep 2021 11:07:43 +1000 Subject: [PATCH 037/335] stm32: Suggest putting code in main.py not boot.py. Don't want users to accidentally use boot.py (because recovering requires knowing how to activate safe mode). Signed-off-by: Jim Mussared --- docs/pyboard/tutorial/usb_mouse.rst | 4 ++-- ports/cc3200/mptask.c | 4 ++-- ports/stm32/factoryreset.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/pyboard/tutorial/usb_mouse.rst b/docs/pyboard/tutorial/usb_mouse.rst index 8166946ecd..d05b16ed5c 100644 --- a/docs/pyboard/tutorial/usb_mouse.rst +++ b/docs/pyboard/tutorial/usb_mouse.rst @@ -8,8 +8,8 @@ To do this we must first edit the ``boot.py`` file to change the USB configuration. If you have not yet touched your ``boot.py`` file then it will look something like this:: - # boot.py -- run on boot-up - # can run arbitrary Python, but best to keep it minimal + # boot.py -- run on boot to configure USB and filesystem + # Put app code in main.py import pyb #pyb.main('main.py') # main script to run after this one diff --git a/ports/cc3200/mptask.c b/ports/cc3200/mptask.c index b764c4712c..599211bdfb 100644 --- a/ports/cc3200/mptask.c +++ b/ports/cc3200/mptask.c @@ -99,8 +99,8 @@ OsiTaskHandle svTaskHandle; static fs_user_mount_t *sflash_vfs_fat; static const char fresh_main_py[] = "# main.py -- put your code here!\r\n"; -static const char fresh_boot_py[] = "# boot.py -- run on boot-up\r\n" - "# can run arbitrary Python, but best to keep it minimal\r\n" +static const char fresh_boot_py[] = "# boot.py -- run on boot to configure USB and filesystem\r\n" + "# Put app code in main.py\r\n" #if MICROPY_STDIO_UART "import os, machine\r\n" "os.dupterm(machine.UART(0, " MP_STRINGIFY(MICROPY_STDIO_UART_BAUD) "))\r\n" diff --git a/ports/stm32/factoryreset.c b/ports/stm32/factoryreset.c index 725ecd12a8..999056e726 100644 --- a/ports/stm32/factoryreset.c +++ b/ports/stm32/factoryreset.c @@ -37,8 +37,8 @@ #if MICROPY_VFS_FAT static const char fresh_boot_py[] = - "# boot.py -- run on boot-up\r\n" - "# can run arbitrary Python, but best to keep it minimal\r\n" + "# boot.py -- run on boot to configure USB and filesystem\r\n" + "# Put app code in main.py\r\n" "\r\n" "import machine\r\n" "import pyb\r\n" From a6907c779af9c5e7c4516e1c722e61e985103ac7 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 15 Sep 2021 17:17:49 +1000 Subject: [PATCH 038/335] stm32/boards/make-pins.py: Allow a CPU pin to be hidden. This change allows a CPU pin to be hidden from the user by prefixing it with a "-" in the pins.csv file for a board. It will still be available in C code, just not exposed to Python. Signed-off-by: Damien George --- ports/stm32/boards/make-pins.py | 64 ++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/ports/stm32/boards/make-pins.py b/ports/stm32/boards/make-pins.py index d898832f09..d3e2d0256f 100755 --- a/ports/stm32/boards/make-pins.py +++ b/ports/stm32/boards/make-pins.py @@ -1,5 +1,49 @@ #!/usr/bin/env python -"""Creates the pin file for the STM32F4xx.""" + +""" +Generates pin source files based on an MCU alternate-function definition (eg +stm32f405_af.csv) and a board-specific pin definition file, pins.csv. + +The pins.csv file must contain lines of the form: + + board,cpu + +Where "board" is the user-facing name of the pin as specified by the particular +board layout and markings, and "cpu" is the corresponding name of the CPU/MCU +pin. + +The "board" entry may be absent if the CPU pin has no additional name, and both +entries may start with "-" to hide them from the corresponding Python dict of +pins, and hence hide them from the user (but they are still accessible in C). + +For example, take the following pins.csv file: + + X1,PA0 + -X2,PA1 + X3,-PA2 + -X4,-PA3 + ,PA4 + ,-PA5 + +The first row here configures: +- The CPU pin PA0 is labelled X1. +- The Python user can access both by the names Pin("X1") and Pin("A0"). +- The Python user can access both by the members Pin.board.X1 and Pin.cpu.A0. +- In C code they are available as pyb_pin_X1 and pin_A0. + +Prefixing the names with "-" hides them from the user. The following table +summarises the various possibilities: + + pins.csv entry | board name | cpu name | C board name | C cpu name + ---------------+------------+----------+--------------+----------- + X1,PA0 "X1" "A0" pyb_pin_X1 pin_A0 + -X2,PA1 - "A1" pyb_pin_X2 pin_A1 + X3,-PA2 "X3" - pyb_pin_X3 pin_A2 + -X4,-PA3 - - pyb_pin_X4 pin_A3 + ,PA4 - "A4" - pin_A4 + ,-PA5 - - - pin_A5 + +""" from __future__ import print_function @@ -273,6 +317,9 @@ class NamedPin(object): self._name = name self._pin = pin + def set_hidden(self, value): + self._is_hidden = value + def is_hidden(self): return self._is_hidden @@ -293,7 +340,7 @@ class Pins(object): for named_pin in self.cpu_pins: pin = named_pin.pin() if pin.port == port_num and pin.pin == pin_num: - return pin + return named_pin def parse_af_file(self, filename, pinname_col, af_col): with open(filename, "r") as csvfile: @@ -315,12 +362,19 @@ class Pins(object): with open(filename, "r") as csvfile: rows = csv.reader(csvfile) for row in rows: + cpu_pin_name = row[1] + cpu_pin_hidden = False + if cpu_pin_name.startswith("-"): + cpu_pin_name = cpu_pin_name[1:] + cpu_pin_hidden = True try: - (port_num, pin_num) = parse_port_pin(row[1]) + (port_num, pin_num) = parse_port_pin(cpu_pin_name) except: continue - pin = self.find_pin(port_num, pin_num) - if pin: + named_pin = self.find_pin(port_num, pin_num) + if named_pin: + named_pin.set_hidden(cpu_pin_hidden) + pin = named_pin.pin() pin.set_is_board_pin() if row[0]: # Only add board pins that have a name self.board_pins.append(NamedPin(row[0], pin)) From c51cc46bf82d1f90e20f96798f27e6f496ec3266 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Sep 2021 12:52:23 +1000 Subject: [PATCH 039/335] stm32/boards/make-pins.py: Allow empty lines and comments in pins.csv. Signed-off-by: Damien George --- ports/stm32/boards/make-pins.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ports/stm32/boards/make-pins.py b/ports/stm32/boards/make-pins.py index d3e2d0256f..c7423cb966 100755 --- a/ports/stm32/boards/make-pins.py +++ b/ports/stm32/boards/make-pins.py @@ -4,7 +4,8 @@ Generates pin source files based on an MCU alternate-function definition (eg stm32f405_af.csv) and a board-specific pin definition file, pins.csv. -The pins.csv file must contain lines of the form: +The pins.csv file can contain empty lines, comments (a line beginning with "#") +or pin definition lines. Pin definition lines must be of the form: board,cpu @@ -362,6 +363,12 @@ class Pins(object): with open(filename, "r") as csvfile: rows = csv.reader(csvfile) for row in rows: + if len(row) == 0 or row[0].startswith("#"): + # Skip empty lines, and lines starting with "#" + continue + if len(row) != 2: + raise ValueError("Expecting two entries in a row") + cpu_pin_name = row[1] cpu_pin_hidden = False if cpu_pin_name.startswith("-"): From 0c0807e08480b5bf3734648bd0f7f4405e1989f5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 15 Sep 2021 21:12:53 +1000 Subject: [PATCH 040/335] stm32/dma: Add functions for external users of DMA to enable clock. Any external user of DMA (eg a board with a custom DMA driver) must call dma_external_acquire() for their DMA controller/stream to ensure that the DMA clock is not automatically turned off while it's still being used externally. Signed-off-by: Damien George --- ports/stm32/dma.c | 10 ++++++++++ ports/stm32/dma.h | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c index ba09dc1707..4b078eebb6 100644 --- a/ports/stm32/dma.c +++ b/ports/stm32/dma.c @@ -1233,3 +1233,13 @@ void dma_nohal_start(const dma_descr_t *descr, uint32_t src_addr, uint32_t dst_a } #endif + +#define DMA_ID_FROM_CONTROLLER_STREAM(c, s) ((s) + (c) * NSTREAMS_PER_CONTROLLER) + +void dma_external_acquire(uint32_t controller, uint32_t stream) { + dma_enable_clock(DMA_ID_FROM_CONTROLLER_STREAM(controller, stream)); +} + +void dma_external_release(uint32_t controller, uint32_t stream) { + dma_disable_clock(DMA_ID_FROM_CONTROLLER_STREAM(controller, stream)); +} diff --git a/ports/stm32/dma.h b/ports/stm32/dma.h index 8bd101a611..00200bae46 100644 --- a/ports/stm32/dma.h +++ b/ports/stm32/dma.h @@ -102,13 +102,21 @@ extern const dma_descr_t dma_I2C_4_RX; #endif +// API that configures the DMA via the HAL. void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint32_t dir, void *data); void dma_init_handle(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint32_t dir, void *data); void dma_deinit(const dma_descr_t *dma_descr); void dma_invalidate_channel(const dma_descr_t *dma_descr); +// API that configures the DMA directly and does not use the HAL. void dma_nohal_init(const dma_descr_t *descr, uint32_t config); void dma_nohal_deinit(const dma_descr_t *descr); void dma_nohal_start(const dma_descr_t *descr, uint32_t src_addr, uint32_t dst_addr, uint16_t len); +// API to be used if DMA is controlled externally, to ensure the clock remains enabled. +// - controller: should be 0 or 1, corresponding to DMA1 or DMA2 +// - stream: should be 0 to N, corresponding to Stream0..StreamN, or Channel1..ChannelN +void dma_external_acquire(uint32_t controller, uint32_t stream); +void dma_external_release(uint32_t controller, uint32_t stream); + #endif // MICROPY_INCLUDED_STM32_DMA_H From 01374d941f9d7398e35990b574769b20c6779457 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 14 Aug 2021 01:43:15 +1000 Subject: [PATCH 041/335] py/mpconfig.h: Define initial templates for "feature levels". This is the beginning of a set of changes to simplify enabling/disabling features. The goals are: - Remove redundancy from mpconfigport.h (never set a value to the default -- make it clear exactly what's being enabled). - Improve consistency between ports. All "similar" ports (i.e. approx same flash size) should get the same features. - Simplify mpconfigport.h -- just get default/sensible options for the size of the port. - Make it easy for defining constrained boards (e.g. STM32F0/L0), they can just set a lower level. This commit makes a step towards this and defines the "core" level as the current default feature set, and a "minimal" level to turn off everything. And a few placeholder levels are added for where the other ports will roughly land. This is a no-op change for all ports. Signed-off-by: Jim Mussared --- py/mpconfig.h | 107 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 36 deletions(-) diff --git a/py/mpconfig.h b/py/mpconfig.h index 1b41b6bd0f..7b98112e17 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -62,6 +62,31 @@ #include #endif +// Disable all optional features (i.e. minimal port). +#define MICROPY_CONFIG_ROM_LEVEL_MINIMUM (0) +// Only enable core features (constrained flash, e.g. STM32L072) +#define MICROPY_CONFIG_ROM_LEVEL_CORE_FEATURES (10) +// Enable most common features (small on-device flash, e.g. STM32F411) +#define MICROPY_CONFIG_ROM_LEVEL_BASIC_FEATURES (20) +// Enable convenience features (medium on-device flash, e.g. STM32F405) +#define MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES (30) +// Enable all common features (large/external flash, rp2, unix) +#define MICROPY_CONFIG_ROM_LEVEL_FULL_FEATURES (40) +// Enable everything (e.g. coverage) +#define MICROPY_CONFIG_ROM_LEVEL_EVERYTHING (50) + +// Ports/boards should set this, but default to level=core. +#ifndef MICROPY_CONFIG_ROM_LEVEL +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_CORE_FEATURES) +#endif + +// Helper macros for "have at least this level". +#define MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES (MICROPY_CONFIG_ROM_LEVEL >= MICROPY_CONFIG_ROM_LEVEL_CORE_FEATURES) +#define MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_BASIC_FEATURES (MICROPY_CONFIG_ROM_LEVEL >= MICROPY_CONFIG_ROM_LEVEL_BASIC_FEATURES) +#define MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES (MICROPY_CONFIG_ROM_LEVEL >= MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES) +#define MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_FULL_FEATURES (MICROPY_CONFIG_ROM_LEVEL >= MICROPY_CONFIG_ROM_LEVEL_FULL_FEATURES) +#define MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING (MICROPY_CONFIG_ROM_LEVEL >= MICROPY_CONFIG_ROM_LEVEL_EVERYTHING) + // Any options not explicitly set in mpconfigport.h will get default // values below. @@ -156,7 +181,7 @@ // Support automatic GC when reaching allocation threshold, // configurable by gc.threshold(). #ifndef MICROPY_GC_ALLOC_THRESHOLD -#define MICROPY_GC_ALLOC_THRESHOLD (1) +#define MICROPY_GC_ALLOC_THRESHOLD (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Number of bytes to allocate initially when creating new chunks to store @@ -249,7 +274,11 @@ // Number of bytes used to store qstr hash #ifndef MICROPY_QSTR_BYTES_IN_HASH +#if MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES #define MICROPY_QSTR_BYTES_IN_HASH (2) +#else +#define MICROPY_QSTR_BYTES_IN_HASH (1) +#endif #endif // Avoid using C stack when making Python function calls. C stack still @@ -383,7 +412,7 @@ // Whether to include the compiler #ifndef MICROPY_ENABLE_COMPILER -#define MICROPY_ENABLE_COMPILER (1) +#define MICROPY_ENABLE_COMPILER (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether the compiler is dynamically configurable (ie at runtime) @@ -403,12 +432,12 @@ // Whether to enable constant folding; eg 1+2 rewritten as 3 #ifndef MICROPY_COMP_CONST_FOLDING -#define MICROPY_COMP_CONST_FOLDING (1) +#define MICROPY_COMP_CONST_FOLDING (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to enable optimisations for constant literals, eg OrderedDict #ifndef MICROPY_COMP_CONST_LITERAL -#define MICROPY_COMP_CONST_LITERAL (1) +#define MICROPY_COMP_CONST_LITERAL (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to enable lookup of constants in modules; eg module.CONST @@ -418,13 +447,13 @@ // Whether to enable constant optimisation; id = const(value) #ifndef MICROPY_COMP_CONST -#define MICROPY_COMP_CONST (1) +#define MICROPY_COMP_CONST (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to enable optimisation of: a, b = c, d // Costs 124 bytes (Thumb2) #ifndef MICROPY_COMP_DOUBLE_TUPLE_ASSIGN -#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (1) +#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to enable optimisation of: a, b, c = d, e, f @@ -517,7 +546,7 @@ // When disabled, only importing of built-in modules is supported // When enabled, a port must implement mp_import_stat (among other things) #ifndef MICROPY_ENABLE_EXTERNAL_IMPORT -#define MICROPY_ENABLE_EXTERNAL_IMPORT (1) +#define MICROPY_ENABLE_EXTERNAL_IMPORT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to use the POSIX reader for importing files @@ -684,7 +713,13 @@ typedef long long mp_longint_impl_t; #define MICROPY_ERROR_REPORTING_DETAILED (3) #ifndef MICROPY_ERROR_REPORTING +#if MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_FULL_FEATURES +#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_DETAILED) +#elif MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL) +#else +#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) +#endif #endif // Whether issue warnings during compiling/execution @@ -740,7 +775,7 @@ typedef double mp_float_t; // TODO: Originally intended as generic category to not // add bunch of once-off options. May need refactoring later #ifndef MICROPY_CPYTHON_COMPAT -#define MICROPY_CPYTHON_COMPAT (1) +#define MICROPY_CPYTHON_COMPAT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Perform full checks as done by CPython. Disabling this @@ -749,7 +784,7 @@ typedef double mp_float_t; // grave issues (in other words, only user app should be, // affected, not system). #ifndef MICROPY_FULL_CHECKS -#define MICROPY_FULL_CHECKS (1) +#define MICROPY_FULL_CHECKS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether POSIX-semantics non-blocking streams are supported @@ -770,7 +805,7 @@ typedef double mp_float_t; // Whether to support module-level __getattr__ (see PEP 562) #ifndef MICROPY_MODULE_GETATTR -#define MICROPY_MODULE_GETATTR (1) +#define MICROPY_MODULE_GETATTR (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether module weak links are supported @@ -804,7 +839,7 @@ typedef double mp_float_t; // list.append([], 1). Without this check such calls will have undefined // behaviour (usually segfault) if the first argument is the wrong type. #ifndef MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG -#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (1) +#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to use internally defined errno's (otherwise system provided ones) @@ -849,7 +884,7 @@ typedef double mp_float_t; // inheritance makes some C functions inherently recursive, and adds a bit of // code overhead. #ifndef MICROPY_MULTIPLE_INHERITANCE -#define MICROPY_MULTIPLE_INHERITANCE (1) +#define MICROPY_MULTIPLE_INHERITANCE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to implement attributes on functions @@ -873,7 +908,7 @@ typedef double mp_float_t; // Support for async/await/async for/async with #ifndef MICROPY_PY_ASYNC_AWAIT -#define MICROPY_PY_ASYNC_AWAIT (1) +#define MICROPY_PY_ASYNC_AWAIT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Support for literal string interpolation, f-strings (see PEP 498, Python 3.6+) @@ -883,7 +918,7 @@ typedef double mp_float_t; // Support for assignment expressions with := (see PEP 572, Python 3.8+) #ifndef MICROPY_PY_ASSIGN_EXPR -#define MICROPY_PY_ASSIGN_EXPR (1) +#define MICROPY_PY_ASSIGN_EXPR (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Non-standard .pend_throw() method for generators, allowing for @@ -892,7 +927,7 @@ typedef double mp_float_t; // to generator's .send() or .__next__(). (This is useful to implement // async schedulers.) #ifndef MICROPY_PY_GENERATOR_PEND_THROW -#define MICROPY_PY_GENERATOR_PEND_THROW (1) +#define MICROPY_PY_GENERATOR_PEND_THROW (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Issue a warning when comparing str and bytes objects @@ -917,12 +952,12 @@ typedef double mp_float_t; // Whether str.count() method provided #ifndef MICROPY_PY_BUILTINS_STR_COUNT -#define MICROPY_PY_BUILTINS_STR_COUNT (1) +#define MICROPY_PY_BUILTINS_STR_COUNT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether str % (...) formatting operator provided #ifndef MICROPY_PY_BUILTINS_STR_OP_MODULO -#define MICROPY_PY_BUILTINS_STR_OP_MODULO (1) +#define MICROPY_PY_BUILTINS_STR_OP_MODULO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether str.partition()/str.rpartition() method provided @@ -937,12 +972,12 @@ typedef double mp_float_t; // Whether to support bytearray object #ifndef MICROPY_PY_BUILTINS_BYTEARRAY -#define MICROPY_PY_BUILTINS_BYTEARRAY (1) +#define MICROPY_PY_BUILTINS_BYTEARRAY (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to support dict.fromkeys() class method #ifndef MICROPY_PY_BUILTINS_DICT_FROMKEYS -#define MICROPY_PY_BUILTINS_DICT_FROMKEYS (1) +#define MICROPY_PY_BUILTINS_DICT_FROMKEYS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to support memoryview object @@ -957,12 +992,12 @@ typedef double mp_float_t; // Whether to support set object #ifndef MICROPY_PY_BUILTINS_SET -#define MICROPY_PY_BUILTINS_SET (1) +#define MICROPY_PY_BUILTINS_SET (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to support slice subscript operators and slice object #ifndef MICROPY_PY_BUILTINS_SLICE -#define MICROPY_PY_BUILTINS_SLICE (1) +#define MICROPY_PY_BUILTINS_SLICE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to support slice attribute read access, @@ -983,13 +1018,13 @@ typedef double mp_float_t; // Whether to support property object #ifndef MICROPY_PY_BUILTINS_PROPERTY -#define MICROPY_PY_BUILTINS_PROPERTY (1) +#define MICROPY_PY_BUILTINS_PROPERTY (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to implement the start/stop/step attributes (readback) on // the "range" builtin type. Rarely used, and costs ~60 bytes (x86). #ifndef MICROPY_PY_BUILTINS_RANGE_ATTRS -#define MICROPY_PY_BUILTINS_RANGE_ATTRS (1) +#define MICROPY_PY_BUILTINS_RANGE_ATTRS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to support binary ops [only (in)equality is defined] between range @@ -1039,7 +1074,7 @@ typedef double mp_float_t; // Whether to support enumerate function(type) #ifndef MICROPY_PY_BUILTINS_ENUMERATE -#define MICROPY_PY_BUILTINS_ENUMERATE (1) +#define MICROPY_PY_BUILTINS_ENUMERATE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to support eval and exec functions @@ -1055,12 +1090,12 @@ typedef double mp_float_t; // Whether to support filter function(type) #ifndef MICROPY_PY_BUILTINS_FILTER -#define MICROPY_PY_BUILTINS_FILTER (1) +#define MICROPY_PY_BUILTINS_FILTER (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to support reversed function(type) #ifndef MICROPY_PY_BUILTINS_REVERSED -#define MICROPY_PY_BUILTINS_REVERSED (1) +#define MICROPY_PY_BUILTINS_REVERSED (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to define "NotImplemented" special constant @@ -1076,7 +1111,7 @@ typedef double mp_float_t; // Whether to support min/max functions #ifndef MICROPY_PY_BUILTINS_MIN_MAX -#define MICROPY_PY_BUILTINS_MIN_MAX (1) +#define MICROPY_PY_BUILTINS_MIN_MAX (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Support for calls to pow() with 3 integer arguments @@ -1102,7 +1137,7 @@ typedef double mp_float_t; // Whether to set __file__ for imported modules #ifndef MICROPY_PY___FILE__ -#define MICROPY_PY___FILE__ (1) +#define MICROPY_PY___FILE__ (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to provide mem-info related functions in micropython module @@ -1124,7 +1159,7 @@ typedef double mp_float_t; // underlying code is shared with "bytearray" builtin type, so to // get real savings, it should be disabled too. #ifndef MICROPY_PY_ARRAY -#define MICROPY_PY_ARRAY (1) +#define MICROPY_PY_ARRAY (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to support slice assignments for array (and bytearray). @@ -1136,12 +1171,12 @@ typedef double mp_float_t; // Whether to support attrtuple type (MicroPython extension) // It provides space-efficient tuples with attribute access #ifndef MICROPY_PY_ATTRTUPLE -#define MICROPY_PY_ATTRTUPLE (1) +#define MICROPY_PY_ATTRTUPLE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to provide "collections" module #ifndef MICROPY_PY_COLLECTIONS -#define MICROPY_PY_COLLECTIONS (1) +#define MICROPY_PY_COLLECTIONS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to provide "ucollections.deque" type @@ -1161,7 +1196,7 @@ typedef double mp_float_t; // Whether to provide "math" module #ifndef MICROPY_PY_MATH -#define MICROPY_PY_MATH (1) +#define MICROPY_PY_MATH (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to provide special math functions: math.{erf,erfc,gamma,lgamma} @@ -1206,7 +1241,7 @@ typedef double mp_float_t; // Whether to provide "gc" module #ifndef MICROPY_PY_GC -#define MICROPY_PY_GC (1) +#define MICROPY_PY_GC (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to return number of collected objects from gc.collect() @@ -1216,7 +1251,7 @@ typedef double mp_float_t; // Whether to provide "io" module #ifndef MICROPY_PY_IO -#define MICROPY_PY_IO (1) +#define MICROPY_PY_IO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to provide "io.IOBase" class to support user streams @@ -1252,12 +1287,12 @@ typedef double mp_float_t; // Whether to provide "struct" module #ifndef MICROPY_PY_STRUCT -#define MICROPY_PY_STRUCT (1) +#define MICROPY_PY_STRUCT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to provide "sys" module #ifndef MICROPY_PY_SYS -#define MICROPY_PY_SYS (1) +#define MICROPY_PY_SYS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to provide "sys.maxsize" constant From 910e060f93c02c51a498f57ef77ccbe02566855b Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 15 Sep 2021 12:24:32 +1000 Subject: [PATCH 042/335] minimal/mpconfigport.h: Use MICROPY_CONFIG_ROM_LEVEL_MINIMUM. Update minimal port to use the new "minimal" rom level config (this is a no-op change, the binary is the same size and contains the exact same symbols). Signed-off-by: Jim Mussared --- ports/minimal/mpconfigport.h | 54 +++++++++++++----------------------- 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/ports/minimal/mpconfigport.h b/ports/minimal/mpconfigport.h index b34217f680..b83e0c2704 100644 --- a/ports/minimal/mpconfigport.h +++ b/ports/minimal/mpconfigport.h @@ -2,46 +2,30 @@ // options to control how MicroPython is built +// Use the minimal starting configuration (disables all optional features). +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_MINIMUM) + // You can disable the built-in MicroPython compiler by setting the following // config option to 0. If you do this then you won't get a REPL prompt, but you // will still be able to execute pre-compiled scripts, compiled with mpy-cross. #define MICROPY_ENABLE_COMPILER (1) -#define MICROPY_QSTR_BYTES_IN_HASH (1) -#define MICROPY_QSTR_EXTRA_POOL mp_qstr_frozen_const_pool -#define MICROPY_ALLOC_PATH_MAX (256) -#define MICROPY_ALLOC_PARSE_CHUNK_INIT (16) -#define MICROPY_COMP_CONST (0) -#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0) -#define MICROPY_ENABLE_GC (1) -#define MICROPY_GC_ALLOC_THRESHOLD (0) -#define MICROPY_HELPER_REPL (1) -#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) -#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) -#define MICROPY_PY_ASYNC_AWAIT (0) -#define MICROPY_PY_ASSIGN_EXPR (0) -#define MICROPY_PY_BUILTINS_BYTEARRAY (0) -#define MICROPY_PY_BUILTINS_DICT_FROMKEYS (0) -#define MICROPY_PY_BUILTINS_ENUMERATE (0) -#define MICROPY_PY_BUILTINS_FILTER (0) -#define MICROPY_PY_BUILTINS_REVERSED (0) -#define MICROPY_PY_BUILTINS_SET (0) -#define MICROPY_PY_BUILTINS_SLICE (0) -#define MICROPY_PY_BUILTINS_PROPERTY (0) -#define MICROPY_PY_BUILTINS_MIN_MAX (0) -#define MICROPY_PY_BUILTINS_STR_COUNT (0) -#define MICROPY_PY_BUILTINS_STR_OP_MODULO (0) -#define MICROPY_PY___FILE__ (0) -#define MICROPY_PY_GC (0) -#define MICROPY_PY_ARRAY (0) -#define MICROPY_PY_ATTRTUPLE (0) -#define MICROPY_PY_COLLECTIONS (0) -#define MICROPY_PY_IO (0) -#define MICROPY_PY_STRUCT (0) -#define MICROPY_PY_SYS (0) -#define MICROPY_MODULE_FROZEN_MPY (1) -#define MICROPY_CPYTHON_COMPAT (0) -#define MICROPY_MODULE_GETATTR (0) +#define MICROPY_QSTR_EXTRA_POOL mp_qstr_frozen_const_pool +#define MICROPY_ENABLE_GC (1) +#define MICROPY_HELPER_REPL (1) +#define MICROPY_MODULE_FROZEN_MPY (1) +#define MICROPY_ENABLE_EXTERNAL_IMPORT (1) +#define MICROPY_PY_MATH (1) + +#define MICROPY_ALLOC_PATH_MAX (256) +#define MICROPY_ALLOC_PARSE_CHUNK_INIT (16) + +#define MICROPY_COMP_CONST_FOLDING (1) +#define MICROPY_COMP_CONST_LITERAL (1) +#define MICROPY_FULL_CHECKS (1) +#define MICROPY_MULTIPLE_INHERITANCE (1) +#define MICROPY_PY_GENERATOR_PEND_THROW (1) +#define MICROPY_PY_BUILTINS_RANGE_ATTRS (1) // type definitions for the specific machine From 7b89ad8dbf432ab51eea6d138e179bf51394c786 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 19 Aug 2021 22:46:40 +1000 Subject: [PATCH 043/335] py/vm: Add a fast path for LOAD_ATTR on instance types. When the LOAD_ATTR opcode is executed there are quite a few different cases that have to be handled, but the common case is accessing a member on an instance type. Typically, built-in types provide methods which is why this is common. Fortunately, for this specific case, if the member is found in the member map then there's no further processing. This optimisation does a relatively cheap check (type is instance) and then forwards directly to the member map lookup, falling back to the regular path if necessary. Signed-off-by: Jim Mussared --- py/mpconfig.h | 6 ++++++ py/objtype.c | 1 + py/runtime.c | 4 ++++ py/vm.c | 21 ++++++++++++++++++++- 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/py/mpconfig.h b/py/mpconfig.h index 7b98112e17..2fbf1490d8 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -527,6 +527,12 @@ #define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0) #endif +// Optimise the fast path for loading attributes from instance types. Increases +// Thumb2 code size by about 48 bytes. +#ifndef MICROPY_OPT_LOAD_ATTR_FAST_PATH +#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (0) +#endif + // Whether to use fast versions of bitwise operations (and, or, xor) when the // arguments are both positive. Increases Thumb2 code size by about 250 bytes. #ifndef MICROPY_OPT_MPZ_BITWISE diff --git a/py/objtype.c b/py/objtype.c index 508bab99d3..0977a67ced 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -579,6 +579,7 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des assert(mp_obj_is_instance_type(mp_obj_get_type(self_in))); mp_obj_instance_t *self = MP_OBJ_TO_PTR(self_in); + // Note: This is fast-path'ed in the VM for the MP_BC_LOAD_ATTR operation. mp_map_elem_t *elem = mp_map_lookup(&self->members, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); if (elem != NULL) { // object member, always treated as a value diff --git a/py/runtime.c b/py/runtime.c index 27e5bc13eb..2f7cf1fa60 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1081,6 +1081,10 @@ void mp_load_method_maybe(mp_obj_t obj, qstr attr, mp_obj_t *dest) { dest[0] = MP_OBJ_NULL; dest[1] = MP_OBJ_NULL; + // Note: the specific case of obj being an instance type is fast-path'ed in the VM + // for the MP_BC_LOAD_ATTR opcode. Instance types handle type->attr and look up directly + // in their member's map. + // get the type const mp_obj_type_t *type = mp_obj_get_type(obj); diff --git a/py/vm.c b/py/vm.c index bbfc9914eb..e5a62e4415 100644 --- a/py/vm.c +++ b/py/vm.c @@ -414,7 +414,26 @@ dispatch_loop: FRAME_UPDATE(); MARK_EXC_IP_SELECTIVE(); DECODE_QSTR; - SET_TOP(mp_load_attr(TOP(), qst)); + mp_obj_t top = TOP(); + mp_obj_t obj; + #if MICROPY_OPT_LOAD_ATTR_FAST_PATH + // For the specific case of an instance type, it implements .attr + // and forwards to its members map. Attribute lookups on instance + // types are extremely common, so avoid all the other checks and + // calls that normally happen first. + mp_map_elem_t *elem = NULL; + if (mp_obj_is_instance_type(mp_obj_get_type(top))) { + mp_obj_instance_t *self = MP_OBJ_TO_PTR(top); + elem = mp_map_lookup(&self->members, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); + } + if (elem) { + obj = elem->value; + } else + #endif + { + obj = mp_load_attr(top, qst); + } + SET_TOP(obj); DISPATCH(); } #else From 11ef8f22fe7701cc75b6aaf2386670891eaacf92 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 18 Aug 2021 14:52:48 +1000 Subject: [PATCH 044/335] py/map: Add an optional cache of (map+index) to speed up map lookups. The existing inline bytecode caching optimisation, selected by MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE, reserves an extra byte in the bytecode after certain opcodes, which at runtime stores a map index of the likely location of this field when looking up the qstr. This scheme is incompatible with bytecode-in-ROM, and doesn't work with native generated code. It also stores bytecode in .mpy files which is of a different format to when the feature is disabled, making generation of .mpy files more complex. This commit provides an alternative optimisation via an approach that adds a global cache for map offsets, then all mp_map_lookup operations use it. It's less precise than bytecode caching, but allows the cache to be independent and external to the bytecode that is executing. It also works for the native emitter and adds a similar performance boost on top of the gain already provided by the native emitter. Signed-off-by: Jim Mussared --- py/map.c | 35 +++++++++++++++++++++++++++++++++++ py/mpconfig.h | 14 ++++++++++++++ py/mpstate.h | 5 +++++ 3 files changed, 54 insertions(+) diff --git a/py/map.c b/py/map.c index 54f4b0204b..1c43616364 100644 --- a/py/map.c +++ b/py/map.c @@ -40,6 +40,27 @@ #define DEBUG_printf(...) (void)0 #endif +#if MICROPY_OPT_MAP_LOOKUP_CACHE +// MP_STATE_VM(map_lookup_cache) provides a cache of index to the last known +// position of that index in any map. On a cache hit, this allows +// short-circuiting the full linear search in the case of an ordered map +// (i.e. all builtin modules and objects' locals dicts), and computation of +// the hash (and potentially some linear probing) in the case of a regular +// map. Note the same cache is shared across all maps. + +// Gets the index into the cache for this index. Shift down by two to remove +// mp_obj_t tag bits. +#define MAP_CACHE_OFFSET(index) ((((uintptr_t)(index)) >> 2) % MICROPY_OPT_MAP_LOOKUP_CACHE_SIZE) +// Gets the map cache entry for the corresponding index. +#define MAP_CACHE_ENTRY(index) (MP_STATE_VM(map_lookup_cache)[MAP_CACHE_OFFSET(index)]) +// Retrieve the mp_obj_t at the location suggested by the cache. +#define MAP_CACHE_GET(map, index) (&(map)->table[MAP_CACHE_ENTRY(index) % (map)->alloc]) +// Update the cache for this index. +#define MAP_CACHE_SET(index, pos) MAP_CACHE_ENTRY(index) = (pos) & 0xff; +#else +#define MAP_CACHE_SET(index, pos) +#endif + // This table of sizes is used to control the growth of hash tables. // The first set of sizes are chosen so the allocation fits exactly in a // 4-word GC block, and it's not so important for these small values to be @@ -136,6 +157,18 @@ mp_map_elem_t *mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t // If the map is a fixed array then we must only be called for a lookup assert(!map->is_fixed || lookup_kind == MP_MAP_LOOKUP); + #if MICROPY_OPT_MAP_LOOKUP_CACHE + // Try the cache for lookup or add-if-not-found. + if (lookup_kind != MP_MAP_LOOKUP_REMOVE_IF_FOUND && map->alloc) { + mp_map_elem_t *slot = MAP_CACHE_GET(map, index); + // Note: Just comparing key for value equality will have false negatives, but + // these will be handled by the regular path below. + if (slot->key == index) { + return slot; + } + } + #endif + // Work out if we can compare just pointers bool compare_only_ptrs = map->all_keys_are_qstrs; if (compare_only_ptrs) { @@ -172,6 +205,7 @@ mp_map_elem_t *mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t elem->value = value; } #endif + MAP_CACHE_SET(index, elem - map->table); return elem; } } @@ -254,6 +288,7 @@ mp_map_elem_t *mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t } // keep slot->value so that caller can access it if needed } + MAP_CACHE_SET(index, pos); return slot; } diff --git a/py/mpconfig.h b/py/mpconfig.h index 2fbf1490d8..97fc9bb580 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -533,6 +533,20 @@ #define MICROPY_OPT_LOAD_ATTR_FAST_PATH (0) #endif +// Use extra RAM to cache map lookups by remembering the likely location of +// the index. Avoids the hash computation on unordered maps, and avoids the +// linear search on ordered (especially in-ROM) maps. Can provide a +10-15% +// performance improvement on benchmarks involving lots of attribute access +// or dictionary lookup. +#ifndef MICROPY_OPT_MAP_LOOKUP_CACHE +#define MICROPY_OPT_MAP_LOOKUP_CACHE (0) +#endif + +// How much RAM (in bytes) to use for the map lookup cache. +#ifndef MICROPY_OPT_MAP_LOOKUP_CACHE_SIZE +#define MICROPY_OPT_MAP_LOOKUP_CACHE_SIZE (128) +#endif + // Whether to use fast versions of bitwise operations (and, or, xor) when the // arguments are both positive. Increases Thumb2 code size by about 250 bytes. #ifndef MICROPY_OPT_MPZ_BITWISE diff --git a/py/mpstate.h b/py/mpstate.h index 07335bae4c..53b2906872 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -231,6 +231,11 @@ typedef struct _mp_state_vm_t { // This is a global mutex used to make the VM/runtime thread-safe. mp_thread_mutex_t gil_mutex; #endif + + #if MICROPY_OPT_MAP_LOOKUP_CACHE + // See mp_map_lookup. + uint8_t map_lookup_cache[MICROPY_OPT_MAP_LOOKUP_CACHE_SIZE]; + #endif } mp_state_vm_t; // This structure holds state that is specific to a given thread. From 68219a295c75457c096ac42dbe8411b84e1e1a51 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Mon, 13 Sep 2021 10:55:23 +1000 Subject: [PATCH 045/335] stm32: Enable LOAD_ATTR fast path, and map lookup caching on >M0. Signed-off-by: Jim Mussared --- ports/stm32/mpconfigport.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 3147e28681..47795c4e71 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -60,6 +60,12 @@ #define MICROPY_OPT_COMPUTED_GOTO (1) #endif #define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0) +#ifndef MICROPY_OPT_LOAD_ATTR_FAST_PATH +#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (1) +#endif +#ifndef MICROPY_OPT_MAP_LOOKUP_CACHE +#define MICROPY_OPT_MAP_LOOKUP_CACHE (__CORTEX_M > 0) +#endif #define MICROPY_OPT_MPZ_BITWISE (1) #define MICROPY_OPT_MATH_FACTORIAL (1) From 60c6d5594f165cf3af6e66076f8dceb24e0d859f Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Mon, 13 Sep 2021 10:56:45 +1000 Subject: [PATCH 046/335] unix: Enable LOAD_ATTR fast path, and map lookup caching. Enabled for all variants except minimal. Signed-off-by: Jim Mussared --- ports/unix/mpconfigport.h | 6 ++++++ ports/unix/variants/minimal/mpconfigvariant.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index de5a65ab73..de45a800d3 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -82,6 +82,12 @@ #ifndef MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE #define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (1) #endif +#ifndef MICROPY_OPT_LOAD_ATTR_FAST_PATH +#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (1) +#endif +#ifndef MICROPY_OPT_MAP_LOOKUP_CACHE +#define MICROPY_OPT_MAP_LOOKUP_CACHE (1) +#endif #define MICROPY_MODULE_WEAK_LINKS (1) #define MICROPY_CAN_OVERRIDE_BUILTINS (1) #define MICROPY_VFS_POSIX_FILE (1) diff --git a/ports/unix/variants/minimal/mpconfigvariant.h b/ports/unix/variants/minimal/mpconfigvariant.h index e87b5d8ec0..d5eab09546 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.h +++ b/ports/unix/variants/minimal/mpconfigvariant.h @@ -56,6 +56,8 @@ #define MICROPY_STREAMS_NON_BLOCK (0) #define MICROPY_OPT_COMPUTED_GOTO (0) #define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0) +#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (0) +#define MICROPY_OPT_MAP_LOOKUP_CACHE (0) #define MICROPY_CAN_OVERRIDE_BUILTINS (0) #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) #define MICROPY_CPYTHON_COMPAT (0) From b326edf68c5edb648fac4dc2a3403ee33510e179 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Mon, 6 Sep 2021 12:28:06 +1000 Subject: [PATCH 047/335] all: Remove MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE. This commit removes all parts of code associated with the existing MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE optimisation option, including the -mcache-lookup-bc option to mpy-cross. This feature originally provided a significant performance boost for Unix, but wasn't able to be enabled for MCU targets (due to frozen bytecode), and added significant extra complexity to generating and distributing .mpy files. The equivalent performance gain is now provided by the combination of MICROPY_OPT_LOAD_ATTR_FAST_PATH and MICROPY_OPT_MAP_LOOKUP_CACHE (which has been enabled on the unix port in the previous commit). It's hard to provide precise performance numbers, but tests have been run on a wide variety of architectures (x86-64, ARM Cortex, Aarch64, RISC-V, xtensa) and they all generally agree on the qualitative improvements seen by the combination of MICROPY_OPT_LOAD_ATTR_FAST_PATH and MICROPY_OPT_MAP_LOOKUP_CACHE. For example, on a "quiet" Linux x64 environment (i3-5010U @ 2.10GHz) the change from CACHE_MAP_LOOKUP_IN_BYTECODE, to LOAD_ATTR_FAST_PATH combined with MAP_LOOKUP_CACHE is: diff of scores (higher is better) N=2000 M=2000 bccache -> attrmapcache diff diff% (error%) bm_chaos.py 13742.56 -> 13905.67 : +163.11 = +1.187% (+/-3.75%) bm_fannkuch.py 60.13 -> 61.34 : +1.21 = +2.012% (+/-2.11%) bm_fft.py 113083.20 -> 114793.68 : +1710.48 = +1.513% (+/-1.57%) bm_float.py 256552.80 -> 243908.29 : -12644.51 = -4.929% (+/-1.90%) bm_hexiom.py 521.93 -> 625.41 : +103.48 = +19.826% (+/-0.40%) bm_nqueens.py 197544.25 -> 217713.12 : +20168.87 = +10.210% (+/-3.01%) bm_pidigits.py 8072.98 -> 8198.75 : +125.77 = +1.558% (+/-3.22%) misc_aes.py 17283.45 -> 16480.52 : -802.93 = -4.646% (+/-0.82%) misc_mandel.py 99083.99 -> 128939.84 : +29855.85 = +30.132% (+/-5.88%) misc_pystone.py 83860.10 -> 82592.56 : -1267.54 = -1.511% (+/-2.27%) misc_raytrace.py 21490.40 -> 22227.23 : +736.83 = +3.429% (+/-1.88%) This shows that the new optimisations are at least as good as the existing inline-bytecode-caching, and are sometimes much better (because the new ones apply caching to a wider variety of map lookups). The new optimisations can also benefit code generated by the native emitter, because they apply to the runtime rather than the generated code. The improvement for the native emitter when LOAD_ATTR_FAST_PATH and MAP_LOOKUP_CACHE are enabled is (same Linux environment as above): diff of scores (higher is better) N=2000 M=2000 native -> nat-attrmapcache diff diff% (error%) bm_chaos.py 14130.62 -> 15464.68 : +1334.06 = +9.441% (+/-7.11%) bm_fannkuch.py 74.96 -> 76.16 : +1.20 = +1.601% (+/-1.80%) bm_fft.py 166682.99 -> 168221.86 : +1538.87 = +0.923% (+/-4.20%) bm_float.py 233415.23 -> 265524.90 : +32109.67 = +13.756% (+/-2.57%) bm_hexiom.py 628.59 -> 734.17 : +105.58 = +16.796% (+/-1.39%) bm_nqueens.py 225418.44 -> 232926.45 : +7508.01 = +3.331% (+/-3.10%) bm_pidigits.py 6322.00 -> 6379.52 : +57.52 = +0.910% (+/-5.62%) misc_aes.py 20670.10 -> 27223.18 : +6553.08 = +31.703% (+/-1.56%) misc_mandel.py 138221.11 -> 152014.01 : +13792.90 = +9.979% (+/-2.46%) misc_pystone.py 85032.14 -> 105681.44 : +20649.30 = +24.284% (+/-2.25%) misc_raytrace.py 19800.01 -> 23350.73 : +3550.72 = +17.933% (+/-2.79%) In summary, compared to MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE, the new MICROPY_OPT_LOAD_ATTR_FAST_PATH and MICROPY_OPT_MAP_LOOKUP_CACHE options: - are simpler; - take less code size; - are faster (generally); - work with code generated by the native emitter; - can be used on embedded targets with a small and constant RAM overhead; - allow the same .mpy bytecode to run on all targets. See #7680 for further discussion. And see also #7653 for a discussion about simplifying mpy-cross options. Signed-off-by: Jim Mussared --- docs/reference/mpyfiles.rst | 2 - examples/embedding/mpconfigport_minimal.h | 1 - mpy-cross/README.md | 5 +- mpy-cross/main.c | 6 -- mpy-cross/mpconfigport.h | 2 - ports/cc3200/mpconfigport.h | 1 - ports/nrf/mpconfigport.h | 1 - ports/stm32/mpconfigport.h | 1 - ports/unix/Makefile | 5 +- ports/unix/mpconfigport.h | 3 - ports/unix/variants/minimal/mpconfigvariant.h | 1 - ports/windows/Makefile | 1 - ports/windows/mpconfigport.h | 1 - ports/windows/msvc/genhdr.targets | 2 +- py/bc.c | 14 --- py/dynruntime.mk | 2 - py/emitbc.c | 6 -- py/mpconfig.h | 9 -- py/mpstate.h | 1 - py/persistentcode.h | 11 +- py/profile.c | 12 --- py/showbc.c | 12 --- py/vm.c | 101 ------------------ tests/cmdline/cmd_parsetree.py.exp | 10 +- tests/cmdline/cmd_showbc.py.exp | 24 ++--- tests/cmdline/cmd_verbose.py.exp | 12 +-- tests/micropython/import_mpy_native_gc.py | 4 +- tests/micropython/import_mpy_native_x64.py | 6 +- tests/run-tests.py | 4 +- tools/mpy-tool.py | 28 +---- tools/mpy_cross_all.py | 5 +- tools/mpy_ld.py | 9 +- 32 files changed, 42 insertions(+), 260 deletions(-) diff --git a/docs/reference/mpyfiles.rst b/docs/reference/mpyfiles.rst index 4791784ac3..6ba7389cf0 100644 --- a/docs/reference/mpyfiles.rst +++ b/docs/reference/mpyfiles.rst @@ -66,8 +66,6 @@ If importing an .mpy file fails then try the following: print('mpy flags:', end='') if arch: print(' -march=' + arch, end='') - if sys_mpy & 0x100: - print(' -mcache-lookup-bc', end='') if not sys_mpy & 0x200: print(' -mno-unicode', end='') print() diff --git a/examples/embedding/mpconfigport_minimal.h b/examples/embedding/mpconfigport_minimal.h index b5ffd376ae..07180a3225 100644 --- a/examples/embedding/mpconfigport_minimal.h +++ b/examples/embedding/mpconfigport_minimal.h @@ -45,7 +45,6 @@ #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE) #define MICROPY_STREAMS_NON_BLOCK (0) #define MICROPY_OPT_COMPUTED_GOTO (0) -#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0) #define MICROPY_CAN_OVERRIDE_BUILTINS (0) #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) #define MICROPY_CPYTHON_COMPAT (0) diff --git a/mpy-cross/README.md b/mpy-cross/README.md index bf743a9031..83f6d6fd8d 100644 --- a/mpy-cross/README.md +++ b/mpy-cross/README.md @@ -17,10 +17,7 @@ by the target MicroPython runtime (eg onto a pyboard's filesystem), and then imported like any other Python module using `import foo`. Different target runtimes may require a different format of the compiled -bytecode, and such options can be passed to the cross compiler. For example, -the unix port of MicroPython requires the following: - - $ ./mpy-cross -mcache-lookup-bc foo.py +bytecode, and such options can be passed to the cross compiler. If the Python code contains `@native` or `@viper` annotations, then you must specify `-march` to match the target architecture. diff --git a/mpy-cross/main.c b/mpy-cross/main.c index 635e53a719..c677929c33 100644 --- a/mpy-cross/main.c +++ b/mpy-cross/main.c @@ -108,7 +108,6 @@ STATIC int usage(char **argv) { "Target specific options:\n" "-msmall-int-bits=number : set the maximum bits used to encode a small-int\n" "-mno-unicode : don't support unicode in compiled strings\n" - "-mcache-lookup-bc : cache map lookups in the bytecode\n" "-march= : set architecture for native emitter; x86, x64, armv6, armv7m, armv7em, armv7emsp, armv7emdp, xtensa, xtensawin\n" "\n" "Implementation specific options:\n", argv[0] @@ -205,7 +204,6 @@ MP_NOINLINE int main_(int argc, char **argv) { // set default compiler configuration mp_dynamic_compiler.small_int_bits = 31; - mp_dynamic_compiler.opt_cache_map_lookup_in_bytecode = 0; mp_dynamic_compiler.py_builtins_str_unicode = 1; #if defined(__i386__) mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_X86; @@ -264,10 +262,6 @@ MP_NOINLINE int main_(int argc, char **argv) { return usage(argv); } // TODO check that small_int_bits is within range of host's capabilities - } else if (strcmp(argv[a], "-mno-cache-lookup-bc") == 0) { - mp_dynamic_compiler.opt_cache_map_lookup_in_bytecode = 0; - } else if (strcmp(argv[a], "-mcache-lookup-bc") == 0) { - mp_dynamic_compiler.opt_cache_map_lookup_in_bytecode = 1; } else if (strcmp(argv[a], "-mno-unicode") == 0) { mp_dynamic_compiler.py_builtins_str_unicode = 0; } else if (strcmp(argv[a], "-municode") == 0) { diff --git a/mpy-cross/mpconfigport.h b/mpy-cross/mpconfigport.h index e7c8edf135..8c716e958d 100644 --- a/mpy-cross/mpconfigport.h +++ b/mpy-cross/mpconfigport.h @@ -57,8 +57,6 @@ #define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (1) #define MICROPY_COMP_RETURN_IF_EXPR (1) -#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0) - #define MICROPY_READER_POSIX (1) #define MICROPY_ENABLE_RUNTIME (0) #define MICROPY_ENABLE_GC (1) diff --git a/ports/cc3200/mpconfigport.h b/ports/cc3200/mpconfigport.h index 87689c505e..345b64fe40 100644 --- a/ports/cc3200/mpconfigport.h +++ b/ports/cc3200/mpconfigport.h @@ -53,7 +53,6 @@ #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE) #define MICROPY_OPT_COMPUTED_GOTO (0) -#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0) #define MICROPY_READER_VFS (1) #ifndef DEBUG // we need ram on the launchxl while debugging #define MICROPY_CPYTHON_COMPAT (1) diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 6290f85e87..3ffb092c61 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -66,7 +66,6 @@ #endif #define MICROPY_OPT_COMPUTED_GOTO (0) -#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0) #define MICROPY_OPT_MPZ_BITWISE (0) // fatfs configuration used in ffconf.h diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 47795c4e71..92f1338d6c 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -59,7 +59,6 @@ #ifndef MICROPY_OPT_COMPUTED_GOTO #define MICROPY_OPT_COMPUTED_GOTO (1) #endif -#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0) #ifndef MICROPY_OPT_LOAD_ATTR_FAST_PATH #define MICROPY_OPT_LOAD_ATTR_FAST_PATH (1) #endif diff --git a/ports/unix/Makefile b/ports/unix/Makefile index bf9d290abf..60e37ade0a 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -269,7 +269,6 @@ ifneq ($(FROZEN_MANIFEST)$(FROZEN_MPY_DIR),) CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool CFLAGS += -DMICROPY_MODULE_FROZEN_MPY CFLAGS += -DMPZ_DIG_SIZE=16 # force 16 bits to work on both 32 and 64 bit archs -MPY_CROSS_FLAGS += -mcache-lookup-bc endif ifneq ($(FROZEN_MANIFEST)$(FROZEN_DIR),) @@ -285,9 +284,7 @@ endif CXXFLAGS += $(filter-out -Wmissing-prototypes -Wold-style-definition -std=gnu99,$(CFLAGS) $(CXXFLAGS_MOD)) ifeq ($(MICROPY_FORCE_32BIT),1) -RUN_TESTS_MPY_CROSS_FLAGS = --mpy-cross-flags='-mcache-lookup-bc -march=x86' -else -RUN_TESTS_MPY_CROSS_FLAGS = --mpy-cross-flags='-mcache-lookup-bc' +RUN_TESTS_MPY_CROSS_FLAGS = --mpy-cross-flags='-march=x86' endif ifeq ($(CROSS_COMPILE),arm-linux-gnueabi-) diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index de45a800d3..d6ab4e5ca9 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -79,9 +79,6 @@ #endif #define MICROPY_STREAMS_POSIX_API (1) #define MICROPY_OPT_COMPUTED_GOTO (1) -#ifndef MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE -#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (1) -#endif #ifndef MICROPY_OPT_LOAD_ATTR_FAST_PATH #define MICROPY_OPT_LOAD_ATTR_FAST_PATH (1) #endif diff --git a/ports/unix/variants/minimal/mpconfigvariant.h b/ports/unix/variants/minimal/mpconfigvariant.h index d5eab09546..973febd572 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.h +++ b/ports/unix/variants/minimal/mpconfigvariant.h @@ -55,7 +55,6 @@ #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE) #define MICROPY_STREAMS_NON_BLOCK (0) #define MICROPY_OPT_COMPUTED_GOTO (0) -#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0) #define MICROPY_OPT_LOAD_ATTR_FAST_PATH (0) #define MICROPY_OPT_MAP_LOOKUP_CACHE (0) #define MICROPY_CAN_OVERRIDE_BUILTINS (0) diff --git a/ports/windows/Makefile b/ports/windows/Makefile index d87affa15c..cb2ebc22f7 100644 --- a/ports/windows/Makefile +++ b/ports/windows/Makefile @@ -60,7 +60,6 @@ SRC_QSTR_AUTO_DEPS += ifneq ($(FROZEN_MANIFEST),) CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool -DMICROPY_MODULE_FROZEN_MPY=1 -DMPZ_DIG_SIZE=16 -MPY_CROSS_FLAGS += -mcache-lookup-bc endif include $(TOP)/py/mkrules.mk diff --git a/ports/windows/mpconfigport.h b/ports/windows/mpconfigport.h index ffcb5b105f..4a8a902597 100644 --- a/ports/windows/mpconfigport.h +++ b/ports/windows/mpconfigport.h @@ -59,7 +59,6 @@ #define MICROPY_STREAMS_NON_BLOCK (1) #define MICROPY_STREAMS_POSIX_API (1) #define MICROPY_OPT_COMPUTED_GOTO (0) -#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (1) #define MICROPY_MODULE_WEAK_LINKS (1) #define MICROPY_CAN_OVERRIDE_BUILTINS (1) #define MICROPY_VFS_POSIX_FILE (1) diff --git a/ports/windows/msvc/genhdr.targets b/ports/windows/msvc/genhdr.targets index 9ea6ed28cb..78e57a34ee 100644 --- a/ports/windows/msvc/genhdr.targets +++ b/ports/windows/msvc/genhdr.targets @@ -123,7 +123,7 @@ using(var outFile = System.IO.File.CreateText(OutputFile)) { MICROPY_MODULE_FROZEN_MPY=1;MICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool;%(PreprocessorDefinitions) - + diff --git a/py/bc.c b/py/bc.c index 58694b97dc..69b6739e8f 100644 --- a/py/bc.c +++ b/py/bc.c @@ -304,24 +304,10 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw // The following table encodes the number of bytes that a specific opcode // takes up. Some opcodes have an extra byte, defined by MP_BC_MASK_EXTRA_BYTE. -// There are 4 special opcodes that have an extra byte only when -// MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE is enabled (and they take a qstr): -// MP_BC_LOAD_NAME -// MP_BC_LOAD_GLOBAL -// MP_BC_LOAD_ATTR -// MP_BC_STORE_ATTR uint mp_opcode_format(const byte *ip, size_t *opcode_size, bool count_var_uint) { uint f = MP_BC_FORMAT(*ip); const byte *ip_start = ip; if (f == MP_BC_FORMAT_QSTR) { - if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE_DYNAMIC) { - if (*ip == MP_BC_LOAD_NAME - || *ip == MP_BC_LOAD_GLOBAL - || *ip == MP_BC_LOAD_ATTR - || *ip == MP_BC_STORE_ATTR) { - ip += 1; - } - } ip += 3; } else { int extra_byte = (*ip & MP_BC_MASK_EXTRA_BYTE) == 0; diff --git a/py/dynruntime.mk b/py/dynruntime.mk index cb5ab845eb..db06d41e73 100644 --- a/py/dynruntime.mk +++ b/py/dynruntime.mk @@ -46,7 +46,6 @@ ifeq ($(ARCH),x86) # x86 CROSS = CFLAGS += -m32 -fno-stack-protector -MPY_CROSS_FLAGS += -mcache-lookup-bc MICROPY_FLOAT_IMPL ?= double else ifeq ($(ARCH),x64) @@ -54,7 +53,6 @@ else ifeq ($(ARCH),x64) # x64 CROSS = CFLAGS += -fno-stack-protector -MPY_CROSS_FLAGS += -mcache-lookup-bc MICROPY_FLOAT_IMPL ?= double else ifeq ($(ARCH),armv7m) diff --git a/py/emitbc.c b/py/emitbc.c index d7e8e05f0f..ca74046033 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -560,9 +560,6 @@ void mp_emit_bc_load_global(emit_t *emit, qstr qst, int kind) { MP_STATIC_ASSERT(MP_BC_LOAD_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_BC_LOAD_GLOBAL); (void)qst; emit_write_bytecode_byte_qstr(emit, 1, MP_BC_LOAD_NAME + kind, qst); - if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE_DYNAMIC) { - emit_write_bytecode_raw_byte(emit, 0); - } } void mp_emit_bc_load_method(emit_t *emit, qstr qst, bool is_super) { @@ -596,9 +593,6 @@ void mp_emit_bc_attr(emit_t *emit, qstr qst, int kind) { } emit_write_bytecode_byte_qstr(emit, -2, MP_BC_STORE_ATTR, qst); } - if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE_DYNAMIC) { - emit_write_bytecode_raw_byte(emit, 0); - } } void mp_emit_bc_store_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) { diff --git a/py/mpconfig.h b/py/mpconfig.h index 97fc9bb580..6a2edc7dc2 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -423,10 +423,8 @@ // Configure dynamic compiler macros #if MICROPY_DYNAMIC_COMPILER -#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE_DYNAMIC (mp_dynamic_compiler.opt_cache_map_lookup_in_bytecode) #define MICROPY_PY_BUILTINS_STR_UNICODE_DYNAMIC (mp_dynamic_compiler.py_builtins_str_unicode) #else -#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE_DYNAMIC MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE #define MICROPY_PY_BUILTINS_STR_UNICODE_DYNAMIC MICROPY_PY_BUILTINS_STR_UNICODE #endif @@ -520,13 +518,6 @@ #define MICROPY_OPT_COMPUTED_GOTO (0) #endif -// Whether to cache result of map lookups in LOAD_NAME, LOAD_GLOBAL, LOAD_ATTR, -// STORE_ATTR bytecodes. Uses 1 byte extra RAM for each of these opcodes and -// uses a bit of extra code ROM, but greatly improves lookup speed. -#ifndef MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE -#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0) -#endif - // Optimise the fast path for loading attributes from instance types. Increases // Thumb2 code size by about 48 bytes. #ifndef MICROPY_OPT_LOAD_ATTR_FAST_PATH diff --git a/py/mpstate.h b/py/mpstate.h index 53b2906872..69360738c2 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -44,7 +44,6 @@ #if MICROPY_DYNAMIC_COMPILER typedef struct mp_dynamic_compiler_t { uint8_t small_int_bits; // must be <= host small_int_bits - bool opt_cache_map_lookup_in_bytecode; bool py_builtins_str_unicode; uint8_t native_arch; uint8_t nlr_buf_num_regs; diff --git a/py/persistentcode.h b/py/persistentcode.h index 8769ef584d..94fc3bf2d3 100644 --- a/py/persistentcode.h +++ b/py/persistentcode.h @@ -41,16 +41,15 @@ #define MPY_FEATURE_ENCODE_ARCH(arch) ((arch) << 2) #define MPY_FEATURE_DECODE_ARCH(feat) ((feat) >> 2) -// The feature flag bits encode the compile-time config options that -// affect the generate bytecode. +// The feature flag bits encode the compile-time config options that affect +// the generate bytecode. Note: position 0 is now unused +// (formerly MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE). #define MPY_FEATURE_FLAGS ( \ - ((MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE) << 0) \ - | ((MICROPY_PY_BUILTINS_STR_UNICODE) << 1) \ + ((MICROPY_PY_BUILTINS_STR_UNICODE) << 1) \ ) // This is a version of the flags that can be configured at runtime. #define MPY_FEATURE_FLAGS_DYNAMIC ( \ - ((MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE_DYNAMIC) << 0) \ - | ((MICROPY_PY_BUILTINS_STR_UNICODE_DYNAMIC) << 1) \ + ((MICROPY_PY_BUILTINS_STR_UNICODE_DYNAMIC) << 1) \ ) // Define the host architecture diff --git a/py/profile.c b/py/profile.c index 054a0f9e61..d0ac99e074 100644 --- a/py/profile.c +++ b/py/profile.c @@ -540,9 +540,6 @@ STATIC const byte *mp_prof_opcode_decode(const byte *ip, const mp_uint_t *const_ instruction->qstr_opname = MP_QSTR_LOAD_NAME; instruction->arg = qst; instruction->argobj = MP_OBJ_NEW_QSTR(qst); - if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE) { - instruction->argobjex_cache = MP_OBJ_NEW_SMALL_INT(*ip++); - } break; case MP_BC_LOAD_GLOBAL: @@ -550,9 +547,6 @@ STATIC const byte *mp_prof_opcode_decode(const byte *ip, const mp_uint_t *const_ instruction->qstr_opname = MP_QSTR_LOAD_GLOBAL; instruction->arg = qst; instruction->argobj = MP_OBJ_NEW_QSTR(qst); - if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE) { - instruction->argobjex_cache = MP_OBJ_NEW_SMALL_INT(*ip++); - } break; case MP_BC_LOAD_ATTR: @@ -560,9 +554,6 @@ STATIC const byte *mp_prof_opcode_decode(const byte *ip, const mp_uint_t *const_ instruction->qstr_opname = MP_QSTR_LOAD_ATTR; instruction->arg = qst; instruction->argobj = MP_OBJ_NEW_QSTR(qst); - if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE) { - instruction->argobjex_cache = MP_OBJ_NEW_SMALL_INT(*ip++); - } break; case MP_BC_LOAD_METHOD: @@ -618,9 +609,6 @@ STATIC const byte *mp_prof_opcode_decode(const byte *ip, const mp_uint_t *const_ instruction->qstr_opname = MP_QSTR_STORE_ATTR; instruction->arg = qst; instruction->argobj = MP_OBJ_NEW_QSTR(qst); - if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE) { - instruction->argobjex_cache = MP_OBJ_NEW_SMALL_INT(*ip++); - } break; case MP_BC_STORE_SUBSCR: diff --git a/py/showbc.c b/py/showbc.c index cb81b88359..c321dfd755 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -208,25 +208,16 @@ const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip) { case MP_BC_LOAD_NAME: DECODE_QSTR; mp_printf(print, "LOAD_NAME %s", qstr_str(qst)); - if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE) { - mp_printf(print, " (cache=%u)", *ip++); - } break; case MP_BC_LOAD_GLOBAL: DECODE_QSTR; mp_printf(print, "LOAD_GLOBAL %s", qstr_str(qst)); - if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE) { - mp_printf(print, " (cache=%u)", *ip++); - } break; case MP_BC_LOAD_ATTR: DECODE_QSTR; mp_printf(print, "LOAD_ATTR %s", qstr_str(qst)); - if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE) { - mp_printf(print, " (cache=%u)", *ip++); - } break; case MP_BC_LOAD_METHOD: @@ -270,9 +261,6 @@ const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip) { case MP_BC_STORE_ATTR: DECODE_QSTR; mp_printf(print, "STORE_ATTR %s", qstr_str(qst)); - if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE) { - mp_printf(print, " (cache=%u)", *ip++); - } break; case MP_BC_STORE_SUBSCR: diff --git a/py/vm.c b/py/vm.c index e5a62e4415..f55d293dc5 100644 --- a/py/vm.c +++ b/py/vm.c @@ -180,23 +180,6 @@ #define TRACE_TICK(current_ip, current_sp, is_exception) #endif // MICROPY_PY_SYS_SETTRACE -#if MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE -static inline mp_map_elem_t *mp_map_cached_lookup(mp_map_t *map, qstr qst, uint8_t *idx_cache) { - size_t idx = *idx_cache; - mp_obj_t key = MP_OBJ_NEW_QSTR(qst); - mp_map_elem_t *elem = NULL; - if (idx < map->alloc && map->table[idx].key == key) { - elem = &map->table[idx]; - } else { - elem = mp_map_lookup(map, key, MP_MAP_LOOKUP); - if (elem != NULL) { - *idx_cache = (elem - &map->table[0]) & 0xff; - } - } - return elem; -} -#endif - // fastn has items in reverse order (fastn[0] is local[0], fastn[-1] is local[1], etc) // sp points to bottom of stack which grows up // returns: @@ -361,55 +344,20 @@ dispatch_loop: goto load_check; } - #if !MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE ENTRY(MP_BC_LOAD_NAME): { MARK_EXC_IP_SELECTIVE(); DECODE_QSTR; PUSH(mp_load_name(qst)); DISPATCH(); } - #else - ENTRY(MP_BC_LOAD_NAME): { - MARK_EXC_IP_SELECTIVE(); - DECODE_QSTR; - mp_map_elem_t *elem = mp_map_cached_lookup(&mp_locals_get()->map, qst, (uint8_t*)ip); - mp_obj_t obj; - if (elem != NULL) { - obj = elem->value; - } else { - obj = mp_load_name(qst); - } - PUSH(obj); - ip++; - DISPATCH(); - } - #endif - #if !MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE ENTRY(MP_BC_LOAD_GLOBAL): { MARK_EXC_IP_SELECTIVE(); DECODE_QSTR; PUSH(mp_load_global(qst)); DISPATCH(); } - #else - ENTRY(MP_BC_LOAD_GLOBAL): { - MARK_EXC_IP_SELECTIVE(); - DECODE_QSTR; - mp_map_elem_t *elem = mp_map_cached_lookup(&mp_globals_get()->map, qst, (uint8_t*)ip); - mp_obj_t obj; - if (elem != NULL) { - obj = elem->value; - } else { - obj = mp_load_global(qst); - } - PUSH(obj); - ip++; - DISPATCH(); - } - #endif - #if !MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE ENTRY(MP_BC_LOAD_ATTR): { FRAME_UPDATE(); MARK_EXC_IP_SELECTIVE(); @@ -436,28 +384,6 @@ dispatch_loop: SET_TOP(obj); DISPATCH(); } - #else - ENTRY(MP_BC_LOAD_ATTR): { - FRAME_UPDATE(); - MARK_EXC_IP_SELECTIVE(); - DECODE_QSTR; - mp_obj_t top = TOP(); - mp_map_elem_t *elem = NULL; - if (mp_obj_is_instance_type(mp_obj_get_type(top))) { - mp_obj_instance_t *self = MP_OBJ_TO_PTR(top); - elem = mp_map_cached_lookup(&self->members, qst, (uint8_t*)ip); - } - mp_obj_t obj; - if (elem != NULL) { - obj = elem->value; - } else { - obj = mp_load_attr(top, qst); - } - SET_TOP(obj); - ip++; - DISPATCH(); - } - #endif ENTRY(MP_BC_LOAD_METHOD): { MARK_EXC_IP_SELECTIVE(); @@ -513,7 +439,6 @@ dispatch_loop: DISPATCH(); } - #if !MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE ENTRY(MP_BC_STORE_ATTR): { FRAME_UPDATE(); MARK_EXC_IP_SELECTIVE(); @@ -522,32 +447,6 @@ dispatch_loop: sp -= 2; DISPATCH(); } - #else - // This caching code works with MICROPY_PY_BUILTINS_PROPERTY and/or - // MICROPY_PY_DESCRIPTORS enabled because if the attr exists in - // self->members then it can't be a property or have descriptors. A - // consequence of this is that we can't use MP_MAP_LOOKUP_ADD_IF_NOT_FOUND - // in the fast-path below, because that store could override a property. - ENTRY(MP_BC_STORE_ATTR): { - FRAME_UPDATE(); - MARK_EXC_IP_SELECTIVE(); - DECODE_QSTR; - mp_map_elem_t *elem = NULL; - mp_obj_t top = TOP(); - if (mp_obj_is_instance_type(mp_obj_get_type(top)) && sp[-1] != MP_OBJ_NULL) { - mp_obj_instance_t *self = MP_OBJ_TO_PTR(top); - elem = mp_map_cached_lookup(&self->members, qst, (uint8_t*)ip); - } - if (elem != NULL) { - elem->value = sp[-1]; - } else { - mp_store_attr(sp[0], qst, sp[-1]); - } - sp -= 2; - ip++; - DISPATCH(); - } - #endif ENTRY(MP_BC_STORE_SUBSCR): MARK_EXC_IP_SELECTIVE(); diff --git a/tests/cmdline/cmd_parsetree.py.exp b/tests/cmdline/cmd_parsetree.py.exp index cc8ba82c05..bee4fc99d1 100644 --- a/tests/cmdline/cmd_parsetree.py.exp +++ b/tests/cmdline/cmd_parsetree.py.exp @@ -78,11 +78,11 @@ arg names: 45 STORE_NAME g 48 LOAD_CONST_OBJ \.\+ 50 LOAD_METHOD format -53 LOAD_NAME b (cache=0) -57 CALL_METHOD n=1 nkw=0 -59 STORE_NAME h -62 LOAD_CONST_NONE -63 RETURN_VALUE +53 LOAD_NAME b +56 CALL_METHOD n=1 nkw=0 +58 STORE_NAME h +61 LOAD_CONST_NONE +62 RETURN_VALUE mem: total=\\d\+, current=\\d\+, peak=\\d\+ stack: \\d\+ out of \\d\+ GC: total: \\d\+, used: \\d\+, free: \\d\+ diff --git a/tests/cmdline/cmd_showbc.py.exp b/tests/cmdline/cmd_showbc.py.exp index 325efc7dba..d93fd7b487 100644 --- a/tests/cmdline/cmd_showbc.py.exp +++ b/tests/cmdline/cmd_showbc.py.exp @@ -119,11 +119,11 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): \\d\+ UNARY_OP 3 \\d\+ STORE_FAST 10 \\d\+ LOAD_DEREF 14 -\\d\+ LOAD_ATTR c (cache=0) +\\d\+ LOAD_ATTR c \\d\+ STORE_FAST 11 \\d\+ LOAD_FAST 11 \\d\+ LOAD_DEREF 14 -\\d\+ STORE_ATTR c (cache=0) +\\d\+ STORE_ATTR c \\d\+ LOAD_DEREF 14 \\d\+ LOAD_CONST_SMALL_INT 0 \\d\+ LOAD_SUBSCR @@ -233,7 +233,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): \\d\+ LOAD_DEREF 16 \\d\+ POP_TOP \\d\+ JUMP \\d\+ -\\d\+ LOAD_GLOBAL y (cache=0) +\\d\+ LOAD_GLOBAL y \\d\+ POP_TOP \\d\+ JUMP \\d\+ \\d\+ LOAD_DEREF 14 @@ -418,13 +418,13 @@ arg names: (N_EXC_STACK 0) bc=0 line=1 ######## - bc=13 line=150 -00 LOAD_NAME __name__ (cache=0) -04 STORE_NAME __module__ -07 LOAD_CONST_STRING 'Class' -10 STORE_NAME __qualname__ -13 LOAD_CONST_NONE -14 RETURN_VALUE + bc=12 line=150 +00 LOAD_NAME __name__ +03 STORE_NAME __module__ +06 LOAD_CONST_STRING 'Class' +09 STORE_NAME __qualname__ +12 LOAD_CONST_NONE +13 RETURN_VALUE File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ bytes) Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): ######## @@ -434,8 +434,8 @@ arg names: self (N_EXC_STACK 0) bc=0 line=1 bc=0 line=157 -00 LOAD_GLOBAL super (cache=0) -\\d\+ LOAD_GLOBAL __class__ (cache=0) +00 LOAD_GLOBAL super +\\d\+ LOAD_GLOBAL __class__ \\d\+ LOAD_FAST 0 \\d\+ LOAD_SUPER_METHOD f \\d\+ CALL_METHOD n=0 nkw=0 diff --git a/tests/cmdline/cmd_verbose.py.exp b/tests/cmdline/cmd_verbose.py.exp index a2fdf1f00d..0edd050c22 100644 --- a/tests/cmdline/cmd_verbose.py.exp +++ b/tests/cmdline/cmd_verbose.py.exp @@ -8,12 +8,12 @@ arg names: (N_EXC_STACK 0) bc=0 line=1 bc=0 line=3 -00 LOAD_NAME print (cache=0) -04 LOAD_CONST_SMALL_INT 1 -05 CALL_FUNCTION n=1 nkw=0 -07 POP_TOP -08 LOAD_CONST_NONE -09 RETURN_VALUE +00 LOAD_NAME print +03 LOAD_CONST_SMALL_INT 1 +04 CALL_FUNCTION n=1 nkw=0 +06 POP_TOP +07 LOAD_CONST_NONE +08 RETURN_VALUE 1 mem: total=\\d\+, current=\\d\+, peak=\\d\+ stack: \\d\+ out of \\d\+ diff --git a/tests/micropython/import_mpy_native_gc.py b/tests/micropython/import_mpy_native_gc.py index e8fac8f179..f982a4ee17 100644 --- a/tests/micropython/import_mpy_native_gc.py +++ b/tests/micropython/import_mpy_native_gc.py @@ -48,8 +48,8 @@ class UserFS: # Pre-compiled examples/natmod/features0 example for various architectures, keyed # by the required value of sys.implementation.mpy. features0_file_contents = { - # -march=x64 -mcache-lookup-bc - 0xB05: b'M\x05\x0b\x1f \x84b\xe9/\x00\x00\x00SH\x8b\x1ds\x00\x00\x00\xbe\x02\x00\x00\x00\xffS\x18\xbf\x01\x00\x00\x00H\x85\xc0u\x0cH\x8bC \xbe\x02\x00\x00\x00[\xff\xe0H\x0f\xaf\xf8H\xff\xc8\xeb\xe6ATUSH\x8b\x1dA\x00\x00\x00H\x8b\x7f\x08L\x8bc(A\xff\xd4H\x8d5\x1f\x00\x00\x00H\x89\xc5H\x8b\x05-\x00\x00\x00\x0f\xb78\xffShH\x89\xefA\xff\xd4H\x8b\x03[]A\\\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x84@\x12factorial\x10\x00\x00\r \x01"\x9f\x1c\x01\x1e\xff', + # -march=x64 + 0xA05: b'M\x05\x0a\x1f \x84b\xe9/\x00\x00\x00SH\x8b\x1ds\x00\x00\x00\xbe\x02\x00\x00\x00\xffS\x18\xbf\x01\x00\x00\x00H\x85\xc0u\x0cH\x8bC \xbe\x02\x00\x00\x00[\xff\xe0H\x0f\xaf\xf8H\xff\xc8\xeb\xe6ATUSH\x8b\x1dA\x00\x00\x00H\x8b\x7f\x08L\x8bc(A\xff\xd4H\x8d5\x1f\x00\x00\x00H\x89\xc5H\x8b\x05-\x00\x00\x00\x0f\xb78\xffShH\x89\xefA\xff\xd4H\x8b\x03[]A\\\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x84@\x12factorial\x10\x00\x00\r \x01"\x9f\x1c\x01\x1e\xff', # -march=armv7m 0x1605: b"M\x05\x16\x1f \x84\x12\x1a\xe0\x00\x00\x13\xb5\nK\nJ{D\x9cX\x02!\xe3h\x98G\x03F\x01 3\xb9\x02!#i\x01\x93\x02\xb0\xbd\xe8\x10@\x18GXC\x01;\xf4\xe7\x00\xbfj\x00\x00\x00\x00\x00\x00\x00\xf8\xb5\tN\tK~D\xf4X@hgi\xb8G\x05F\x07K\x07I\xf2XyD\x10\x88ck\x98G(F\xb8G h\xf8\xbd6\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x01\x84\x00\x12factorial\x10\x00\x00\r<\x01>\x9f8\x01:\xff", } diff --git a/tests/micropython/import_mpy_native_x64.py b/tests/micropython/import_mpy_native_x64.py index 3e7b2058eb..cad59e9916 100644 --- a/tests/micropython/import_mpy_native_x64.py +++ b/tests/micropython/import_mpy_native_x64.py @@ -52,11 +52,11 @@ class UserFS: # fmt: off user_files = { # bad architecture - '/mod0.mpy': b'M\x05\xff\x00\x10', + '/mod0.mpy': b'M\x05\xfe\x00\x10', # test loading of viper and asm '/mod1.mpy': ( - b'M\x05\x0b\x1f\x20' # header + b'M\x05\x0a\x1f\x20' # header b'\x20' # n bytes, bytecode b'\x00\x08\x02m\x02m' # prelude @@ -78,7 +78,7 @@ user_files = { # test loading viper with additional scope flags and relocation '/mod2.mpy': ( - b'M\x05\x0b\x1f\x20' # header + b'M\x05\x0a\x1f\x20' # header b'\x20' # n bytes, bytecode b'\x00\x08\x02m\x02m' # prelude diff --git a/tests/run-tests.py b/tests/run-tests.py index 3e97a7c87d..a8a31c0ae5 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -742,9 +742,7 @@ the last matching regex is used: cmd_parser.add_argument( "--via-mpy", action="store_true", help="compile .py files to .mpy first" ) - cmd_parser.add_argument( - "--mpy-cross-flags", default="-mcache-lookup-bc", help="flags to pass to mpy-cross" - ) + cmd_parser.add_argument("--mpy-cross-flags", default="", help="flags to pass to mpy-cross") cmd_parser.add_argument( "--keep-path", action="store_true", help="do not clear MICROPYPATH when running tests" ) diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index bfc3cf27e3..6868ed5d4e 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -132,14 +132,6 @@ def mp_opcode_format(bytecode, ip, count_var_uint): ip_start = ip f = (0x000003A4 >> (2 * ((opcode) >> 4))) & 3 if f == MP_BC_FORMAT_QSTR: - if config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE: - if ( - opcode == MP_BC_LOAD_NAME - or opcode == MP_BC_LOAD_GLOBAL - or opcode == MP_BC_LOAD_ATTR - or opcode == MP_BC_STORE_ATTR - ): - ip += 1 ip += 3 else: extra_byte = (opcode & MP_BC_MASK_EXTRA_BYTE) == 0 @@ -440,10 +432,7 @@ class RawCodeBytecode(RawCode): "// frozen bytecode for file %s, scope %s%s" % (self.source_file.str, parent_name, self.simple_name.str) ) - print("STATIC ", end="") - if not config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE: - print("const ", end="") - print("byte fun_data_%s[%u] = {" % (self.escaped_name, len(self.bytecode))) + print("STATIC const byte fun_data_%s[%u] = {" % (self.escaped_name, len(self.bytecode))) print(" ", end="") for i in range(self.ip2): print(" 0x%02x," % self.bytecode[i], end="") @@ -798,7 +787,6 @@ def read_mpy(filename): raise Exception("incompatible .mpy version") feature_byte = header[2] qw_size = read_uint(f) - config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE = (feature_byte & 1) != 0 config.MICROPY_PY_BUILTINS_STR_UNICODE = (feature_byte & 2) != 0 mpy_native_arch = feature_byte >> 2 if mpy_native_arch != MP_NATIVE_ARCH_NONE: @@ -836,14 +824,6 @@ def freeze_mpy(base_qstrs, raw_codes): print('#include "py/nativeglue.h"') print() - print( - "#if MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE != %u" - % config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE - ) - print('#error "incompatible MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE"') - print("#endif") - print() - print("#if MICROPY_LONGINT_IMPL != %u" % config.MICROPY_LONGINT_IMPL) print('#error "incompatible MICROPY_LONGINT_IMPL"') print("#endif") @@ -940,11 +920,7 @@ def merge_mpy(raw_codes, output_file): header = bytearray(5) header[0] = ord("M") header[1] = config.MPY_VERSION - header[2] = ( - config.native_arch << 2 - | config.MICROPY_PY_BUILTINS_STR_UNICODE << 1 - | config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE - ) + header[2] = config.native_arch << 2 | config.MICROPY_PY_BUILTINS_STR_UNICODE << 1 header[3] = config.mp_small_int_bits header[4] = 32 # qstr_win_size merged_mpy.extend(header) diff --git a/tools/mpy_cross_all.py b/tools/mpy_cross_all.py index d542bde42e..4b1edf9d6c 100755 --- a/tools/mpy_cross_all.py +++ b/tools/mpy_cross_all.py @@ -6,14 +6,11 @@ import os.path argparser = argparse.ArgumentParser(description="Compile all .py files to .mpy recursively") argparser.add_argument("-o", "--out", help="output directory (default: input dir)") argparser.add_argument("--target", help="select MicroPython target config") -argparser.add_argument( - "-mcache-lookup-bc", action="store_true", help="cache map lookups in the bytecode" -) argparser.add_argument("dir", help="input directory") args = argparser.parse_args() TARGET_OPTS = { - "unix": "-mcache-lookup-bc", + "unix": "", "baremetal": "", } diff --git a/tools/mpy_ld.py b/tools/mpy_ld.py index 8522499438..6bc1dbac05 100755 --- a/tools/mpy_ld.py +++ b/tools/mpy_ld.py @@ -48,7 +48,6 @@ MP_CODE_NATIVE_VIPER = 4 MP_SCOPE_FLAG_VIPERRELOC = 0x10 MP_SCOPE_FLAG_VIPERRODATA = 0x20 MP_SCOPE_FLAG_VIPERBSS = 0x40 -MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE = 1 MICROPY_PY_BUILTINS_STR_UNICODE = 2 MP_SMALL_INT_BITS = 31 QSTR_WINDOW_SIZE = 32 @@ -118,9 +117,7 @@ class ArchData: ARCH_DATA = { "x86": ArchData( "EM_386", - MP_NATIVE_ARCH_X86 << 2 - | MICROPY_PY_BUILTINS_STR_UNICODE - | MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE, + MP_NATIVE_ARCH_X86 << 2 | MICROPY_PY_BUILTINS_STR_UNICODE, 2, 4, (R_386_PC32, R_386_GOT32, R_386_GOT32X), @@ -128,9 +125,7 @@ ARCH_DATA = { ), "x64": ArchData( "EM_X86_64", - MP_NATIVE_ARCH_X64 << 2 - | MICROPY_PY_BUILTINS_STR_UNICODE - | MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE, + MP_NATIVE_ARCH_X64 << 2 | MICROPY_PY_BUILTINS_STR_UNICODE, 2, 8, (R_X86_64_GOTPCREL, R_X86_64_REX_GOTPCRELX), From 54d33b266ca337d8fb42852422cc6bf87c813e4e Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Sep 2021 22:16:36 +1000 Subject: [PATCH 048/335] esp32: Add support for ESP32-S3 SoCs. Thanks to Seon Rozenblum aka @UnexpectedMaker for the work. Signed-off-by: Damien George --- ports/esp32/machine_adc.c | 10 ++++++++-- ports/esp32/machine_hw_spi.c | 2 ++ ports/esp32/machine_i2s.c | 5 +++++ ports/esp32/machine_timer.c | 4 ++++ ports/esp32/modmachine.c | 2 ++ ports/esp32/partitions-8MiB.csv | 7 +++++++ ports/esp32/uart.c | 9 +++++++-- 7 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 ports/esp32/partitions-8MiB.csv diff --git a/ports/esp32/machine_adc.c b/ports/esp32/machine_adc.c index 5ac05d56b5..6731978e28 100644 --- a/ports/esp32/machine_adc.c +++ b/ports/esp32/machine_adc.c @@ -164,10 +164,14 @@ STATIC mp_obj_t madc_width(mp_obj_t cls_in, mp_obj_t width_in) { case ADC_WIDTH_12Bit: adc_bit_width = 12; break; - #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 + #elif CONFIG_IDF_TARGET_ESP32S2 case ADC_WIDTH_BIT_13: adc_bit_width = 13; break; + #elif CONFIG_IDF_TARGET_ESP32S3 + case ADC_WIDTH_BIT_12: + adc_bit_width = 12; + break; #endif default: break; @@ -194,8 +198,10 @@ STATIC const mp_rom_map_elem_t madc_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_WIDTH_10BIT), MP_ROM_INT(ADC_WIDTH_10Bit) }, { MP_ROM_QSTR(MP_QSTR_WIDTH_11BIT), MP_ROM_INT(ADC_WIDTH_11Bit) }, { MP_ROM_QSTR(MP_QSTR_WIDTH_12BIT), MP_ROM_INT(ADC_WIDTH_12Bit) }, - #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 + #elif CONFIG_IDF_TARGET_ESP32S2 { MP_ROM_QSTR(MP_QSTR_WIDTH_13BIT), MP_ROM_INT(ADC_WIDTH_BIT_13) }, + #elif CONFIG_IDF_TARGET_ESP32S3 + { MP_ROM_QSTR(MP_QSTR_WIDTH_12BIT), MP_ROM_INT(ADC_WIDTH_BIT_12) }, #endif }; diff --git a/ports/esp32/machine_hw_spi.c b/ports/esp32/machine_hw_spi.c index ca530ba943..4c0989b9a6 100644 --- a/ports/esp32/machine_hw_spi.c +++ b/ports/esp32/machine_hw_spi.c @@ -55,6 +55,8 @@ #if CONFIG_IDF_TARGET_ESP32C3 #define HSPI_HOST SPI2_HOST +#elif CONFIG_IDF_TARGET_ESP32S3 +#define HSPI_HOST SPI3_HOST #endif typedef struct _machine_hw_spi_default_pins_t { diff --git a/ports/esp32/machine_i2s.c b/ports/esp32/machine_i2s.c index c650a33bef..dc583e8e96 100644 --- a/ports/esp32/machine_i2s.c +++ b/ports/esp32/machine_i2s.c @@ -455,8 +455,13 @@ STATIC void machine_i2s_init_helper(machine_i2s_obj_t *self, size_t n_pos_args, // apply low-level workaround for bug in some ESP-IDF versions that swap // the left and right channels // https://github.com/espressif/esp-idf/issues/6625 + #if CONFIG_IDF_TARGET_ESP32S3 + REG_SET_BIT(I2S_TX_CONF_REG(self->port), I2S_TX_MSB_SHIFT); + REG_SET_BIT(I2S_TX_CONF_REG(self->port), I2S_RX_MSB_SHIFT); + #else REG_SET_BIT(I2S_CONF_REG(self->port), I2S_TX_MSB_RIGHT); REG_SET_BIT(I2S_CONF_REG(self->port), I2S_RX_MSB_RIGHT); + #endif i2s_pin_config_t pin_config; pin_config.bck_io_num = self->sck; diff --git a/ports/esp32/machine_timer.c b/ports/esp32/machine_timer.c index 803849e1be..020ba4447d 100644 --- a/ports/esp32/machine_timer.c +++ b/ports/esp32/machine_timer.c @@ -138,7 +138,11 @@ STATIC void machine_timer_isr(void *self_in) { device->hw_timer[self->index].update = 1; #else #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) + #if CONFIG_IDF_TARGET_ESP32S3 + device->hw_timer[self->index].update.tn_update = 1; + #else device->hw_timer[self->index].update.tx_update = 1; + #endif #else device->hw_timer[self->index].update.update = 1; #endif diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c index 00271a37ed..cca2015729 100644 --- a/ports/esp32/modmachine.c +++ b/ports/esp32/modmachine.c @@ -91,6 +91,8 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) { esp_pm_config_esp32c3_t pm; #elif CONFIG_IDF_TARGET_ESP32S2 esp_pm_config_esp32s2_t pm; + #elif CONFIG_IDF_TARGET_ESP32S3 + esp_pm_config_esp32s3_t pm; #endif pm.max_freq_mhz = freq; pm.min_freq_mhz = freq; diff --git a/ports/esp32/partitions-8MiB.csv b/ports/esp32/partitions-8MiB.csv new file mode 100644 index 0000000000..582d3b50e5 --- /dev/null +++ b/ports/esp32/partitions-8MiB.csv @@ -0,0 +1,7 @@ +# Notes: the offset of the partition table itself is set in +# $IDF_PATH/components/partition_table/Kconfig.projbuild. +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 0x1F0000, +vfs, data, fat, 0x200000, 0x600000, diff --git a/ports/esp32/uart.c b/ports/esp32/uart.c index 480b364a59..58fc0c6c61 100644 --- a/ports/esp32/uart.c +++ b/ports/esp32/uart.c @@ -45,13 +45,18 @@ void uart_init(void) { // all code executed in ISR must be in IRAM, and any const data must be in DRAM STATIC void IRAM_ATTR uart_irq_handler(void *arg) { volatile uart_dev_t *uart = &UART0; + #if CONFIG_IDF_TARGET_ESP32S3 + uart->int_clr.rxfifo_full_int_clr = 1; + uart->int_clr.rxfifo_tout_int_clr = 1; + #else uart->int_clr.rxfifo_full = 1; - uart->int_clr.frm_err = 1; uart->int_clr.rxfifo_tout = 1; + uart->int_clr.frm_err = 1; + #endif while (uart->status.rxfifo_cnt) { #if CONFIG_IDF_TARGET_ESP32 uint8_t c = uart->fifo.rw_byte; - #elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2 + #elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 uint8_t c = READ_PERI_REG(UART_FIFO_AHB_REG(0)); // UART0 #endif if (c == mp_interrupt_char) { From 80fe25689f424b1d7a0f892a0c111bef21181f7d Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Sep 2021 22:18:32 +1000 Subject: [PATCH 049/335] esp32/boards: Add new GENERIC_S3 board definition. Thanks to Seon Rozenblum aka @UnexpectedMaker for the work. Signed-off-by: Damien George --- ports/esp32/boards/GENERIC_S3/mpconfigboard.cmake | 11 +++++++++++ ports/esp32/boards/GENERIC_S3/mpconfigboard.h | 13 +++++++++++++ ports/esp32/boards/GENERIC_S3/sdkconfig.board | 12 ++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 ports/esp32/boards/GENERIC_S3/mpconfigboard.cmake create mode 100644 ports/esp32/boards/GENERIC_S3/mpconfigboard.h create mode 100644 ports/esp32/boards/GENERIC_S3/sdkconfig.board diff --git a/ports/esp32/boards/GENERIC_S3/mpconfigboard.cmake b/ports/esp32/boards/GENERIC_S3/mpconfigboard.cmake new file mode 100644 index 0000000000..eae671d286 --- /dev/null +++ b/ports/esp32/boards/GENERIC_S3/mpconfigboard.cmake @@ -0,0 +1,11 @@ +set(IDF_TARGET esp32s3) + +set(SDKCONFIG_DEFAULTS + boards/sdkconfig.base + boards/sdkconfig.usb + boards/GENERIC_S3/sdkconfig.board +) + +if(NOT MICROPY_FROZEN_MANIFEST) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +endif() diff --git a/ports/esp32/boards/GENERIC_S3/mpconfigboard.h b/ports/esp32/boards/GENERIC_S3/mpconfigboard.h new file mode 100644 index 0000000000..562521c368 --- /dev/null +++ b/ports/esp32/boards/GENERIC_S3/mpconfigboard.h @@ -0,0 +1,13 @@ +#define MICROPY_HW_BOARD_NAME "ESP32S3 module" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_PY_BLUETOOTH (0) +#define MICROPY_HW_ENABLE_SDCARD (0) +#define MICROPY_PY_MACHINE_DAC (0) + +#define MICROPY_HW_I2C0_SCL (9) +#define MICROPY_HW_I2C0_SDA (8) + +#define MICROPY_HW_SPI1_MOSI (35) // SDO +#define MICROPY_HW_SPI1_MISO (37) // SDI +#define MICROPY_HW_SPI1_SCK (36) diff --git a/ports/esp32/boards/GENERIC_S3/sdkconfig.board b/ports/esp32/boards/GENERIC_S3/sdkconfig.board new file mode 100644 index 0000000000..c9726d4232 --- /dev/null +++ b/ports/esp32/boards/GENERIC_S3/sdkconfig.board @@ -0,0 +1,12 @@ +CONFIG_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_AFTER_NORESET=y + +CONFIG_SPIRAM_MEMTEST= + +CONFIG_ESPTOOLPY_FLASHSIZE_4MB= +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB= +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-8MiB.csv" From da4593f937003e5593725bfa61f727d429a1e061 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Sep 2021 22:22:40 +1000 Subject: [PATCH 050/335] tools/ci.sh: Use IDF v4.4 as part of esp32 CI and build GENERIC_S3. IDF v4.4 does not have an official release so for now use the latest master. Also remove building GENERIC with no options (all the other boards are no-option builds), to keep CI time reasonable. Signed-off-by: Damien George --- .github/workflows/ports_esp32.yml | 4 ++-- tools/ci.sh | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ports_esp32.yml b/.github/workflows/ports_esp32.yml index 09817ee126..de88de3755 100644 --- a/.github/workflows/ports_esp32.yml +++ b/.github/workflows/ports_esp32.yml @@ -22,11 +22,11 @@ jobs: - name: Build run: source tools/ci.sh && ci_esp32_build - build_idf43: + build_idf44: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - name: Install packages - run: source tools/ci.sh && ci_esp32_idf43_setup + run: source tools/ci.sh && ci_esp32_idf44_setup - name: Build run: source tools/ci.sh && ci_esp32_build diff --git a/tools/ci.sh b/tools/ci.sh index 4c216257d2..407ea04579 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -106,16 +106,14 @@ function ci_esp32_idf402_setup { ci_esp32_setup_helper v4.0.2 } -function ci_esp32_idf43_setup { - ci_esp32_setup_helper v4.3 +function ci_esp32_idf44_setup { + ci_esp32_setup_helper master } function ci_esp32_build { source esp-idf/export.sh make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/esp32 submodules - make ${MAKEOPTS} -C ports/esp32 - make ${MAKEOPTS} -C ports/esp32 clean make ${MAKEOPTS} -C ports/esp32 USER_C_MODULES=../../../examples/usercmodule/micropython.cmake FROZEN_MANIFEST=$(pwd)/ports/esp32/boards/manifest.py if [ -d $IDF_PATH/components/esp32c3 ]; then make ${MAKEOPTS} -C ports/esp32 BOARD=GENERIC_C3 @@ -123,6 +121,9 @@ function ci_esp32_build { if [ -d $IDF_PATH/components/esp32s2 ]; then make ${MAKEOPTS} -C ports/esp32 BOARD=GENERIC_S2 fi + if [ -d $IDF_PATH/components/esp32s3 ]; then + make ${MAKEOPTS} -C ports/esp32 BOARD=GENERIC_S3 + fi } ######################################################################################## From 13e6e0d7f5dc830639fd21e2b1380c6cc1996cab Mon Sep 17 00:00:00 2001 From: Seon Rozenblum Date: Fri, 17 Sep 2021 19:44:06 +1000 Subject: [PATCH 051/335] esp32/machine_hw_spi: Fix hardware SPI DMA channels for S2/S3. --- ports/esp32/machine_hw_spi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ports/esp32/machine_hw_spi.c b/ports/esp32/machine_hw_spi.c index 4c0989b9a6..467bff7ccb 100644 --- a/ports/esp32/machine_hw_spi.c +++ b/ports/esp32/machine_hw_spi.c @@ -57,6 +57,7 @@ #define HSPI_HOST SPI2_HOST #elif CONFIG_IDF_TARGET_ESP32S3 #define HSPI_HOST SPI3_HOST +#define FSPI_HOST SPI2_HOST #endif typedef struct _machine_hw_spi_default_pins_t { @@ -195,6 +196,9 @@ STATIC void machine_hw_spi_init_internal( } if (self->host != HSPI_HOST + #ifdef FSPI_HOST + && self->host != FSPI_HOST + #endif #ifdef VSPI_HOST && self->host != VSPI_HOST #endif @@ -233,7 +237,15 @@ STATIC void machine_hw_spi_init_internal( // Select DMA channel based on the hardware SPI host int dma_chan = 0; if (self->host == HSPI_HOST) { + #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 + dma_chan = 3; + #else dma_chan = 1; + #endif + #ifdef FSPI_HOST + } else if (self->host == FSPI_HOST) { + dma_chan = 1; + #endif #ifdef VSPI_HOST } else if (self->host == VSPI_HOST) { dma_chan = 2; From 4cfd85eb4a4dbab02efb1b22e87789f552e68fc0 Mon Sep 17 00:00:00 2001 From: patrick Date: Wed, 25 Aug 2021 22:17:10 +1000 Subject: [PATCH 052/335] esp32/boards: Add board definition for ESP32-S2-WROVER module. --- .../boards/ESP32_S2_WROVER/mpconfigboard.cmake | 12 ++++++++++++ .../esp32/boards/ESP32_S2_WROVER/mpconfigboard.h | 15 +++++++++++++++ .../esp32/boards/ESP32_S2_WROVER/sdkconfig.board | 11 +++++++++++ 3 files changed, 38 insertions(+) create mode 100644 ports/esp32/boards/ESP32_S2_WROVER/mpconfigboard.cmake create mode 100644 ports/esp32/boards/ESP32_S2_WROVER/mpconfigboard.h create mode 100644 ports/esp32/boards/ESP32_S2_WROVER/sdkconfig.board diff --git a/ports/esp32/boards/ESP32_S2_WROVER/mpconfigboard.cmake b/ports/esp32/boards/ESP32_S2_WROVER/mpconfigboard.cmake new file mode 100644 index 0000000000..806312e5ac --- /dev/null +++ b/ports/esp32/boards/ESP32_S2_WROVER/mpconfigboard.cmake @@ -0,0 +1,12 @@ +set(IDF_TARGET esp32s2) + +set(SDKCONFIG_DEFAULTS + boards/sdkconfig.base + boards/sdkconfig.spiram_sx + boards/sdkconfig.usb + boards/ESP32_S2_WROVER/sdkconfig.board +) + +if(NOT MICROPY_FROZEN_MANIFEST) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +endif() diff --git a/ports/esp32/boards/ESP32_S2_WROVER/mpconfigboard.h b/ports/esp32/boards/ESP32_S2_WROVER/mpconfigboard.h new file mode 100644 index 0000000000..f9219c8767 --- /dev/null +++ b/ports/esp32/boards/ESP32_S2_WROVER/mpconfigboard.h @@ -0,0 +1,15 @@ +#define MICROPY_HW_BOARD_NAME "ESP32-S2-WROVER" +#define MICROPY_HW_MCU_NAME "ESP32-S2" + +#define MICROPY_PY_BLUETOOTH (0) +#define MICROPY_HW_ENABLE_SDCARD (0) + +#define MICROPY_HW_I2C0_SCL (7) +#define MICROPY_HW_I2C0_SDA (6) + +#define MICROPY_HW_SPI1_MOSI (35) +#define MICROPY_HW_SPI1_MISO (37) +#define MICROPY_HW_SPI1_SCK (36) +#define MICROPY_HW_SPI2_MOSI (11) +#define MICROPY_HW_SPI2_MISO (13) +#define MICROPY_HW_SPI2_SCK (12) diff --git a/ports/esp32/boards/ESP32_S2_WROVER/sdkconfig.board b/ports/esp32/boards/ESP32_S2_WROVER/sdkconfig.board new file mode 100644 index 0000000000..9373a52232 --- /dev/null +++ b/ports/esp32/boards/ESP32_S2_WROVER/sdkconfig.board @@ -0,0 +1,11 @@ +CONFIG_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_AFTER_NORESET=y + +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_USB_AND_UART=y + +# LWIP +CONFIG_LWIP_LOCAL_HOSTNAME="ESP32-S2-WROVER" +# end of LWIP From 6e39f2cc1ed7d4e6a6b1d3132a1b5a73b198ef38 Mon Sep 17 00:00:00 2001 From: Chris Fiege Date: Tue, 14 Sep 2021 11:50:53 +0200 Subject: [PATCH 053/335] stm32/boards: Add OLIMEX H407 board definition. This change adds the OLIMEX H407 support to the STM32 port. The H407 (https://www.olimex.com/Products/ARM/ST/STM32-H407/) is simliar to the already existing E407 (https://www.olimex.com/Products/ARM/ST/STM32-E407) but does not support Ethernet and has a full-size USB-A port instead of a Mini-USB socket. Both boards use the STM32F407ZGT6 CPU. This port is basically a copy of the E407 but with changed pinmux: * Removed Ethernet pin definition * Removed UART1 (pins are used for other functions) * Removed UART3 flow control pins (pins are used for other functions) * Removed SD-Card detect pin (since it is not connected on the H407) A REPL on UART3 is connected to the U3BOOT-header, a 3-pin header with RX, TX and GND that is intended for the serial terminal. Tested: * Micro-SD Card is detected when inserted on RESET * REPL on UART3 works * Serial port on the mini USB socket Signed-off-by: Chris Fiege --- ports/stm32/boards/OLIMEX_H407/README.md | 18 ++++ .../stm32/boards/OLIMEX_H407/mpconfigboard.h | 81 +++++++++++++++++ .../stm32/boards/OLIMEX_H407/mpconfigboard.mk | 6 ++ ports/stm32/boards/OLIMEX_H407/pins.csv | 89 +++++++++++++++++++ .../boards/OLIMEX_H407/stm32f4xx_hal_conf.h | 19 ++++ 5 files changed, 213 insertions(+) create mode 100644 ports/stm32/boards/OLIMEX_H407/README.md create mode 100644 ports/stm32/boards/OLIMEX_H407/mpconfigboard.h create mode 100644 ports/stm32/boards/OLIMEX_H407/mpconfigboard.mk create mode 100644 ports/stm32/boards/OLIMEX_H407/pins.csv create mode 100644 ports/stm32/boards/OLIMEX_H407/stm32f4xx_hal_conf.h diff --git a/ports/stm32/boards/OLIMEX_H407/README.md b/ports/stm32/boards/OLIMEX_H407/README.md new file mode 100644 index 0000000000..458e288e7a --- /dev/null +++ b/ports/stm32/boards/OLIMEX_H407/README.md @@ -0,0 +1,18 @@ +OLIMEX H407 board +================= + +This board definition supports the OLIMEX H407 board: +https://www.olimex.com/Products/ARM/ST/STM32-H407/ + +A REPL is available at the U3BOOT connector with 115200 baud and on the +micro USB socket. + +What works +---------- + +* REPL +* UART +* SD-Card +* Timer +* GPIOs +* USB device on the mini USB socket diff --git a/ports/stm32/boards/OLIMEX_H407/mpconfigboard.h b/ports/stm32/boards/OLIMEX_H407/mpconfigboard.h new file mode 100644 index 0000000000..813fffeac3 --- /dev/null +++ b/ports/stm32/boards/OLIMEX_H407/mpconfigboard.h @@ -0,0 +1,81 @@ +#define MICROPY_HW_BOARD_NAME "OLIMEX STM32-H407" +#define MICROPY_HW_MCU_NAME "STM32F407" + +#define MICROPY_HW_HAS_SWITCH (1) +#define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SDCARD (1) + +// HSE is 12MHz +#define MICROPY_HW_CLK_PLLM (12) +#define MICROPY_HW_CLK_PLLN (336) +#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2) +#define MICROPY_HW_CLK_PLLQ (7) + +// UART config + +#define MICROPY_HW_UART2_TX (pin_A2) +#define MICROPY_HW_UART2_RX (pin_A3) + +#define MICROPY_HW_UART3_TX (pin_B10) +#define MICROPY_HW_UART3_RX (pin_B11) + +#define MICROPY_HW_UART3_RTS (pin_D12) +#define MICROPY_HW_UART3_CTS (pin_D11) + +#if MICROPY_HW_HAS_SWITCH == 0 +// NOTE: A0 also connects to the user switch. To use UART4 you should +// set MICROPY_HW_HAS_SWITCH to 0, and also remove SB20 (on the back +// of the board near the USER switch). +#define MICROPY_HW_UART4_TX (pin_A0) +#define MICROPY_HW_UART4_RX (pin_A1) +#endif + +#define MICROPY_HW_UART6_TX (pin_C6) +#define MICROPY_HW_UART6_RX (pin_C7) + +// REPL mapping +#define MICROPY_HW_UART_REPL PYB_UART_3 +#define MICROPY_HW_UART_REPL_BAUD 115200 + +// I2C buses +#define MICROPY_HW_I2C1_SCL (pin_B8) +#define MICROPY_HW_I2C1_SDA (pin_B9) +#define MICROPY_HW_I2C2_SCL (pin_B10) +#define MICROPY_HW_I2C2_SDA (pin_B11) + +// SPI buses +#define MICROPY_HW_SPI1_NSS (pin_A4) +#define MICROPY_HW_SPI1_SCK (pin_A5) +#define MICROPY_HW_SPI1_MISO (pin_A6) +#define MICROPY_HW_SPI1_MOSI (pin_A7) +#define MICROPY_HW_SPI2_NSS (pin_B12) +#define MICROPY_HW_SPI2_SCK (pin_B13) +#define MICROPY_HW_SPI2_MISO (pin_B14) +#define MICROPY_HW_SPI2_MOSI (pin_B15) + +// CAN buses +#define MICROPY_HW_CAN1_TX (pin_B9) +#define MICROPY_HW_CAN1_RX (pin_B8) +#define MICROPY_HW_CAN2_TX (pin_B13) +#define MICROPY_HW_CAN2_RX (pin_B12) + +// USRSW is pulled low. Pressing the button makes the input go high. +#define MICROPY_HW_USRSW_PIN (pin_A0) +#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) +#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_RISING) +#define MICROPY_HW_USRSW_PRESSED (1) + +// LEDs +#define MICROPY_HW_LED1 (pin_C13) +#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) +#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) + +// USB config +#define MICROPY_HW_USB_HS (1) +#define MICROPY_HW_USB_HS_IN_FS (1) +#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_B13) +#define MICROPY_HW_USB_OTG_ID_PIN (pin_B12) diff --git a/ports/stm32/boards/OLIMEX_H407/mpconfigboard.mk b/ports/stm32/boards/OLIMEX_H407/mpconfigboard.mk new file mode 100644 index 0000000000..b154dcfbac --- /dev/null +++ b/ports/stm32/boards/OLIMEX_H407/mpconfigboard.mk @@ -0,0 +1,6 @@ +MCU_SERIES = f4 +CMSIS_MCU = STM32F407xx +AF_FILE = boards/stm32f405_af.csv +LD_FILES = boards/stm32f405.ld boards/common_ifs.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08020000 diff --git a/ports/stm32/boards/OLIMEX_H407/pins.csv b/ports/stm32/boards/OLIMEX_H407/pins.csv new file mode 100644 index 0000000000..cb0a49916e --- /dev/null +++ b/ports/stm32/boards/OLIMEX_H407/pins.csv @@ -0,0 +1,89 @@ +PC0,PC0 +PC1,PC1 +PC2,PC2 +PC3,PC3 +PA0,PA0 +PA1,PA1 +PA2,PA2 +PA3,PA3 +PA4,PA4 +PA5,PA5 +PA6,PA6 +PA7,PA7 +PC4,PC4 +PC5,PC5 +PB0,PB0 +PB1,PB1 +PB2,PB2 +PE7,PE7 +PE8,PE8 +PE9,PE9 +PE10,PE10 +PE11,PE11 +PE12,PE12 +PE13,PE13 +PE14,PE14 +PE15,PE15 +PB10,PB10 +PB11,PB11 +PB12,PB12 +PB13,PB13 +PB14,PB14 +PB15,PB15 +PD8,PD8 +PD9,PD9 +PD10,PD10 +PD11,PD11 +PD12,PD12 +PD13,PD13 +PD14,PD14 +PD15,PD15 +PC6,PC6 +PC7,PC7 +PC8,PC8 +PC9,PC9 +PA8,PA8 +PA9,PA9 +PA10,PA10 +PA13,PA13 +PA14,PA14 +PA15,PA15 +PC10,PC10 +PC11,PC11 +PC12,PC12 +PD0,PD0 +PD1,PD1 +PD2,PD2 +PD3,PD3 +PD4,PD4 +PD5,PD5 +PD6,PD6 +PD7,PD7 +PB4,PB4 +PB5,PB5 +PB6,PB6 +PB7,PB7 +PB8,PB8 +PB9,PB9 +PE0,PE0 +PE1,PE1 +PE2,PE2 +PE3,PE3 +PE4,PE4 +PE5,PE5 +PE6,PE6 +LED_GREEN,PC13 +PC14,PC14 +PC15,PC15 +PH0,PH0 +PH1,PH1 +PD12,PD12 +PD13,PD13 +PD14,PD14 +PD15,PD15 +PA0,PA0 +USB_DM,PA11 +USB_DP,PA12 +PG11,PG11 +PG13,PG13 +PG14,PG14 diff --git a/ports/stm32/boards/OLIMEX_H407/stm32f4xx_hal_conf.h b/ports/stm32/boards/OLIMEX_H407/stm32f4xx_hal_conf.h new file mode 100644 index 0000000000..9719157e55 --- /dev/null +++ b/ports/stm32/boards/OLIMEX_H407/stm32f4xx_hal_conf.h @@ -0,0 +1,19 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2019 Damien P. George + */ +#ifndef MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H + +#include "boards/stm32f4xx_hal_conf_base.h" + +// Oscillator values in Hz +#define HSE_VALUE (12000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (100) +#define LSE_STARTUP_TIMEOUT (5000) + +#endif // MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H From 80f2c794e60f59179cf530d3add53a4acbe75e55 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 22 Jul 2021 14:39:44 +0200 Subject: [PATCH 054/335] extmod/mpbthci.h: Add mp_bluetooth_hci_uart_any prototype. This allows drivers to use mpbthciport functions to read/write/poll UART. --- extmod/mpbthci.h | 1 + 1 file changed, 1 insertion(+) diff --git a/extmod/mpbthci.h b/extmod/mpbthci.h index acb5b832ba..6997238033 100644 --- a/extmod/mpbthci.h +++ b/extmod/mpbthci.h @@ -45,6 +45,7 @@ int mp_bluetooth_hci_controller_wakeup(void); int mp_bluetooth_hci_uart_init(uint32_t port, uint32_t baudrate); int mp_bluetooth_hci_uart_deinit(void); int mp_bluetooth_hci_uart_set_baudrate(uint32_t baudrate); +int mp_bluetooth_hci_uart_any(void); int mp_bluetooth_hci_uart_readchar(void); int mp_bluetooth_hci_uart_write(const uint8_t *buf, size_t len); From 8064c3bf9c99d3aa63f560fab83509f39c999b51 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 22 Jul 2021 14:41:31 +0200 Subject: [PATCH 055/335] extmod/nimble: Add nimble CMake fragment file. --- extmod/nimble/nimble.cmake | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 extmod/nimble/nimble.cmake diff --git a/extmod/nimble/nimble.cmake b/extmod/nimble/nimble.cmake new file mode 100644 index 0000000000..3dff1d7d05 --- /dev/null +++ b/extmod/nimble/nimble.cmake @@ -0,0 +1,80 @@ +set(NIMBLE_LIB_DIR "${MICROPY_DIR}/lib/mynewt-nimble") +set(NIMBLE_EXTMOD_DIR "${MICROPY_DIR}/extmod/nimble") + +add_library(micropy_extmod_nimble INTERFACE) + +target_include_directories(micropy_extmod_nimble INTERFACE + ${MICROPY_DIR}/ + ${MICROPY_PORT_DIR}/ + ${NIMBLE_EXTMOD_DIR}/ + ${NIMBLE_LIB_DIR}/ + ${NIMBLE_LIB_DIR}/ext/tinycrypt/include + ${NIMBLE_LIB_DIR}/nimble/host/include + ${NIMBLE_LIB_DIR}/nimble/host/services/gap/include + ${NIMBLE_LIB_DIR}/nimble/host/services/gatt/include + ${NIMBLE_LIB_DIR}/nimble/host/store/ram/include + ${NIMBLE_LIB_DIR}/nimble/host/util/include + ${NIMBLE_LIB_DIR}/nimble/include + ${NIMBLE_LIB_DIR}/nimble/transport/uart/include + ${NIMBLE_LIB_DIR}/porting/nimble/include +) + +target_sources(micropy_extmod_nimble INTERFACE + ${NIMBLE_EXTMOD_DIR}/hal/hal_uart.c + ${NIMBLE_EXTMOD_DIR}/nimble/nimble_npl_os.c + ${NIMBLE_LIB_DIR}/ext/tinycrypt/src/aes_encrypt.c + ${NIMBLE_LIB_DIR}/ext/tinycrypt/src/cmac_mode.c + ${NIMBLE_LIB_DIR}/ext/tinycrypt/src/ecc.c + ${NIMBLE_LIB_DIR}/ext/tinycrypt/src/ecc_dh.c + ${NIMBLE_LIB_DIR}/ext/tinycrypt/src/utils.c + ${NIMBLE_LIB_DIR}/nimble/host/services/gap/src/ble_svc_gap.c + ${NIMBLE_LIB_DIR}/nimble/host/services/gatt/src/ble_svc_gatt.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_att.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_att_clt.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_att_cmd.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_att_svr.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_eddystone.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_gap.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_gattc.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_gatts.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_adv.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_atomic.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_cfg.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_conn.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_flow.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_hci.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_hci_cmd.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_hci_evt.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_hci_util.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_id.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_log.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_mbuf.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_misc.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_mqueue.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_pvcy.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_startup.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_hs_stop.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_ibeacon.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_l2cap.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_l2cap_coc.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_l2cap_sig.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_l2cap_sig_cmd.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_monitor.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_sm.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_sm_alg.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_sm_cmd.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_sm_lgcy.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_sm_sc.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_store.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_store_util.c + ${NIMBLE_LIB_DIR}/nimble/host/src/ble_uuid.c + ${NIMBLE_LIB_DIR}/nimble/host/util/src/addr.c + ${NIMBLE_LIB_DIR}/nimble/transport/uart/src/ble_hci_uart.c + ${NIMBLE_LIB_DIR}/porting/nimble/src/endian.c + ${NIMBLE_LIB_DIR}/porting/nimble/src/mem.c + ${NIMBLE_LIB_DIR}/porting/nimble/src/nimble_port.c + ${NIMBLE_LIB_DIR}/porting/nimble/src/os_mbuf.c + ${NIMBLE_LIB_DIR}/porting/nimble/src/os_mempool.c + ${NIMBLE_LIB_DIR}/porting/nimble/src/os_msys_init.c +) From c973cfd2f33175cacefd0608853d0db1d7fa813c Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 22 Jul 2021 14:42:52 +0200 Subject: [PATCH 056/335] rp2: Add support for bluetooth module using NimBLE. --- ports/rp2/CMakeLists.txt | 26 +++++ ports/rp2/main.c | 9 ++ ports/rp2/mpbthciport.c | 200 +++++++++++++++++++++++++++++++++++++++ ports/rp2/mpbthciport.h | 42 ++++++++ ports/rp2/mpconfigport.h | 16 ++++ ports/rp2/mpnimbleport.c | 80 ++++++++++++++++ ports/rp2/mpnimbleport.h | 29 ++++++ 7 files changed, 402 insertions(+) create mode 100644 ports/rp2/mpbthciport.c create mode 100644 ports/rp2/mpbthciport.h create mode 100644 ports/rp2/mpnimbleport.c create mode 100644 ports/rp2/mpnimbleport.h diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index 2e7347fd53..40b10434b0 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -159,6 +159,32 @@ set(PICO_SDK_COMPONENTS tinyusb_device ) +if(MICROPY_PY_BLUETOOTH) + list(APPEND MICROPY_SOURCE_PORT mpbthciport.c) + target_compile_definitions(${MICROPY_TARGET} PRIVATE + MICROPY_PY_BLUETOOTH=1 + MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE=1 + MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING=1 + MICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS=1 + ) +endif() + +if(MICROPY_BLUETOOTH_NIMBLE) + list(APPEND MICROPY_SOURCE_PORT mpnimbleport.c) + target_compile_definitions(${MICROPY_TARGET} PRIVATE + MICROPY_BLUETOOTH_NIMBLE=1 + MICROPY_BLUETOOTH_NIMBLE_BINDINGS_ONLY=0 + ) + target_compile_options(${MICROPY_TARGET} PRIVATE + # TODO: This flag is currently needed to make nimble build. + -Wno-unused-but-set-variable + ) + include(${MICROPY_DIR}/extmod/nimble/nimble.cmake) + target_link_libraries(${MICROPY_TARGET} micropy_extmod_nimble) + get_target_property(NIMBLE_INCLUDE micropy_extmod_nimble INTERFACE_INCLUDE_DIRECTORIES) + list(APPEND MICROPY_INC_CORE ${NIMBLE_INCLUDE}) +endif() + # Define mpy-cross flags and frozen manifest set(MICROPY_CROSS_FLAGS -march=armv7m) if (NOT MICROPY_FROZEN_MANIFEST) diff --git a/ports/rp2/main.c b/ports/rp2/main.c index d0b89c8d6d..807de18e63 100644 --- a/ports/rp2/main.c +++ b/ports/rp2/main.c @@ -32,6 +32,7 @@ #include "py/mperrno.h" #include "py/mphal.h" #include "py/stackctrl.h" +#include "extmod/modbluetooth.h" #include "shared/readline/readline.h" #include "shared/runtime/gchelper.h" #include "shared/runtime/pyexec.h" @@ -39,6 +40,7 @@ #include "uart.h" #include "modmachine.h" #include "modrp2.h" +#include "mpbthciport.h" #include "genhdr/mpversion.h" #include "pico/stdlib.h" @@ -107,6 +109,10 @@ int main(int argc, char **argv) { machine_pin_init(); rp2_pio_init(); + #if MICROPY_PY_BLUETOOTH + mp_bluetooth_hci_init(); + #endif + // Execute _boot.py to set up the filesystem. pyexec_frozen_module("_boot.py"); @@ -137,6 +143,9 @@ int main(int argc, char **argv) { soft_reset_exit: mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); rp2_pio_deinit(); + #if MICROPY_PY_BLUETOOTH + mp_bluetooth_deinit(); + #endif machine_pin_deinit(); #if MICROPY_PY_THREAD mp_thread_deinit(); diff --git a/ports/rp2/mpbthciport.c b/ports/rp2/mpbthciport.c new file mode 100644 index 0000000000..58639fd5b0 --- /dev/null +++ b/ports/rp2/mpbthciport.c @@ -0,0 +1,200 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Ibrahim Abdelkader + * + * 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/runtime.h" +#include "py/stream.h" +#include "py/mphal.h" +#include "extmod/modbluetooth.h" +#include "extmod/mpbthci.h" +#include "modmachine.h" +#include "mpbthciport.h" +#include "pico/stdlib.h" + +#if MICROPY_PY_BLUETOOTH + +#define debug_printf(...) // mp_printf(&mp_plat_print, "mpbthciport.c: " __VA_ARGS__) +#define error_printf(...) mp_printf(&mp_plat_print, "mpbthciport.c: " __VA_ARGS__) + +// Poll timer ID. +static alarm_id_t poll_timer_id = 0; + +uint8_t mp_bluetooth_hci_cmd_buf[4 + 256]; + +// Prevent double-enqueuing of the scheduled task. +STATIC volatile bool events_task_is_scheduled; + +void mp_bluetooth_hci_init(void) { + events_task_is_scheduled = false; +} + +STATIC void mp_bluetooth_hci_start_polling(void) { + events_task_is_scheduled = false; + mp_bluetooth_hci_poll_now(); +} + +static int64_t mp_bluetooth_hci_timer_callback(alarm_id_t id, void *user_data) { + poll_timer_id = 0; + mp_bluetooth_hci_poll_now(); + return 0; +} + +void mp_bluetooth_hci_poll_in_ms(uint32_t ms) { + poll_timer_id = add_alarm_in_ms(ms, mp_bluetooth_hci_timer_callback, NULL, true); +} + +// For synchronous mode, we run all BLE stack code inside a scheduled task. +// This task is scheduled periodically via a timer, or immediately after UART RX IRQ. +STATIC mp_obj_t run_events_scheduled_task(mp_obj_t none_in) { + (void)none_in; + events_task_is_scheduled = false; + // This will process all buffered HCI UART data, and run any callouts or events. + mp_bluetooth_hci_poll(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(run_events_scheduled_task_obj, run_events_scheduled_task); + +// Called periodically (systick) or directly (e.g. UART RX IRQ) in order to +// request that processing happens ASAP in the scheduler. +void mp_bluetooth_hci_poll_now(void) { + if (!events_task_is_scheduled) { + events_task_is_scheduled = mp_sched_schedule(MP_OBJ_FROM_PTR(&run_events_scheduled_task_obj), mp_const_none); + if (!events_task_is_scheduled) { + // The schedule queue is full, set callback to try again soon. + mp_bluetooth_hci_poll_in_ms(5); + } + } +} + +mp_obj_t mp_bthci_uart; + +int mp_bluetooth_hci_uart_init(uint32_t port, uint32_t baudrate) { + debug_printf("mp_bluetooth_hci_uart_init\n"); + + mp_obj_t args[] = { + MP_OBJ_NEW_SMALL_INT(MICROPY_HW_BLE_UART_ID), + MP_OBJ_NEW_SMALL_INT(MICROPY_HW_BLE_UART_BAUDRATE), + MP_OBJ_NEW_QSTR(MP_QSTR_flow), MP_OBJ_NEW_SMALL_INT((1 | 2)), + MP_OBJ_NEW_QSTR(MP_QSTR_timeout), MP_OBJ_NEW_SMALL_INT(1000), + }; + + mp_bthci_uart = machine_uart_type.make_new((mp_obj_t)&machine_uart_type, 2, 2, args); + MP_STATE_PORT(mp_bthci_uart) = mp_bthci_uart; + + // Start the HCI polling to process any initial events/packets. + mp_bluetooth_hci_start_polling(); + return 0; +} + +int mp_bluetooth_hci_uart_deinit(void) { + debug_printf("mp_bluetooth_hci_uart_deinit\n"); + + // If a poll callback is set cancel it now. + if (poll_timer_id > 0) { + cancel_alarm(poll_timer_id); + } + poll_timer_id = 0; + return 0; +} + +int mp_bluetooth_hci_uart_set_baudrate(uint32_t baudrate) { + debug_printf("mp_bluetooth_hci_uart_set_baudrate(%lu)\n", baudrate); + return 0; +} + +int mp_bluetooth_hci_uart_any(void) { + int errcode = 0; + const mp_stream_p_t *proto = (mp_stream_p_t *)machine_uart_type.protocol; + + mp_uint_t ret = proto->ioctl(mp_bthci_uart, MP_STREAM_POLL, MP_STREAM_POLL_RD, &errcode); + if (errcode != 0) { + error_printf("Uart ioctl failed to poll UART %d\n", errcode); + return -1; + } + return ret & MP_STREAM_POLL_RD; +} + +int mp_bluetooth_hci_uart_write(const uint8_t *buf, size_t len) { + debug_printf("mp_bluetooth_hci_uart_write\n"); + + int errcode = 0; + const mp_stream_p_t *proto = (mp_stream_p_t *)machine_uart_type.protocol; + + mp_bluetooth_hci_controller_wakeup(); + + if (proto->write(mp_bthci_uart, (void *)buf, len, &errcode) < 0) { + error_printf("mp_bluetooth_hci_uart_write: failed to write to UART %d\n", errcode); + } + return 0; +} + +// This function expects the controller to be in the wake state via a previous call +// to mp_bluetooth_hci_controller_woken. +int mp_bluetooth_hci_uart_readchar(void) { + debug_printf("mp_bluetooth_hci_uart_readchar\n"); + if (mp_bluetooth_hci_uart_any()) { + int errcode = 0; + uint8_t buf = 0; + const mp_stream_p_t *proto = (mp_stream_p_t *)machine_uart_type.protocol; + if (proto->read(mp_bthci_uart, (void *)&buf, 1, &errcode) < 0) { + error_printf("mp_bluetooth_hci_uart_readchar: failed to read UART %d\n", errcode); + return -1; + } + return buf; + } else { + debug_printf("mp_bluetooth_hci_uart_readchar: not ready\n"); + return -1; + } +} + +// Default (weak) implementation of the HCI controller interface. +// A driver (e.g. cywbt43.c) can override these for controller-specific +// functionality (i.e. power management). +MP_WEAK int mp_bluetooth_hci_controller_init(void) { + debug_printf("mp_bluetooth_hci_controller_init (default)\n"); + return 0; +} + +MP_WEAK int mp_bluetooth_hci_controller_deinit(void) { + debug_printf("mp_bluetooth_hci_controller_deinit (default)\n"); + return 0; +} + +MP_WEAK int mp_bluetooth_hci_controller_sleep_maybe(void) { + debug_printf("mp_bluetooth_hci_controller_sleep_maybe (default)\n"); + return 0; +} + +MP_WEAK bool mp_bluetooth_hci_controller_woken(void) { + debug_printf("mp_bluetooth_hci_controller_woken (default)\n"); + return true; +} + +MP_WEAK int mp_bluetooth_hci_controller_wakeup(void) { + debug_printf("mp_bluetooth_hci_controller_wakeup (default)\n"); + return 0; +} + +#endif // MICROPY_PY_BLUETOOTH diff --git a/ports/rp2/mpbthciport.h b/ports/rp2/mpbthciport.h new file mode 100644 index 0000000000..ac5263aa11 --- /dev/null +++ b/ports/rp2/mpbthciport.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Damien P. George + * + * 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_RP2_MPBTHCIPORT_H +#define MICROPY_INCLUDED_RP2_MPBTHCIPORT_H + +// Initialise the HCI subsystem (should be called once, early on). +void mp_bluetooth_hci_init(void); + +// Poll the HCI now, or after a certain timeout. +void mp_bluetooth_hci_poll_now(void); +void mp_bluetooth_hci_poll_in_ms(uint32_t ms); + +// Must be provided by the stack bindings (e.g. mpnimbleport.c or mpbtstackport.c). +// Request new data from the uart and pass to the stack, and run pending events/callouts. +// This is a low-level function and should not be called directly, use +// mp_bluetooth_hci_poll_now/mp_bluetooth_hci_poll_in_ms instead. +void mp_bluetooth_hci_poll(void); + +#endif // MICROPY_INCLUDED_RP2_MPBTHCIPORT_H diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index bb2f505b6e..237c1a5d83 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -171,6 +171,20 @@ extern const struct _mp_obj_module_t mp_module_rp2; extern const struct _mp_obj_module_t mp_module_uos; extern const struct _mp_obj_module_t mp_module_utime; +#if MICROPY_PY_BLUETOOTH +#define MICROPY_PORT_ROOT_POINTER_BLUETOOTH struct _machine_uart_obj_t *mp_bthci_uart; +#else +#define MICROPY_PORT_ROOT_POINTER_BLUETOOTH +#endif + +#if MICROPY_BLUETOOTH_NIMBLE +struct _mp_bluetooth_nimble_root_pointers_t; +struct _mp_bluetooth_nimble_malloc_t; +#define MICROPY_PORT_ROOT_POINTER_BLUETOOTH_NIMBLE struct _mp_bluetooth_nimble_malloc_t *bluetooth_nimble_memory; struct _mp_bluetooth_nimble_root_pointers_t *bluetooth_nimble_root_pointers; +#else +#define MICROPY_PORT_ROOT_POINTER_BLUETOOTH_NIMBLE +#endif + #define MICROPY_PORT_BUILTIN_MODULES \ { MP_OBJ_NEW_QSTR(MP_QSTR_machine), (mp_obj_t)&mp_module_machine }, \ { MP_OBJ_NEW_QSTR(MP_QSTR__onewire), (mp_obj_t)&mp_module_onewire }, \ @@ -190,6 +204,8 @@ extern const struct _mp_obj_module_t mp_module_utime; void *rp2_uart_rx_buffer[2]; \ void *rp2_uart_tx_buffer[2]; \ MICROPY_BOARD_ROOT_POINTERS \ + MICROPY_PORT_ROOT_POINTER_BLUETOOTH \ + MICROPY_PORT_ROOT_POINTER_BLUETOOTH_NIMBLE \ #define MP_STATE_PORT MP_STATE_VM diff --git a/ports/rp2/mpnimbleport.c b/ports/rp2/mpnimbleport.c new file mode 100644 index 0000000000..74e9ecb026 --- /dev/null +++ b/ports/rp2/mpnimbleport.c @@ -0,0 +1,80 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Jim Mussared + * Copyright (c) 2020 Damien P. George + * + * 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/runtime.h" +#include "py/mperrno.h" +#include "py/mphal.h" +#include "py/stream.h" + +#if MICROPY_PY_BLUETOOTH && MICROPY_BLUETOOTH_NIMBLE + +#define DEBUG_printf(...) // printf("mpnimbleport.c: " __VA_ARGS__) + +#include "host/ble_hs.h" +#include "nimble/nimble_npl.h" + +#include "extmod/modbluetooth.h" +#include "extmod/mpbthci.h" +#include "extmod/nimble/modbluetooth_nimble.h" +#include "extmod/nimble/hal/hal_uart.h" +#include "mpbthciport.h" + +// Get any pending data from the UART and send it to NimBLE's HCI buffers. +// Any further processing by NimBLE will be run via its event queue. +void mp_bluetooth_hci_poll(void) { + if (mp_bluetooth_nimble_ble_state >= MP_BLUETOOTH_NIMBLE_BLE_STATE_WAITING_FOR_SYNC) { + // DEBUG_printf("mp_bluetooth_hci_poll_uart %d\n", mp_bluetooth_nimble_ble_state); + + // Run any timers. + mp_bluetooth_nimble_os_callout_process(); + + // Process incoming UART data, and run events as they are generated. + mp_bluetooth_nimble_hci_uart_process(true); + + // Run any remaining events (e.g. if there was no UART data). + mp_bluetooth_nimble_os_eventq_run_all(); + } + + if (mp_bluetooth_nimble_ble_state != MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF) { + // Call this function again in 128ms to check for new events. + // TODO: improve this by only calling back when needed. + mp_bluetooth_hci_poll_in_ms(128); + } +} + +// --- Port-specific helpers for the generic NimBLE bindings. ----------------- + +void mp_bluetooth_nimble_hci_uart_wfi(void) { + #if defined(__WFI) + __WFI(); + #endif + // This is called while NimBLE is waiting in ble_npl_sem_pend, i.e. waiting for an HCI ACK. + // Do not need to run events here (it must not invoke Python code), only processing incoming HCI data. + mp_bluetooth_nimble_hci_uart_process(false); +} + +#endif // MICROPY_PY_BLUETOOTH && MICROPY_BLUETOOTH_NIMBLE diff --git a/ports/rp2/mpnimbleport.h b/ports/rp2/mpnimbleport.h new file mode 100644 index 0000000000..64debea33a --- /dev/null +++ b/ports/rp2/mpnimbleport.h @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jim Mussared + * + * 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_RP2_MPNIMBLEPORT_H +#define MICROPY_INCLUDED_RP2_MPNIMBLEPORT_H + +#endif // MICROPY_INCLUDED_RP2_MPNIMBLEPORT_H From 38f8e852e04013e4616097320bf9cf75051a1b6b Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 15 Aug 2021 18:30:18 +0200 Subject: [PATCH 057/335] rp2: Add framework for networking. MICROPY_PY_NETWORK and MICROPY_PY_USOCKET need to be enabled by a board to get networking. No NICs have yet been defined. --- extmod/extmod.cmake | 2 ++ extmod/modusocket.c | 4 ++-- ports/rp2/CMakeLists.txt | 1 + ports/rp2/main.c | 7 +++++++ ports/rp2/mpconfigport.h | 20 ++++++++++++++++++++ 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/extmod/extmod.cmake b/extmod/extmod.cmake index 69ec39759b..3353112ba6 100644 --- a/extmod/extmod.cmake +++ b/extmod/extmod.cmake @@ -16,6 +16,7 @@ set(MICROPY_SOURCE_EXTMOD ${MICROPY_EXTMOD_DIR}/modbluetooth.c ${MICROPY_EXTMOD_DIR}/modbtree.c ${MICROPY_EXTMOD_DIR}/modframebuf.c + ${MICROPY_EXTMOD_DIR}/modnetwork.c ${MICROPY_EXTMOD_DIR}/modonewire.c ${MICROPY_EXTMOD_DIR}/moduasyncio.c ${MICROPY_EXTMOD_DIR}/modubinascii.c @@ -27,6 +28,7 @@ set(MICROPY_SOURCE_EXTMOD ${MICROPY_EXTMOD_DIR}/modurandom.c ${MICROPY_EXTMOD_DIR}/modure.c ${MICROPY_EXTMOD_DIR}/moduselect.c + ${MICROPY_EXTMOD_DIR}/modusocket.c ${MICROPY_EXTMOD_DIR}/modussl_axtls.c ${MICROPY_EXTMOD_DIR}/modussl_mbedtls.c ${MICROPY_EXTMOD_DIR}/modutimeq.c diff --git a/extmod/modusocket.c b/extmod/modusocket.c index e08f8134fd..9c2dc6fcad 100644 --- a/extmod/modusocket.c +++ b/extmod/modusocket.c @@ -35,7 +35,7 @@ #include "shared/netutils/netutils.h" #include "modnetwork.h" -#if MICROPY_PY_USOCKET && !MICROPY_PY_LWIP +#if MICROPY_PY_NETWORK && MICROPY_PY_USOCKET && !MICROPY_PY_LWIP /******************************************************************************/ // socket class @@ -517,4 +517,4 @@ const mp_obj_module_t mp_module_usocket = { .globals = (mp_obj_dict_t *)&mp_module_usocket_globals, }; -#endif // MICROPY_PY_USOCKET && !MICROPY_PY_LWIP +#endif // MICROPY_PY_NETWORK && MICROPY_PY_USOCKET && !MICROPY_PY_LWIP diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index 40b10434b0..14f4e33ebe 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -66,6 +66,7 @@ set(MICROPY_SOURCE_LIB ${MICROPY_DIR}/lib/littlefs/lfs2_util.c ${MICROPY_DIR}/lib/oofatfs/ff.c ${MICROPY_DIR}/lib/oofatfs/ffunicode.c + ${MICROPY_DIR}/shared/netutils/netutils.c ${MICROPY_DIR}/shared/readline/readline.c ${MICROPY_DIR}/shared/runtime/gchelper_m0.s ${MICROPY_DIR}/shared/runtime/gchelper_native.c diff --git a/ports/rp2/main.c b/ports/rp2/main.c index 807de18e63..0dac85c49d 100644 --- a/ports/rp2/main.c +++ b/ports/rp2/main.c @@ -33,6 +33,7 @@ #include "py/mphal.h" #include "py/stackctrl.h" #include "extmod/modbluetooth.h" +#include "extmod/modnetwork.h" #include "shared/readline/readline.h" #include "shared/runtime/gchelper.h" #include "shared/runtime/pyexec.h" @@ -112,6 +113,9 @@ int main(int argc, char **argv) { #if MICROPY_PY_BLUETOOTH mp_bluetooth_hci_init(); #endif + #if MICROPY_PY_NETWORK + mod_network_init(); + #endif // Execute _boot.py to set up the filesystem. pyexec_frozen_module("_boot.py"); @@ -142,6 +146,9 @@ int main(int argc, char **argv) { soft_reset_exit: mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); + #if MICROPY_PY_NETWORK + mod_network_deinit(); + #endif rp2_pio_deinit(); #if MICROPY_PY_BLUETOOTH mp_bluetooth_deinit(); diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index 237c1a5d83..cc979b5c30 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -166,11 +166,26 @@ { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) }, extern const struct _mp_obj_module_t mp_module_machine; +extern const struct _mp_obj_module_t mp_module_network; extern const struct _mp_obj_module_t mp_module_onewire; extern const struct _mp_obj_module_t mp_module_rp2; extern const struct _mp_obj_module_t mp_module_uos; +extern const struct _mp_obj_module_t mp_module_usocket; extern const struct _mp_obj_module_t mp_module_utime; +#if MICROPY_PY_USOCKET +#define SOCKET_BUILTIN_MODULE { MP_ROM_QSTR(MP_QSTR_usocket), MP_ROM_PTR(&mp_module_usocket) }, +#else +#define SOCKET_BUILTIN_MODULE +#endif +#if MICROPY_PY_NETWORK +#define NETWORK_BUILTIN_MODULE { MP_ROM_QSTR(MP_QSTR_network), MP_ROM_PTR(&mp_module_network) }, +#define NETWORK_ROOT_POINTERS mp_obj_list_t mod_network_nic_list; +#else +#define NETWORK_BUILTIN_MODULE +#define NETWORK_ROOT_POINTERS +#endif + #if MICROPY_PY_BLUETOOTH #define MICROPY_PORT_ROOT_POINTER_BLUETOOTH struct _machine_uart_obj_t *mp_bthci_uart; #else @@ -191,11 +206,15 @@ struct _mp_bluetooth_nimble_malloc_t; { MP_OBJ_NEW_QSTR(MP_QSTR__rp2), (mp_obj_t)&mp_module_rp2 }, \ { MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_uos) }, \ { MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_utime) }, \ + SOCKET_BUILTIN_MODULE \ + NETWORK_BUILTIN_MODULE \ #ifndef MICROPY_BOARD_ROOT_POINTERS #define MICROPY_BOARD_ROOT_POINTERS #endif +#define MICROPY_PORT_NETWORK_INTERFACES \ + #define MICROPY_PORT_ROOT_POINTERS \ const char *readline_hist[8]; \ void *machine_pin_irq_obj[30]; \ @@ -203,6 +222,7 @@ struct _mp_bluetooth_nimble_malloc_t; void *rp2_state_machine_irq_obj[8]; \ void *rp2_uart_rx_buffer[2]; \ void *rp2_uart_tx_buffer[2]; \ + NETWORK_ROOT_POINTERS \ MICROPY_BOARD_ROOT_POINTERS \ MICROPY_PORT_ROOT_POINTER_BLUETOOTH \ MICROPY_PORT_ROOT_POINTER_BLUETOOTH_NIMBLE \ From 2c5e9bbdface4eb163b53f486359ca2208b7b0a5 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 29 Aug 2021 18:58:31 +0200 Subject: [PATCH 058/335] extmod: Add platform module. It contains the compiler version, and underlying system HAL/SDK version. --- extmod/extmod.cmake | 1 + extmod/moduplatform.c | 136 ++++++++++++++++++++++++++++++++++++++++++ py/builtin.h | 1 + py/objmodule.c | 3 + py/py.mk | 1 + 5 files changed, 142 insertions(+) create mode 100644 extmod/moduplatform.c diff --git a/extmod/extmod.cmake b/extmod/extmod.cmake index 3353112ba6..67f7d8fd39 100644 --- a/extmod/extmod.cmake +++ b/extmod/extmod.cmake @@ -25,6 +25,7 @@ set(MICROPY_SOURCE_EXTMOD ${MICROPY_EXTMOD_DIR}/moduhashlib.c ${MICROPY_EXTMOD_DIR}/moduheapq.c ${MICROPY_EXTMOD_DIR}/modujson.c + ${MICROPY_EXTMOD_DIR}/moduplatform.c ${MICROPY_EXTMOD_DIR}/modurandom.c ${MICROPY_EXTMOD_DIR}/modure.c ${MICROPY_EXTMOD_DIR}/moduselect.c diff --git a/extmod/moduplatform.c b/extmod/moduplatform.c new file mode 100644 index 0000000000..06bb9d5ce8 --- /dev/null +++ b/extmod/moduplatform.c @@ -0,0 +1,136 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2021 Ibrahim Abdelkader + * + * 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/runtime.h" +#include "py/objtuple.h" +#include "py/objstr.h" +#include "py/mphal.h" +#include "genhdr/mpversion.h" + +#if MICROPY_PY_UPLATFORM + +// platform - Access to underlying platform's identifying data + +// TODO: Add more architectures, compilers and libraries. +// See: https://sourceforge.net/p/predef/wiki/Home/ + +#if defined(__ARM_ARCH) +#define PLATFORM_ARCH "arm" +#elif defined(__x86_64__) +#define PLATFORM_ARCH "x86_64" +#else +#define PLATFORM_ARCH "" +#endif + +#if defined(__GNUC__) +#define PLATFORM_COMPILER \ + "GCC " \ + MP_STRINGIFY(__GNUC__) "." \ + MP_STRINGIFY(__GNUC_MINOR__) "." \ + MP_STRINGIFY(__GNUC_PATCHLEVEL__) +#elif defined(__ARMCC_VERSION) +#define PLATFORM_COMPILER \ + "ARMCC " \ + MP_STRINGIFY((__ARMCC_VERSION / 1000000)) "." \ + MP_STRINGIFY((__ARMCC_VERSION / 10000 % 100)) "." \ + MP_STRINGIFY((__ARMCC_VERSION % 10000)) +#else +#define PLATFORM_COMPILER "" +#endif + +#if defined(__GLIBC__) +#define PLATFORM_LIBC_LIB "glibc" +#define PLATFORM_LIBC_VER \ + MP_STRINGIFY(__GLIBC__) "." \ + MP_STRINGIFY(__GLIBC_MINOR__) +#elif defined(__NEWLIB__) +#define PLATFORM_LIBC_LIB "newlib" +#define PLATFORM_LIBC_VER _NEWLIB_VERSION +#else +#define PLATFORM_LIBC_LIB "" +#define PLATFORM_LIBC_VER "" +#endif + +#if defined(__linux) +#define PLATFORM_SYSTEM "Linux" +#elif defined(__unix__) +#define PLATFORM_SYSTEM "Unix" +#elif defined(__CYGWIN__) +#define PLATFORM_SYSTEM "Cygwin" +#elif defined(__WIN32__) +#define PLATFORM_SYSTEM "Windows" +#else +#define PLATFORM_SYSTEM "MicroPython" +#endif + +#ifndef MICROPY_HW_BOARD_NAME +#define MICROPY_HW_BOARD_NAME PLATFORM_ARCH +#endif + +#ifndef MICROPY_HW_MCU_NAME +#define MICROPY_HW_MCU_NAME "" +#endif + +STATIC const MP_DEFINE_STR_OBJ(info_platform_obj, PLATFORM_SYSTEM "-" MICROPY_VERSION_STRING "-HAL" \ + MICROPY_HAL_VERSION "-" PLATFORM_ARCH "-with-" PLATFORM_LIBC_LIB "" PLATFORM_LIBC_VER); +STATIC const MP_DEFINE_STR_OBJ(info_python_compiler_obj, PLATFORM_COMPILER); +STATIC const MP_DEFINE_STR_OBJ(info_libc_lib_obj, PLATFORM_LIBC_LIB); +STATIC const MP_DEFINE_STR_OBJ(info_libc_ver_obj, PLATFORM_LIBC_VER); +STATIC const mp_rom_obj_tuple_t info_libc_tuple_obj = { + {&mp_type_tuple}, 2, {MP_ROM_PTR(&info_libc_lib_obj), MP_ROM_PTR(&info_libc_ver_obj)} +}; + +STATIC mp_obj_t platform_platform(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + return MP_OBJ_FROM_PTR(&info_platform_obj); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(platform_platform_obj, 0, platform_platform); + +STATIC mp_obj_t platform_python_compiler(void) { + return MP_OBJ_FROM_PTR(&info_python_compiler_obj); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(platform_python_compiler_obj, platform_python_compiler); + +STATIC mp_obj_t platform_libc_ver(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + return MP_OBJ_FROM_PTR(&info_libc_tuple_obj); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(platform_libc_ver_obj, 0, platform_libc_ver); + +STATIC const mp_rom_map_elem_t modplatform_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uplatform) }, + { MP_ROM_QSTR(MP_QSTR_platform), MP_ROM_PTR(&platform_platform_obj) }, + { MP_ROM_QSTR(MP_QSTR_python_compiler), MP_ROM_PTR(&platform_python_compiler_obj) }, + { MP_ROM_QSTR(MP_QSTR_libc_ver), MP_ROM_PTR(&platform_libc_ver_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(modplatform_globals, modplatform_globals_table); + +const mp_obj_module_t mp_module_uplatform = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&modplatform_globals, +}; + +#endif // MICROPY_PY_UPLATFORM diff --git a/py/builtin.h b/py/builtin.h index 1e4769cd69..8639e978ff 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -124,6 +124,7 @@ extern const mp_obj_module_t mp_module_webrepl; extern const mp_obj_module_t mp_module_framebuf; extern const mp_obj_module_t mp_module_btree; extern const mp_obj_module_t mp_module_ubluetooth; +extern const mp_obj_module_t mp_module_uplatform; extern const char MICROPY_PY_BUILTINS_HELP_TEXT[]; diff --git a/py/objmodule.c b/py/objmodule.c index a1f9d9d7f1..d648f0f8ce 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -230,6 +230,9 @@ STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = { #if MICROPY_PY_BLUETOOTH { MP_ROM_QSTR(MP_QSTR_ubluetooth), MP_ROM_PTR(&mp_module_ubluetooth) }, #endif + #if MICROPY_PY_UPLATFORM + { MP_ROM_QSTR(MP_QSTR_uplatform), MP_ROM_PTR(&mp_module_uplatform) }, + #endif // extra builtin modules as defined by a port MICROPY_PORT_BUILTIN_MODULES diff --git a/py/py.mk b/py/py.mk index be8296e5e8..8e1e23554f 100644 --- a/py/py.mk +++ b/py/py.mk @@ -195,6 +195,7 @@ PY_EXTMOD_O_BASENAME = \ extmod/modbluetooth.o \ extmod/modussl_axtls.o \ extmod/modussl_mbedtls.o \ + extmod/moduplatform.o\ extmod/modurandom.o \ extmod/moduselect.o \ extmod/moduwebsocket.o \ From 782d5b2e534c96f4668443efe37c0514e8fcfe91 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 10 Sep 2021 14:28:41 +0200 Subject: [PATCH 059/335] stm32: Enable platform module. The HAL version is based on the stm32lib version. --- ports/stm32/mpconfigport.h | 3 +++ ports/stm32/mphalport.h | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 92f1338d6c..6a9e8bf414 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -228,6 +228,9 @@ #ifndef MICROPY_PY_ONEWIRE #define MICROPY_PY_ONEWIRE (1) #endif +#ifndef MICROPY_PY_UPLATFORM +#define MICROPY_PY_UPLATFORM (1) +#endif // fatfs configuration used in ffconf.h #define MICROPY_FATFS_ENABLE_LFN (1) diff --git a/ports/stm32/mphalport.h b/ports/stm32/mphalport.h index a76945db5f..edb8d8f64b 100644 --- a/ports/stm32/mphalport.h +++ b/ports/stm32/mphalport.h @@ -2,6 +2,23 @@ #include STM32_HAL_H #include "pin.h" +// F0-1.9.0+F4-1.16.0+F7-1.7.0+H7-1.6.0+L0-1.11.2+L4-1.8.1+WB-1.10.0 +#if defined(STM32F0) +#define MICROPY_HAL_VERSION "1.9.0" +#elif defined(STM32F4) +#define MICROPY_HAL_VERSION "1.16.0" +#elif defined(STM32F7) +#define MICROPY_HAL_VERSION "1.7.0" +#elif defined(STM32H7) +#define MICROPY_HAL_VERSION "1.6.0" +#elif defined(STM32L0) +#define MICROPY_HAL_VERSION "1.11.2" +#elif defined(STM32L4) +#define MICROPY_HAL_VERSION "1.8.1" +#elif defined(STM32WB) +#define MICROPY_HAL_VERSION "1.10.0" +#endif + extern const unsigned char mp_hal_status_to_errno_table[4]; static inline int mp_hal_status_to_neg_errno(HAL_StatusTypeDef status) { From 8c214ed2000fd6334c8f03589f36c6fd2286f2c8 Mon Sep 17 00:00:00 2001 From: Ned Konz Date: Thu, 19 Aug 2021 08:12:19 -0700 Subject: [PATCH 060/335] stm32: Extended flash filesystem space to 512K on H743 boards. The H743 has equal sized pages of 128k, which means the filesystem doesn't need to be near the beginning. This commit moves the filesystem to the very end of flash, and extends it to 512k (4 pages). Signed-off-by: Damien George --- ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.mk | 11 +++++------ .../stm32/boards/VCC_GND_H743VI/mpconfigboard.mk | 11 +++++------ ports/stm32/boards/stm32h743.ld | 15 +++++++++++---- ports/stm32/flashbdev.c | 15 ++++++++++----- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.mk b/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.mk index ce8f83e57d..be9e56e4e1 100644 --- a/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.mk +++ b/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.mk @@ -7,14 +7,13 @@ MICROPY_FLOAT_IMPL = double AF_FILE = boards/stm32h743_af.csv ifeq ($(USE_MBOOT),1) -# When using Mboot all the text goes together after the filesystem -LD_FILES = boards/stm32h743.ld boards/common_blifs.ld -TEXT0_ADDR = 0x08040000 +# When using Mboot everything goes after the bootloader +LD_FILES = boards/stm32h743.ld boards/common_bl.ld +TEXT0_ADDR = 0x08020000 else -# When not using Mboot the ISR text goes first, then the rest after the filesystem -LD_FILES = boards/stm32h743.ld boards/common_ifs.ld +# When not using Mboot everything goes at the start of flash +LD_FILES = boards/stm32h743.ld boards/common_basic.ld TEXT0_ADDR = 0x08000000 -TEXT1_ADDR = 0x08040000 endif # MicroPython settings diff --git a/ports/stm32/boards/VCC_GND_H743VI/mpconfigboard.mk b/ports/stm32/boards/VCC_GND_H743VI/mpconfigboard.mk index 1f5fa32a1b..8860829484 100644 --- a/ports/stm32/boards/VCC_GND_H743VI/mpconfigboard.mk +++ b/ports/stm32/boards/VCC_GND_H743VI/mpconfigboard.mk @@ -7,14 +7,13 @@ MICROPY_FLOAT_IMPL = double AF_FILE = boards/stm32h743_af.csv ifeq ($(USE_MBOOT),1) -# When using Mboot all the text goes together after the filesystem -LD_FILES = boards/stm32h743.ld boards/common_blifs.ld -TEXT0_ADDR = 0x08040000 +# When using Mboot everything goes after the bootloader +LD_FILES = boards/stm32h743.ld boards/common_bl.ld +TEXT0_ADDR = 0x08020000 else -# When not using Mboot the ISR text goes first, then the rest after the filesystem -LD_FILES = boards/stm32h743.ld boards/common_ifs.ld +# When not using Mboot everything goes at the start of flash +LD_FILES = boards/stm32h743.ld boards/common_basic.ld TEXT0_ADDR = 0x08000000 -TEXT1_ADDR = 0x08040000 endif # MicroPython settings diff --git a/ports/stm32/boards/stm32h743.ld b/ports/stm32/boards/stm32h743.ld index 72d915b2bb..13fa0c52c0 100644 --- a/ports/stm32/boards/stm32h743.ld +++ b/ports/stm32/boards/stm32h743.ld @@ -5,10 +5,9 @@ /* Specify the memory areas */ MEMORY { - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K - FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 128K /* sector 0, 128K */ - FLASH_FS (r) : ORIGIN = 0x08020000, LENGTH = 128K /* sector 1, 128K */ - FLASH_TEXT (rx) : ORIGIN = 0x08040000, LENGTH = 1792K /* sectors 6*128 + 8*128 */ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1536K /* sectors (0-7) + (0-3) */ + FLASH_APP (rx) : ORIGIN = 0x08020000, LENGTH = 1408K /* sectors (1-7) + (0-3) */ + FLASH_FS (r) : ORIGIN = 0x08180000, LENGTH = 512K /* sectors (4-7) */ DTCM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for storage cache */ RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 512K /* AXI SRAM */ RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K @@ -29,6 +28,14 @@ _ram_end = ORIGIN(RAM) + LENGTH(RAM); _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _sstack; +/* Location of filesystem RAM cache */ +_ram_fs_cache_start = ORIGIN(DTCM); +_ram_fs_cache_end = ORIGIN(DTCM) + LENGTH(DTCM); + +/* Location of filesystem flash storage */ +_flash_fs_start = ORIGIN(FLASH_FS); +_flash_fs_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); + /* Define output sections */ SECTIONS { diff --git a/ports/stm32/flashbdev.c b/ports/stm32/flashbdev.c index 6ed891300d..6be0cfee8a 100644 --- a/ports/stm32/flashbdev.c +++ b/ports/stm32/flashbdev.c @@ -104,11 +104,16 @@ STATIC byte flash_cache_mem[0x4000] __attribute__((aligned(4))); // 16k #elif defined(STM32H743xx) -// The STM32H743 flash sectors are 128K -#define CACHE_MEM_START_ADDR (0x20000000) // DTCM data RAM, 128k -#define FLASH_SECTOR_SIZE_MAX (0x20000) // 128k max -#define FLASH_MEM_SEG1_START_ADDR (0x08020000) // sector 1 -#define FLASH_MEM_SEG1_NUM_BLOCKS (256) // Sector 1: 128k / 512b = 256 blocks +// The STM32H743 flash sectors are 128K, with locations defined in the linker script +extern uint8_t _flash_fs_start; +extern uint8_t _flash_fs_end; +extern uint8_t _ram_fs_cache_start[]; +extern uint8_t _ram_fs_cache_end[]; + +#define CACHE_MEM_START_ADDR ((uintptr_t)&_ram_fs_cache_start[0]) +#define FLASH_SECTOR_SIZE_MAX (&_ram_fs_cache_end[0] - &_ram_fs_cache_start[0]) +#define FLASH_MEM_SEG1_START_ADDR ((long)&_flash_fs_start) +#define FLASH_MEM_SEG1_NUM_BLOCKS ((&_flash_fs_end - &_flash_fs_start) / 512) #elif defined(STM32L432xx) || \ defined(STM32L451xx) || defined(STM32L452xx) || defined(STM32L462xx) || \ From 99bb52047c2942182b4be4df4f8b7f9a48dd5e8c Mon Sep 17 00:00:00 2001 From: Ned Konz Date: Thu, 19 Aug 2021 08:12:46 -0700 Subject: [PATCH 061/335] stm32/boards/NUCLEO_H743ZI: Enable VfsLfs2 on NUCLEO_H743ZI(2) boards. --- ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.mk b/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.mk index be9e56e4e1..8a16c2f010 100644 --- a/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.mk +++ b/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.mk @@ -20,3 +20,4 @@ endif MICROPY_PY_LWIP = 1 MICROPY_PY_USSL = 1 MICROPY_SSL_MBEDTLS = 1 +MICROPY_VFS_LFS2 = 1 From 9eff4029ab66ed30c08d65e5ed91a20d70173bcd Mon Sep 17 00:00:00 2001 From: roland van straten Date: Sun, 19 Sep 2021 14:35:53 +0200 Subject: [PATCH 062/335] stm32/boards: Add PF11-BOOT0 to stm32f091_af.csv. PF11 is added so it can be used as GPIO. --- ports/stm32/boards/stm32f091_af.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/stm32/boards/stm32f091_af.csv b/ports/stm32/boards/stm32f091_af.csv index 38e134f8a9..8074fd22b7 100644 --- a/ports/stm32/boards/stm32f091_af.csv +++ b/ports/stm32/boards/stm32f091_af.csv @@ -87,3 +87,4 @@ PortF,PF3,EVENTOUT,USART7_RX,USART6_CK/USART6_RTS,,,,,,,,,,,,,, PortF,PF6,,,,,,,,,,,,,,,,, PortF,PF9,TIM15_CH1,USART6_TX,,,,,,,,,,,,,,, PortF,PF10,TIM15_CH2,USART6_RX,,,,,,,,,,,,,,, +PortF,PF11,,,,,,,,,,,,,,,,, From 67d1dca9c2f7c04ff7078d94b4a58cdb73d0c58f Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 18 Sep 2021 16:49:50 +0200 Subject: [PATCH 063/335] stm32/machine_i2c: Use hardware I2C for STM32H7. --- ports/stm32/i2c.c | 9 +++++++-- ports/stm32/machine_i2c.c | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ports/stm32/i2c.c b/ports/stm32/i2c.c index 0b7105344c..c63fe21624 100644 --- a/ports/stm32/i2c.c +++ b/ports/stm32/i2c.c @@ -268,7 +268,12 @@ int i2c_write(i2c_t *i2c, const uint8_t *src, size_t len, size_t next_len) { return num_acks; } -#elif defined(STM32F0) || defined(STM32F7) +#elif defined(STM32F0) || defined(STM32F7) || defined(STM32H7) + +#if defined(STM32H7) +#define APB1ENR APB1LENR +#define RCC_APB1ENR_I2C1EN RCC_APB1LENR_I2C1EN +#endif STATIC uint16_t i2c_timeout_ms[MICROPY_HW_MAX_I2C]; @@ -468,7 +473,7 @@ int i2c_write(i2c_t *i2c, const uint8_t *src, size_t len, size_t next_len) { #endif -#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) +#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) int i2c_readfrom(i2c_t *i2c, uint16_t addr, uint8_t *dest, size_t len, bool stop) { int ret; diff --git a/ports/stm32/machine_i2c.c b/ports/stm32/machine_i2c.c index 41e65cf05c..0976c18c81 100644 --- a/ports/stm32/machine_i2c.c +++ b/ports/stm32/machine_i2c.c @@ -38,7 +38,7 @@ #define I2C_POLL_DEFAULT_TIMEOUT_US (50000) // 50ms -#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) +#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) typedef struct _machine_hard_i2c_obj_t { mp_obj_base_t base; From 0d9429f44cd23f5cfdd80d53adccbf384e23665a Mon Sep 17 00:00:00 2001 From: Stewart Bonnick Date: Wed, 15 Sep 2021 09:09:01 -0400 Subject: [PATCH 064/335] esp32/boards: Add LOLIN_S2_MINI ESP32-S2 board. To support Lolin S2 Mini ESP32-S2 Variant board. More information about this board can be found at https://www.wemos.cc/en/latest/s2/s2_mini.html --- ports/esp32/boards/LOLIN_S2_MINI/manifest.py | 2 ++ .../boards/LOLIN_S2_MINI/modules/s2mini.py | 31 +++++++++++++++++++ .../boards/LOLIN_S2_MINI/mpconfigboard.cmake | 11 +++++++ .../boards/LOLIN_S2_MINI/mpconfigboard.h | 12 +++++++ .../boards/LOLIN_S2_MINI/sdkconfig.board | 6 ++++ 5 files changed, 62 insertions(+) create mode 100644 ports/esp32/boards/LOLIN_S2_MINI/manifest.py create mode 100644 ports/esp32/boards/LOLIN_S2_MINI/modules/s2mini.py create mode 100644 ports/esp32/boards/LOLIN_S2_MINI/mpconfigboard.cmake create mode 100644 ports/esp32/boards/LOLIN_S2_MINI/mpconfigboard.h create mode 100644 ports/esp32/boards/LOLIN_S2_MINI/sdkconfig.board diff --git a/ports/esp32/boards/LOLIN_S2_MINI/manifest.py b/ports/esp32/boards/LOLIN_S2_MINI/manifest.py new file mode 100644 index 0000000000..f993d4fa6b --- /dev/null +++ b/ports/esp32/boards/LOLIN_S2_MINI/manifest.py @@ -0,0 +1,2 @@ +include("$(PORT_DIR)/boards/manifest.py") +freeze("./modules") diff --git a/ports/esp32/boards/LOLIN_S2_MINI/modules/s2mini.py b/ports/esp32/boards/LOLIN_S2_MINI/modules/s2mini.py new file mode 100644 index 0000000000..4fc038c81a --- /dev/null +++ b/ports/esp32/boards/LOLIN_S2_MINI/modules/s2mini.py @@ -0,0 +1,31 @@ +# LOLIN S2 MINI MicroPython Helper Library + +from micropython import const +from machine import Pin + +# Pin Assignments + +# SPI +SPI_MOSI = const(11) +SPI_MISO = const(9) +SPI_CLK = const(7) + +# I2C +I2C_SDA = const(33) +I2C_SCL = const(35) + +# DAC +DAC1 = const(17) +DAC2 = const(18) + +# LED +LED = const(15) + +# BUTTON +BUTTON = const(0) + +# Helper methods for built in sensors + +led = Pin(LED, Pin.OUT, value=0) + +button = Pin(BUTTON, Pin.IN, Pin.PULL_UP) diff --git a/ports/esp32/boards/LOLIN_S2_MINI/mpconfigboard.cmake b/ports/esp32/boards/LOLIN_S2_MINI/mpconfigboard.cmake new file mode 100644 index 0000000000..5f157e7e77 --- /dev/null +++ b/ports/esp32/boards/LOLIN_S2_MINI/mpconfigboard.cmake @@ -0,0 +1,11 @@ +set(IDF_TARGET esp32s2) + +set(SDKCONFIG_DEFAULTS + boards/sdkconfig.base + boards/sdkconfig.spiram_sx + boards/sdkconfig.usb +) + +if(NOT MICROPY_FROZEN_MANIFEST) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) +endif() diff --git a/ports/esp32/boards/LOLIN_S2_MINI/mpconfigboard.h b/ports/esp32/boards/LOLIN_S2_MINI/mpconfigboard.h new file mode 100644 index 0000000000..e0ef10d1db --- /dev/null +++ b/ports/esp32/boards/LOLIN_S2_MINI/mpconfigboard.h @@ -0,0 +1,12 @@ +#define MICROPY_HW_BOARD_NAME "LOLIN_S2_MINI" +#define MICROPY_HW_MCU_NAME "ESP32-S2FN4R2" + +#define MICROPY_PY_BLUETOOTH (0) +#define MICROPY_HW_ENABLE_SDCARD (0) + +#define MICROPY_HW_I2C0_SCL (35) +#define MICROPY_HW_I2C0_SDA (33) + +#define MICROPY_HW_SPI1_MOSI (11) +#define MICROPY_HW_SPI1_MISO (9) +#define MICROPY_HW_SPI1_SCK (7) diff --git a/ports/esp32/boards/LOLIN_S2_MINI/sdkconfig.board b/ports/esp32/boards/LOLIN_S2_MINI/sdkconfig.board new file mode 100644 index 0000000000..1a7ef3f8b9 --- /dev/null +++ b/ports/esp32/boards/LOLIN_S2_MINI/sdkconfig.board @@ -0,0 +1,6 @@ +CONFIG_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_USB_AND_UART=y +# LWIP +CONFIG_LWIP_LOCAL_HOSTNAME="LOLIN_S2_MINI" +# end of LWIP From 52636fa69232002f3d8ebed583f8ee61a55878d4 Mon Sep 17 00:00:00 2001 From: IhorNehrutsa Date: Sun, 19 Sep 2021 00:38:37 +0300 Subject: [PATCH 065/335] esp32/machine_pwm: Add support for all PWM timers and channels. This commit allows using all the available PWM timers (up to 8) and channels (up to 16), without affecting the PWM API. If a new frequency is set, first it checks if another timer is using the same frequency. If yes, then it uses this timer, otherwise, it creates a new one. If all timers are used, the user should set an already used frequency, or de-init a channel. This work is based on #6276 and #3608. --- ports/esp32/machine_pwm.c | 421 ++++++++++++++++++++++++++++---------- 1 file changed, 315 insertions(+), 106 deletions(-) diff --git a/ports/esp32/machine_pwm.c b/ports/esp32/machine_pwm.c index 9fe06aa699..41b8dbcbfe 100644 --- a/ports/esp32/machine_pwm.c +++ b/ports/esp32/machine_pwm.c @@ -3,7 +3,10 @@ * * The MIT License (MIT) * - * Copyright (c) 2016 Damien P. George + * Copyright (c) 2016-2021 Damien P. George + * Copyright (c) 2018 Alan Dragomirecky + * Copyright (c) 2020 Antoine Aubert + * Copyright (c) 2021 Ihor Nehrutsa * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,54 +33,105 @@ #include "driver/ledc.h" #include "esp_err.h" -// Which channel has which GPIO pin assigned? -// (-1 if not assigned) -STATIC int chan_gpio[LEDC_CHANNEL_MAX]; +#define PWM_DBG(...) +// #define PWM_DBG(...) mp_printf(&mp_plat_print, __VA_ARGS__) + +// Total number of channels +#define PWM_CHANNEL_MAX (LEDC_SPEED_MODE_MAX * LEDC_CHANNEL_MAX) +typedef struct _chan_t { + // Which channel has which GPIO pin assigned? + // (-1 if not assigned) + gpio_num_t pin; + // Which channel has which timer assigned? + // (-1 if not assigned) + int timer_idx; +} chan_t; +// List of PWM channels +STATIC chan_t chans[PWM_CHANNEL_MAX]; + +// channel_idx is an index (end-to-end sequential numbering) for all channels +// available on the chip and described in chans[] +#define CHANNEL_IDX(mode, channel) (mode * LEDC_CHANNEL_MAX + channel) +#define CHANNEL_IDX_TO_MODE(channel_idx) (channel_idx / LEDC_CHANNEL_MAX) +#define CHANNEL_IDX_TO_CHANNEL(channel_idx) (channel_idx % LEDC_CHANNEL_MAX) + +// Total number of timers +#define PWM_TIMER_MAX (LEDC_SPEED_MODE_MAX * LEDC_TIMER_MAX) +// List of timer configs +STATIC ledc_timer_config_t timers[PWM_TIMER_MAX]; + +// timer_idx is an index (end-to-end sequential numbering) for all timers +// available on the chip and configured in timers[] +#define TIMER_IDX(mode, timer) (mode * LEDC_TIMER_MAX + timer) +#define TIMER_IDX_TO_MODE(timer_idx) (timer_idx / LEDC_TIMER_MAX) +#define TIMER_IDX_TO_TIMER(timer_idx) (timer_idx % LEDC_TIMER_MAX) // Params for PW operation -// 5khz +// 5khz is default frequency #define PWFREQ (5000) -// High speed mode -#if CONFIG_IDF_TARGET_ESP32 -#define PWMODE (LEDC_HIGH_SPEED_MODE) -#else -#define PWMODE (LEDC_LOW_SPEED_MODE) -#endif + // 10-bit resolution (compatible with esp8266 PWM) #define PWRES (LEDC_TIMER_10_BIT) -// Timer 1 -#define PWTIMER (LEDC_TIMER_1) // Config of timer upon which we run all PWM'ed GPIO pins STATIC bool pwm_inited = false; -STATIC ledc_timer_config_t timer_cfg = { - .duty_resolution = PWRES, - .freq_hz = PWFREQ, - .speed_mode = PWMODE, - .timer_num = PWTIMER -}; + +// MicroPython PWM object struct +typedef struct _machine_pwm_obj_t { + mp_obj_base_t base; + gpio_num_t pin; + bool active; + int mode; + int channel; + int timer; +} machine_pwm_obj_t; STATIC void pwm_init(void) { - // Initial condition: no channels assigned - for (int x = 0; x < LEDC_CHANNEL_MAX; ++x) { - chan_gpio[x] = -1; + for (int i = 0; i < PWM_CHANNEL_MAX; ++i) { + chans[i].pin = -1; + chans[i].timer_idx = -1; } - // Init with default timer params - ledc_timer_config(&timer_cfg); + // Prepare all timers config + // Initial condition: no timers assigned + for (int i = 0; i < PWM_TIMER_MAX; ++i) { + timers[i].duty_resolution = PWRES; + // unset timer is -1 + timers[i].freq_hz = -1; + timers[i].speed_mode = TIMER_IDX_TO_MODE(i); + timers[i].timer_num = TIMER_IDX_TO_TIMER(i); + timers[i].clk_cfg = LEDC_AUTO_CLK; + } } -STATIC int set_freq(int newval) { - int ores = timer_cfg.duty_resolution; - int oval = timer_cfg.freq_hz; +STATIC void configure_channel(machine_pwm_obj_t *self) { + ledc_channel_config_t cfg = { + .channel = self->channel, + .duty = (1 << (timers[TIMER_IDX(self->mode, self->timer)].duty_resolution)) / 2, + .gpio_num = self->pin, + .intr_type = LEDC_INTR_DISABLE, + .speed_mode = self->mode, + .timer_sel = self->timer, + }; + if (ledc_channel_config(&cfg) != ESP_OK) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("PWM not supported on Pin(%d)"), self->pin); + } +} + +STATIC void set_freq(int newval, ledc_timer_config_t *timer) { + // If already set, do nothing + if (newval == timer->freq_hz) { + return; + } // Find the highest bit resolution for the requested frequency if (newval <= 0) { newval = 1; } unsigned int res = 0; - for (unsigned int i = LEDC_APB_CLK_HZ / newval; i > 1; i >>= 1, ++res) { + for (unsigned int i = LEDC_APB_CLK_HZ / newval; i > 1; i >>= 1) { + ++res; } if (res == 0) { res = 1; @@ -87,32 +141,113 @@ STATIC int set_freq(int newval) { } // Configure the new resolution and frequency - timer_cfg.duty_resolution = res; - timer_cfg.freq_hz = newval; - if (ledc_timer_config(&timer_cfg) != ESP_OK) { - timer_cfg.duty_resolution = ores; - timer_cfg.freq_hz = oval; - return 0; + timer->duty_resolution = res; + timer->freq_hz = newval; + + // set freq + esp_err_t err = ledc_timer_config(timer); + if (err != ESP_OK) { + if (err == ESP_FAIL) { + PWM_DBG("timer timer->speed_mode %d, timer->timer_num %d, timer->clk_cfg %d, timer->freq_hz %d, timer->duty_resolution %d)", timer->speed_mode, timer->timer_num, timer->clk_cfg, timer->freq_hz, timer->duty_resolution); + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("bad frequency %d"), newval); + } else { + check_esp_err(err); + } } - return 1; +} + +STATIC int get_duty(machine_pwm_obj_t *self) { + uint32_t duty = ledc_get_duty(self->mode, self->channel); + duty <<= PWRES - timers[TIMER_IDX(self->mode, self->timer)].duty_resolution; + return duty; +} + +STATIC void set_duty(machine_pwm_obj_t *self, int duty) { + if ((duty < 0) || (duty > (1 << PWRES) - 1)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("duty must be between 0 and %u"), (1 << PWRES) - 1); + } + duty &= (1 << PWRES) - 1; + duty >>= PWRES - timers[TIMER_IDX(self->mode, self->timer)].duty_resolution; + check_esp_err(ledc_set_duty(self->mode, self->channel, duty)); + check_esp_err(ledc_update_duty(self->mode, self->channel)); + // check_esp_err(ledc_set_duty_and_update(self->mode, self->channel, duty, (1 << PWRES) - 1)); // thread safe function ??? + + // Bug: Sometimes duty is not set right now. + // See https://github.com/espressif/esp-idf/issues/7288 + /* + if (duty != get_duty(self)) { + PWM_DBG("\n duty_set %u %u %d %d \n", duty, get_duty(self), PWRES, timers[TIMER_IDX(self->mode, self->timer)].duty_resolution); + } + */ +} + +/******************************************************************************/ +#define SAME_FREQ_ONLY (true) +#define SAME_FREQ_OR_FREE (false) +#define ANY_MODE (-1) +// Return timer_idx. Use TIMER_IDX_TO_MODE(timer_idx) and TIMER_IDX_TO_TIMER(timer_idx) to get mode and timer +STATIC int find_timer(int freq, bool same_freq_only, int mode) { + int free_timer_idx_found = -1; + // Find a free PWM Timer using the same freq + for (int timer_idx = 0; timer_idx < PWM_TIMER_MAX; ++timer_idx) { + if ((mode == ANY_MODE) || (mode == TIMER_IDX_TO_MODE(timer_idx))) { + if (timers[timer_idx].freq_hz == freq) { + // A timer already uses the same freq. Use it now. + return timer_idx; + } + if (!same_freq_only && (free_timer_idx_found == -1) && (timers[timer_idx].freq_hz == -1)) { + free_timer_idx_found = timer_idx; + // Continue to check if a channel with the same freq is in use. + } + } + } + + return free_timer_idx_found; +} + +// Return true if the timer is in use in addition to current channel +STATIC bool is_timer_in_use(int current_channel_idx, int timer_idx) { + for (int i = 0; i < PWM_CHANNEL_MAX; ++i) { + if ((i != current_channel_idx) && (chans[i].timer_idx == timer_idx)) { + return true; + } + } + + return false; +} + +// Find a free PWM channel, also spot if our pin is already mentioned. +// Return channel_idx. Use CHANNEL_IDX_TO_MODE(channel_idx) and CHANNEL_IDX_TO_CHANNEL(channel_idx) to get mode and channel +STATIC int find_channel(int pin, int mode) { + int avail_idx = -1; + int channel_idx; + for (channel_idx = 0; channel_idx < PWM_CHANNEL_MAX; ++channel_idx) { + if ((mode == ANY_MODE) || (mode == CHANNEL_IDX_TO_MODE(channel_idx))) { + if (chans[channel_idx].pin == pin) { + break; + } + if ((avail_idx == -1) && (chans[channel_idx].pin == -1)) { + avail_idx = channel_idx; + } + } + } + if (channel_idx >= PWM_CHANNEL_MAX) { + channel_idx = avail_idx; + } + return channel_idx; } /******************************************************************************/ // MicroPython bindings for PWM -typedef struct _machine_pwm_obj_t { - mp_obj_base_t base; - gpio_num_t pin; - uint8_t active; - uint8_t channel; -} machine_pwm_obj_t; - STATIC void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "PWM(%u", self->pin); + mp_printf(print, "PWM(pin=%u", self->pin); if (self->active) { - mp_printf(print, ", freq=%u, duty=%u", timer_cfg.freq_hz, - ledc_get_duty(PWMODE, self->channel)); + int duty = get_duty(self); + mp_printf(print, ", freq=%u, duty=%u", ledc_get_freq(self->mode, self->timer), duty); + mp_printf(print, ", resolution=%u", timers[TIMER_IDX(self->mode, self->timer)].duty_resolution); + mp_printf(print, ", mode=%d, channel=%d, timer=%d", self->mode, self->channel, self->timer); } mp_printf(print, ")"); } @@ -128,61 +263,72 @@ STATIC void mp_machine_pwm_init_helper(machine_pwm_obj_t *self, mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - int channel; - int avail = -1; + int channel_idx = find_channel(self->pin, ANY_MODE); + if (channel_idx == -1) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("out of PWM channels:%d"), PWM_CHANNEL_MAX); // in all modes + } - // Find a free PWM channel, also spot if our pin is - // already mentioned. - for (channel = 0; channel < LEDC_CHANNEL_MAX; ++channel) { - if (chan_gpio[channel] == self->pin) { - break; + int freq = args[ARG_freq].u_int; + if ((freq < -1) || (freq > 40000000)) { + mp_raise_ValueError(MP_ERROR_TEXT("freqency must be between 1Hz and 40MHz")); + } + // Check if freq wasn't passed as an argument + if (freq == -1) { + // Check if already set, otherwise use the default freq. + // Possible case: + // pwm = PWM(pin, freq=1000, duty=256) + // pwm = PWM(pin, duty=128) + if (chans[channel_idx].timer_idx != -1) { + freq = timers[chans[channel_idx].timer_idx].freq_hz; } - if ((avail == -1) && (chan_gpio[channel] == -1)) { - avail = channel; + if (freq < 0) { + freq = PWFREQ; } } - if (channel >= LEDC_CHANNEL_MAX) { - if (avail == -1) { - mp_raise_ValueError(MP_ERROR_TEXT("out of PWM channels")); - } - channel = avail; + + int timer_idx = find_timer(freq, SAME_FREQ_OR_FREE, CHANNEL_IDX_TO_MODE(channel_idx)); + if (timer_idx == -1) { + timer_idx = find_timer(freq, SAME_FREQ_OR_FREE, ANY_MODE); } - self->channel = channel; + if (timer_idx == -1) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("out of PWM timers:%d"), PWM_TIMER_MAX); // in all modes + } + + int mode = TIMER_IDX_TO_MODE(timer_idx); + if (CHANNEL_IDX_TO_MODE(channel_idx) != mode) { + // unregister old channel + chans[channel_idx].pin = -1; + chans[channel_idx].timer_idx = -1; + // find new channel + channel_idx = find_channel(self->pin, mode); + if (CHANNEL_IDX_TO_MODE(channel_idx) != mode) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("out of PWM channels:%d"), PWM_CHANNEL_MAX); // in current mode + } + } + self->mode = mode; + self->timer = TIMER_IDX_TO_TIMER(timer_idx); + self->channel = CHANNEL_IDX_TO_CHANNEL(channel_idx); // New PWM assignment - self->active = 1; - if (chan_gpio[channel] == -1) { - ledc_channel_config_t cfg = { - .channel = channel, - .duty = (1 << timer_cfg.duty_resolution) / 2, - .gpio_num = self->pin, - .intr_type = LEDC_INTR_DISABLE, - .speed_mode = PWMODE, - .timer_sel = PWTIMER, - }; - if (ledc_channel_config(&cfg) != ESP_OK) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("PWM not supported on pin %d"), self->pin); - } - chan_gpio[channel] = self->pin; + if ((chans[channel_idx].pin == -1) || (chans[channel_idx].timer_idx != timer_idx)) { + configure_channel(self); + chans[channel_idx].pin = self->pin; } + chans[channel_idx].timer_idx = timer_idx; + self->active = true; - // Maybe change PWM timer - int tval = args[ARG_freq].u_int; - if (tval != -1) { - if (tval != timer_cfg.freq_hz) { - if (!set_freq(tval)) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("bad frequency %d"), tval); - } - } - } + // Set timer frequency + set_freq(freq, &timers[timer_idx]); // Set duty cycle? - int dval = args[ARG_duty].u_int; - if (dval != -1) { - dval &= ((1 << PWRES) - 1); - dval >>= PWRES - timer_cfg.duty_resolution; - ledc_set_duty(PWMODE, channel, dval); - ledc_update_duty(PWMODE, channel); + int duty = args[ARG_duty].u_int; + if (duty != -1) { + set_duty(self, duty); + } + + // Reset the timer if low speed + if (self->mode == LEDC_LOW_SPEED_MODE) { + check_esp_err(ledc_timer_rst(self->mode, self->timer)); } } @@ -195,8 +341,10 @@ STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, machine_pwm_obj_t *self = m_new_obj(machine_pwm_obj_t); self->base.type = &machine_pwm_type; self->pin = pin_id; - self->active = 0; + self->active = false; + self->mode = -1; self->channel = -1; + self->timer = -1; // start the PWM subsystem if it's not already running if (!pwm_inited) { @@ -213,38 +361,99 @@ STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, } STATIC void mp_machine_pwm_deinit(machine_pwm_obj_t *self) { - int chan = self->channel; + int chan = CHANNEL_IDX(self->mode, self->channel); // Valid channel? - if ((chan >= 0) && (chan < LEDC_CHANNEL_MAX)) { + if ((chan >= 0) && (chan < PWM_CHANNEL_MAX)) { + // Clean up timer if necessary + if (!is_timer_in_use(chan, chans[chan].timer_idx)) { + check_esp_err(ledc_timer_rst(self->mode, self->timer)); + // Flag it unused + timers[chans[chan].timer_idx].freq_hz = -1; + } + // Mark it unused, and tell the hardware to stop routing - chan_gpio[chan] = -1; - ledc_stop(PWMODE, chan, 0); - self->active = 0; + check_esp_err(ledc_stop(self->mode, chan, 0)); + // Disable ledc signal for the pin + // gpio_matrix_out(self->pin, SIG_GPIO_OUT_IDX, false, false); + if (self->mode == LEDC_LOW_SPEED_MODE) { + gpio_matrix_out(self->pin, LEDC_LS_SIG_OUT0_IDX + self->channel, false, true); + } else { + #if LEDC_SPEED_MODE_MAX > 1 + #if CONFIG_IDF_TARGET_ESP32 + gpio_matrix_out(self->pin, LEDC_HS_SIG_OUT0_IDX + self->channel, false, true); + #else + #error Add supported CONFIG_IDF_TARGET_ESP32_xxx + #endif + #endif + } + chans[chan].pin = -1; + chans[chan].timer_idx = -1; + self->active = false; + self->mode = -1; self->channel = -1; - gpio_matrix_out(self->pin, SIG_GPIO_OUT_IDX, false, false); + self->timer = -1; } } STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) { - return MP_OBJ_NEW_SMALL_INT(timer_cfg.freq_hz); + return MP_OBJ_NEW_SMALL_INT(ledc_get_freq(self->mode, self->timer)); } STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) { - if (!set_freq(freq)) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("bad frequency %d"), freq); + if (freq == timers[TIMER_IDX(self->mode, self->timer)].freq_hz) { + return; + } + + int current_timer_idx = chans[CHANNEL_IDX(self->mode, self->channel)].timer_idx; + bool current_in_use = is_timer_in_use(CHANNEL_IDX(self->mode, self->channel), current_timer_idx); + + // Check if an already running timer with the same freq is running + int new_timer_idx = find_timer(freq, SAME_FREQ_ONLY, self->mode); + + // If no existing timer was found, and the current one is in use, then find a new one + if ((new_timer_idx == -1) && current_in_use) { + // Have to find a new timer + new_timer_idx = find_timer(freq, SAME_FREQ_OR_FREE, self->mode); + + if (new_timer_idx == -1) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("out of PWM timers:%d"), PWM_TIMER_MAX); // in current mode + } + } + + if ((new_timer_idx != -1) && (new_timer_idx != current_timer_idx)) { + // Bind the channel to the new timer + chans[self->channel].timer_idx = new_timer_idx; + + if (ledc_bind_channel_timer(self->mode, self->channel, TIMER_IDX_TO_TIMER(new_timer_idx)) != ESP_OK) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("failed to bind timer to channel")); + } + + if (!current_in_use) { + // Free the old timer + check_esp_err(ledc_timer_rst(self->mode, self->timer)); + // Flag it unused + timers[current_timer_idx].freq_hz = -1; + } + + current_timer_idx = new_timer_idx; + } + self->mode = TIMER_IDX_TO_MODE(current_timer_idx); + self->timer = TIMER_IDX_TO_TIMER(current_timer_idx); + + // Set the freq + set_freq(freq, &timers[current_timer_idx]); + + // Reset the timer if low speed + if (self->mode == LEDC_LOW_SPEED_MODE) { + check_esp_err(ledc_timer_rst(self->mode, self->timer)); } } STATIC mp_obj_t mp_machine_pwm_duty_get(machine_pwm_obj_t *self) { - int duty = ledc_get_duty(PWMODE, self->channel); - duty <<= PWRES - timer_cfg.duty_resolution; - return MP_OBJ_NEW_SMALL_INT(duty); + return MP_OBJ_NEW_SMALL_INT(get_duty(self)); } STATIC void mp_machine_pwm_duty_set(machine_pwm_obj_t *self, mp_int_t duty) { - duty &= ((1 << PWRES) - 1); - duty >>= PWRES - timer_cfg.duty_resolution; - ledc_set_duty(PWMODE, self->channel, duty); - ledc_update_duty(PWMODE, self->channel); + set_duty(self, duty); } From 71111cffbaef778635e212550ff3f0521c43f592 Mon Sep 17 00:00:00 2001 From: IhorNehrutsa Date: Sun, 19 Sep 2021 00:41:42 +0300 Subject: [PATCH 066/335] docs/esp32: Explain ESP32 PWM modes, timers, and channels. --- docs/esp32/quickref.rst | 26 ++++++++++++++++--- docs/esp32/tutorial/index.rst | 22 ++++++++++++++++ docs/esp32/tutorial/pwm.rst | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 docs/esp32/tutorial/index.rst create mode 100644 docs/esp32/tutorial/pwm.rst diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index 3153ebd571..7391a4aa4b 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -16,7 +16,7 @@ working with this board it may be useful to get an overview of the microcontroll :maxdepth: 1 general.rst - tutorial/intro.rst + tutorial/index.rst Installing MicroPython ---------------------- @@ -225,13 +225,31 @@ Use the ``machine.PWM`` class:: from machine import Pin, PWM pwm0 = PWM(Pin(0)) # create PWM object from a pin - pwm0.freq() # get current frequency + pwm0.freq() # get current frequency (default 5kHz) pwm0.freq(1000) # set frequency - pwm0.duty() # get current duty cycle + pwm0.duty() # get current duty cycle (default 512, 50%) pwm0.duty(200) # set duty cycle pwm0.deinit() # turn off PWM on the pin - pwm2 = PWM(Pin(2), freq=20000, duty=512) # create and configure in one go + pwm2 = PWM(Pin(2), freq=20000, duty=512) # create and configure in one go + +ESP chips have different hardware peripherals: + +===================================================== ======== ======== ======== +Hardware specification ESP32 ESP32-S2 ESP32-C3 +----------------------------------------------------- -------- -------- -------- +Number of groups (speed modes) 2 1 1 +Number of timers per group 4 4 4 +Number of channels per group 8 8 6 +----------------------------------------------------- -------- -------- -------- +Different of PWM frequencies (groups * timers) 8 4 4 +Total PWM channels (Pins, duties) (groups * channels) 16 8 6 +===================================================== ======== ======== ======== + +A maximum number of PWM channels (Pins) are available on the ESP32 - 16 channels, +but only 8 different PWM frequencies are available, the remaining 8 channels must +have the same frequency. On the other hand, 16 independent PWM duty cycles are +possible at the same frequency. ADC (analog to digital conversion) ---------------------------------- diff --git a/docs/esp32/tutorial/index.rst b/docs/esp32/tutorial/index.rst new file mode 100644 index 0000000000..e9cfd9db10 --- /dev/null +++ b/docs/esp32/tutorial/index.rst @@ -0,0 +1,22 @@ +.. _esp32_tutorial: + +MicroPython tutorial for ESP32 +============================== + +This tutorial is intended to get you started using MicroPython on the ESP32 +system-on-a-chip. If it is your first time it is recommended to follow the +tutorial through in the order below. Otherwise the sections are mostly self +contained, so feel free to skip to those that interest you. + +The tutorial does not assume that you know Python, but it also does not attempt +to explain any of the details of the Python language. Instead it provides you +with commands that are ready to run, and hopes that you will gain a bit of +Python knowledge along the way. To learn more about Python itself please refer +to ``__. + +.. toctree:: + :maxdepth: 1 + :numbered: + + intro.rst + pwm.rst diff --git a/docs/esp32/tutorial/pwm.rst b/docs/esp32/tutorial/pwm.rst new file mode 100644 index 0000000000..0c1afb213b --- /dev/null +++ b/docs/esp32/tutorial/pwm.rst @@ -0,0 +1,49 @@ +.. _esp32_pwm: + +Pulse Width Modulation +====================== + +Pulse width modulation (PWM) is a way to get an artificial analog output on a +digital pin. It achieves this by rapidly toggling the pin from low to high. +There are two parameters associated with this: the frequency of the toggling, +and the duty cycle. The duty cycle is defined to be how long the pin is high +compared with the length of a single period (low plus high time). Maximum +duty cycle is when the pin is high all of the time, and minimum is when it is +low all of the time. + +More comprehensive example with all 16 PWM channels and 8 timers:: + + from machine import Pin, PWM + try: + f = 100 # Hz + d = 1024 // 16 # 6.25% + pins = (15, 2, 4, 16, 18, 19, 22, 23, 25, 26, 27, 14 , 12, 13, 32, 33) + pwms = [] + for i, pin in enumerate(pins): + pwms.append(PWM(Pin(pin), freq=f * (i // 2 + 1), duty= 1023 if i==15 else d * (i + 1))) + print(pwms[i]) + finally: + for pwm in pwms: + try: + pwm.deinit() + except: + pass + +Output is:: + + PWM(pin=15, freq=100, duty=64, resolution=10, mode=0, channel=0, timer=0) + PWM(pin=2, freq=100, duty=128, resolution=10, mode=0, channel=1, timer=0) + PWM(pin=4, freq=200, duty=192, resolution=10, mode=0, channel=2, timer=1) + PWM(pin=16, freq=200, duty=256, resolution=10, mode=0, channel=3, timer=1) + PWM(pin=18, freq=300, duty=320, resolution=10, mode=0, channel=4, timer=2) + PWM(pin=19, freq=300, duty=384, resolution=10, mode=0, channel=5, timer=2) + PWM(pin=22, freq=400, duty=448, resolution=10, mode=0, channel=6, timer=3) + PWM(pin=23, freq=400, duty=512, resolution=10, mode=0, channel=7, timer=3) + PWM(pin=25, freq=500, duty=576, resolution=10, mode=1, channel=0, timer=0) + PWM(pin=26, freq=500, duty=640, resolution=10, mode=1, channel=1, timer=0) + PWM(pin=27, freq=600, duty=704, resolution=10, mode=1, channel=2, timer=1) + PWM(pin=14, freq=600, duty=768, resolution=10, mode=1, channel=3, timer=1) + PWM(pin=12, freq=700, duty=832, resolution=10, mode=1, channel=4, timer=2) + PWM(pin=13, freq=700, duty=896, resolution=10, mode=1, channel=5, timer=2) + PWM(pin=32, freq=800, duty=960, resolution=10, mode=1, channel=6, timer=3) + PWM(pin=33, freq=800, duty=1023, resolution=10, mode=1, channel=7, timer=3) From 7bf466a2811fcad6518441c6a2987beb590e3326 Mon Sep 17 00:00:00 2001 From: Seon Rozenblum Date: Mon, 20 Sep 2021 11:34:52 +1000 Subject: [PATCH 067/335] esp32/README: Updated readme with req IDF vers for ESP32-S2, C3 and S3. --- ports/esp32/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ports/esp32/README.md b/ports/esp32/README.md index c7d40070d1..42cd588171 100644 --- a/ports/esp32/README.md +++ b/ports/esp32/README.md @@ -75,6 +75,12 @@ $ source export.sh # (or export.bat on Windows) The `install.sh` step only needs to be done once. You will need to source `export.sh` for every new session. +**Note:** If you are building MicroPython for the ESP32-S2, ESP32-C3 or ESP32-S3, +please ensure you are using the following required IDF versions: +- ESP32-S3 currently requires latest `master`, but eventually `v4.4` or later when + it's available. +- ESP32-S2 and ESP32-C3 require `v4.3.1` or later. + Building the firmware --------------------- From 35fb90bd57e1a3259aaf67cede50628da6888485 Mon Sep 17 00:00:00 2001 From: Seon Rozenblum Date: Mon, 20 Sep 2021 14:04:08 +1000 Subject: [PATCH 068/335] esp32/usb: Add USB host connection detection for CDC serial output. This callback allows detecting if there is a USB host connected to the CDC or not, in which case the stdout_tx should skip CDC TX writing and flushing or the system will block. Fixes issue #7820. --- ports/esp32/usb.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ports/esp32/usb.c b/ports/esp32/usb.c index 85a7a11c9e..21047fa2be 100644 --- a/ports/esp32/usb.c +++ b/ports/esp32/usb.c @@ -36,6 +36,7 @@ #define CDC_ITF TINYUSB_CDC_ACM_0 static uint8_t usb_rx_buf[CONFIG_USB_CDC_RX_BUFSIZE]; +static uint8_t usb_cdc_connected; static void usb_callback_rx(int itf, cdcacm_event_t *event) { // TODO: what happens if more chars come in during this function, are they lost? @@ -58,6 +59,13 @@ static void usb_callback_rx(int itf, cdcacm_event_t *event) { } } +void usb_callback_line_state_changed(int itf, cdcacm_event_t *event) { + int dtr = event->line_state_changed_data.dtr; + int rts = event->line_state_changed_data.rts; + // If dtr && rts are both true, the CDC is connected to a HOST. + usb_cdc_connected = dtr && rts; +} + void usb_init(void) { // Initialise the USB with defaults. tinyusb_config_t tusb_cfg = {0}; @@ -70,13 +78,20 @@ void usb_init(void) { .rx_unread_buf_sz = 256, .callback_rx = &usb_callback_rx, .callback_rx_wanted_char = NULL, - .callback_line_state_changed = NULL, + .callback_line_state_changed = &usb_callback_line_state_changed, .callback_line_coding_changed = NULL }; + usb_cdc_connected = 0; ESP_ERROR_CHECK(tusb_cdc_acm_init(&amc_cfg)); + } void usb_tx_strn(const char *str, size_t len) { + // If no HOST is connected, we can exit this early. + if (usb_cdc_connected == 0) { + return; + } + while (len) { size_t l = len; if (l > CONFIG_USB_CDC_TX_BUFSIZE) { From a39a596b791f14e277ba526f9b6bd8ce2da36550 Mon Sep 17 00:00:00 2001 From: Seon Rozenblum Date: Mon, 20 Sep 2021 11:03:38 +1000 Subject: [PATCH 069/335] esp32/machine_pin: Block out IO16 and IO17 when using SPIRAM on ESP32. Fixes issue #7819. --- ports/esp32/machine_pin.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ports/esp32/machine_pin.c b/ports/esp32/machine_pin.c index 6c1e96879f..bf61122811 100644 --- a/ports/esp32/machine_pin.c +++ b/ports/esp32/machine_pin.c @@ -84,8 +84,13 @@ STATIC const machine_pin_obj_t machine_pin_obj[] = { {{&machine_pin_type}, GPIO_NUM_13}, {{&machine_pin_type}, GPIO_NUM_14}, {{&machine_pin_type}, GPIO_NUM_15}, + #if CONFIG_ESP32_SPIRAM_SUPPORT + {{NULL}, -1}, + {{NULL}, -1}, + #else {{&machine_pin_type}, GPIO_NUM_16}, {{&machine_pin_type}, GPIO_NUM_17}, + #endif {{&machine_pin_type}, GPIO_NUM_18}, {{&machine_pin_type}, GPIO_NUM_19}, {{NULL}, -1}, @@ -518,8 +523,13 @@ STATIC const machine_pin_irq_obj_t machine_pin_irq_object[] = { {{&machine_pin_irq_type}, GPIO_NUM_13}, {{&machine_pin_irq_type}, GPIO_NUM_14}, {{&machine_pin_irq_type}, GPIO_NUM_15}, + #if CONFIG_ESP32_SPIRAM_SUPPORT + {{NULL}, -1}, + {{NULL}, -1}, + #else {{&machine_pin_irq_type}, GPIO_NUM_16}, {{&machine_pin_irq_type}, GPIO_NUM_17}, + #endif {{&machine_pin_irq_type}, GPIO_NUM_18}, {{&machine_pin_irq_type}, GPIO_NUM_19}, {{NULL}, -1}, From 4fdf795efa4eca3a9f8166e33b991a762569ae20 Mon Sep 17 00:00:00 2001 From: leo chung Date: Thu, 16 Sep 2021 17:02:14 +0800 Subject: [PATCH 070/335] esp32/mpthreadport: Fix TCB cleanup function so thread_mutex is ready. Because vPortCleanUpTCB is called by the FreeRTOS idle task, and it checks thread, but didn't check the thread_mutex. And if thread is not NULL, but thread_mutex not ready then it will crash with an error when calling mp_thread_mutex_lock(&thread_mutex, 1). As suggested by @dpgeorge, move the thread = &thread_entry0 line to the end of mp_thread_init(). Signed-off-by: leo chung --- ports/esp32/mpthreadport.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/ports/esp32/mpthreadport.c b/ports/esp32/mpthreadport.c index f575d99e6e..9d1c4a758c 100644 --- a/ports/esp32/mpthreadport.c +++ b/ports/esp32/mpthreadport.c @@ -59,14 +59,19 @@ STATIC thread_t *thread = NULL; // root pointer, handled by mp_thread_gc_others void mp_thread_init(void *stack, uint32_t stack_len) { mp_thread_set_state(&mp_state_ctx.thread); // create the first entry in the linked list of all threads - thread = &thread_entry0; - thread->id = xTaskGetCurrentTaskHandle(); - thread->ready = 1; - thread->arg = NULL; - thread->stack = stack; - thread->stack_len = stack_len; - thread->next = NULL; + thread_entry0.id = xTaskGetCurrentTaskHandle(); + thread_entry0.ready = 1; + thread_entry0.arg = NULL; + thread_entry0.stack = stack; + thread_entry0.stack_len = stack_len; + thread_entry0.next = NULL; mp_thread_mutex_init(&thread_mutex); + + // memory barrier to ensure above data is committed + __sync_synchronize(); + + // vPortCleanUpTCB needs the thread ready after thread_mutex is ready + thread = &thread_entry0; } void mp_thread_gc_others(void) { From f046b50ca591e16f78ffaae3c45a19afaeba839b Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 22 Sep 2021 00:00:26 +1000 Subject: [PATCH 071/335] esp32/main: Add option for a board to hook code into startup sequence. To do this the board must define MICROPY_BOARD_STARTUP, set MICROPY_SOURCE_BOARD then define the new start-up code. For example, in mpconfigboard.h: #define MICROPY_BOARD_STARTUP board_startup void board_startup(void); in mpconfigboard.cmake: set(MICROPY_SOURCE_BOARD ${MICROPY_BOARD_DIR}/board.c ) and in a new board.c file in the board directory: #include "py/mpconfig.h" void board_startup(void) { boardctrl_startup(); // extra custom startup } This follows stm32's boardctrl facilities. Signed-off-by: Damien George --- ports/esp32/main.c | 10 +++++++++- ports/esp32/main/CMakeLists.txt | 2 ++ ports/esp32/mpconfigport.h | 6 ++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ports/esp32/main.c b/ports/esp32/main.c index 2ba6136681..ca0ab1488a 100644 --- a/ports/esp32/main.c +++ b/ports/esp32/main.c @@ -202,12 +202,20 @@ soft_reset_exit: goto soft_reset; } -void app_main(void) { +void boardctrl_startup(void) { esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { nvs_flash_erase(); nvs_flash_init(); } +} + +void app_main(void) { + // Hook for a board to run code at start up. + // This defaults to initialising NVS. + MICROPY_BOARD_STARTUP(); + + // Create and transfer control to the MicroPython task. xTaskCreatePinnedToCore(mp_task, "mp_task", MP_TASK_STACK_SIZE / sizeof(StackType_t), NULL, MP_TASK_PRIORITY, &mp_main_task_handle, MP_TASK_COREID); } diff --git a/ports/esp32/main/CMakeLists.txt b/ports/esp32/main/CMakeLists.txt index 75e123f4e0..18d7dc7fae 100644 --- a/ports/esp32/main/CMakeLists.txt +++ b/ports/esp32/main/CMakeLists.txt @@ -89,6 +89,7 @@ set(MICROPY_SOURCE_QSTR ${MICROPY_SOURCE_SHARED} ${MICROPY_SOURCE_LIB} ${MICROPY_SOURCE_PORT} + ${MICROPY_SOURCE_BOARD} ) set(IDF_COMPONENTS @@ -156,6 +157,7 @@ idf_component_register( ${MICROPY_SOURCE_LIB} ${MICROPY_SOURCE_DRIVERS} ${MICROPY_SOURCE_PORT} + ${MICROPY_SOURCE_BOARD} INCLUDE_DIRS ${MICROPY_INC_CORE} ${MICROPY_INC_USERMOD} diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 6a48ce5023..5affbb0692 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -308,3 +308,9 @@ typedef long mp_off_t; #ifndef MICROPY_HW_ENABLE_MDNS_RESPONDER #define MICROPY_HW_ENABLE_MDNS_RESPONDER (1) #endif + +#ifndef MICROPY_BOARD_STARTUP +#define MICROPY_BOARD_STARTUP boardctrl_startup +#endif + +void boardctrl_startup(void); From ea186de4c5d69729d1a5bb607e1a302923782bee Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 22 Sep 2021 00:35:46 +1000 Subject: [PATCH 072/335] esp32: Split out WLAN code from modnetwork.c to network_wlan.c. To match network_lan.c and network_ppp.c, and make it clear what code is specifically for WLAN support. Also provide a configuration option MICROPY_PY_NETWORK_WLAN which can be used to fully disable network.WLAN (it's enabled by default). Signed-off-by: Damien George --- ports/esp32/main/CMakeLists.txt | 1 + ports/esp32/modnetwork.c | 596 ++------------------------------ ports/esp32/modnetwork.h | 25 ++ ports/esp32/mpconfigport.h | 3 + ports/esp32/network_wlan.c | 578 +++++++++++++++++++++++++++++++ 5 files changed, 627 insertions(+), 576 deletions(-) create mode 100644 ports/esp32/network_wlan.c diff --git a/ports/esp32/main/CMakeLists.txt b/ports/esp32/main/CMakeLists.txt index 18d7dc7fae..3294ca7c04 100644 --- a/ports/esp32/main/CMakeLists.txt +++ b/ports/esp32/main/CMakeLists.txt @@ -67,6 +67,7 @@ set(MICROPY_SOURCE_PORT ${PROJECT_DIR}/modnetwork.c ${PROJECT_DIR}/network_lan.c ${PROJECT_DIR}/network_ppp.c + ${PROJECT_DIR}/network_wlan.c ${PROJECT_DIR}/mpnimbleport.c ${PROJECT_DIR}/modsocket.c ${PROJECT_DIR}/modesp.c diff --git a/ports/esp32/modnetwork.c b/ports/esp32/modnetwork.c index 2b64105e79..51aaa59e87 100644 --- a/ports/esp32/modnetwork.c +++ b/ports/esp32/modnetwork.c @@ -31,28 +31,16 @@ * THE SOFTWARE. */ -#include -#include #include -#include "py/nlr.h" -#include "py/objlist.h" #include "py/runtime.h" -#include "py/mphal.h" #include "py/mperrno.h" #include "shared/netutils/netutils.h" -#include "esp_eth.h" +#include "modnetwork.h" + #include "esp_wifi.h" #include "esp_log.h" #include "lwip/dns.h" -#include "mdns.h" - -#if !MICROPY_ESP_IDF_4 -#include "esp_wifi_types.h" -#include "esp_event_loop.h" -#endif - -#include "modnetwork.h" #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 1, 0) #define DNS_MAIN TCPIP_ADAPTER_DNS_MAIN @@ -62,7 +50,7 @@ #define MODNETWORK_INCLUDE_CONSTANTS (1) -NORETURN void _esp_exceptions(esp_err_t e) { +NORETURN void esp_exceptions_helper(esp_err_t e) { switch (e) { case ESP_ERR_WIFI_NOT_INIT: mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Not Initialized")); @@ -107,122 +95,16 @@ NORETURN void _esp_exceptions(esp_err_t e) { } } -static inline void esp_exceptions(esp_err_t e) { - if (e != ESP_OK) { - _esp_exceptions(e); - } -} - -#define ESP_EXCEPTIONS(x) do { esp_exceptions(x); } while (0); - -typedef struct _wlan_if_obj_t { - mp_obj_base_t base; - int if_id; -} wlan_if_obj_t; - -const mp_obj_type_t wlan_if_type; -STATIC const wlan_if_obj_t wlan_sta_obj = {{&wlan_if_type}, WIFI_IF_STA}; -STATIC const wlan_if_obj_t wlan_ap_obj = {{&wlan_if_type}, WIFI_IF_AP}; - -// Set to "true" if esp_wifi_start() was called -static bool wifi_started = false; - -// Set to "true" if the STA interface is requested to be connected by the -// user, used for automatic reassociation. -static bool wifi_sta_connect_requested = false; - -// Set to "true" if the STA interface is connected to wifi and has IP address. -static bool wifi_sta_connected = false; - -// Store the current status. 0 means None here, safe to do so as first enum value is WIFI_REASON_UNSPECIFIED=1. -static uint8_t wifi_sta_disconn_reason = 0; - -#if MICROPY_HW_ENABLE_MDNS_QUERIES || MICROPY_HW_ENABLE_MDNS_RESPONDER -// Whether mDNS has been initialised or not -static bool mdns_initialised = false; -#endif - -static uint8_t conf_wifi_sta_reconnects = 0; -static uint8_t wifi_sta_reconnects; - // This function is called by the system-event task and so runs in a different // thread to the main MicroPython task. It must not raise any Python exceptions. static esp_err_t event_handler(void *ctx, system_event_t *event) { switch (event->event_id) { case SYSTEM_EVENT_STA_START: - ESP_LOGI("wifi", "STA_START"); - wifi_sta_reconnects = 0; - break; case SYSTEM_EVENT_STA_CONNECTED: - ESP_LOGI("network", "CONNECTED"); - break; case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI("network", "GOT_IP"); - wifi_sta_connected = true; - wifi_sta_disconn_reason = 0; // Success so clear error. (in case of new error will be replaced anyway) - #if MICROPY_HW_ENABLE_MDNS_QUERIES || MICROPY_HW_ENABLE_MDNS_RESPONDER - if (!mdns_initialised) { - mdns_init(); - #if MICROPY_HW_ENABLE_MDNS_RESPONDER - const char *hostname = NULL; - if (tcpip_adapter_get_hostname(WIFI_IF_STA, &hostname) != ESP_OK || hostname == NULL) { - hostname = "esp32"; - } - mdns_hostname_set(hostname); - mdns_instance_name_set(hostname); - #endif - mdns_initialised = true; - } - #endif + case SYSTEM_EVENT_STA_DISCONNECTED: + network_wlan_event_handler(event); break; - case SYSTEM_EVENT_STA_DISCONNECTED: { - // This is a workaround as ESP32 WiFi libs don't currently - // auto-reassociate. - system_event_sta_disconnected_t *disconn = &event->event_info.disconnected; - char *message = ""; - wifi_sta_disconn_reason = disconn->reason; - switch (disconn->reason) { - case WIFI_REASON_BEACON_TIMEOUT: - // AP has dropped out; try to reconnect. - message = "\nbeacon timeout"; - break; - case WIFI_REASON_NO_AP_FOUND: - // AP may not exist, or it may have momentarily dropped out; try to reconnect. - message = "\nno AP found"; - break; - case WIFI_REASON_AUTH_FAIL: - // Password may be wrong, or it just failed to connect; try to reconnect. - message = "\nauthentication failed"; - break; - default: - // Let other errors through and try to reconnect. - break; - } - ESP_LOGI("wifi", "STA_DISCONNECTED, reason:%d%s", disconn->reason, message); - - wifi_sta_connected = false; - if (wifi_sta_connect_requested) { - wifi_mode_t mode; - if (esp_wifi_get_mode(&mode) != ESP_OK) { - break; - } - if (!(mode & WIFI_MODE_STA)) { - break; - } - if (conf_wifi_sta_reconnects) { - ESP_LOGI("wifi", "reconnect counter=%d, max=%d", - wifi_sta_reconnects, conf_wifi_sta_reconnects); - if (++wifi_sta_reconnects >= conf_wifi_sta_reconnects) { - break; - } - } - esp_err_t e = esp_wifi_connect(); - if (e != ESP_OK) { - ESP_LOGI("wifi", "error attempting to reconnect: 0x%04x", e); - } - } - break; - } case SYSTEM_EVENT_GOT_IP6: ESP_LOGI("network", "Got IPv6"); break; @@ -248,49 +130,13 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) { return ESP_OK; } -/*void error_check(bool status, const char *msg) { - if (!status) { - mp_raise_msg(&mp_type_OSError, msg); - } -} -*/ - -STATIC void require_if(mp_obj_t wlan_if, int if_no) { - wlan_if_obj_t *self = MP_OBJ_TO_PTR(wlan_if); - if (self->if_id != if_no) { - mp_raise_msg(&mp_type_OSError, if_no == WIFI_IF_STA ? MP_ERROR_TEXT("STA required") : MP_ERROR_TEXT("AP required")); - } -} - -STATIC mp_obj_t get_wlan(size_t n_args, const mp_obj_t *args) { - static int initialized = 0; - if (!initialized) { - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_LOGD("modnetwork", "Initializing WiFi"); - ESP_EXCEPTIONS(esp_wifi_init(&cfg)); - ESP_EXCEPTIONS(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_LOGD("modnetwork", "Initialized"); - initialized = 1; - } - - int idx = (n_args > 0) ? mp_obj_get_int(args[0]) : WIFI_IF_STA; - if (idx == WIFI_IF_STA) { - return MP_OBJ_FROM_PTR(&wlan_sta_obj); - } else if (idx == WIFI_IF_AP) { - return MP_OBJ_FROM_PTR(&wlan_ap_obj); - } else { - mp_raise_ValueError(MP_ERROR_TEXT("invalid WLAN interface identifier")); - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(get_wlan_obj, 0, 1, get_wlan); - STATIC mp_obj_t esp_initialize() { static int initialized = 0; if (!initialized) { ESP_LOGD("modnetwork", "Initializing TCP/IP"); tcpip_adapter_init(); ESP_LOGD("modnetwork", "Initializing Event Loop"); - ESP_EXCEPTIONS(esp_event_loop_init(event_handler, NULL)); + esp_exceptions(esp_event_loop_init(event_handler, NULL)); ESP_LOGD("modnetwork", "esp_event_loop_init done"); initialized = 1; } @@ -298,214 +144,6 @@ STATIC mp_obj_t esp_initialize() { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_initialize_obj, esp_initialize); -#if (WIFI_MODE_STA & WIFI_MODE_AP != WIFI_MODE_NULL || WIFI_MODE_STA | WIFI_MODE_AP != WIFI_MODE_APSTA) -#error WIFI_MODE_STA and WIFI_MODE_AP are supposed to be bitfields! -#endif - -STATIC mp_obj_t esp_active(size_t n_args, const mp_obj_t *args) { - wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); - - wifi_mode_t mode; - if (!wifi_started) { - mode = WIFI_MODE_NULL; - } else { - ESP_EXCEPTIONS(esp_wifi_get_mode(&mode)); - } - - int bit = (self->if_id == WIFI_IF_STA) ? WIFI_MODE_STA : WIFI_MODE_AP; - - if (n_args > 1) { - bool active = mp_obj_is_true(args[1]); - mode = active ? (mode | bit) : (mode & ~bit); - if (mode == WIFI_MODE_NULL) { - if (wifi_started) { - ESP_EXCEPTIONS(esp_wifi_stop()); - wifi_started = false; - } - } else { - ESP_EXCEPTIONS(esp_wifi_set_mode(mode)); - if (!wifi_started) { - ESP_EXCEPTIONS(esp_wifi_start()); - wifi_started = true; - } - } - } - - return (mode & bit) ? mp_const_true : mp_const_false; -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_active_obj, 1, 2, esp_active); - -STATIC mp_obj_t esp_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_ssid, ARG_password, ARG_bssid }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_bssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - wifi_config_t wifi_sta_config = {0}; - - // configure any parameters that are given - if (n_args > 1) { - size_t len; - const char *p; - if (args[ARG_ssid].u_obj != mp_const_none) { - p = mp_obj_str_get_data(args[ARG_ssid].u_obj, &len); - memcpy(wifi_sta_config.sta.ssid, p, MIN(len, sizeof(wifi_sta_config.sta.ssid))); - } - if (args[ARG_password].u_obj != mp_const_none) { - p = mp_obj_str_get_data(args[ARG_password].u_obj, &len); - memcpy(wifi_sta_config.sta.password, p, MIN(len, sizeof(wifi_sta_config.sta.password))); - } - if (args[ARG_bssid].u_obj != mp_const_none) { - p = mp_obj_str_get_data(args[ARG_bssid].u_obj, &len); - if (len != sizeof(wifi_sta_config.sta.bssid)) { - mp_raise_ValueError(NULL); - } - wifi_sta_config.sta.bssid_set = 1; - memcpy(wifi_sta_config.sta.bssid, p, sizeof(wifi_sta_config.sta.bssid)); - } - ESP_EXCEPTIONS(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_sta_config)); - } - - wifi_sta_reconnects = 0; - // connect to the WiFi AP - MP_THREAD_GIL_EXIT(); - ESP_EXCEPTIONS(esp_wifi_connect()); - MP_THREAD_GIL_ENTER(); - wifi_sta_connect_requested = true; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp_connect_obj, 1, esp_connect); - -STATIC mp_obj_t esp_disconnect(mp_obj_t self_in) { - wifi_sta_connect_requested = false; - ESP_EXCEPTIONS(esp_wifi_disconnect()); - return mp_const_none; -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_disconnect_obj, esp_disconnect); - -// Cases similar to ESP8266 user_interface.h -// Error cases are referenced from wifi_err_reason_t in ESP-IDF -enum { - STAT_IDLE = 1000, - STAT_CONNECTING = 1001, - STAT_GOT_IP = 1010, -}; - -STATIC mp_obj_t esp_status(size_t n_args, const mp_obj_t *args) { - wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); - if (n_args == 1) { - if (self->if_id == WIFI_IF_STA) { - // Case of no arg is only for the STA interface - if (wifi_sta_connected) { - // Happy path, connected with IP - return MP_OBJ_NEW_SMALL_INT(STAT_GOT_IP); - } else if (wifi_sta_connect_requested - && (conf_wifi_sta_reconnects == 0 - || wifi_sta_reconnects < conf_wifi_sta_reconnects)) { - // No connection or error, but is requested = Still connecting - return MP_OBJ_NEW_SMALL_INT(STAT_CONNECTING); - } else if (wifi_sta_disconn_reason == 0) { - // No activity, No error = Idle - return MP_OBJ_NEW_SMALL_INT(STAT_IDLE); - } else { - // Simply pass the error through from ESP-identifier - return MP_OBJ_NEW_SMALL_INT(wifi_sta_disconn_reason); - } - } - return mp_const_none; - } - - // one argument: return status based on query parameter - switch ((uintptr_t)args[1]) { - case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_stations): { - // return list of connected stations, only if in soft-AP mode - require_if(args[0], WIFI_IF_AP); - wifi_sta_list_t station_list; - ESP_EXCEPTIONS(esp_wifi_ap_get_sta_list(&station_list)); - wifi_sta_info_t *stations = (wifi_sta_info_t *)station_list.sta; - mp_obj_t list = mp_obj_new_list(0, NULL); - for (int i = 0; i < station_list.num; ++i) { - mp_obj_tuple_t *t = mp_obj_new_tuple(1, NULL); - t->items[0] = mp_obj_new_bytes(stations[i].mac, sizeof(stations[i].mac)); - mp_obj_list_append(list, t); - } - return list; - } - case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_rssi): { - // return signal of AP, only in STA mode - require_if(args[0], WIFI_IF_STA); - - wifi_ap_record_t info; - ESP_EXCEPTIONS(esp_wifi_sta_get_ap_info(&info)); - return MP_OBJ_NEW_SMALL_INT(info.rssi); - } - default: - mp_raise_ValueError(MP_ERROR_TEXT("unknown status param")); - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_status_obj, 1, 2, esp_status); - -STATIC mp_obj_t esp_scan(mp_obj_t self_in) { - // check that STA mode is active - wifi_mode_t mode; - ESP_EXCEPTIONS(esp_wifi_get_mode(&mode)); - if ((mode & WIFI_MODE_STA) == 0) { - mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("STA must be active")); - } - - mp_obj_t list = mp_obj_new_list(0, NULL); - wifi_scan_config_t config = { 0 }; - config.show_hidden = true; - MP_THREAD_GIL_EXIT(); - esp_err_t status = esp_wifi_scan_start(&config, 1); - MP_THREAD_GIL_ENTER(); - if (status == 0) { - uint16_t count = 0; - ESP_EXCEPTIONS(esp_wifi_scan_get_ap_num(&count)); - wifi_ap_record_t *wifi_ap_records = calloc(count, sizeof(wifi_ap_record_t)); - ESP_EXCEPTIONS(esp_wifi_scan_get_ap_records(&count, wifi_ap_records)); - for (uint16_t i = 0; i < count; i++) { - mp_obj_tuple_t *t = mp_obj_new_tuple(6, NULL); - uint8_t *x = memchr(wifi_ap_records[i].ssid, 0, sizeof(wifi_ap_records[i].ssid)); - int ssid_len = x ? x - wifi_ap_records[i].ssid : sizeof(wifi_ap_records[i].ssid); - t->items[0] = mp_obj_new_bytes(wifi_ap_records[i].ssid, ssid_len); - t->items[1] = mp_obj_new_bytes(wifi_ap_records[i].bssid, sizeof(wifi_ap_records[i].bssid)); - t->items[2] = MP_OBJ_NEW_SMALL_INT(wifi_ap_records[i].primary); - t->items[3] = MP_OBJ_NEW_SMALL_INT(wifi_ap_records[i].rssi); - t->items[4] = MP_OBJ_NEW_SMALL_INT(wifi_ap_records[i].authmode); - t->items[5] = mp_const_false; // XXX hidden? - mp_obj_list_append(list, MP_OBJ_FROM_PTR(t)); - } - free(wifi_ap_records); - } - return list; -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_scan_obj, esp_scan); - -STATIC mp_obj_t esp_isconnected(mp_obj_t self_in) { - wlan_if_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->if_id == WIFI_IF_STA) { - return mp_obj_new_bool(wifi_sta_connected); - } else { - wifi_sta_list_t sta; - esp_wifi_ap_get_sta_list(&sta); - return mp_obj_new_bool(sta.num != 0); - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_isconnected_obj, esp_isconnected); - STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) { wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); tcpip_adapter_ip_info_t info; @@ -543,18 +181,18 @@ STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) { if (self->if_id == WIFI_IF_STA || self->if_id == ESP_IF_ETH) { esp_err_t e = tcpip_adapter_dhcpc_stop(self->if_id); if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED) { - _esp_exceptions(e); + esp_exceptions_helper(e); } - ESP_EXCEPTIONS(tcpip_adapter_set_ip_info(self->if_id, &info)); - ESP_EXCEPTIONS(tcpip_adapter_set_dns_info(self->if_id, DNS_MAIN, &dns_info)); + esp_exceptions(tcpip_adapter_set_ip_info(self->if_id, &info)); + esp_exceptions(tcpip_adapter_set_dns_info(self->if_id, DNS_MAIN, &dns_info)); } else if (self->if_id == WIFI_IF_AP) { esp_err_t e = tcpip_adapter_dhcps_stop(WIFI_IF_AP); if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED) { - _esp_exceptions(e); + esp_exceptions_helper(e); } - ESP_EXCEPTIONS(tcpip_adapter_set_ip_info(WIFI_IF_AP, &info)); - ESP_EXCEPTIONS(tcpip_adapter_set_dns_info(WIFI_IF_AP, DNS_MAIN, &dns_info)); - ESP_EXCEPTIONS(tcpip_adapter_dhcps_start(WIFI_IF_AP)); + esp_exceptions(tcpip_adapter_set_ip_info(WIFI_IF_AP, &info)); + esp_exceptions(tcpip_adapter_set_dns_info(WIFI_IF_AP, DNS_MAIN, &dns_info)); + esp_exceptions(tcpip_adapter_dhcps_start(WIFI_IF_AP)); } } else { // check for the correct string @@ -562,213 +200,13 @@ STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) { if ((self->if_id != WIFI_IF_STA && self->if_id != ESP_IF_ETH) || strcmp("dhcp", mode)) { mp_raise_ValueError(MP_ERROR_TEXT("invalid arguments")); } - ESP_EXCEPTIONS(tcpip_adapter_dhcpc_start(self->if_id)); + esp_exceptions(tcpip_adapter_dhcpc_start(self->if_id)); } return mp_const_none; } } - MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj, 1, 2, esp_ifconfig); -STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { - if (n_args != 1 && kwargs->used != 0) { - mp_raise_TypeError(MP_ERROR_TEXT("either pos or kw args are allowed")); - } - - wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); - - bool is_wifi = self->if_id == WIFI_IF_AP || self->if_id == WIFI_IF_STA; - - wifi_config_t cfg; - if (is_wifi) { - ESP_EXCEPTIONS(esp_wifi_get_config(self->if_id, &cfg)); - } - - #define QS(x) (uintptr_t)MP_OBJ_NEW_QSTR(x) - - if (kwargs->used != 0) { - if (!is_wifi) { - goto unknown; - } - - for (size_t i = 0; i < kwargs->alloc; i++) { - if (mp_map_slot_is_filled(kwargs, i)) { - int req_if = -1; - - switch ((uintptr_t)kwargs->table[i].key) { - case QS(MP_QSTR_mac): { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(kwargs->table[i].value, &bufinfo, MP_BUFFER_READ); - if (bufinfo.len != 6) { - mp_raise_ValueError(MP_ERROR_TEXT("invalid buffer length")); - } - ESP_EXCEPTIONS(esp_wifi_set_mac(self->if_id, bufinfo.buf)); - break; - } - case QS(MP_QSTR_essid): { - req_if = WIFI_IF_AP; - size_t len; - const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len); - len = MIN(len, sizeof(cfg.ap.ssid)); - memcpy(cfg.ap.ssid, s, len); - cfg.ap.ssid_len = len; - break; - } - case QS(MP_QSTR_hidden): { - req_if = WIFI_IF_AP; - cfg.ap.ssid_hidden = mp_obj_is_true(kwargs->table[i].value); - break; - } - case QS(MP_QSTR_authmode): { - req_if = WIFI_IF_AP; - cfg.ap.authmode = mp_obj_get_int(kwargs->table[i].value); - break; - } - case QS(MP_QSTR_password): { - req_if = WIFI_IF_AP; - size_t len; - const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len); - len = MIN(len, sizeof(cfg.ap.password) - 1); - memcpy(cfg.ap.password, s, len); - cfg.ap.password[len] = 0; - break; - } - case QS(MP_QSTR_channel): { - req_if = WIFI_IF_AP; - cfg.ap.channel = mp_obj_get_int(kwargs->table[i].value); - break; - } - case QS(MP_QSTR_dhcp_hostname): { - const char *s = mp_obj_str_get_str(kwargs->table[i].value); - ESP_EXCEPTIONS(tcpip_adapter_set_hostname(self->if_id, s)); - break; - } - case QS(MP_QSTR_max_clients): { - req_if = WIFI_IF_AP; - cfg.ap.max_connection = mp_obj_get_int(kwargs->table[i].value); - break; - } - case QS(MP_QSTR_reconnects): { - int reconnects = mp_obj_get_int(kwargs->table[i].value); - req_if = WIFI_IF_STA; - // parameter reconnects == -1 means to retry forever. - // here means conf_wifi_sta_reconnects == 0 to retry forever. - conf_wifi_sta_reconnects = (reconnects == -1) ? 0 : reconnects + 1; - break; - } - default: - goto unknown; - } - - // We post-check interface requirements to save on code size - if (req_if >= 0) { - require_if(args[0], req_if); - } - } - } - - ESP_EXCEPTIONS(esp_wifi_set_config(self->if_id, &cfg)); - - return mp_const_none; - } - - // Get config - - if (n_args != 2) { - mp_raise_TypeError(MP_ERROR_TEXT("can query only one param")); - } - - int req_if = -1; - mp_obj_t val = mp_const_none; - - switch ((uintptr_t)args[1]) { - case QS(MP_QSTR_mac): { - uint8_t mac[6]; - switch (self->if_id) { - case WIFI_IF_AP: // fallthrough intentional - case WIFI_IF_STA: - ESP_EXCEPTIONS(esp_wifi_get_mac(self->if_id, mac)); - return mp_obj_new_bytes(mac, sizeof(mac)); - default: - goto unknown; - } - } - case QS(MP_QSTR_essid): - switch (self->if_id) { - case WIFI_IF_STA: - val = mp_obj_new_str((char *)cfg.sta.ssid, strlen((char *)cfg.sta.ssid)); - break; - case WIFI_IF_AP: - val = mp_obj_new_str((char *)cfg.ap.ssid, cfg.ap.ssid_len); - break; - default: - req_if = WIFI_IF_AP; - } - break; - case QS(MP_QSTR_hidden): - req_if = WIFI_IF_AP; - val = mp_obj_new_bool(cfg.ap.ssid_hidden); - break; - case QS(MP_QSTR_authmode): - req_if = WIFI_IF_AP; - val = MP_OBJ_NEW_SMALL_INT(cfg.ap.authmode); - break; - case QS(MP_QSTR_channel): - req_if = WIFI_IF_AP; - val = MP_OBJ_NEW_SMALL_INT(cfg.ap.channel); - break; - case QS(MP_QSTR_dhcp_hostname): { - const char *s; - ESP_EXCEPTIONS(tcpip_adapter_get_hostname(self->if_id, &s)); - val = mp_obj_new_str(s, strlen(s)); - break; - } - case QS(MP_QSTR_max_clients): { - val = MP_OBJ_NEW_SMALL_INT(cfg.ap.max_connection); - break; - } - case QS(MP_QSTR_reconnects): - req_if = WIFI_IF_STA; - int rec = conf_wifi_sta_reconnects - 1; - val = MP_OBJ_NEW_SMALL_INT(rec); - break; - default: - goto unknown; - } - -#undef QS - - // We post-check interface requirements to save on code size - if (req_if >= 0) { - require_if(args[0], req_if); - } - - return val; - -unknown: - mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); -} -MP_DEFINE_CONST_FUN_OBJ_KW(esp_config_obj, 1, esp_config); - -STATIC const mp_rom_map_elem_t wlan_if_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&esp_active_obj) }, - { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&esp_connect_obj) }, - { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&esp_disconnect_obj) }, - { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&esp_status_obj) }, - { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&esp_scan_obj) }, - { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&esp_isconnected_obj) }, - { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&esp_config_obj) }, - { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&esp_ifconfig_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(wlan_if_locals_dict, wlan_if_locals_dict_table); - -const mp_obj_type_t wlan_if_type = { - { &mp_type_type }, - .name = MP_QSTR_WLAN, - .locals_dict = (mp_obj_t)&wlan_if_locals_dict, -}; - STATIC mp_obj_t esp_phy_mode(size_t n_args, const mp_obj_t *args) { return mp_const_none; } @@ -777,7 +215,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_phy_mode_obj, 0, 1, esp_phy_mode) STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) }, { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&esp_initialize_obj) }, + + #if MICROPY_PY_NETWORK_WLAN { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&get_wlan_obj) }, + #endif #if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 1) && (CONFIG_IDF_TARGET_ESP32) { MP_ROM_QSTR(MP_QSTR_LAN), MP_ROM_PTR(&get_lan_obj) }, @@ -786,6 +227,8 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_phy_mode), MP_ROM_PTR(&esp_phy_mode_obj) }, #if MODNETWORK_INCLUDE_CONSTANTS + + #if MICROPY_PY_NETWORK_WLAN { MP_ROM_QSTR(MP_QSTR_STA_IF), MP_ROM_INT(WIFI_IF_STA)}, { MP_ROM_QSTR(MP_QSTR_AP_IF), MP_ROM_INT(WIFI_IF_AP)}, @@ -804,6 +247,7 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_AUTH_WPA2_WPA3_PSK), MP_ROM_INT(WIFI_AUTH_WPA2_WPA3_PSK) }, #endif { MP_ROM_QSTR(MP_QSTR_AUTH_MAX), MP_ROM_INT(WIFI_AUTH_MAX) }, + #endif #if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 1) && (CONFIG_IDF_TARGET_ESP32) { MP_ROM_QSTR(MP_QSTR_PHY_LAN8720), MP_ROM_INT(PHY_LAN8720) }, diff --git a/ports/esp32/modnetwork.h b/ports/esp32/modnetwork.h index be6aa67068..7bcfa0e6fc 100644 --- a/ports/esp32/modnetwork.h +++ b/ports/esp32/modnetwork.h @@ -26,14 +26,39 @@ #ifndef MICROPY_INCLUDED_ESP32_MODNETWORK_H #define MICROPY_INCLUDED_ESP32_MODNETWORK_H +#include "esp_event.h" + enum { PHY_LAN8720, PHY_IP101, PHY_RTL8201, PHY_DP83848, PHY_KSZ8041 }; enum { ETH_INITIALIZED, ETH_STARTED, ETH_STOPPED, ETH_CONNECTED, ETH_DISCONNECTED, ETH_GOT_IP }; +// Cases similar to ESP8266 user_interface.h +// Error cases are referenced from wifi_err_reason_t in ESP-IDF +enum { + STAT_IDLE = 1000, + STAT_CONNECTING = 1001, + STAT_GOT_IP = 1010, +}; + +typedef struct _wlan_if_obj_t { + mp_obj_base_t base; + int if_id; +} wlan_if_obj_t; + +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(get_wlan_obj); MP_DECLARE_CONST_FUN_OBJ_KW(get_lan_obj); MP_DECLARE_CONST_FUN_OBJ_1(ppp_make_new_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj); MP_DECLARE_CONST_FUN_OBJ_KW(esp_config_obj); +NORETURN void esp_exceptions_helper(esp_err_t e); + +static inline void esp_exceptions(esp_err_t e) { + if (e != ESP_OK) { + esp_exceptions_helper(e); + } +} + void usocket_events_deinit(void); +void network_wlan_event_handler(system_event_t *event); #endif diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 5affbb0692..3d1fc10e12 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -174,6 +174,9 @@ #ifndef MICROPY_PY_MACHINE_I2S #define MICROPY_PY_MACHINE_I2S (1) #endif +#ifndef MICROPY_PY_NETWORK_WLAN +#define MICROPY_PY_NETWORK_WLAN (1) +#endif #ifndef MICROPY_HW_ENABLE_SDCARD #define MICROPY_HW_ENABLE_SDCARD (1) #endif diff --git a/ports/esp32/network_wlan.c b/ports/esp32/network_wlan.c new file mode 100644 index 0000000000..3af7225440 --- /dev/null +++ b/ports/esp32/network_wlan.c @@ -0,0 +1,578 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * Development of the code in this file was sponsored by Microbric Pty Ltd + * and Mnemote Pty Ltd + * + * The MIT License (MIT) + * + * Copyright (c) 2016, 2017 Nick Moore @mnemote + * Copyright (c) 2017 "Eric Poulsen" + * + * Based on esp8266/modnetwork.c which is Copyright (c) 2015 Paul Sokolovsky + * And the ESP IDF example code which is Public Domain / CC0 + * + * 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 + +#include "py/objlist.h" +#include "py/runtime.h" +#include "modnetwork.h" + +#include "esp_wifi.h" +#include "esp_log.h" +#include "mdns.h" + +#if MICROPY_PY_NETWORK_WLAN + +#if (WIFI_MODE_STA & WIFI_MODE_AP != WIFI_MODE_NULL || WIFI_MODE_STA | WIFI_MODE_AP != WIFI_MODE_APSTA) +#error WIFI_MODE_STA and WIFI_MODE_AP are supposed to be bitfields! +#endif + +STATIC const mp_obj_type_t wlan_if_type; +STATIC const wlan_if_obj_t wlan_sta_obj = {{&wlan_if_type}, WIFI_IF_STA}; +STATIC const wlan_if_obj_t wlan_ap_obj = {{&wlan_if_type}, WIFI_IF_AP}; + +// Set to "true" if esp_wifi_start() was called +static bool wifi_started = false; + +// Set to "true" if the STA interface is requested to be connected by the +// user, used for automatic reassociation. +static bool wifi_sta_connect_requested = false; + +// Set to "true" if the STA interface is connected to wifi and has IP address. +static bool wifi_sta_connected = false; + +// Store the current status. 0 means None here, safe to do so as first enum value is WIFI_REASON_UNSPECIFIED=1. +static uint8_t wifi_sta_disconn_reason = 0; + +#if MICROPY_HW_ENABLE_MDNS_QUERIES || MICROPY_HW_ENABLE_MDNS_RESPONDER +// Whether mDNS has been initialised or not +static bool mdns_initialised = false; +#endif + +static uint8_t conf_wifi_sta_reconnects = 0; +static uint8_t wifi_sta_reconnects; + +// This function is called by the system-event task and so runs in a different +// thread to the main MicroPython task. It must not raise any Python exceptions. +void network_wlan_event_handler(system_event_t *event) { + switch (event->event_id) { + case SYSTEM_EVENT_STA_START: + ESP_LOGI("wifi", "STA_START"); + wifi_sta_reconnects = 0; + break; + case SYSTEM_EVENT_STA_CONNECTED: + ESP_LOGI("network", "CONNECTED"); + break; + case SYSTEM_EVENT_STA_GOT_IP: + ESP_LOGI("network", "GOT_IP"); + wifi_sta_connected = true; + wifi_sta_disconn_reason = 0; // Success so clear error. (in case of new error will be replaced anyway) + #if MICROPY_HW_ENABLE_MDNS_QUERIES || MICROPY_HW_ENABLE_MDNS_RESPONDER + if (!mdns_initialised) { + mdns_init(); + #if MICROPY_HW_ENABLE_MDNS_RESPONDER + const char *hostname = NULL; + if (tcpip_adapter_get_hostname(WIFI_IF_STA, &hostname) != ESP_OK || hostname == NULL) { + hostname = "esp32"; + } + mdns_hostname_set(hostname); + mdns_instance_name_set(hostname); + #endif + mdns_initialised = true; + } + #endif + break; + case SYSTEM_EVENT_STA_DISCONNECTED: { + // This is a workaround as ESP32 WiFi libs don't currently + // auto-reassociate. + system_event_sta_disconnected_t *disconn = &event->event_info.disconnected; + char *message = ""; + wifi_sta_disconn_reason = disconn->reason; + switch (disconn->reason) { + case WIFI_REASON_BEACON_TIMEOUT: + // AP has dropped out; try to reconnect. + message = "\nbeacon timeout"; + break; + case WIFI_REASON_NO_AP_FOUND: + // AP may not exist, or it may have momentarily dropped out; try to reconnect. + message = "\nno AP found"; + break; + case WIFI_REASON_AUTH_FAIL: + // Password may be wrong, or it just failed to connect; try to reconnect. + message = "\nauthentication failed"; + break; + default: + // Let other errors through and try to reconnect. + break; + } + ESP_LOGI("wifi", "STA_DISCONNECTED, reason:%d%s", disconn->reason, message); + + wifi_sta_connected = false; + if (wifi_sta_connect_requested) { + wifi_mode_t mode; + if (esp_wifi_get_mode(&mode) != ESP_OK) { + break; + } + if (!(mode & WIFI_MODE_STA)) { + break; + } + if (conf_wifi_sta_reconnects) { + ESP_LOGI("wifi", "reconnect counter=%d, max=%d", + wifi_sta_reconnects, conf_wifi_sta_reconnects); + if (++wifi_sta_reconnects >= conf_wifi_sta_reconnects) { + break; + } + } + esp_err_t e = esp_wifi_connect(); + if (e != ESP_OK) { + ESP_LOGI("wifi", "error attempting to reconnect: 0x%04x", e); + } + } + break; + } + default: + break; + } +} + +STATIC void require_if(mp_obj_t wlan_if, int if_no) { + wlan_if_obj_t *self = MP_OBJ_TO_PTR(wlan_if); + if (self->if_id != if_no) { + mp_raise_msg(&mp_type_OSError, if_no == WIFI_IF_STA ? MP_ERROR_TEXT("STA required") : MP_ERROR_TEXT("AP required")); + } +} + +STATIC mp_obj_t get_wlan(size_t n_args, const mp_obj_t *args) { + static int initialized = 0; + if (!initialized) { + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_LOGD("modnetwork", "Initializing WiFi"); + esp_exceptions(esp_wifi_init(&cfg)); + esp_exceptions(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_LOGD("modnetwork", "Initialized"); + initialized = 1; + } + + int idx = (n_args > 0) ? mp_obj_get_int(args[0]) : WIFI_IF_STA; + if (idx == WIFI_IF_STA) { + return MP_OBJ_FROM_PTR(&wlan_sta_obj); + } else if (idx == WIFI_IF_AP) { + return MP_OBJ_FROM_PTR(&wlan_ap_obj); + } else { + mp_raise_ValueError(MP_ERROR_TEXT("invalid WLAN interface identifier")); + } +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(get_wlan_obj, 0, 1, get_wlan); + +STATIC mp_obj_t network_wlan_active(size_t n_args, const mp_obj_t *args) { + wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); + + wifi_mode_t mode; + if (!wifi_started) { + mode = WIFI_MODE_NULL; + } else { + esp_exceptions(esp_wifi_get_mode(&mode)); + } + + int bit = (self->if_id == WIFI_IF_STA) ? WIFI_MODE_STA : WIFI_MODE_AP; + + if (n_args > 1) { + bool active = mp_obj_is_true(args[1]); + mode = active ? (mode | bit) : (mode & ~bit); + if (mode == WIFI_MODE_NULL) { + if (wifi_started) { + esp_exceptions(esp_wifi_stop()); + wifi_started = false; + } + } else { + esp_exceptions(esp_wifi_set_mode(mode)); + if (!wifi_started) { + esp_exceptions(esp_wifi_start()); + wifi_started = true; + } + } + } + + return (mode & bit) ? mp_const_true : mp_const_false; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_wlan_active_obj, 1, 2, network_wlan_active); + +STATIC mp_obj_t network_wlan_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_ssid, ARG_password, ARG_bssid }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_bssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + wifi_config_t wifi_sta_config = {0}; + + // configure any parameters that are given + if (n_args > 1) { + size_t len; + const char *p; + if (args[ARG_ssid].u_obj != mp_const_none) { + p = mp_obj_str_get_data(args[ARG_ssid].u_obj, &len); + memcpy(wifi_sta_config.sta.ssid, p, MIN(len, sizeof(wifi_sta_config.sta.ssid))); + } + if (args[ARG_password].u_obj != mp_const_none) { + p = mp_obj_str_get_data(args[ARG_password].u_obj, &len); + memcpy(wifi_sta_config.sta.password, p, MIN(len, sizeof(wifi_sta_config.sta.password))); + } + if (args[ARG_bssid].u_obj != mp_const_none) { + p = mp_obj_str_get_data(args[ARG_bssid].u_obj, &len); + if (len != sizeof(wifi_sta_config.sta.bssid)) { + mp_raise_ValueError(NULL); + } + wifi_sta_config.sta.bssid_set = 1; + memcpy(wifi_sta_config.sta.bssid, p, sizeof(wifi_sta_config.sta.bssid)); + } + esp_exceptions(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_sta_config)); + } + + wifi_sta_reconnects = 0; + // connect to the WiFi AP + MP_THREAD_GIL_EXIT(); + esp_exceptions(esp_wifi_connect()); + MP_THREAD_GIL_ENTER(); + wifi_sta_connect_requested = true; + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(network_wlan_connect_obj, 1, network_wlan_connect); + +STATIC mp_obj_t network_wlan_disconnect(mp_obj_t self_in) { + wifi_sta_connect_requested = false; + esp_exceptions(esp_wifi_disconnect()); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_wlan_disconnect_obj, network_wlan_disconnect); + +STATIC mp_obj_t network_wlan_status(size_t n_args, const mp_obj_t *args) { + wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (n_args == 1) { + if (self->if_id == WIFI_IF_STA) { + // Case of no arg is only for the STA interface + if (wifi_sta_connected) { + // Happy path, connected with IP + return MP_OBJ_NEW_SMALL_INT(STAT_GOT_IP); + } else if (wifi_sta_connect_requested + && (conf_wifi_sta_reconnects == 0 + || wifi_sta_reconnects < conf_wifi_sta_reconnects)) { + // No connection or error, but is requested = Still connecting + return MP_OBJ_NEW_SMALL_INT(STAT_CONNECTING); + } else if (wifi_sta_disconn_reason == 0) { + // No activity, No error = Idle + return MP_OBJ_NEW_SMALL_INT(STAT_IDLE); + } else { + // Simply pass the error through from ESP-identifier + return MP_OBJ_NEW_SMALL_INT(wifi_sta_disconn_reason); + } + } + return mp_const_none; + } + + // one argument: return status based on query parameter + switch ((uintptr_t)args[1]) { + case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_stations): { + // return list of connected stations, only if in soft-AP mode + require_if(args[0], WIFI_IF_AP); + wifi_sta_list_t station_list; + esp_exceptions(esp_wifi_ap_get_sta_list(&station_list)); + wifi_sta_info_t *stations = (wifi_sta_info_t *)station_list.sta; + mp_obj_t list = mp_obj_new_list(0, NULL); + for (int i = 0; i < station_list.num; ++i) { + mp_obj_tuple_t *t = mp_obj_new_tuple(1, NULL); + t->items[0] = mp_obj_new_bytes(stations[i].mac, sizeof(stations[i].mac)); + mp_obj_list_append(list, t); + } + return list; + } + case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_rssi): { + // return signal of AP, only in STA mode + require_if(args[0], WIFI_IF_STA); + + wifi_ap_record_t info; + esp_exceptions(esp_wifi_sta_get_ap_info(&info)); + return MP_OBJ_NEW_SMALL_INT(info.rssi); + } + default: + mp_raise_ValueError(MP_ERROR_TEXT("unknown status param")); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_wlan_status_obj, 1, 2, network_wlan_status); + +STATIC mp_obj_t network_wlan_scan(mp_obj_t self_in) { + // check that STA mode is active + wifi_mode_t mode; + esp_exceptions(esp_wifi_get_mode(&mode)); + if ((mode & WIFI_MODE_STA) == 0) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("STA must be active")); + } + + mp_obj_t list = mp_obj_new_list(0, NULL); + wifi_scan_config_t config = { 0 }; + config.show_hidden = true; + MP_THREAD_GIL_EXIT(); + esp_err_t status = esp_wifi_scan_start(&config, 1); + MP_THREAD_GIL_ENTER(); + if (status == 0) { + uint16_t count = 0; + esp_exceptions(esp_wifi_scan_get_ap_num(&count)); + wifi_ap_record_t *wifi_ap_records = calloc(count, sizeof(wifi_ap_record_t)); + esp_exceptions(esp_wifi_scan_get_ap_records(&count, wifi_ap_records)); + for (uint16_t i = 0; i < count; i++) { + mp_obj_tuple_t *t = mp_obj_new_tuple(6, NULL); + uint8_t *x = memchr(wifi_ap_records[i].ssid, 0, sizeof(wifi_ap_records[i].ssid)); + int ssid_len = x ? x - wifi_ap_records[i].ssid : sizeof(wifi_ap_records[i].ssid); + t->items[0] = mp_obj_new_bytes(wifi_ap_records[i].ssid, ssid_len); + t->items[1] = mp_obj_new_bytes(wifi_ap_records[i].bssid, sizeof(wifi_ap_records[i].bssid)); + t->items[2] = MP_OBJ_NEW_SMALL_INT(wifi_ap_records[i].primary); + t->items[3] = MP_OBJ_NEW_SMALL_INT(wifi_ap_records[i].rssi); + t->items[4] = MP_OBJ_NEW_SMALL_INT(wifi_ap_records[i].authmode); + t->items[5] = mp_const_false; // XXX hidden? + mp_obj_list_append(list, MP_OBJ_FROM_PTR(t)); + } + free(wifi_ap_records); + } + return list; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_wlan_scan_obj, network_wlan_scan); + +STATIC mp_obj_t network_wlan_isconnected(mp_obj_t self_in) { + wlan_if_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->if_id == WIFI_IF_STA) { + return mp_obj_new_bool(wifi_sta_connected); + } else { + wifi_sta_list_t sta; + esp_wifi_ap_get_sta_list(&sta); + return mp_obj_new_bool(sta.num != 0); + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_wlan_isconnected_obj, network_wlan_isconnected); + +STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + if (n_args != 1 && kwargs->used != 0) { + mp_raise_TypeError(MP_ERROR_TEXT("either pos or kw args are allowed")); + } + + wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); + + bool is_wifi = self->if_id == WIFI_IF_AP || self->if_id == WIFI_IF_STA; + + wifi_config_t cfg; + if (is_wifi) { + esp_exceptions(esp_wifi_get_config(self->if_id, &cfg)); + } + + #define QS(x) (uintptr_t)MP_OBJ_NEW_QSTR(x) + + if (kwargs->used != 0) { + if (!is_wifi) { + goto unknown; + } + + for (size_t i = 0; i < kwargs->alloc; i++) { + if (mp_map_slot_is_filled(kwargs, i)) { + int req_if = -1; + + switch ((uintptr_t)kwargs->table[i].key) { + case QS(MP_QSTR_mac): { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(kwargs->table[i].value, &bufinfo, MP_BUFFER_READ); + if (bufinfo.len != 6) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid buffer length")); + } + esp_exceptions(esp_wifi_set_mac(self->if_id, bufinfo.buf)); + break; + } + case QS(MP_QSTR_essid): { + req_if = WIFI_IF_AP; + size_t len; + const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len); + len = MIN(len, sizeof(cfg.ap.ssid)); + memcpy(cfg.ap.ssid, s, len); + cfg.ap.ssid_len = len; + break; + } + case QS(MP_QSTR_hidden): { + req_if = WIFI_IF_AP; + cfg.ap.ssid_hidden = mp_obj_is_true(kwargs->table[i].value); + break; + } + case QS(MP_QSTR_authmode): { + req_if = WIFI_IF_AP; + cfg.ap.authmode = mp_obj_get_int(kwargs->table[i].value); + break; + } + case QS(MP_QSTR_password): { + req_if = WIFI_IF_AP; + size_t len; + const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len); + len = MIN(len, sizeof(cfg.ap.password) - 1); + memcpy(cfg.ap.password, s, len); + cfg.ap.password[len] = 0; + break; + } + case QS(MP_QSTR_channel): { + req_if = WIFI_IF_AP; + cfg.ap.channel = mp_obj_get_int(kwargs->table[i].value); + break; + } + case QS(MP_QSTR_dhcp_hostname): { + const char *s = mp_obj_str_get_str(kwargs->table[i].value); + esp_exceptions(tcpip_adapter_set_hostname(self->if_id, s)); + break; + } + case QS(MP_QSTR_max_clients): { + req_if = WIFI_IF_AP; + cfg.ap.max_connection = mp_obj_get_int(kwargs->table[i].value); + break; + } + case QS(MP_QSTR_reconnects): { + int reconnects = mp_obj_get_int(kwargs->table[i].value); + req_if = WIFI_IF_STA; + // parameter reconnects == -1 means to retry forever. + // here means conf_wifi_sta_reconnects == 0 to retry forever. + conf_wifi_sta_reconnects = (reconnects == -1) ? 0 : reconnects + 1; + break; + } + default: + goto unknown; + } + + // We post-check interface requirements to save on code size + if (req_if >= 0) { + require_if(args[0], req_if); + } + } + } + + esp_exceptions(esp_wifi_set_config(self->if_id, &cfg)); + + return mp_const_none; + } + + // Get config + + if (n_args != 2) { + mp_raise_TypeError(MP_ERROR_TEXT("can query only one param")); + } + + int req_if = -1; + mp_obj_t val = mp_const_none; + + switch ((uintptr_t)args[1]) { + case QS(MP_QSTR_mac): { + uint8_t mac[6]; + switch (self->if_id) { + case WIFI_IF_AP: // fallthrough intentional + case WIFI_IF_STA: + esp_exceptions(esp_wifi_get_mac(self->if_id, mac)); + return mp_obj_new_bytes(mac, sizeof(mac)); + default: + goto unknown; + } + } + case QS(MP_QSTR_essid): + switch (self->if_id) { + case WIFI_IF_STA: + val = mp_obj_new_str((char *)cfg.sta.ssid, strlen((char *)cfg.sta.ssid)); + break; + case WIFI_IF_AP: + val = mp_obj_new_str((char *)cfg.ap.ssid, cfg.ap.ssid_len); + break; + default: + req_if = WIFI_IF_AP; + } + break; + case QS(MP_QSTR_hidden): + req_if = WIFI_IF_AP; + val = mp_obj_new_bool(cfg.ap.ssid_hidden); + break; + case QS(MP_QSTR_authmode): + req_if = WIFI_IF_AP; + val = MP_OBJ_NEW_SMALL_INT(cfg.ap.authmode); + break; + case QS(MP_QSTR_channel): + req_if = WIFI_IF_AP; + val = MP_OBJ_NEW_SMALL_INT(cfg.ap.channel); + break; + case QS(MP_QSTR_dhcp_hostname): { + const char *s; + esp_exceptions(tcpip_adapter_get_hostname(self->if_id, &s)); + val = mp_obj_new_str(s, strlen(s)); + break; + } + case QS(MP_QSTR_max_clients): { + val = MP_OBJ_NEW_SMALL_INT(cfg.ap.max_connection); + break; + } + case QS(MP_QSTR_reconnects): + req_if = WIFI_IF_STA; + int rec = conf_wifi_sta_reconnects - 1; + val = MP_OBJ_NEW_SMALL_INT(rec); + break; + default: + goto unknown; + } + +#undef QS + + // We post-check interface requirements to save on code size + if (req_if >= 0) { + require_if(args[0], req_if); + } + + return val; + +unknown: + mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); +} +MP_DEFINE_CONST_FUN_OBJ_KW(network_wlan_config_obj, 1, network_wlan_config); + +STATIC const mp_rom_map_elem_t wlan_if_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&network_wlan_active_obj) }, + { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&network_wlan_connect_obj) }, + { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&network_wlan_disconnect_obj) }, + { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_wlan_status_obj) }, + { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&network_wlan_scan_obj) }, + { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&network_wlan_isconnected_obj) }, + { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_wlan_config_obj) }, + { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&esp_ifconfig_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(wlan_if_locals_dict, wlan_if_locals_dict_table); + +STATIC const mp_obj_type_t wlan_if_type = { + { &mp_type_type }, + .name = MP_QSTR_WLAN, + .locals_dict = (mp_obj_t)&wlan_if_locals_dict, +}; + +#endif // MICROPY_PY_NETWORK_WLAN From ea880d5674b987aa3d3b196d2e6baadcb69c4c06 Mon Sep 17 00:00:00 2001 From: stijn Date: Tue, 21 Sep 2021 12:00:01 +0200 Subject: [PATCH 073/335] py/builtinimport: Forward all debug printing to MICROPY_DEBUG_PRINTER. --- py/builtinimport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py/builtinimport.c b/py/builtinimport.c index cdee5e4070..08921f873b 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -248,7 +248,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { DEBUG_printf("__import__:\n"); for (size_t i = 0; i < n_args; i++) { DEBUG_printf(" "); - mp_obj_print(args[i], PRINT_REPR); + mp_obj_print_helper(MICROPY_DEBUG_PRINTER, args[i], PRINT_REPR); DEBUG_printf("\n"); } #endif @@ -292,7 +292,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { #if DEBUG_PRINT DEBUG_printf("Current module/package: "); - mp_obj_print(this_name_q, PRINT_REPR); + mp_obj_print_helper(MICROPY_DEBUG_PRINTER, this_name_q, PRINT_REPR); DEBUG_printf(", is_package: %d", is_pkg); DEBUG_printf("\n"); #endif From d42cba0d22cac812cc5a12f4670010b45932eafa Mon Sep 17 00:00:00 2001 From: stijn Date: Tue, 21 Sep 2021 12:42:39 +0200 Subject: [PATCH 074/335] extmod/moduplatform: Improve implementation for PC ports. Fix identification of 32/64 bit and of the Windows platform and add a platform string mimicking CPython for the latter. --- extmod/moduplatform.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/extmod/moduplatform.c b/extmod/moduplatform.c index 06bb9d5ce8..149df7c56f 100644 --- a/extmod/moduplatform.c +++ b/extmod/moduplatform.c @@ -40,8 +40,10 @@ #if defined(__ARM_ARCH) #define PLATFORM_ARCH "arm" -#elif defined(__x86_64__) +#elif defined(__x86_64__) || defined(_WIN64) #define PLATFORM_ARCH "x86_64" +#elif defined(__i386__) || defined(_M_IX86) +#define PLATFORM_ARCH "x86" #else #define PLATFORM_ARCH "" #endif @@ -58,6 +60,16 @@ MP_STRINGIFY((__ARMCC_VERSION / 1000000)) "." \ MP_STRINGIFY((__ARMCC_VERSION / 10000 % 100)) "." \ MP_STRINGIFY((__ARMCC_VERSION % 10000)) +#elif defined(_MSC_VER) +#if defined(_WIN64) +#define COMPILER_BITS "64 bit" +#elif defined(_M_IX86) +#define COMPILER_BITS "32 bit" +#else +#define COMPILER_BITS "" +#endif +#define PLATFORM_COMPILER \ + "MSC v." MP_STRINGIFY(_MSC_VER) " " COMPILER_BITS #else #define PLATFORM_COMPILER "" #endif @@ -81,7 +93,7 @@ #define PLATFORM_SYSTEM "Unix" #elif defined(__CYGWIN__) #define PLATFORM_SYSTEM "Cygwin" -#elif defined(__WIN32__) +#elif defined(_WIN32) #define PLATFORM_SYSTEM "Windows" #else #define PLATFORM_SYSTEM "MicroPython" @@ -95,6 +107,10 @@ #define MICROPY_HW_MCU_NAME "" #endif +#ifndef MICROPY_HAL_VERSION +#define MICROPY_HAL_VERSION "" +#endif + STATIC const MP_DEFINE_STR_OBJ(info_platform_obj, PLATFORM_SYSTEM "-" MICROPY_VERSION_STRING "-HAL" \ MICROPY_HAL_VERSION "-" PLATFORM_ARCH "-with-" PLATFORM_LIBC_LIB "" PLATFORM_LIBC_VER); STATIC const MP_DEFINE_STR_OBJ(info_python_compiler_obj, PLATFORM_COMPILER); From baa5a76fc09855dd0899077c09d72ba5d8681442 Mon Sep 17 00:00:00 2001 From: NitiKaur Date: Wed, 7 Jul 2021 02:40:32 +0530 Subject: [PATCH 075/335] docs/rp2: Add reference for PIO assembly instructions, and PIO tutorial. --- docs/library/rp2.rst | 152 ++++++++++++++++++++++++++++++++++++ docs/rp2/tutorial/intro.rst | 5 ++ docs/rp2/tutorial/pio.rst | 123 +++++++++++++++++++++++++++++ 3 files changed, 280 insertions(+) create mode 100644 docs/rp2/tutorial/pio.rst diff --git a/docs/library/rp2.rst b/docs/library/rp2.rst index 5d168bce20..43143fe089 100644 --- a/docs/library/rp2.rst +++ b/docs/library/rp2.rst @@ -72,6 +72,158 @@ For running PIO programs, see :class:`rp2.StateMachine`. an error assembling a PIO program. +PIO assembly language instructions +---------------------------------- + +PIO state machines are programmed in a custom assembly language with nine core +PIO-machine instructions. In MicroPython, PIO assembly routines are written as +a Python function with the decorator ``@rp2.asm_pio()``, and they use Python +syntax. Such routines support standard Python variables and arithmetic, as well +as the following custom functions that encode PIO instructions and direct the +assembler. See sec 3.4 of the RP2040 datasheet for further details. + +wrap_target() + Specify the location where execution continues after program wrapping. + By default this is the start of the PIO routine. + +wrap() + Specify the location where the program finishes and wraps around. + If this directive is not used then it is added automatically at the end of + the PIO routine. Wrapping does not cost any execution cycles. + +label(label) + Define a label called *label* at the current location. *label* can be a + string or integer. + +word(instr, label=None) + Insert an arbitrary 16-bit word in the assembled output. + + - *instr*: the 16-bit value + - *label*: if given, look up the label and logical-or the label's value with + *instr* + +jmp(...) + This instruction takes two forms: + + jmp(label) + - *label*: label to jump to unconditionally + + jmp(cond, label) + - *cond*: the condition to check, one of: + + - ``not_x``, ``not_y``: true if register is zero + - ``x_dec``, ``y_dec``: true if register is non-zero, and do post + decrement + - ``x_not_y``: true if X is not equal to Y + - ``pin``: true if the input pin is set + - ``not_osre``: true if OSR is not empty (hasn't reached its + threshold) + + - *label*: label to jump to if condition is true + +wait(polarity, src, index) + Block, waiting for high/low on a pin or IRQ line. + + - *polarity*: 0 or 1, whether to wait for a low or high value + - *src*: one of: ``gpio`` (absolute pin), ``pin`` (pin relative to + StateMachine's ``in_base`` argument), ``irq`` + - *index*: 0-31, the index for *src* + +in_(src, bit_count) + Shift data in from *src* to ISR. + + - *src*: one of: ``pins``, ``x``, ``y``, ``null``, ``isr``, ``osr`` + - *bit_count*: number of bits to shift in (1-32) + +out(dest, bit_count) + Shift data out from OSR to *dest*. + + - *dest*: one of: ``pins``, ``x``, ``y``, ``pindirs``, ``pc``, ``isr``, + ``exec`` + - *bit_count*: number of bits to shift out (1-32) + +push(...) + Push ISR to the RX FIFO, then clear ISR to zero. + This instruction takes the following forms: + + - push() + - push(block) + - push(noblock) + - push(iffull) + - push(iffull, block) + - push(iffull, noblock) + + If ``block`` is used then the instruction stalls if the RX FIFO is full. + The default is to block. If ``iffull`` is used then it only pushes if the + input shift count has reached its threshold. + +pull(...) + Pull from the TX FIFO into OSR. + This instruction takes the following forms: + + - pull() + - pull(block) + - pull(noblock) + - pull(ifempty) + - pull(ifempty, block) + - pull(ifempty, noblock) + + If ``block`` is used then the instruction stalls if the TX FIFO is empty. + The default is to block. If ``ifempty`` is used then it only pulls if the + output shift count has reached its threshold. + +mov(dest, src) + Move into *dest* the value from *src*. + + - *dest*: one of: ``pins``, ``x``, ``y``, ``exec``, ``pc``, ``isr``, ``osr`` + - *src*: one of: ``pins``, ``x``, ``y``, ``null``, ``status``, ``isr``, + ``osr``; this argument can be optionally modified by wrapping it in + ``invert()`` or ``reverse()`` (but not both together) + +irq(...) + Set or clear an IRQ flag. + This instruction takes two forms: + + irq(index) + - *index*: 0-7, or ``rel(0)`` to ``rel(7)`` + + irq(mode, index) + - *mode*: one of: ``block``, ``clear`` + - *index*: 0-7, or ``rel(0)`` to ``rel(7)`` + + If ``block`` is used then the instruction stalls until the flag is cleared + by another entity. If ``clear`` is used then the flag is cleared instead of + being set. Relative IRQ indices add the state machine ID to the IRQ index + with modulo-4 addition. IRQs 0-3 are visible from to the processor, 4-7 are + internal to the state machines. + +set(dest, data) + Set *dest* with the value *data*. + + - *dest*: ``pins``, ``x``, ``y``, ``pindirs`` + - *data*: value (0-31) + +nop() + This is a pseudoinstruction that assembles to ``mov(y, y)`` and has no side + effect. + +.side(value) + This is a modifier which can be applied to any instruction, and is used to + control side-set pin values. + + - *value*: the value (bits) to output on the side-set pins + +.delay(value) + This is a modifier which can be applied to any instruction, and specifies + how many cycles to delay for after the instruction executes. + + - *value*: cycles to delay, 0-31 (maximum value reduced if side-set pins are + used) + +[value] + This is a modifier and is equivalent to ``.delay(value)``. + + Classes ------- diff --git a/docs/rp2/tutorial/intro.rst b/docs/rp2/tutorial/intro.rst index 5609ab3798..69c3e6b0a5 100644 --- a/docs/rp2/tutorial/intro.rst +++ b/docs/rp2/tutorial/intro.rst @@ -4,3 +4,8 @@ Getting started with MicroPython on the RP2xxx ============================================== Let's get started! + +.. toctree:: + :maxdepth: 1 + + pio.rst diff --git a/docs/rp2/tutorial/pio.rst b/docs/rp2/tutorial/pio.rst new file mode 100644 index 0000000000..9981aed832 --- /dev/null +++ b/docs/rp2/tutorial/pio.rst @@ -0,0 +1,123 @@ +Programmable IO +=============== + +The RP2040 has hardware support for standard communication protocols like I2C, +SPI and UART. For protocols where there is no hardware support, or where there +is a requirement of custom I/O behaviour, Programmable Input Output (PIO) comes +into play. Also, some MicroPython applications make use of a technique called +bit banging in which pins are rapidly turned on and off to transmit data. This +can make the entire process slow as the processor concentrates on bit banging +rather than executing other logic. However, PIO allows bit banging to happen +in the background while the CPU is executing the main work. + +Along with the two central Cortex-M0+ processing cores, the RP2040 has two PIO +blocks each of which has four independent state machines. These state machines +can transfer data to/from other entities using First-In-First-Out (FIFO) buffers, +which allow the state machine and main processor to work independently yet also +synchronise their data. Each FIFO has four words (each of 32 bits) which can be +linked to the DMA to transfer larger amounts of data. + +All PIO instructions follow a common pattern:: + + .side() [] + +The side-set ``.side(...)`` and delay ``[...]`` parts are both optional, and if +specified allow the instruction to perform more than one operation. This keeps +PIO programs small and efficient. + +There are nine instructions which perform the following tasks: + +- ``jmp()`` transfers control to a different part of the code +- ``wait()`` pauses until a particular action happens +- ``in_()`` shifts the bits from a source (scratch register or set of pins) to the + input shift register +- ``out()`` shifts the bits from the output shift register to a destination +- ``push()`` sends data to the RX FIFO +- ``pull()`` receives data from the TX FIFO +- ``mov()`` moves data from a source to a destination +- ``irq()`` sets or clears an IRQ flag +- ``set()`` writes a literal value to a destination + +The instruction modifiers are: + +- ``.side()`` sets the side-set pins at the start of the instruction +- ``[]`` delays for a certain number of cycles after execution of the instruction + +There are also directives: + +- ``wrap_target()`` specifies where the program execution will get continued from +- ``wrap()`` specifies the instruction where the control flow of the program will + get wrapped from +- ``label()`` sets a label for use with ``jmp()`` instructions +- ``word()`` emits a raw 16-bit value which acts as an instruction in the program + +An example +---------- + +Take the ``pio_1hz.py`` example for a simple understanding of how to use the PIO +and state machines. Below is the code for reference. + +.. code-block:: python3 + + # Example using PIO to blink an LED and raise an IRQ at 1Hz. + + import time + from machine import Pin + import rp2 + + + @rp2.asm_pio(set_init=rp2.PIO.OUT_LOW) + def blink_1hz(): + # Cycles: 1 + 1 + 6 + 32 * (30 + 1) = 1000 + irq(rel(0)) + set(pins, 1) + set(x, 31) [5] + label("delay_high") + nop() [29] + jmp(x_dec, "delay_high") + + # Cycles: 1 + 7 + 32 * (30 + 1) = 1000 + set(pins, 0) + set(x, 31) [6] + label("delay_low") + nop() [29] + jmp(x_dec, "delay_low") + + + # Create the StateMachine with the blink_1hz program, outputting on Pin(25). + sm = rp2.StateMachine(0, blink_1hz, freq=2000, set_base=Pin(25)) + + # Set the IRQ handler to print the millisecond timestamp. + sm.irq(lambda p: print(time.ticks_ms())) + + # Start the StateMachine. + sm.active(1) + +This creates an instance of class :class:`rp2.StateMachine` which runs the +``blink_1hz`` program at 2000Hz, and connects to pin 25. The ``blink_1hz`` +program uses the PIO to blink an LED connected to this pin at 1Hz, and also +raises an IRQ as the LED turns on. This IRQ then calls the ``lambda`` function +which prints out a millisecond timestamp. + +The ``blink_1hz`` program is a PIO assembler routine. It connects to a single +pin which is configured as an output and starts out low. The instructions do +the following: + +- ``irq(rel(0))`` raises the IRQ associated with the state machine. +- The LED is turned on via the ``set(pins, 1)`` instruction. +- The value 31 is put into register X, and then there is a delay for 5 more + cycles, specified by the ``[5]``. +- The ``nop() [29]`` instruction waits for 30 cycles. +- The ``jmp(x_dec, "delay_high")`` will keep looping to the ``delay_high`` label + as long as the register X is non-zero, and will also post-decrement X. Since + X starts with the value 31 this jump will happen 31 times, so the ``nop() [29]`` + runs 32 times in total (note there is also one instruction cycle taken by the + ``jmp`` for each of these 32 loops). +- ``set(pins, 0)`` will turn the LED off by setting pin 25 low. +- Another 32 loops of ``nop() [29]`` and ``jmp(...)`` will execute. +- Because ``wrap_target()`` and ``wrap()`` are not specified, their default will + be used and execution of the program will wrap around from the bottom to the + top. This wrapping does not cost any execution cycles. + +The entire routine takes exactly 2000 cycles of the state machine. Setting the +frequency of the state machine to 2000Hz makes the LED blink at 1Hz. From c42c1c8718fb20b5ce41aac9c88e77e2b4c8c9b6 Mon Sep 17 00:00:00 2001 From: NitiKaur Date: Thu, 5 Aug 2021 00:38:33 +0530 Subject: [PATCH 076/335] docs/library/random.rst: Document the random module. --- docs/library/index.rst | 1 + docs/library/random.rst | 82 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 docs/library/random.rst diff --git a/docs/library/index.rst b/docs/library/index.rst index 070e9f9667..2b9af5b930 100644 --- a/docs/library/index.rst +++ b/docs/library/index.rst @@ -65,6 +65,7 @@ library. json.rst math.rst os.rst + random.rst re.rst select.rst socket.rst diff --git a/docs/library/random.rst b/docs/library/random.rst new file mode 100644 index 0000000000..dd8b47c80f --- /dev/null +++ b/docs/library/random.rst @@ -0,0 +1,82 @@ +:mod:`random` -- generate random numbers +======================================== + +.. module:: random + :synopsis: random numbers + +This module implements a pseudo-random number generator (PRNG). + +|see_cpython_module| :mod:`python:random` . + +.. note:: + + The following notation is used for intervals: + + - () are open interval brackets and do not include their endpoints. + For example, (0, 1) means greater than 0 and less than 1. + In set notation: (0, 1) = {x | 0 < x < 1}. + + - [] are closed interval brackets which include all their limit points. + For example, [0, 1] means greater than or equal to 0 and less than + or equal to 1. + In set notation: [0, 1] = {x | 0 <= x <= 1}. + +.. note:: + + The :func:`randrange`, :func:`randint` and :func:`choice` functions are only + available if the ``MICROPY_PY_URANDOM_EXTRA_FUNCS`` configuration option is + enabled. + + +Functions for integers +---------------------- + +.. function:: getrandbits(n) + + Return an integer with *n* random bits (0 <= n <= 32). + +.. function:: randint(a, b) + + Return a random integer in the range [*a*, *b*]. + +.. function:: randrange(stop) + randrange(start, stop) + randrange(start, stop[, step]) + + The first form returns a random integer from the range [0, *stop*). + The second form returns a random integer from the range [*start*, *stop*). + The third form returns a random integer from the range [*start*, *stop*) in + steps of *step*. For instance, calling ``randrange(1, 10, 2)`` will + return odd numbers between 1 and 9 inclusive. + + +Functions for floats +-------------------- + +.. function:: random() + + Return a random floating point number in the range [0.0, 1.0). + +.. function:: uniform(a, b) + + Return a random floating point number N such that *a* <= N <= *b* for *a* <= *b*, + and *b* <= N <= *a* for *b* < *a*. + + +Other Functions +--------------- + +.. function:: seed(n=None, /) + + Initialise the random number generator module with the seed *n* which should + be an integer. When no argument (or ``None``) is passed in it will (if + supported by the port) initialise the PRNG with a true random number + (usually a hardware generated random number). + + The ``None`` case only works if ``MICROPY_PY_URANDOM_SEED_INIT_FUNC`` is + enabled by the port, otherwise it raises ``ValueError``. + +.. function:: choice(sequence) + + Chooses and returns one item at random from *sequence* (tuple, list or + any object that supports the subscript operation). From 135339ce3ab8a50ae5160d1d84062475baeb1798 Mon Sep 17 00:00:00 2001 From: NitiKaur Date: Thu, 5 Aug 2021 08:57:22 +0530 Subject: [PATCH 077/335] docs/reference/mpremote.rst: Add docs for mpremote. --- docs/reference/index.rst | 1 + docs/reference/mpremote.rst | 196 ++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 docs/reference/mpremote.rst diff --git a/docs/reference/index.rst b/docs/reference/index.rst index 8cd5f03df4..853bbe7e36 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -21,6 +21,7 @@ implementation and the best practices to use them. glossary.rst repl.rst + mpremote.rst mpyfiles.rst isr_rules.rst speed_python.rst diff --git a/docs/reference/mpremote.rst b/docs/reference/mpremote.rst new file mode 100644 index 0000000000..7a7d787a5a --- /dev/null +++ b/docs/reference/mpremote.rst @@ -0,0 +1,196 @@ +MicroPython remote control: mpremote +==================================== + +The ``mpremote`` command line tool provides an integrated set of utilities to +remotely interact with and automate a MicroPython device over a serial +connection. + +To use mpremote install it via ``pip``: + +.. code-block:: bash + + $ pip install mpremote + +The simplest way to use this tool is just by invoking it without any arguments: + +.. code-block:: bash + + mpremote + +This command automatically detects and connects to the first available serial +device and provides an interactive REPL. Serial ports are opened in exclusive +mode, so running a second (or third, etc) instance of ``mpremote`` will connect +to subsequent serial devices, if any are available. + + +Commands +-------- + +For REPL access, running ``mpremote`` without any arguments is usually all that +is needed. ``mpremote`` also supports a set of commands given at the command +line which will perform various actions on remote MicroPython devices. + +The full list of supported commands are: + +- connect to a specified device via a device-name shortcut: + + .. code-block:: bash + + $ mpremote + +- connect to specified device via name: + + .. code-block:: bash + + $ mpremote connect + + ```` may be one of: + + - ``list``: list available devices + - ``auto``: connect to the first available device + - ``id:``: connect to the device with USB serial number + ```` (the second entry in the output from the ``connect list`` + command) + - ``port:``: connect to the device with the given path + - any valid device name/path, to connect to that device + +- disconnect current device: + + .. code-block:: bash + + $ mpremote disconnect + +- enter the REPL on the connected device: + + .. code-block:: bash + + $ mpremote repl [options] + + Options are: + + - ``--capture ``, to capture output of the REPL session to the given + file + - ``--inject-code ``, to specify characters to inject at the REPL when + Ctrl-J is pressed + - ``--inject-file ``, to specify a file to inject at the REPL when + Ctrl-K is pressed + +- evaluate and print the result of a Python expression: + + .. code-block:: bash + + $ mpremote eval + +- execute the given Python code: + + .. code-block:: bash + + $ mpremote exec + +- run a script from the local filesystem: + + .. code-block:: bash + + $ mpremote run + +- execute filesystem commands on the device: + + .. code-block:: bash + + $ mpremote fs + + ```` may be: + + - ``cat `` to show the contents of a file or files on the device + - ``ls`` to list the current directory + - ``ls `` to list the given directories + - ``cp [-r] `` to copy files; use ":" as a prefix to specify + a file on the device + - ``rm `` to remove files on the device + - ``mkdir `` to create directories on the device + - ``rmdir `` to remove directories on the device + +- mount the local directory on the remote device: + + .. code-block:: bash + + $ mpremote mount + +Multiple commands can be specified and they will be run sequentially. +Connection and disconnection will be done automatically at the start and end of +the execution of the tool, if such commands are not explicitly given. Automatic +connection will search for the first available serial device. If no action is +specified then the REPL will be entered. + +Shortcuts +--------- + +Shortcuts can be defined using the macro system. Built-in shortcuts are:: + +- ``devs``: list available devices (shortcut for ``connect list``) + +- ``a0``, ``a1``, ``a2``, ``a3``: connect to /dev/ttyACM? + +- ``u0``, ``u1``, ``u2``, ``u3``: connect to /dev/ttyUSB? + +- ``c0``, ``c1``, ``c2``, ``c3``: connect to COM? + +- ``cat``, ``ls``, ``cp``, ``rm``, ``mkdir``, ``rmdir``, ``df``: filesystem + commands + +- ``reset``: reset the device + +- ``bootloader``: make the device enter its bootloader + +Any user configuration, including user-defined shortcuts, can be placed in the file +``.config/mpremote/config.py``. For example: + +.. code-block:: python3 + + commands = { + "c33": "connect id:334D335C3138", + "bl": "bootloader", + "double x=4": "eval x*2", # x is an argument, with default 4 + "wl_scan": ["exec", """ + import network + wl = network.WLAN() + wl.active(1) + for ap in wl.scan(): + print(ap) + """,], + "test": ["mount", ".", "exec", "import test"], + } + + +Examples +-------- + +.. code-block:: bash + + mpremote + + mpremote a1 + + mpremote connect /dev/ttyUSB0 repl + + mpremote ls + + mpremote a1 ls + + mpremote exec "import micropython; micropython.mem_info()" + + mpremote eval 1/2 eval 3/4 + + mpremote mount . + + mpremote mount . exec "import local_script" + + mpremote ls + + mpremote cat boot.py + + mpremote cp :main.py . + + mpremote cp main.py : + + mpremote cp -r dir/ : From e87b2e8bfa71a09f0fe585fc0127e9fa42b68f19 Mon Sep 17 00:00:00 2001 From: NitiKaur Date: Thu, 5 Aug 2021 09:42:30 +0530 Subject: [PATCH 078/335] docs/reference/manifest.rst: Add docs for manifest.py files. --- docs/reference/index.rst | 1 + docs/reference/manifest.rst | 145 ++++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 docs/reference/manifest.rst diff --git a/docs/reference/index.rst b/docs/reference/index.rst index 853bbe7e36..8ac92c22eb 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -26,6 +26,7 @@ implementation and the best practices to use them. isr_rules.rst speed_python.rst constrained.rst + manifest.rst packages.rst asm_thumb2_index.rst filesystem.rst diff --git a/docs/reference/manifest.rst b/docs/reference/manifest.rst new file mode 100644 index 0000000000..078c4c7cf6 --- /dev/null +++ b/docs/reference/manifest.rst @@ -0,0 +1,145 @@ +MicroPython manifest files +========================== + +When building firmware for a device the following components are included in +the compilation process: + +- the core MicroPython virtual machine and runtime +- port-specific system code and drivers to interface with the + microcontroller/device that the firmware is targeting +- standard built-in modules, like ``sys`` +- extended built-in modules, like ``json`` and ``machine`` +- extra modules written in C/C++ +- extra modules written in Python + +All the modules included in the firmware are available via ``import`` from +Python code. The extra modules written in Python that are included in a build +(the last point above) are called *frozen modules*, and are specified by a +``manifest.py`` file. Changing this manifest requires rebuilding the firmware. + +It's also possible to add additional modules to the filesystem of the device +once it is up and running. Adding and removing modules to/from the filesystem +does not require rebuilding the firmware so is a simpler process than rebuilding +firmware. The benefit of using a manifest is that frozen modules are more +efficient: they are faster to import and take up less RAM once imported. + +MicroPython manifest files are Python files and can contain arbitrary Python +code. There are also a set of commands (predefined functions) which are used +to specify the Python source files to include. These commands are described +below. + +Freezing source code +-------------------- + +.. function:: freeze(path, script=None, opt=0) + + Freeze the input specified by *path*, automatically determining its type. A + ``.py`` script will be compiled to a ``.mpy`` first then frozen, and a + ``.mpy`` file will be frozen directly. + + *path* must be a directory, which is the base directory to begin searching + for files. When importing the resulting frozen modules, the name of the + module will start after *path*, i.e. *path* is excluded from the module + name. + + If *path* is relative, it is resolved to the current ``manifest.py``. Use + ``$(MPY_DIR)``, ``$(MPY_LIB_DIR)``, ``$(PORT_DIR)``, ``$(BOARD_DIR)`` if you + need to access specific paths. + + If *script* is None, all files in *path* will be frozen. + + If *script* is an iterable then ``freeze()`` is called on all items of the + iterable (with the same *path* and *opt* passed through). + + If *script* is a string then it specifies the file or directory to freeze, + and can include extra directories before the file or last directory. The + file or directory will be searched for in *path*. If *script* is a + directory then all files in that directory will be frozen. + + *opt* is the optimisation level to pass to mpy-cross when compiling ``.py`` + to ``.mpy``. + +.. function:: freeze_as_str(path) + + Freeze the given *path* and all ``.py`` scripts within it as a string, which + will be compiled upon import. + +.. function:: freeze_as_mpy(path, script=None, opt=0) + + Freeze the input by first compiling the ``.py`` scripts to ``.mpy`` files, + then freezing the resulting ``.mpy`` files. See ``freeze()`` for further + details on the arguments. + +.. function:: freeze_mpy(path, script=None, opt=0) + + Freeze the input, which must be ``.mpy`` files that are frozen directly. + See ``freeze()`` for further details on the arguments. + + +Including other manifest files +------------------------------ + +.. function:: include(manifest, **kwargs) + + Include another manifest. + + The *manifest* argument can be a string (filename) or an iterable of + strings. + + Relative paths are resolved with respect to the current manifest file. + + Optional *kwargs* can be provided which will be available to the included + script via the *options* variable. + + For example: + + .. code-block:: python3 + + include("path.py", extra_features=True) + + then in path.py: + + .. code-block:: python3 + + options.defaults(standard_features=True) + # freeze minimal modules. + if options.standard_features: + # freeze standard modules. + if options.extra_features: + # freeze extra modules. + + +Examples +-------- + +To freeze a single file which is available as ``import mydriver``, use: + +.. code-block:: python3 + + freeze(".", "mydriver.py") + +To freeze a set of files which are available as ``import test1`` and +``import test2``, and which are compiled with optimisation level 3, use: + +.. code-block:: python3 + + freeze("/path/to/tests", ("test1.py", "test2.py"), opt=3) + +To freeze a module which can be imported as ``import mymodule``, use: + +.. code-block:: python3 + + freeze( + "../relative/path", + ( + "mymodule/__init__.py", + "mymodule/core.py", + "mymodule/extra.py", + ), + ) + +To include a manifest from the MicroPython repository, use: + +.. code-block:: python3 + + include("$(MPY_DIR)/extmod/uasyncio/manifest.py") From 763042a28701ace91e63b263dc0d8faa6b8871a9 Mon Sep 17 00:00:00 2001 From: NitiKaur Date: Thu, 12 Aug 2021 14:21:02 +0530 Subject: [PATCH 079/335] docs/library/stm.rst: Document the stm module. --- docs/library/index.rst | 1 + docs/library/stm.rst | 104 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 docs/library/stm.rst diff --git a/docs/library/index.rst b/docs/library/index.rst index 2b9af5b930..2b1d6b9651 100644 --- a/docs/library/index.rst +++ b/docs/library/index.rst @@ -120,6 +120,7 @@ The following libraries are specific to the pyboard. :maxdepth: 2 pyb.rst + stm.rst lcd160cr.rst diff --git a/docs/library/stm.rst b/docs/library/stm.rst new file mode 100644 index 0000000000..a181d6044c --- /dev/null +++ b/docs/library/stm.rst @@ -0,0 +1,104 @@ +.. currentmodule:: stm + +:mod:`stm` --- functionality specific to STM32 MCUs +=================================================== + +.. module:: stm + :synopsis: functionality specific to STM32 MCUs + +This module provides functionality specific to STM32 microcontrollers, including +direct access to peripheral registers. + +Memory access +------------- + +The module exposes three objects used for raw memory access. + +.. data:: mem8 + + Read/write 8 bits of memory. + +.. data:: mem16 + + Read/write 16 bits of memory. + +.. data:: mem32 + + Read/write 32 bits of memory. + +Use subscript notation ``[...]`` to index these objects with the address of +interest. + +These memory objects can be used in combination with the peripheral register +constants to read and write registers of the MCU hardware peripherals, as well +as all other areas of address space. + + +Peripheral register constants +----------------------------- + +The module defines constants for registers which are generated from CMSIS header +files, and the constants available depend on the microcontroller series that is +being compiled for. Examples of some constants include: + +.. data:: GPIOA + + Base address of the GPIOA peripheral. + +.. data:: GPIOB + + Base address of the GPIOB peripheral. + +.. data:: GPIO_BSRR + + Offset of the GPIO bit set/reset register. + +.. data:: GPIO_IDR + + Offset of the GPIO input data register. + +.. data:: GPIO_ODR + + Offset of the GPIO output data register. + +Constants that are named after a peripheral, like ``GPIOA``, are the absolute +address of that peripheral. Constants that have a prefix which is the name of a +peripheral, like ``GPIO_BSRR``, are relative offsets of the register. Accessing +peripheral registers requires adding the absolute base address of the peripheral +and the relative register offset. For example ``GPIOA + GPIO_BSRR`` is the +full, absolute address of the ``GPIOA->BSRR`` register. + +Example use: + +.. code-block:: python3 + + # set PA2 high + stm.mem32[stm.GPIOA + stm.GPIO_BSRR] = 1 << 2 + + # read PA3 + value = (stm.mem32[stm.GPIOA + stm.GPIO_IDR] >> 3) & 1 + + +Functions specific to STM32WBxx MCUs +------------------------------------ + +These functions are available on STM32WBxx microcontrollers, and interact with +the second CPU, the RF core. + +.. function:: rfcore_status() + + Returns the status of the second CPU as an integer (the first word of device + info table). + +.. function:: rfcore_fw_version(id) + + Get the version of the firmware running on the second CPU. Pass in 0 for + *id* to get the FUS version, and 1 to get the WS version. + + Returns a 5-tuple with the full version number. + +.. function:: rfcore_sys_hci(ogf, ocf, data, timeout_ms=0) + + Execute a HCI command on the SYS channel. The execution is synchronous. + + Returns a bytes object with the result of the SYS command. From 4c9e17e0a16266523e5d89640f756a1a0ad2d8e3 Mon Sep 17 00:00:00 2001 From: NitiKaur Date: Thu, 26 Aug 2021 08:49:10 +0530 Subject: [PATCH 080/335] docs/esp32/tutorial: Add an example of peripheral control via regs. --- docs/esp32/tutorial/index.rst | 1 + docs/esp32/tutorial/peripheral_access.rst | 44 +++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 docs/esp32/tutorial/peripheral_access.rst diff --git a/docs/esp32/tutorial/index.rst b/docs/esp32/tutorial/index.rst index e9cfd9db10..c6242d731f 100644 --- a/docs/esp32/tutorial/index.rst +++ b/docs/esp32/tutorial/index.rst @@ -20,3 +20,4 @@ to ``__. intro.rst pwm.rst + peripheral_access.rst diff --git a/docs/esp32/tutorial/peripheral_access.rst b/docs/esp32/tutorial/peripheral_access.rst new file mode 100644 index 0000000000..3304c341de --- /dev/null +++ b/docs/esp32/tutorial/peripheral_access.rst @@ -0,0 +1,44 @@ +Accessing peripherals directly via registers +============================================ + +The ESP32's peripherals can be controlled via direct register reads and writes. +This requires reading the datasheet to know what registers to use and what +values to write to them. The following example shows how to turn on and change +the prescaler of the MCPWM0 peripheral. + +.. code-block:: python3 + + from micropython import const + from machine import mem32 + + # Define the register addresses that will be used. + DR_REG_DPORT_BASE = const(0x3FF00000) + DPORT_PERIP_CLK_EN_REG = const(DR_REG_DPORT_BASE + 0x0C0) + DPORT_PERIP_RST_EN_REG = const(DR_REG_DPORT_BASE + 0x0C4) + DPORT_PWM0_CLK_EN = const(1 << 17) + MCPWM0 = const(0x3FF5E000) + MCPWM1 = const(0x3FF6C000) + + # Enable CLK and disable RST. + print(hex(mem32[DPORT_PERIP_CLK_EN_REG] & 0xffffffff)) + print(hex(mem32[DPORT_PERIP_RST_EN_REG] & 0xffffffff)) + mem32[DPORT_PERIP_CLK_EN_REG] |= DPORT_PWM0_CLK_EN + mem32[DPORT_PERIP_RST_EN_REG] &= ~DPORT_PWM0_CLK_EN + print(hex(mem32[DPORT_PERIP_CLK_EN_REG] & 0xffffffff)) + print(hex(mem32[DPORT_PERIP_RST_EN_REG] & 0xffffffff)) + + # Change the MCPWM0 prescaler. + print(hex(mem32[MCPWM0])) # read PWM_CLK_CFG_REG (reset value = 0) + mem32[MCPWM0] = 0x55 # change PWM_CLK_PRESCALE + print(hex(mem32[MCPWM0])) # read PWM_CLK_CFG_REG + +Note that before a peripheral can be used its clock must be enabled and it must +be taken out of reset. In the above example the following registers are used +for this: + +- ``DPORT_PERI_CLK_EN_REG``: used to enable a peripheral clock + +- ``DPORT_PERI_RST_EN_REG``: used to reset (or take out of reset) a peripheral + +The MCPWM0 peripheral is in bit position 17 of the above two registers, hence +the value of ``DPORT_PWM0_CLK_EN``. From eea6cd85b37351ceda1b4c80a804912605977997 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 30 Sep 2021 09:13:15 +1000 Subject: [PATCH 081/335] stm32/sdram: Enforce gcc opt, and use volatile and DSB in sdram_test. Ensures consistent behaviour and resolves the D-Cache bug (the "exhaustive" argument being lost due to cache being turned off) when O0 is used. The changes in this commit are: - Change -O0 to -Os because "gcc is considered broken at -O0" according to https://github.com/ARM-software/CMSIS_5/issues/620#issuecomment-550235656 - Use volatile for mem_base so the compiler doesn't optimise away reads or writes to the SDRAM, which is being tested. - Use DSB to prevent any other compiler optimisations that would change the testing logic. - Use alternating pattern/antipattern in exhaustive test to catch more hardware/configuration errors. Implementation adapted by @andrewleech, taken directly from investigation by @iabdalkader and @dpgeorge. See #7841 and #7869 for further discussion. --- ports/stm32/sdram.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/ports/stm32/sdram.c b/ports/stm32/sdram.c index e0e3500836..4615c4fe1e 100644 --- a/ports/stm32/sdram.c +++ b/ports/stm32/sdram.c @@ -283,10 +283,10 @@ void sdram_leave_low_power(void) { #pragma GCC diagnostic ignored "-Wstringop-overflow" #endif -bool __attribute__((optimize("O0"))) sdram_test(bool exhaustive) { +bool __attribute__((optimize("Os"))) sdram_test(bool exhaustive) { uint8_t const pattern = 0xaa; uint8_t const antipattern = 0x55; - uint8_t *const mem_base = (uint8_t *)sdram_start(); + volatile uint8_t *const mem_base = (uint8_t *)sdram_start(); #if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR char error_buffer[1024]; @@ -310,12 +310,13 @@ bool __attribute__((optimize("O0"))) sdram_test(bool exhaustive) { // Test data bus for (uint32_t i = 0; i < MICROPY_HW_SDRAM_MEM_BUS_WIDTH; i++) { - *((uint32_t *)mem_base) = (1 << i); - if (*((uint32_t *)mem_base) != (1 << i)) { + *((volatile uint32_t *)mem_base) = (1 << i); + __DSB(); + if (*((volatile uint32_t *)mem_base) != (1 << i)) { #if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR snprintf(error_buffer, sizeof(error_buffer), "Data bus test failed at 0x%p expected 0x%x found 0x%lx", - &mem_base[0], (1 << i), ((uint32_t *)mem_base)[0]); + &mem_base[0], (1 << i), ((volatile uint32_t *)mem_base)[0]); __fatal_error(error_buffer); #endif return false; @@ -325,6 +326,7 @@ bool __attribute__((optimize("O0"))) sdram_test(bool exhaustive) { // Test address bus for (uint32_t i = 1; i < MICROPY_HW_SDRAM_SIZE; i <<= 1) { mem_base[i] = pattern; + __DSB(); if (mem_base[i] != pattern) { #if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR snprintf(error_buffer, sizeof(error_buffer), @@ -338,6 +340,7 @@ bool __attribute__((optimize("O0"))) sdram_test(bool exhaustive) { // Check for aliasing (overlaping addresses) mem_base[0] = antipattern; + __DSB(); for (uint32_t i = 1; i < MICROPY_HW_SDRAM_SIZE; i <<= 1) { if (mem_base[i] != pattern) { #if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR @@ -356,15 +359,15 @@ bool __attribute__((optimize("O0"))) sdram_test(bool exhaustive) { // is enabled, it's not just writing and reading from cache. // Note: This test should also detect refresh rate issues. for (uint32_t i = 0; i < MICROPY_HW_SDRAM_SIZE; i++) { - mem_base[i] = pattern; + mem_base[i] = ((i % 2) ? pattern : antipattern); } for (uint32_t i = 0; i < MICROPY_HW_SDRAM_SIZE; i++) { - if (mem_base[i] != pattern) { + if (mem_base[i] != ((i % 2) ? pattern : antipattern)) { #if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR snprintf(error_buffer, sizeof(error_buffer), "Address bus slow test failed at 0x%p expected 0x%x found 0x%x", - &mem_base[i], pattern, mem_base[i]); + &mem_base[i], ((i % 2) ? pattern : antipattern), mem_base[i]); __fatal_error(error_buffer); #endif return false; From 8412568e7bec1b63b686eb46a2790c6f182e7d5b Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 24 Sep 2021 12:49:51 +1000 Subject: [PATCH 082/335] py: Add wrapper macros so hot VM functions can go in fast code location. For example, on esp32 they can go in iRAM to improve performance. Signed-off-by: Damien George --- py/map.c | 2 +- py/mpconfig.h | 24 ++++++++++++++++++++++++ py/obj.c | 2 +- py/runtime.c | 6 +++--- py/vm.c | 2 +- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/py/map.c b/py/map.c index 1c43616364..b194250cb4 100644 --- a/py/map.c +++ b/py/map.c @@ -153,7 +153,7 @@ STATIC void mp_map_rehash(mp_map_t *map) { // - returns slot, with key non-null and value=MP_OBJ_NULL if it was added // MP_MAP_LOOKUP_REMOVE_IF_FOUND behaviour: // - returns NULL if not found, else the slot if was found in with key null and value non-null -mp_map_elem_t *mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind) { +mp_map_elem_t *MICROPY_WRAP_MP_MAP_LOOKUP(mp_map_lookup)(mp_map_t * map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind) { // If the map is a fixed array then we must only be called for a lookup assert(!map->is_fixed || lookup_kind == MP_MAP_LOOKUP); diff --git a/py/mpconfig.h b/py/mpconfig.h index 6a2edc7dc2..d20ad04480 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1594,6 +1594,30 @@ typedef double mp_float_t; /*****************************************************************************/ /* Hooks for a port to wrap functions with attributes */ +#ifndef MICROPY_WRAP_MP_BINARY_OP +#define MICROPY_WRAP_MP_BINARY_OP(f) f +#endif + +#ifndef MICROPY_WRAP_MP_EXECUTE_BYTECODE +#define MICROPY_WRAP_MP_EXECUTE_BYTECODE(f) f +#endif + +#ifndef MICROPY_WRAP_MP_LOAD_GLOBAL +#define MICROPY_WRAP_MP_LOAD_GLOBAL(f) f +#endif + +#ifndef MICROPY_WRAP_MP_LOAD_NAME +#define MICROPY_WRAP_MP_LOAD_NAME(f) f +#endif + +#ifndef MICROPY_WRAP_MP_MAP_LOOKUP +#define MICROPY_WRAP_MP_MAP_LOOKUP(f) f +#endif + +#ifndef MICROPY_WRAP_MP_OBJ_GET_TYPE +#define MICROPY_WRAP_MP_OBJ_GET_TYPE(f) f +#endif + #ifndef MICROPY_WRAP_MP_SCHED_EXCEPTION #define MICROPY_WRAP_MP_SCHED_EXCEPTION(f) f #endif diff --git a/py/obj.c b/py/obj.c index f66a9d183c..5255e96553 100644 --- a/py/obj.c +++ b/py/obj.c @@ -37,7 +37,7 @@ #include "py/stackctrl.h" #include "py/stream.h" // for mp_obj_print -const mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in) { +const mp_obj_type_t *MICROPY_WRAP_MP_OBJ_GET_TYPE(mp_obj_get_type)(mp_const_obj_t o_in) { #if MICROPY_OBJ_IMMEDIATE_OBJS && MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A if (mp_obj_is_obj(o_in)) { diff --git a/py/runtime.c b/py/runtime.c index 2f7cf1fa60..0133d813f7 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -157,7 +157,7 @@ void mp_deinit(void) { #endif } -mp_obj_t mp_load_name(qstr qst) { +mp_obj_t MICROPY_WRAP_MP_LOAD_NAME(mp_load_name)(qstr qst) { // logic: search locals, globals, builtins DEBUG_OP_printf("load name %s\n", qstr_str(qst)); // If we're at the outer scope (locals == globals), dispatch to load_global right away @@ -170,7 +170,7 @@ mp_obj_t mp_load_name(qstr qst) { return mp_load_global(qst); } -mp_obj_t mp_load_global(qstr qst) { +mp_obj_t MICROPY_WRAP_MP_LOAD_GLOBAL(mp_load_global)(qstr qst) { // logic: search globals, builtins DEBUG_OP_printf("load global %s\n", qstr_str(qst)); mp_map_elem_t *elem = mp_map_lookup(&mp_globals_get()->map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); @@ -311,7 +311,7 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) { } } -mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { +mp_obj_t MICROPY_WRAP_MP_BINARY_OP(mp_binary_op)(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { DEBUG_OP_printf("binary " UINT_FMT " %q %p %p\n", op, mp_binary_op_method_name[op], lhs, rhs); // TODO correctly distinguish inplace operators for mutable objects diff --git a/py/vm.c b/py/vm.c index f55d293dc5..0289bcfae5 100644 --- a/py/vm.c +++ b/py/vm.c @@ -186,7 +186,7 @@ // MP_VM_RETURN_NORMAL, sp valid, return value in *sp // MP_VM_RETURN_YIELD, ip, sp valid, yielded value in *sp // MP_VM_RETURN_EXCEPTION, exception in state[0] -mp_vm_return_kind_t mp_execute_bytecode(mp_code_state_t *code_state, volatile mp_obj_t inject_exc) { +mp_vm_return_kind_t MICROPY_WRAP_MP_EXECUTE_BYTECODE(mp_execute_bytecode)(mp_code_state_t *code_state, volatile mp_obj_t inject_exc) { #define SELECTIVE_EXC_IP (0) #if SELECTIVE_EXC_IP #define MARK_EXC_IP_SELECTIVE() { code_state->ip = ip; } /* stores ip 1 byte past last opcode */ From 549448e8bbc8ce0b6b5fc51c0660acdaff18c3d6 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 24 Sep 2021 12:50:59 +1000 Subject: [PATCH 083/335] esp32: Enable optimisations and move code to iRAM to boost performance. This commit enables some significant optimisations for esp32: - move the VM to iRAM - move hot parts of the runtime to iRAM (map lookup, load global/name, mp_obj_get_type) - enable MICROPY_OPT_LOAD_ATTR_FAST_PATH - enable MICROPY_OPT_MAP_LOOKUP_CACHE - disable assertions - change from -Os to -O2 for compilation It's hard to measure performance on esp32 due to external flash and hardware caching. But this set of changes improves performance compared to master by (on a TinyPICO with the GENERIC build, using IDF 4.2.2, running at 160MHz): diff of scores (higher is better) N=100 M=100 esp32-master -> esp32-perf diff diff% (error%) bm_chaos.py 71.28 -> 268.08 : +196.80 = +276.094% (+/-0.04%) bm_fannkuch.py 44.10 -> 69.31 : +25.21 = +57.166% (+/-0.01%) bm_fft.py 1385.27 -> 2538.23 : +1152.96 = +83.230% (+/-0.01%) bm_float.py 1060.94 -> 3900.62 : +2839.68 = +267.657% (+/-0.03%) bm_hexiom.py 10.90 -> 32.79 : +21.89 = +200.826% (+/-0.02%) bm_nqueens.py 1000.83 -> 2372.87 : +1372.04 = +137.090% (+/-0.01%) bm_pidigits.py 288.13 -> 664.40 : +376.27 = +130.590% (+/-0.46%) misc_aes.py 102.45 -> 345.69 : +243.24 = +237.423% (+/-0.01%) misc_mandel.py 1016.58 -> 2121.92 : +1105.34 = +108.731% (+/-0.01%) misc_pystone.py 632.91 -> 1801.87 : +1168.96 = +184.696% (+/-0.08%) misc_raytrace.py 76.66 -> 281.78 : +205.12 = +267.571% (+/-0.05%) viper_call0.py 210.63 -> 273.17 : +62.54 = +29.692% (+/-0.01%) viper_call1a.py 208.45 -> 269.51 : +61.06 = +29.292% (+/-0.00%) viper_call1b.py 185.44 -> 228.25 : +42.81 = +23.086% (+/-0.01%) viper_call1c.py 185.86 -> 228.90 : +43.04 = +23.157% (+/-0.01%) viper_call2a.py 207.10 -> 267.25 : +60.15 = +29.044% (+/-0.00%) viper_call2b.py 173.76 -> 209.42 : +35.66 = +20.523% (+/-0.00%) Five tests have more than 3x speed up (200%+). The performance of the tests bm_fft, bm_pidigits and misc_aes now scale with CPU frequency (eg changing frequency to 240MHz boosts the performance of these by 50%), which means they are no longer influenced by timing of external flash access. (The viper_call* tests did previously scale with CPU frequency, and they still do.) Turning off assertions reduces code size by about 80k, and going from -Os to -O2 costs about 100k, so the net change in code size (for the GENERIC board) is about +20k. If a board wants to enable assertions, or use -Os instead of -O2, that's still possible by overriding the sdkconfig parameters. Signed-off-by: Damien George --- ports/esp32/boards/sdkconfig.base | 6 +++--- ports/esp32/mpconfigport.h | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ports/esp32/boards/sdkconfig.base b/ports/esp32/boards/sdkconfig.base index 5ca3f6a1a2..71229e8beb 100644 --- a/ports/esp32/boards/sdkconfig.base +++ b/ports/esp32/boards/sdkconfig.base @@ -3,11 +3,11 @@ CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 -# Compiler options: use -Os to reduce size, but keep full assertions +# Compiler options: use -O2 and disable assertions to improve performance # (CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is for IDF 4.0.2) CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y -CONFIG_COMPILER_OPTIMIZATION_SIZE=y -CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +CONFIG_COMPILER_OPTIMIZATION_PERF=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y # Application manager CONFIG_APP_EXCLUDE_PROJECT_VER_VAR=y diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 3d1fc10e12..53d706be3f 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -30,6 +30,8 @@ // optimisations #define MICROPY_OPT_COMPUTED_GOTO (1) +#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (1) +#define MICROPY_OPT_MAP_LOOKUP_CACHE (1) #define MICROPY_OPT_MPZ_BITWISE (1) // Python internal features @@ -289,6 +291,12 @@ void *esp_native_code_commit(void *, size_t, void *); #endif // Functions that should go in IRAM +#define MICROPY_WRAP_MP_BINARY_OP(f) IRAM_ATTR f +#define MICROPY_WRAP_MP_EXECUTE_BYTECODE(f) IRAM_ATTR f +#define MICROPY_WRAP_MP_LOAD_GLOBAL(f) IRAM_ATTR f +#define MICROPY_WRAP_MP_LOAD_NAME(f) IRAM_ATTR f +#define MICROPY_WRAP_MP_MAP_LOOKUP(f) IRAM_ATTR f +#define MICROPY_WRAP_MP_OBJ_GET_TYPE(f) IRAM_ATTR f #define MICROPY_WRAP_MP_SCHED_EXCEPTION(f) IRAM_ATTR f #define MICROPY_WRAP_MP_SCHED_KEYBOARD_INTERRUPT(f) IRAM_ATTR f From ba940250a5b630018c8d9b0e21c5ed858a20450f Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 24 Sep 2021 14:11:44 +1000 Subject: [PATCH 084/335] esp32/usb: Improve speed of USB CDC output. Signed-off-by: Damien George --- ports/esp32/usb.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/ports/esp32/usb.c b/ports/esp32/usb.c index 21047fa2be..95c8277299 100644 --- a/ports/esp32/usb.c +++ b/ports/esp32/usb.c @@ -93,15 +93,28 @@ void usb_tx_strn(const char *str, size_t len) { } while (len) { - size_t l = len; - if (l > CONFIG_USB_CDC_TX_BUFSIZE) { - l = CONFIG_USB_CDC_TX_BUFSIZE; + // Get amount of CDC output buffer space available, making sure + // there is at least one byte available. + size_t avail = tud_cdc_n_write_available(CDC_ITF); + if (avail == 0) { + if (tinyusb_cdcacm_write_flush(CDC_ITF, pdMS_TO_TICKS(1000)) != ESP_OK) { + return; + } + avail = tud_cdc_n_write_available(CDC_ITF); } - tinyusb_cdcacm_write_queue(CDC_ITF, (uint8_t *)str, l); - tinyusb_cdcacm_write_flush(CDC_ITF, pdMS_TO_TICKS(1000)); + + // Write as much data as possible. + size_t l = len; + if (l > avail) { + l = avail; + } + tud_cdc_n_write(CDC_ITF, (uint8_t *)str, l); str += l; len -= l; } + + // Queue a flush to write out the data in the CDC buffer (if any). + tud_cdc_n_write_flush(CDC_ITF); } #endif // CONFIG_USB_ENABLED From 2ceeabf1800e816345baad76214e8d6fe73b2901 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Fri, 13 Aug 2021 16:02:41 +1000 Subject: [PATCH 085/335] extmod/vfs_posix_file: Support MP_STREAM_POLL in vfs_posix_file_ioctl. Allows asyncio reading of sys.stdin when MICROPY_PY_USELECT is used in the build configuration. --- extmod/vfs_posix_file.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index f3eac98ce3..837c5489b0 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -37,6 +37,8 @@ #ifdef _WIN32 #define fsync _commit +#else +#include #endif typedef struct _mp_obj_vfs_posix_file_t { @@ -206,6 +208,32 @@ STATIC mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_ return 0; case MP_STREAM_GET_FILENO: return o->fd; + #if MICROPY_PY_USELECT + case MP_STREAM_POLL: { + #ifdef _WIN32 + mp_raise_NotImplementedError(MP_ERROR_TEXT("poll on file not available on win32")); + #else + mp_uint_t ret = 0; + uint8_t pollevents = 0; + if (arg & MP_STREAM_POLL_RD) { + pollevents |= POLLIN; + } + if (arg & MP_STREAM_POLL_WR) { + pollevents |= POLLOUT; + } + struct pollfd pfd = { .fd = o->fd, .events = pollevents }; + if (poll(&pfd, 1, 0) > 0) { + if (pfd.revents & POLLIN) { + ret |= MP_STREAM_POLL_RD; + } + if (pfd.revents & POLLOUT) { + ret |= MP_STREAM_POLL_WR; + } + } + return ret; + #endif + } + #endif default: *errcode = EINVAL; return MP_STREAM_ERROR; From cc42b7c88b0b2b11e1e6d389c773e36545e2aef0 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Fri, 17 Sep 2021 11:48:37 +1000 Subject: [PATCH 086/335] unix/modusocket: Support MP_STREAM_POLL in unix socket_ioctl. Allows asyncio reading of network sockets when MICROPY_PY_USELECT is used in the build configuration. --- ports/unix/modusocket.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index 1c9ef33622..951cb7a21c 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -46,6 +46,7 @@ #include "py/builtin.h" #include "py/mphal.h" #include "py/mpthread.h" +#include /* The idea of this module is to implement reasonable minimum of @@ -144,6 +145,29 @@ STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, i case MP_STREAM_GET_FILENO: return self->fd; + #if MICROPY_PY_USELECT + case MP_STREAM_POLL: { + mp_uint_t ret = 0; + uint8_t pollevents = 0; + if (arg & MP_STREAM_POLL_RD) { + pollevents |= POLLIN; + } + if (arg & MP_STREAM_POLL_WR) { + pollevents |= POLLOUT; + } + struct pollfd pfd = { .fd = self->fd, .events = pollevents }; + if (poll(&pfd, 1, 0) > 0) { + if (pfd.revents & POLLIN) { + ret |= MP_STREAM_POLL_RD; + } + if (pfd.revents & POLLOUT) { + ret |= MP_STREAM_POLL_WR; + } + } + return ret; + } + #endif + default: *errcode = MP_EINVAL; return MP_STREAM_ERROR; From 5f2f9044ff0fd936618931fa60b2376c43f1e25b Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 13 Oct 2021 18:29:00 +1100 Subject: [PATCH 087/335] stm32/usbd_cdc_interface: Allow a board to hook into USBD CDC RX events. Signed-off-by: Damien George --- ports/stm32/boardctrl.h | 6 ++++++ ports/stm32/usbd_cdc_interface.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ports/stm32/boardctrl.h b/ports/stm32/boardctrl.h index 551be3453e..851922f412 100644 --- a/ports/stm32/boardctrl.h +++ b/ports/stm32/boardctrl.h @@ -60,6 +60,12 @@ #define MICROPY_BOARD_END_SOFT_RESET boardctrl_end_soft_reset #endif +// Called when USBD CDC data is available. +// Default function defined in usbd_cdc_interface.h. +#ifndef MICROPY_BOARD_USBD_CDC_RX_EVENT +#define MICROPY_BOARD_USBD_CDC_RX_EVENT usbd_cdc_rx_event_callback +#endif + // Constants to return from boardctrl_run_boot_py, boardctrl_run_main_py. enum { BOARDCTRL_CONTINUE, diff --git a/ports/stm32/usbd_cdc_interface.c b/ports/stm32/usbd_cdc_interface.c index 61a7c82486..b369524ca7 100644 --- a/ports/stm32/usbd_cdc_interface.c +++ b/ports/stm32/usbd_cdc_interface.c @@ -37,6 +37,7 @@ #include #include +#include "boardctrl.h" #include "usbd_cdc_msc_hid.h" #include "usbd_cdc_interface.h" #include "pendsv.h" @@ -308,7 +309,7 @@ int8_t usbd_cdc_receive(usbd_cdc_state_t *cdc_in, size_t len) { } } - usbd_cdc_rx_event_callback(cdc); + MICROPY_BOARD_USBD_CDC_RX_EVENT(cdc); if ((cdc->flow & USBD_CDC_FLOWCONTROL_RTS) && (usbd_cdc_rx_buffer_full(cdc))) { cdc->rx_buf_full = true; From 69522822ded80a2462d89ebee11197d3ef24499f Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 13 Oct 2021 18:37:48 +1100 Subject: [PATCH 088/335] stm32/mpbthciport: Allow a board to hook BT HCI poll functions. Signed-off-by: Damien George --- ports/stm32/boardctrl.h | 12 ++++++++++++ ports/stm32/mpbthciport.c | 6 +++--- ports/stm32/mpbthciport.h | 18 +++++++++++++++--- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/ports/stm32/boardctrl.h b/ports/stm32/boardctrl.h index 851922f412..c870af32a4 100644 --- a/ports/stm32/boardctrl.h +++ b/ports/stm32/boardctrl.h @@ -66,6 +66,18 @@ #define MICROPY_BOARD_USBD_CDC_RX_EVENT usbd_cdc_rx_event_callback #endif +// Called to poll Bluetooth HCI now. +// Default function defined in mpbthciport.h. +#ifndef MICROPY_BOARD_BT_HCI_POLL_NOW +#define MICROPY_BOARD_BT_HCI_POLL_NOW mp_bluetooth_hci_poll_now_default +#endif + +// Called to poll Bluetooth HCI after the given timeout. +// Default function defined in mpbthciport.h. +#ifndef MICROPY_BOARD_BT_HCI_POLL_IN_MS +#define MICROPY_BOARD_BT_HCI_POLL_IN_MS mp_bluetooth_hci_poll_in_ms_default +#endif + // Constants to return from boardctrl_run_boot_py, boardctrl_run_main_py. enum { BOARDCTRL_CONTINUE, diff --git a/ports/stm32/mpbthciport.c b/ports/stm32/mpbthciport.c index 369c91e303..a1ab3258b6 100644 --- a/ports/stm32/mpbthciport.c +++ b/ports/stm32/mpbthciport.c @@ -71,7 +71,7 @@ STATIC void mp_bluetooth_hci_start_polling(void) { mp_bluetooth_hci_poll_now(); } -void mp_bluetooth_hci_poll_in_ms(uint32_t ms) { +void mp_bluetooth_hci_poll_in_ms_default(uint32_t ms) { soft_timer_reinsert(&mp_bluetooth_hci_soft_timer, ms); } @@ -92,7 +92,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(run_events_scheduled_task_obj, run_events_sched // Called periodically (systick) or directly (e.g. UART RX IRQ) in order to // request that processing happens ASAP in the scheduler. -void mp_bluetooth_hci_poll_now(void) { +void mp_bluetooth_hci_poll_now_default(void) { if (!events_task_is_scheduled) { events_task_is_scheduled = mp_sched_schedule(MP_OBJ_FROM_PTR(&run_events_scheduled_task_obj), mp_const_none); if (!events_task_is_scheduled) { @@ -104,7 +104,7 @@ void mp_bluetooth_hci_poll_now(void) { #else // !MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS -void mp_bluetooth_hci_poll_now(void) { +void mp_bluetooth_hci_poll_now_default(void) { pendsv_schedule_dispatch(PENDSV_DISPATCH_BLUETOOTH_HCI, mp_bluetooth_hci_poll); } diff --git a/ports/stm32/mpbthciport.h b/ports/stm32/mpbthciport.h index 77919ee0e6..d510ab52ad 100644 --- a/ports/stm32/mpbthciport.h +++ b/ports/stm32/mpbthciport.h @@ -26,12 +26,24 @@ #ifndef MICROPY_INCLUDED_STM32_MPBTHCIPORT_H #define MICROPY_INCLUDED_STM32_MPBTHCIPORT_H +#include "boardctrl.h" + // Initialise the HCI subsystem (should be called once, early on). void mp_bluetooth_hci_init(void); -// Poll the HCI now, or after a certain timeout. -void mp_bluetooth_hci_poll_now(void); -void mp_bluetooth_hci_poll_in_ms(uint32_t ms); +// Default implementations of poll functions (a board can override them). +void mp_bluetooth_hci_poll_now_default(void); +void mp_bluetooth_hci_poll_in_ms_default(uint32_t ms); + +// Call this to poll the HCI now. +static inline void mp_bluetooth_hci_poll_now(void) { + MICROPY_BOARD_BT_HCI_POLL_NOW(); +} + +// Call this to poll the HCI after a certain timeout. +static inline void mp_bluetooth_hci_poll_in_ms(uint32_t ms) { + MICROPY_BOARD_BT_HCI_POLL_IN_MS(ms); +} // Must be provided by the stack bindings (e.g. mpnimbleport.c or mpbtstackport.c). // Request new data from the uart and pass to the stack, and run pending events/callouts. From 30268c93dc52116bc6c2041c55de486180b4eb03 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 13 Oct 2021 18:40:06 +1100 Subject: [PATCH 089/335] stm32/pendsv: Allow a board to add entries for pendsv_schedule_dispatch. Signed-off-by: Damien George --- ports/stm32/boardctrl.h | 5 +++++ ports/stm32/pendsv.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/ports/stm32/boardctrl.h b/ports/stm32/boardctrl.h index c870af32a4..0878a453b3 100644 --- a/ports/stm32/boardctrl.h +++ b/ports/stm32/boardctrl.h @@ -28,6 +28,11 @@ #include "py/mpconfig.h" +// Additional entries for use with pendsv_schedule_dispatch. +#ifndef MICROPY_BOARD_PENDSV_ENTRIES +#define MICROPY_BOARD_PENDSV_ENTRIES +#endif + #ifndef MICROPY_BOARD_STARTUP #define MICROPY_BOARD_STARTUP powerctrl_check_enter_bootloader #endif diff --git a/ports/stm32/pendsv.h b/ports/stm32/pendsv.h index aa8f90e3e4..0733d355d3 100644 --- a/ports/stm32/pendsv.h +++ b/ports/stm32/pendsv.h @@ -26,6 +26,8 @@ #ifndef MICROPY_INCLUDED_STM32_PENDSV_H #define MICROPY_INCLUDED_STM32_PENDSV_H +#include "boardctrl.h" + enum { PENDSV_DISPATCH_SOFT_TIMER, #if MICROPY_PY_NETWORK && MICROPY_PY_LWIP @@ -37,6 +39,7 @@ enum { #if MICROPY_PY_BLUETOOTH && !MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS PENDSV_DISPATCH_BLUETOOTH_HCI, #endif + MICROPY_BOARD_PENDSV_ENTRIES PENDSV_DISPATCH_MAX }; From fe2bc92b4d20c116fbb14b6fe92db459d8ce2126 Mon Sep 17 00:00:00 2001 From: Mike Wadsten Date: Mon, 13 Jan 2020 11:51:04 -0600 Subject: [PATCH 090/335] py/runtime: Fix crash when exc __new__ doesn't return an exc instance. See CPython bug https://bugs.python.org/issue39091 for more details. --- py/runtime.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/py/runtime.c b/py/runtime.c index 0133d813f7..27e77fc290 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1372,8 +1372,10 @@ mp_obj_t mp_make_raise_obj(mp_obj_t o) { // create and return a new exception instance by calling o // TODO could have an option to disable traceback, then builtin exceptions (eg TypeError) // could have const instances in ROM which we return here instead - return mp_call_function_n_kw(o, 0, 0, NULL); - } else if (mp_obj_is_exception_instance(o)) { + o = mp_call_function_n_kw(o, 0, 0, NULL); + } + + if (mp_obj_is_exception_instance(o)) { // o is an instance of an exception, so use it as the exception return o; } else { From c3c2c37fbcc59f8ecd58dc294b31ad4d239fd52c Mon Sep 17 00:00:00 2001 From: Mike Wadsten Date: Mon, 13 Jan 2020 11:52:36 -0600 Subject: [PATCH 091/335] tests/basics: Add tests for type-checking subclassed exc instances. --- tests/basics/subclass_native_exc_new.py | 39 +++++++++++++++++++++ tests/basics/subclass_native_exc_new.py.exp | 6 ++++ 2 files changed, 45 insertions(+) create mode 100644 tests/basics/subclass_native_exc_new.py create mode 100644 tests/basics/subclass_native_exc_new.py.exp diff --git a/tests/basics/subclass_native_exc_new.py b/tests/basics/subclass_native_exc_new.py new file mode 100644 index 0000000000..c1bd89a6fa --- /dev/null +++ b/tests/basics/subclass_native_exc_new.py @@ -0,0 +1,39 @@ +# test subclassing exceptions and providing __new__ + + +class Dummy(BaseException): + pass + + +class GoodException(BaseException): + def __new__(cls, *args, **kwargs): + print("GoodException __new__") + return Dummy(*args, **kwargs) + + +class BadException(BaseException): + def __new__(cls, *args, **kwargs): + print("BadException __new__") + return 1 + + +try: + raise GoodException("good message") +except BaseException as good: + print(type(good), good.args[0]) + +try: + raise BadException("bad message") +except Exception as bad: + # Should be TypeError 'exceptions must derive from BaseException' + print(type(bad), bad.args[0]) + +try: + + def gen(): + yield + + gen().throw(BadException) +except Exception as genbad: + # Should be TypeError 'exceptions must derive from BaseException' + print(type(genbad), genbad.args[0]) diff --git a/tests/basics/subclass_native_exc_new.py.exp b/tests/basics/subclass_native_exc_new.py.exp new file mode 100644 index 0000000000..65709b2ccf --- /dev/null +++ b/tests/basics/subclass_native_exc_new.py.exp @@ -0,0 +1,6 @@ +GoodException __new__ + good message +BadException __new__ + exceptions must derive from BaseException +BadException __new__ + exceptions must derive from BaseException From f4c1389fbcc21e3e4b37a7dbe5018e1a7314f6cd Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 21 Oct 2021 12:59:59 +1100 Subject: [PATCH 092/335] github/workflows: Use Python 3.8 for macos workflow. Otherwise it gets a more recent version which fails some of the test suite. Signed-off-by: Damien George --- .github/workflows/ports_unix.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ports_unix.yml b/.github/workflows/ports_unix.yml index 0e6a98f6b2..4e75172b64 100644 --- a/.github/workflows/ports_unix.yml +++ b/.github/workflows/ports_unix.yml @@ -190,7 +190,9 @@ jobs: runs-on: macos-11.0 steps: - uses: actions/checkout@v2 - - uses: actions/setup-python@v1 + - uses: actions/setup-python@v2 + with: + python-version: '3.8' - name: Build run: source tools/ci.sh && ci_unix_macos_build - name: Run tests From 7e62c9707a72d47498ba38bdb23980eb1a3c883d Mon Sep 17 00:00:00 2001 From: Philipp Ebensberger Date: Fri, 20 Aug 2021 21:41:58 +0200 Subject: [PATCH 093/335] mimxrt/sdram: Add SDRAM support. Adds support for SDRAM via `SEMC` peripheral. SDRAM support can be enabled in the mpconfigboard.mk file by setting `MICROPY_HW_SDRAM_AVAIL` to `1` and poviding the size of the RAM via `MICROPY_HW_FLASH_SIZE`. When SDRAM support is enabled the whole SDRAM is currently used used for MicroPython heap. Signed-off-by: Philipp Ebensberger --- ports/mimxrt/Makefile | 39 ++-- ports/mimxrt/board_init.c | 6 +- .../boards/MIMXRT1010_EVK/mpconfigboard.mk | 4 +- .../MIMXRT1010_EVK/qspi_nor_flash_config.c | 2 +- ports/mimxrt/boards/MIMXRT1011.ld | 10 +- .../boards/MIMXRT1020_EVK/mpconfigboard.h | 45 +++++ .../boards/MIMXRT1020_EVK/mpconfigboard.mk | 7 +- .../MIMXRT1020_EVK/qspi_nor_flash_config.c | 2 +- ports/mimxrt/boards/MIMXRT1021.ld | 20 +- .../boards/MIMXRT1050_EVK/mpconfigboard.h | 45 +++++ .../boards/MIMXRT1050_EVK/mpconfigboard.mk | 7 +- .../MIMXRT1050_EVK/qspi_hyper_flash_config.c | 2 +- .../MIMXRT1050_EVK/qspi_nor_flash_config.c | 2 +- ports/mimxrt/boards/MIMXRT1052.ld | 22 ++- .../boards/MIMXRT1060_EVK/mpconfigboard.h | 45 +++++ .../boards/MIMXRT1060_EVK/mpconfigboard.mk | 7 +- .../MIMXRT1060_EVK/qspi_hyper_flash_config.c | 2 +- .../MIMXRT1060_EVK/qspi_nor_flash_config.c | 2 +- ports/mimxrt/boards/MIMXRT1062.ld | 22 ++- ports/mimxrt/boards/MIMXRT1064.ld | 24 ++- .../boards/MIMXRT1064_EVK/mpconfigboard.h | 45 +++++ .../boards/MIMXRT1064_EVK/mpconfigboard.mk | 7 +- .../MIMXRT1064_EVK/qspi_hyper_flash_config.c | 2 +- .../MIMXRT1064_EVK/qspi_nor_flash_config.c | 2 +- ports/mimxrt/boards/TEENSY40/mpconfigboard.mk | 6 +- .../boards/TEENSY40/qspi_nor_flash_config.c | 2 +- ports/mimxrt/boards/TEENSY41/mpconfigboard.mk | 6 +- .../boards/TEENSY41/qspi_nor_flash_config.c | 2 +- ports/mimxrt/boards/common.ld | 7 + ports/mimxrt/boards/make-pins.py | 2 +- ports/mimxrt/mimxrt_flash.c | 2 - ports/mimxrt/mimxrt_sdram.c | 186 ++++++++++++++++++ ports/mimxrt/modmachine.h | 1 + ports/mimxrt/pin.h | 1 + 34 files changed, 514 insertions(+), 72 deletions(-) create mode 100644 ports/mimxrt/mimxrt_sdram.c diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index fcbd97b20c..1b83f36abf 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -13,15 +13,22 @@ endif include ../../py/mkenv.mk include $(BOARD_DIR)/mpconfigboard.mk -# Set optional flash configuration variables -BOARD_FLASH_RESERVED ?= +LD_MEMORY_CONFIG_DEFINES += \ + MICROPY_HW_FLASH_TYPE=$(MICROPY_HW_FLASH_TYPE) \ + MICROPY_HW_FLASH_SIZE=$(MICROPY_HW_FLASH_SIZE) + +ifdef MICROPY_HW_FLASH_RESERVED +LD_MEMORY_CONFIG_DEFINES += MICROPY_HW_FLASH_RESERVED=$(MICROPY_HW_FLASH_RESERVED) +endif + +ifdef MICROPY_HW_SDRAM_AVAIL +CFLAGS += \ + -DMICROPY_HW_SDRAM_AVAIL=$(MICROPY_HW_SDRAM_AVAIL) \ + -DMICROPY_HW_SDRAM_SIZE=$(MICROPY_HW_SDRAM_SIZE) LD_MEMORY_CONFIG_DEFINES += \ - BOARD_FLASH_TYPE=$(BOARD_FLASH_TYPE) \ - BOARD_FLASH_SIZE=$(BOARD_FLASH_SIZE) - -ifdef $(BOARD_FLASH_RESERVED) -LD_MEMORY_CONFIG_DEFINES += BOARD_FLASH_RESERVED=$(BOARD_FLASH_RESERVED) + MICROPY_HW_SDRAM_AVAIL=$(MICROPY_HW_SDRAM_AVAIL) \ + MICROPY_HW_SDRAM_SIZE=$(MICROPY_HW_SDRAM_SIZE) endif # Qstr definitions (must come before including py.mk) @@ -81,12 +88,13 @@ CFLAGS += -DXIP_EXTERNAL_FLASH=1 \ -D__STARTUP_INITIALIZE_RAMFUNCTION \ -D__START=main \ -DCPU_HEADER_H='<$(MCU_SERIES).h>' \ - -DBOARD_FLASH_SIZE=$(BOARD_FLASH_SIZE) \ + -DBOARD_FLASH_SIZE=$(MICROPY_HW_FLASH_SIZE) \ + -DMICROPY_HW_FLASH_SIZE=$(MICROPY_HW_FLASH_SIZE) \ -DBOARD_FLASH_CONFIG_HEADER_H=\"$(BOARD)_flexspi_nor_config.h\" -ifeq ($(BOARD_FLASH_TYPE), qspi_nor) +ifeq ($(MICROPY_HW_FLASH_TYPE), qspi_nor) CFLAGS += -DBOARD_FLASH_OPS_HEADER_H=\"hal/flexspi_nor_flash.h\" -else ifeq ($(BOARD_FLASH_TYPE), hyperflash) +else ifeq ($(MICROPY_HW_FLASH_TYPE), hyperflash) CFLAGS += -DBOARD_FLASH_OPS_HEADER_H=\"hal/flexspi_hyper_flash.h\" endif @@ -163,6 +171,10 @@ SRC_HAL_IMX_C += \ $(MCU_DIR)/system_$(MCU_SERIES).c \ $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ +ifeq ($(MICROPY_HW_SDRAM_AVAIL), 1) +SRC_HAL_IMX_C += $(MCU_DIR)/drivers/fsl_semc.c +endif + ifeq ($(MICROPY_PY_MACHINE_SDCARD),1) SRC_HAL_IMX_C += $(MCU_DIR)/drivers/fsl_usdhc.c endif @@ -186,6 +198,7 @@ SRC_C += \ machine_uart.c \ main.c \ mimxrt_flash.c \ + mimxrt_sdram.c \ modmachine.c \ modmimxrt.c \ moduos.c \ @@ -207,16 +220,16 @@ SRC_C += \ $(SRC_TINYUSB_C) \ $(SRC_HAL_IMX_C) \ -ifeq ($(BOARD_FLASH_TYPE), qspi_nor) +ifeq ($(MICROPY_HW_FLASH_TYPE), qspi_nor) SRC_C += \ hal/flexspi_nor_flash.c \ $(BOARD_DIR)/qspi_nor_flash_config.c -else ifeq ($(BOARD_FLASH_TYPE), hyperflash) +else ifeq ($(MICROPY_HW_FLASH_TYPE), hyperflash) SRC_C += \ hal/flexspi_hyper_flash.c \ $(BOARD_DIR)/qspi_hyper_flash_config.c else -$(error Error: Unknown board flash type $(BOARD_FLASH_TYPE)) +$(error Error: Unknown board flash type $(MICROPY_HW_FLASH_TYPE)) endif ifeq ($(MICROPY_FLOAT_IMPL),double) diff --git a/ports/mimxrt/board_init.c b/ports/mimxrt/board_init.c index 091e23eb5d..e37ed1f149 100644 --- a/ports/mimxrt/board_init.c +++ b/ports/mimxrt/board_init.c @@ -51,8 +51,12 @@ void board_init(void) { // Enable IOCON clock CLOCK_EnableClock(kCLOCK_Iomuxc); - // ------------- USB0 ------------- // + // ------------- SDRAM ------------ // + #ifdef MICROPY_HW_SDRAM_AVAIL + mimxrt_sdram_init(); + #endif + // ------------- USB0 ------------- // // Clock CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U); CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U); diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk index c4c911d7db..c2a50d722b 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk @@ -3,8 +3,8 @@ MCU_VARIANT = MIMXRT1011DAE5A MICROPY_FLOAT_IMPL = single MICROPY_PY_MACHINE_SDCARD = 0 -BOARD_FLASH_TYPE ?= qspi_nor -BOARD_FLASH_SIZE ?= 0x1000000 # 16MB +MICROPY_HW_FLASH_TYPE ?= qspi_nor +MICROPY_HW_FLASH_SIZE ?= 0x1000000 # 16MB JLINK_PATH ?= /media/RT1010-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1010_EVK/qspi_nor_flash_config.c index 83a45159c0..60d435433a 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/qspi_nor_flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/qspi_nor_flash_config.c @@ -34,7 +34,7 @@ const flexspi_nor_config_t qspiflash_config = { .csSetupTime = 3u, .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_100MHz, - .sflashA1Size = BOARD_FLASH_SIZE, + .sflashA1Size = MICROPY_HW_FLASH_SIZE, .lookupTable = { // 0 Read LUTs 0 -> 0 diff --git a/ports/mimxrt/boards/MIMXRT1011.ld b/ports/mimxrt/boards/MIMXRT1011.ld index 22d5da3199..19bbc27701 100644 --- a/ports/mimxrt/boards/MIMXRT1011.ld +++ b/ports/mimxrt/boards/MIMXRT1011.ld @@ -1,14 +1,14 @@ /* Memory configuration */ -#if BOARD_FLASH_RESERVED -reserved_size = BOARD_FLASH_RESERVED; +#if MICROPY_HW_FLASH_RESERVED +reserved_size = MICROPY_HW_FLASH_RESERVED; #endif -#if BOARD_FLASH_TYPE==qspi_nor +#if MICROPY_HW_FLASH_TYPE==qspi_nor flash_start = 0x60000000; #else -#error Unknown BOARD_FLASH_TYPE +#error Unknown MICROPY_HW_FLASH_TYPE #endif -flash_size = BOARD_FLASH_SIZE; +flash_size = MICROPY_HW_FLASH_SIZE; flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); flash_config_start = flash_start + 0x00000400; flash_config_size = 0x00000C00; diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h index 35c24b3d47..4f33bb2087 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h @@ -72,3 +72,48 @@ .data2 = { GPIO_SD_B0_00_USDHC1_DATA2 }, \ .data3 = { GPIO_SD_B0_01_USDHC1_DATA3 }, \ } + +// --- SEMC --- // +#define MIMXRT_IOMUXC_SEMC_DATA00 IOMUXC_GPIO_EMC_00_SEMC_DATA00 +#define MIMXRT_IOMUXC_SEMC_DATA01 IOMUXC_GPIO_EMC_01_SEMC_DATA01 +#define MIMXRT_IOMUXC_SEMC_DATA02 IOMUXC_GPIO_EMC_02_SEMC_DATA02 +#define MIMXRT_IOMUXC_SEMC_DATA03 IOMUXC_GPIO_EMC_03_SEMC_DATA03 +#define MIMXRT_IOMUXC_SEMC_DATA04 IOMUXC_GPIO_EMC_04_SEMC_DATA04 +#define MIMXRT_IOMUXC_SEMC_DATA05 IOMUXC_GPIO_EMC_05_SEMC_DATA05 +#define MIMXRT_IOMUXC_SEMC_DATA06 IOMUXC_GPIO_EMC_06_SEMC_DATA06 +#define MIMXRT_IOMUXC_SEMC_DATA07 IOMUXC_GPIO_EMC_07_SEMC_DATA07 +#define MIMXRT_IOMUXC_SEMC_DATA08 IOMUXC_GPIO_EMC_32_SEMC_DATA08 +#define MIMXRT_IOMUXC_SEMC_DATA09 IOMUXC_GPIO_EMC_33_SEMC_DATA09 +#define MIMXRT_IOMUXC_SEMC_DATA10 IOMUXC_GPIO_EMC_34_SEMC_DATA10 +#define MIMXRT_IOMUXC_SEMC_DATA11 IOMUXC_GPIO_EMC_35_SEMC_DATA11 +#define MIMXRT_IOMUXC_SEMC_DATA12 IOMUXC_GPIO_EMC_36_SEMC_DATA12 +#define MIMXRT_IOMUXC_SEMC_DATA13 IOMUXC_GPIO_EMC_37_SEMC_DATA13 +#define MIMXRT_IOMUXC_SEMC_DATA14 IOMUXC_GPIO_EMC_38_SEMC_DATA14 +#define MIMXRT_IOMUXC_SEMC_DATA15 IOMUXC_GPIO_EMC_39_SEMC_DATA15 + +#define MIMXRT_IOMUXC_SEMC_ADDR00 IOMUXC_GPIO_EMC_16_SEMC_ADDR00 +#define MIMXRT_IOMUXC_SEMC_ADDR01 IOMUXC_GPIO_EMC_17_SEMC_ADDR01 +#define MIMXRT_IOMUXC_SEMC_ADDR02 IOMUXC_GPIO_EMC_18_SEMC_ADDR02 +#define MIMXRT_IOMUXC_SEMC_ADDR03 IOMUXC_GPIO_EMC_19_SEMC_ADDR03 +#define MIMXRT_IOMUXC_SEMC_ADDR04 IOMUXC_GPIO_EMC_20_SEMC_ADDR04 +#define MIMXRT_IOMUXC_SEMC_ADDR05 IOMUXC_GPIO_EMC_21_SEMC_ADDR05 +#define MIMXRT_IOMUXC_SEMC_ADDR06 IOMUXC_GPIO_EMC_22_SEMC_ADDR06 +#define MIMXRT_IOMUXC_SEMC_ADDR07 IOMUXC_GPIO_EMC_23_SEMC_ADDR07 +#define MIMXRT_IOMUXC_SEMC_ADDR08 IOMUXC_GPIO_EMC_24_SEMC_ADDR08 +#define MIMXRT_IOMUXC_SEMC_ADDR09 IOMUXC_GPIO_EMC_25_SEMC_ADDR09 +#define MIMXRT_IOMUXC_SEMC_ADDR10 IOMUXC_GPIO_EMC_15_SEMC_ADDR10 +#define MIMXRT_IOMUXC_SEMC_ADDR11 IOMUXC_GPIO_EMC_26_SEMC_ADDR11 +#define MIMXRT_IOMUXC_SEMC_ADDR12 IOMUXC_GPIO_EMC_27_SEMC_ADDR12 + +#define MIMXRT_IOMUXC_SEMC_BA0 IOMUXC_GPIO_EMC_13_SEMC_BA0 +#define MIMXRT_IOMUXC_SEMC_BA1 IOMUXC_GPIO_EMC_14_SEMC_BA1 +#define MIMXRT_IOMUXC_SEMC_CAS IOMUXC_GPIO_EMC_10_SEMC_CAS +#define MIMXRT_IOMUXC_SEMC_CKE IOMUXC_GPIO_EMC_29_SEMC_CKE +#define MIMXRT_IOMUXC_SEMC_CLK IOMUXC_GPIO_EMC_30_SEMC_CLK +#define MIMXRT_IOMUXC_SEMC_DM00 IOMUXC_GPIO_EMC_08_SEMC_DM00 +#define MIMXRT_IOMUXC_SEMC_DM01 IOMUXC_GPIO_EMC_31_SEMC_DM01 +#define MIMXRT_IOMUXC_SEMC_DQS IOMUXC_GPIO_EMC_28_SEMC_DQS +#define MIMXRT_IOMUXC_SEMC_RAS IOMUXC_GPIO_EMC_11_SEMC_RAS +#define MIMXRT_IOMUXC_SEMC_WE IOMUXC_GPIO_EMC_09_SEMC_WE + +#define MIMXRT_IOMUXC_SEMC_CS0 IOMUXC_GPIO_EMC_12_SEMC_CS0 diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk index 34b714e623..e08b3357fd 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk @@ -3,8 +3,11 @@ MCU_VARIANT = MIMXRT1021DAG5A MICROPY_FLOAT_IMPL = double MICROPY_PY_MACHINE_SDCARD = 1 -BOARD_FLASH_TYPE ?= qspi_nor -BOARD_FLASH_SIZE ?= 0x800000 # 8MB +MICROPY_HW_FLASH_TYPE ?= qspi_nor +MICROPY_HW_FLASH_SIZE ?= 0x800000 # 8MB + +MICROPY_HW_SDRAM_AVAIL = 1 +MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB JLINK_PATH ?= /media/RT1020-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1020_EVK/qspi_nor_flash_config.c index 7b2584d3de..fc4d3c10c1 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/qspi_nor_flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/qspi_nor_flash_config.c @@ -45,7 +45,7 @@ const flexspi_nor_config_t qspiflash_config = { .deviceType = kFlexSpiDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_100MHz, - .sflashA1Size = BOARD_FLASH_SIZE, + .sflashA1Size = MICROPY_HW_FLASH_SIZE, .lookupTable = { // 0 Read LUTs 0 -> 0 diff --git a/ports/mimxrt/boards/MIMXRT1021.ld b/ports/mimxrt/boards/MIMXRT1021.ld index 92cd59d668..8d981a7c61 100644 --- a/ports/mimxrt/boards/MIMXRT1021.ld +++ b/ports/mimxrt/boards/MIMXRT1021.ld @@ -1,14 +1,14 @@ /* Memory configuration */ -#if defined BOARD_FLASH_RESERVED -reserved_size = BOARD_FLASH_RESERVED; +#if defined MICROPY_HW_FLASH_RESERVED +reserved_size = MICROPY_HW_FLASH_RESERVED; #endif -#if BOARD_FLASH_TYPE == qspi_nor +#if MICROPY_HW_FLASH_TYPE == qspi_nor flash_start = 0x60000000; #else -#error Unknown BOARD_FLASH_TYPE +#error Unknown MICROPY_HW_FLASH_TYPE #endif -flash_size = BOARD_FLASH_SIZE; +flash_size = MICROPY_HW_FLASH_SIZE; flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); flash_config_start = flash_start; flash_config_size = 0x00001000; @@ -27,11 +27,21 @@ dtcm_size = 0x00018000; ocrm_start = 0x20200000; ocrm_size = 0x00020000; +#ifdef MICROPY_HW_SDRAM_AVAIL +sdram_start = 0x80000000; +sdram_size = MICROPY_HW_SDRAM_SIZE; +#endif + /* 24kiB stack. */ __stack_size__ = 0x6000; _estack = __StackTop; _sstack = __StackLimit; +#ifdef MICROPY_HW_SDRAM_AVAIL +_gc_heap_start = ORIGIN(m_sdram); +_gc_heap_end = ORIGIN(m_sdram) + LENGTH(m_sdram); +#else /* Use second OCRAM bank for GC heap. */ _gc_heap_start = ORIGIN(m_ocrm); _gc_heap_end = ORIGIN(m_ocrm) + LENGTH(m_ocrm); +#endif diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h index b6b70be058..f6021ac788 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h @@ -63,3 +63,48 @@ .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 }, \ .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 }, \ } + +// --- SEMC --- // +#define MIMXRT_IOMUXC_SEMC_DATA00 IOMUXC_GPIO_EMC_00_SEMC_DATA00 +#define MIMXRT_IOMUXC_SEMC_DATA01 IOMUXC_GPIO_EMC_01_SEMC_DATA01 +#define MIMXRT_IOMUXC_SEMC_DATA02 IOMUXC_GPIO_EMC_02_SEMC_DATA02 +#define MIMXRT_IOMUXC_SEMC_DATA03 IOMUXC_GPIO_EMC_03_SEMC_DATA03 +#define MIMXRT_IOMUXC_SEMC_DATA04 IOMUXC_GPIO_EMC_04_SEMC_DATA04 +#define MIMXRT_IOMUXC_SEMC_DATA05 IOMUXC_GPIO_EMC_05_SEMC_DATA05 +#define MIMXRT_IOMUXC_SEMC_DATA06 IOMUXC_GPIO_EMC_06_SEMC_DATA06 +#define MIMXRT_IOMUXC_SEMC_DATA07 IOMUXC_GPIO_EMC_07_SEMC_DATA07 +#define MIMXRT_IOMUXC_SEMC_DATA08 IOMUXC_GPIO_EMC_30_SEMC_DATA08 +#define MIMXRT_IOMUXC_SEMC_DATA09 IOMUXC_GPIO_EMC_31_SEMC_DATA09 +#define MIMXRT_IOMUXC_SEMC_DATA10 IOMUXC_GPIO_EMC_32_SEMC_DATA10 +#define MIMXRT_IOMUXC_SEMC_DATA11 IOMUXC_GPIO_EMC_33_SEMC_DATA11 +#define MIMXRT_IOMUXC_SEMC_DATA12 IOMUXC_GPIO_EMC_34_SEMC_DATA12 +#define MIMXRT_IOMUXC_SEMC_DATA13 IOMUXC_GPIO_EMC_35_SEMC_DATA13 +#define MIMXRT_IOMUXC_SEMC_DATA14 IOMUXC_GPIO_EMC_36_SEMC_DATA14 +#define MIMXRT_IOMUXC_SEMC_DATA15 IOMUXC_GPIO_EMC_37_SEMC_DATA15 + +#define MIMXRT_IOMUXC_SEMC_ADDR00 IOMUXC_GPIO_EMC_09_SEMC_ADDR00 +#define MIMXRT_IOMUXC_SEMC_ADDR01 IOMUXC_GPIO_EMC_10_SEMC_ADDR01 +#define MIMXRT_IOMUXC_SEMC_ADDR02 IOMUXC_GPIO_EMC_11_SEMC_ADDR02 +#define MIMXRT_IOMUXC_SEMC_ADDR03 IOMUXC_GPIO_EMC_12_SEMC_ADDR03 +#define MIMXRT_IOMUXC_SEMC_ADDR04 IOMUXC_GPIO_EMC_13_SEMC_ADDR04 +#define MIMXRT_IOMUXC_SEMC_ADDR05 IOMUXC_GPIO_EMC_14_SEMC_ADDR05 +#define MIMXRT_IOMUXC_SEMC_ADDR06 IOMUXC_GPIO_EMC_15_SEMC_ADDR06 +#define MIMXRT_IOMUXC_SEMC_ADDR07 IOMUXC_GPIO_EMC_16_SEMC_ADDR07 +#define MIMXRT_IOMUXC_SEMC_ADDR08 IOMUXC_GPIO_EMC_17_SEMC_ADDR08 +#define MIMXRT_IOMUXC_SEMC_ADDR09 IOMUXC_GPIO_EMC_18_SEMC_ADDR09 +#define MIMXRT_IOMUXC_SEMC_ADDR10 IOMUXC_GPIO_EMC_23_SEMC_ADDR10 +#define MIMXRT_IOMUXC_SEMC_ADDR11 IOMUXC_GPIO_EMC_19_SEMC_ADDR11 +#define MIMXRT_IOMUXC_SEMC_ADDR12 IOMUXC_GPIO_EMC_20_SEMC_ADDR12 + +#define MIMXRT_IOMUXC_SEMC_BA0 IOMUXC_GPIO_EMC_21_SEMC_BA0 +#define MIMXRT_IOMUXC_SEMC_BA1 IOMUXC_GPIO_EMC_22_SEMC_BA1 +#define MIMXRT_IOMUXC_SEMC_CAS IOMUXC_GPIO_EMC_24_SEMC_CAS +#define MIMXRT_IOMUXC_SEMC_CKE IOMUXC_GPIO_EMC_27_SEMC_CKE +#define MIMXRT_IOMUXC_SEMC_CLK IOMUXC_GPIO_EMC_26_SEMC_CLK +#define MIMXRT_IOMUXC_SEMC_DM00 IOMUXC_GPIO_EMC_08_SEMC_DM00 +#define MIMXRT_IOMUXC_SEMC_DM01 IOMUXC_GPIO_EMC_38_SEMC_DM01 +#define MIMXRT_IOMUXC_SEMC_DQS IOMUXC_GPIO_EMC_39_SEMC_DQS +#define MIMXRT_IOMUXC_SEMC_RAS IOMUXC_GPIO_EMC_25_SEMC_RAS +#define MIMXRT_IOMUXC_SEMC_WE IOMUXC_GPIO_EMC_28_SEMC_WE + +#define MIMXRT_IOMUXC_SEMC_CS0 IOMUXC_GPIO_EMC_29_SEMC_CS0 diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk index 1ea85b7b4f..4165b72c26 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk @@ -3,8 +3,11 @@ MCU_VARIANT = MIMXRT1052DVL6B MICROPY_FLOAT_IMPL = double MICROPY_PY_MACHINE_SDCARD = 1 -BOARD_FLASH_TYPE ?= hyperflash -BOARD_FLASH_SIZE ?= 0x4000000 # 64MB +MICROPY_HW_FLASH_TYPE ?= hyperflash +MICROPY_HW_FLASH_SIZE ?= 0x4000000 # 64MB + +MICROPY_HW_SDRAM_AVAIL = 1 +MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB JLINK_PATH ?= /media/RT1050-EVKB/ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_hyper_flash_config.c b/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_hyper_flash_config.c index 1b3349f911..f5ffbe8413 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_hyper_flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_hyper_flash_config.c @@ -37,7 +37,7 @@ const flexspi_nor_config_t qspiflash_config = { (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), .sflashPadType = kSerialFlash_8Pads, .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = BOARD_FLASH_SIZE, + .sflashA1Size = MICROPY_HW_FLASH_SIZE, .dataValidTime = {16u, 16u}, .lookupTable = { diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_nor_flash_config.c index 290c6bc152..73525b5dfc 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_nor_flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_nor_flash_config.c @@ -37,7 +37,7 @@ const flexspi_nor_config_t qspiflash_config = { (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), .sflashPadType = kSerialFlash_8Pads, .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = BOARD_FLASH_SIZE, + .sflashA1Size = MICROPY_HW_FLASH_SIZE, .dataValidTime = {16u, 16u}, .lookupTable = { diff --git a/ports/mimxrt/boards/MIMXRT1052.ld b/ports/mimxrt/boards/MIMXRT1052.ld index d8c51d530a..78d21ef3c4 100644 --- a/ports/mimxrt/boards/MIMXRT1052.ld +++ b/ports/mimxrt/boards/MIMXRT1052.ld @@ -1,16 +1,16 @@ /* Memory configuration */ -#if BOARD_FLASH_RESERVED -reserved_size = BOARD_FLASH_RESERVED; +#if MICROPY_HW_FLASH_RESERVED +reserved_size = MICROPY_HW_FLASH_RESERVED; #endif -#if BOARD_FLASH_TYPE==qspi_nor +#if MICROPY_HW_FLASH_TYPE==qspi_nor flash_start = 0x60000000; -#elif BOARD_FLASH_TYPE==hyperflash +#elif MICROPY_HW_FLASH_TYPE==hyperflash flash_start = 0x60000000; #else -#error Unknown BOARD_FLASH_TYPE +#error Unknown MICROPY_HW_FLASH_TYPE #endif -flash_size = BOARD_FLASH_SIZE; +flash_size = MICROPY_HW_FLASH_SIZE; flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); flash_config_start = flash_start; flash_config_size = 0x00001000; @@ -29,11 +29,21 @@ dtcm_size = 0x00020000; ocrm_start = 0x20200000; ocrm_size = 0x00040000; +#ifdef MICROPY_HW_SDRAM_AVAIL +sdram_start = 0x80000000; +sdram_size = MICROPY_HW_SDRAM_SIZE; +#endif + /* 24kiB stack. */ __stack_size__ = 0x6000; _estack = __StackTop; _sstack = __StackLimit; +#ifdef MICROPY_HW_SDRAM_AVAIL +_gc_heap_start = ORIGIN(m_sdram); +_gc_heap_end = ORIGIN(m_sdram) + LENGTH(m_sdram); +#else /* Use second OCRAM bank for GC heap. */ _gc_heap_start = ORIGIN(m_ocrm); _gc_heap_end = ORIGIN(m_ocrm) + LENGTH(m_ocrm); +#endif diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h index 5cf31aa25a..af44010486 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h @@ -62,3 +62,48 @@ .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 }, \ .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 }, \ } + +// --- SEMC --- // +#define MIMXRT_IOMUXC_SEMC_DATA00 IOMUXC_GPIO_EMC_00_SEMC_DATA00 +#define MIMXRT_IOMUXC_SEMC_DATA01 IOMUXC_GPIO_EMC_01_SEMC_DATA01 +#define MIMXRT_IOMUXC_SEMC_DATA02 IOMUXC_GPIO_EMC_02_SEMC_DATA02 +#define MIMXRT_IOMUXC_SEMC_DATA03 IOMUXC_GPIO_EMC_03_SEMC_DATA03 +#define MIMXRT_IOMUXC_SEMC_DATA04 IOMUXC_GPIO_EMC_04_SEMC_DATA04 +#define MIMXRT_IOMUXC_SEMC_DATA05 IOMUXC_GPIO_EMC_05_SEMC_DATA05 +#define MIMXRT_IOMUXC_SEMC_DATA06 IOMUXC_GPIO_EMC_06_SEMC_DATA06 +#define MIMXRT_IOMUXC_SEMC_DATA07 IOMUXC_GPIO_EMC_07_SEMC_DATA07 +#define MIMXRT_IOMUXC_SEMC_DATA08 IOMUXC_GPIO_EMC_30_SEMC_DATA08 +#define MIMXRT_IOMUXC_SEMC_DATA09 IOMUXC_GPIO_EMC_31_SEMC_DATA09 +#define MIMXRT_IOMUXC_SEMC_DATA10 IOMUXC_GPIO_EMC_32_SEMC_DATA10 +#define MIMXRT_IOMUXC_SEMC_DATA11 IOMUXC_GPIO_EMC_33_SEMC_DATA11 +#define MIMXRT_IOMUXC_SEMC_DATA12 IOMUXC_GPIO_EMC_34_SEMC_DATA12 +#define MIMXRT_IOMUXC_SEMC_DATA13 IOMUXC_GPIO_EMC_35_SEMC_DATA13 +#define MIMXRT_IOMUXC_SEMC_DATA14 IOMUXC_GPIO_EMC_36_SEMC_DATA14 +#define MIMXRT_IOMUXC_SEMC_DATA15 IOMUXC_GPIO_EMC_37_SEMC_DATA15 + +#define MIMXRT_IOMUXC_SEMC_ADDR00 IOMUXC_GPIO_EMC_09_SEMC_ADDR00 +#define MIMXRT_IOMUXC_SEMC_ADDR01 IOMUXC_GPIO_EMC_10_SEMC_ADDR01 +#define MIMXRT_IOMUXC_SEMC_ADDR02 IOMUXC_GPIO_EMC_11_SEMC_ADDR02 +#define MIMXRT_IOMUXC_SEMC_ADDR03 IOMUXC_GPIO_EMC_12_SEMC_ADDR03 +#define MIMXRT_IOMUXC_SEMC_ADDR04 IOMUXC_GPIO_EMC_13_SEMC_ADDR04 +#define MIMXRT_IOMUXC_SEMC_ADDR05 IOMUXC_GPIO_EMC_14_SEMC_ADDR05 +#define MIMXRT_IOMUXC_SEMC_ADDR06 IOMUXC_GPIO_EMC_15_SEMC_ADDR06 +#define MIMXRT_IOMUXC_SEMC_ADDR07 IOMUXC_GPIO_EMC_16_SEMC_ADDR07 +#define MIMXRT_IOMUXC_SEMC_ADDR08 IOMUXC_GPIO_EMC_17_SEMC_ADDR08 +#define MIMXRT_IOMUXC_SEMC_ADDR09 IOMUXC_GPIO_EMC_18_SEMC_ADDR09 +#define MIMXRT_IOMUXC_SEMC_ADDR10 IOMUXC_GPIO_EMC_23_SEMC_ADDR10 +#define MIMXRT_IOMUXC_SEMC_ADDR11 IOMUXC_GPIO_EMC_19_SEMC_ADDR11 +#define MIMXRT_IOMUXC_SEMC_ADDR12 IOMUXC_GPIO_EMC_20_SEMC_ADDR12 + +#define MIMXRT_IOMUXC_SEMC_BA0 IOMUXC_GPIO_EMC_21_SEMC_BA0 +#define MIMXRT_IOMUXC_SEMC_BA1 IOMUXC_GPIO_EMC_22_SEMC_BA1 +#define MIMXRT_IOMUXC_SEMC_CAS IOMUXC_GPIO_EMC_24_SEMC_CAS +#define MIMXRT_IOMUXC_SEMC_CKE IOMUXC_GPIO_EMC_27_SEMC_CKE +#define MIMXRT_IOMUXC_SEMC_CLK IOMUXC_GPIO_EMC_26_SEMC_CLK +#define MIMXRT_IOMUXC_SEMC_DM00 IOMUXC_GPIO_EMC_08_SEMC_DM00 +#define MIMXRT_IOMUXC_SEMC_DM01 IOMUXC_GPIO_EMC_38_SEMC_DM01 +#define MIMXRT_IOMUXC_SEMC_DQS IOMUXC_GPIO_EMC_39_SEMC_DQS +#define MIMXRT_IOMUXC_SEMC_RAS IOMUXC_GPIO_EMC_25_SEMC_RAS +#define MIMXRT_IOMUXC_SEMC_WE IOMUXC_GPIO_EMC_28_SEMC_WE + +#define MIMXRT_IOMUXC_SEMC_CS0 IOMUXC_GPIO_EMC_29_SEMC_CS0 diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk index 1e041c8eb5..4c4a2ff980 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk @@ -3,8 +3,11 @@ MCU_VARIANT = MIMXRT1062DVJ6A MICROPY_FLOAT_IMPL = double MICROPY_PY_MACHINE_SDCARD = 1 -BOARD_FLASH_TYPE ?= qspi_nor -BOARD_FLASH_SIZE ?= 0x800000 # 8MB +MICROPY_HW_FLASH_TYPE ?= qspi_nor +MICROPY_HW_FLASH_SIZE ?= 0x800000 # 8MB + +MICROPY_HW_SDRAM_AVAIL = 1 +MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB JLINK_PATH ?= /media/RT1060-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_hyper_flash_config.c b/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_hyper_flash_config.c index 1b3349f911..f5ffbe8413 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_hyper_flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_hyper_flash_config.c @@ -37,7 +37,7 @@ const flexspi_nor_config_t qspiflash_config = { (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), .sflashPadType = kSerialFlash_8Pads, .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = BOARD_FLASH_SIZE, + .sflashA1Size = MICROPY_HW_FLASH_SIZE, .dataValidTime = {16u, 16u}, .lookupTable = { diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_nor_flash_config.c index 290c6bc152..73525b5dfc 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_nor_flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_nor_flash_config.c @@ -37,7 +37,7 @@ const flexspi_nor_config_t qspiflash_config = { (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), .sflashPadType = kSerialFlash_8Pads, .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = BOARD_FLASH_SIZE, + .sflashA1Size = MICROPY_HW_FLASH_SIZE, .dataValidTime = {16u, 16u}, .lookupTable = { diff --git a/ports/mimxrt/boards/MIMXRT1062.ld b/ports/mimxrt/boards/MIMXRT1062.ld index 03c1193344..f588e5bd9e 100644 --- a/ports/mimxrt/boards/MIMXRT1062.ld +++ b/ports/mimxrt/boards/MIMXRT1062.ld @@ -1,16 +1,16 @@ /* Memory configuration */ -#if BOARD_FLASH_RESERVED -reserved_size = BOARD_FLASH_RESERVED; +#if MICROPY_HW_FLASH_RESERVED +reserved_size = MICROPY_HW_FLASH_RESERVED; #endif -#if BOARD_FLASH_TYPE==qspi_nor +#if MICROPY_HW_FLASH_TYPE==qspi_nor flash_start = 0x60000000; -#elif BOARD_FLASH_TYPE==hyperflash +#elif MICROPY_HW_FLASH_TYPE==hyperflash flash_start = 0x60000000; #else -#error Unknown BOARD_FLASH_TYPE +#error Unknown MICROPY_HW_FLASH_TYPE #endif -flash_size = BOARD_FLASH_SIZE; +flash_size = MICROPY_HW_FLASH_SIZE; flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); flash_config_start = flash_start; flash_config_size = 0x00001000; @@ -29,11 +29,21 @@ dtcm_size = 0x00020000; ocrm_start = 0x20200000; ocrm_size = 0x000C0000; +#ifdef MICROPY_HW_SDRAM_AVAIL +sdram_start = 0x80000000; +sdram_size = MICROPY_HW_SDRAM_SIZE; +#endif + /* 32kiB stack. */ __stack_size__ = 0x8000; _estack = __StackTop; _sstack = __StackLimit; +#ifdef MICROPY_HW_SDRAM_AVAIL +_gc_heap_start = ORIGIN(m_sdram); +_gc_heap_end = ORIGIN(m_sdram) + LENGTH(m_sdram); +#else /* Use second OCRAM bank for GC heap. */ _gc_heap_start = ORIGIN(m_ocrm); _gc_heap_end = ORIGIN(m_ocrm) + LENGTH(m_ocrm); +#endif diff --git a/ports/mimxrt/boards/MIMXRT1064.ld b/ports/mimxrt/boards/MIMXRT1064.ld index 88720896f4..b36c528453 100644 --- a/ports/mimxrt/boards/MIMXRT1064.ld +++ b/ports/mimxrt/boards/MIMXRT1064.ld @@ -1,18 +1,18 @@ /* Memory configuration */ -#if BOARD_FLASH_RESERVED -reserved_size = BOARD_FLASH_RESERVED; +#if MICROPY_HW_FLASH_RESERVED +reserved_size = MICROPY_HW_FLASH_RESERVED; #endif -#if BOARD_FLASH_TYPE==qspi_nor +#if MICROPY_HW_FLASH_TYPE==qspi_nor flash_start = 0x60000000; -#elif BOARD_FLASH_TYPE==hyperflash +#elif MICROPY_HW_FLASH_TYPE==hyperflash flash_start = 0x60000000; -#elif BOARD_FLASH_TYPE==internal +#elif MICROPY_HW_FLASH_TYPE==internal flash_start = 0x70000000; #else -#error Unknown BOARD_FLASH_TYPE +#error Unknown MICROPY_HW_FLASH_TYPE #endif -flash_size = BOARD_FLASH_SIZE; +flash_size = MICROPY_HW_FLASH_SIZE; flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); flash_config_start = flash_start; flash_config_size = 0x00001000; @@ -31,11 +31,21 @@ dtcm_size = 0x00020000; ocrm_start = 0x20200000; ocrm_size = 0x000C0000; +#ifdef MICROPY_HW_SDRAM_AVAIL +sdram_start = 0x80000000; +sdram_size = MICROPY_HW_SDRAM_SIZE; +#endif + /* 24kiB stack. */ __stack_size__ = 0x6000; _estack = __StackTop; _sstack = __StackLimit; +#ifdef MICROPY_HW_SDRAM_AVAIL +_gc_heap_start = ORIGIN(m_sdram); +_gc_heap_end = ORIGIN(m_sdram) + LENGTH(m_sdram); +#else /* Use second OCRAM bank for GC heap. */ _gc_heap_start = ORIGIN(m_ocrm); _gc_heap_end = ORIGIN(m_ocrm) + LENGTH(m_ocrm); +#endif diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h index ab8a80a3a4..17268b0a56 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h @@ -62,3 +62,48 @@ .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 }, \ .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 }, \ } + +// --- SEMC --- // +#define MIMXRT_IOMUXC_SEMC_DATA00 IOMUXC_GPIO_EMC_00_SEMC_DATA00 +#define MIMXRT_IOMUXC_SEMC_DATA01 IOMUXC_GPIO_EMC_01_SEMC_DATA01 +#define MIMXRT_IOMUXC_SEMC_DATA02 IOMUXC_GPIO_EMC_02_SEMC_DATA02 +#define MIMXRT_IOMUXC_SEMC_DATA03 IOMUXC_GPIO_EMC_03_SEMC_DATA03 +#define MIMXRT_IOMUXC_SEMC_DATA04 IOMUXC_GPIO_EMC_04_SEMC_DATA04 +#define MIMXRT_IOMUXC_SEMC_DATA05 IOMUXC_GPIO_EMC_05_SEMC_DATA05 +#define MIMXRT_IOMUXC_SEMC_DATA06 IOMUXC_GPIO_EMC_06_SEMC_DATA06 +#define MIMXRT_IOMUXC_SEMC_DATA07 IOMUXC_GPIO_EMC_07_SEMC_DATA07 +#define MIMXRT_IOMUXC_SEMC_DATA08 IOMUXC_GPIO_EMC_30_SEMC_DATA08 +#define MIMXRT_IOMUXC_SEMC_DATA09 IOMUXC_GPIO_EMC_31_SEMC_DATA09 +#define MIMXRT_IOMUXC_SEMC_DATA10 IOMUXC_GPIO_EMC_32_SEMC_DATA10 +#define MIMXRT_IOMUXC_SEMC_DATA11 IOMUXC_GPIO_EMC_33_SEMC_DATA11 +#define MIMXRT_IOMUXC_SEMC_DATA12 IOMUXC_GPIO_EMC_34_SEMC_DATA12 +#define MIMXRT_IOMUXC_SEMC_DATA13 IOMUXC_GPIO_EMC_35_SEMC_DATA13 +#define MIMXRT_IOMUXC_SEMC_DATA14 IOMUXC_GPIO_EMC_36_SEMC_DATA14 +#define MIMXRT_IOMUXC_SEMC_DATA15 IOMUXC_GPIO_EMC_37_SEMC_DATA15 + +#define MIMXRT_IOMUXC_SEMC_ADDR00 IOMUXC_GPIO_EMC_09_SEMC_ADDR00 +#define MIMXRT_IOMUXC_SEMC_ADDR01 IOMUXC_GPIO_EMC_10_SEMC_ADDR01 +#define MIMXRT_IOMUXC_SEMC_ADDR02 IOMUXC_GPIO_EMC_11_SEMC_ADDR02 +#define MIMXRT_IOMUXC_SEMC_ADDR03 IOMUXC_GPIO_EMC_12_SEMC_ADDR03 +#define MIMXRT_IOMUXC_SEMC_ADDR04 IOMUXC_GPIO_EMC_13_SEMC_ADDR04 +#define MIMXRT_IOMUXC_SEMC_ADDR05 IOMUXC_GPIO_EMC_14_SEMC_ADDR05 +#define MIMXRT_IOMUXC_SEMC_ADDR06 IOMUXC_GPIO_EMC_15_SEMC_ADDR06 +#define MIMXRT_IOMUXC_SEMC_ADDR07 IOMUXC_GPIO_EMC_16_SEMC_ADDR07 +#define MIMXRT_IOMUXC_SEMC_ADDR08 IOMUXC_GPIO_EMC_17_SEMC_ADDR08 +#define MIMXRT_IOMUXC_SEMC_ADDR09 IOMUXC_GPIO_EMC_18_SEMC_ADDR09 +#define MIMXRT_IOMUXC_SEMC_ADDR10 IOMUXC_GPIO_EMC_23_SEMC_ADDR10 +#define MIMXRT_IOMUXC_SEMC_ADDR11 IOMUXC_GPIO_EMC_19_SEMC_ADDR11 +#define MIMXRT_IOMUXC_SEMC_ADDR12 IOMUXC_GPIO_EMC_20_SEMC_ADDR12 + +#define MIMXRT_IOMUXC_SEMC_BA0 IOMUXC_GPIO_EMC_21_SEMC_BA0 +#define MIMXRT_IOMUXC_SEMC_BA1 IOMUXC_GPIO_EMC_22_SEMC_BA1 +#define MIMXRT_IOMUXC_SEMC_CAS IOMUXC_GPIO_EMC_24_SEMC_CAS +#define MIMXRT_IOMUXC_SEMC_CKE IOMUXC_GPIO_EMC_27_SEMC_CKE +#define MIMXRT_IOMUXC_SEMC_CLK IOMUXC_GPIO_EMC_26_SEMC_CLK +#define MIMXRT_IOMUXC_SEMC_DM00 IOMUXC_GPIO_EMC_08_SEMC_DM00 +#define MIMXRT_IOMUXC_SEMC_DM01 IOMUXC_GPIO_EMC_38_SEMC_DM01 +#define MIMXRT_IOMUXC_SEMC_DQS IOMUXC_GPIO_EMC_39_SEMC_DQS +#define MIMXRT_IOMUXC_SEMC_RAS IOMUXC_GPIO_EMC_25_SEMC_RAS +#define MIMXRT_IOMUXC_SEMC_WE IOMUXC_GPIO_EMC_28_SEMC_WE + +#define MIMXRT_IOMUXC_SEMC_CS0 IOMUXC_GPIO_EMC_29_SEMC_CS0 diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk index 19655da616..8bc35dd0dd 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk @@ -3,8 +3,11 @@ MCU_VARIANT = MIMXRT1064DVL6A MICROPY_FLOAT_IMPL = double MICROPY_PY_MACHINE_SDCARD = 1 -BOARD_FLASH_TYPE ?= hyperflash -BOARD_FLASH_SIZE ?= 0x4000000 # 64MB +MICROPY_HW_FLASH_TYPE ?= hyperflash +MICROPY_HW_FLASH_SIZE ?= 0x4000000 # 64MB + +MICROPY_HW_SDRAM_AVAIL = 1 +MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB JLINK_PATH ?= /media/RT1064-EVK/ diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_hyper_flash_config.c b/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_hyper_flash_config.c index 1b3349f911..f5ffbe8413 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_hyper_flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_hyper_flash_config.c @@ -37,7 +37,7 @@ const flexspi_nor_config_t qspiflash_config = { (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), .sflashPadType = kSerialFlash_8Pads, .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = BOARD_FLASH_SIZE, + .sflashA1Size = MICROPY_HW_FLASH_SIZE, .dataValidTime = {16u, 16u}, .lookupTable = { diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_nor_flash_config.c index 290c6bc152..73525b5dfc 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_nor_flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_nor_flash_config.c @@ -37,7 +37,7 @@ const flexspi_nor_config_t qspiflash_config = { (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), .sflashPadType = kSerialFlash_8Pads, .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = BOARD_FLASH_SIZE, + .sflashA1Size = MICROPY_HW_FLASH_SIZE, .dataValidTime = {16u, 16u}, .lookupTable = { diff --git a/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk b/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk index 170f93dcf8..94e427cc16 100644 --- a/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk +++ b/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk @@ -3,9 +3,9 @@ MCU_VARIANT = MIMXRT1062DVJ6A MICROPY_FLOAT_IMPL = double MICROPY_PY_MACHINE_SDCARD = 1 -BOARD_FLASH_TYPE ?= qspi_nor -BOARD_FLASH_SIZE ?= 0x200000 # 2MB -BOARD_FLASH_RESERVED ?= 0x1000 # 4KB +MICROPY_HW_FLASH_TYPE ?= qspi_nor +MICROPY_HW_FLASH_SIZE ?= 0x200000 # 2MB +MICROPY_HW_FLASH_RESERVED ?= 0x1000 # 4KB deploy: $(BUILD)/firmware.hex teensy_loader_cli --mcu=imxrt1062 -v -w $< diff --git a/ports/mimxrt/boards/TEENSY40/qspi_nor_flash_config.c b/ports/mimxrt/boards/TEENSY40/qspi_nor_flash_config.c index 71d871b751..69135f6b47 100644 --- a/ports/mimxrt/boards/TEENSY40/qspi_nor_flash_config.c +++ b/ports/mimxrt/boards/TEENSY40/qspi_nor_flash_config.c @@ -53,7 +53,7 @@ const flexspi_nor_config_t qspiflash_config = { // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_60MHz, - .sflashA1Size = BOARD_FLASH_SIZE, + .sflashA1Size = MICROPY_HW_FLASH_SIZE, .lookupTable = { // 0 Read LUTs 0 -> 0 diff --git a/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk b/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk index 9a29a9b75d..27039648b8 100755 --- a/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk +++ b/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk @@ -3,9 +3,9 @@ MCU_VARIANT = MIMXRT1062DVJ6A MICROPY_FLOAT_IMPL = double MICROPY_PY_MACHINE_SDCARD = 1 -BOARD_FLASH_TYPE ?= qspi_nor -BOARD_FLASH_SIZE ?= 0x800000 # 8MB -BOARD_FLASH_RESERVED ?= 0x1000 # 4KB +MICROPY_HW_FLASH_TYPE ?= qspi_nor +MICROPY_HW_FLASH_SIZE ?= 0x800000 # 8MB +MICROPY_HW_FLASH_RESERVED ?= 0x1000 # 4KB deploy: $(BUILD)/firmware.hex teensy_loader_cli --mcu=imxrt1062 -v -w $< diff --git a/ports/mimxrt/boards/TEENSY41/qspi_nor_flash_config.c b/ports/mimxrt/boards/TEENSY41/qspi_nor_flash_config.c index 71d871b751..69135f6b47 100644 --- a/ports/mimxrt/boards/TEENSY41/qspi_nor_flash_config.c +++ b/ports/mimxrt/boards/TEENSY41/qspi_nor_flash_config.c @@ -53,7 +53,7 @@ const flexspi_nor_config_t qspiflash_config = { // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_60MHz, - .sflashA1Size = BOARD_FLASH_SIZE, + .sflashA1Size = MICROPY_HW_FLASH_SIZE, .lookupTable = { // 0 Read LUTs 0 -> 0 diff --git a/ports/mimxrt/boards/common.ld b/ports/mimxrt/boards/common.ld index 6f45da24d1..5dd7097fab 100644 --- a/ports/mimxrt/boards/common.ld +++ b/ports/mimxrt/boards/common.ld @@ -45,12 +45,19 @@ MEMORY m_itcm (RX) : ORIGIN = itcm_start, LENGTH = itcm_size m_dtcm (RW) : ORIGIN = dtcm_start, LENGTH = dtcm_size m_ocrm (RW) : ORIGIN = ocrm_start, LENGTH = ocrm_size + + #ifdef MICROPY_HW_SDRAM_AVAIL + m_sdram (RX) : ORIGIN = sdram_start, LENGTH = sdram_size + #endif } /* Define output sections */ SECTIONS { __flash_start = flash_start; + #ifdef MICROPY_HW_SDRAM_AVAIL + __sdram_start = sdram_start; + #endif __vfs_start = ORIGIN(m_vfs); __vfs_end = __vfs_start + LENGTH(m_vfs); diff --git a/ports/mimxrt/boards/make-pins.py b/ports/mimxrt/boards/make-pins.py index d75592124a..aba517127c 100644 --- a/ports/mimxrt/boards/make-pins.py +++ b/ports/mimxrt/boards/make-pins.py @@ -8,7 +8,7 @@ import sys import csv import re -SUPPORTED_AFS = {"GPIO", "USDHC"} +SUPPORTED_AFS = {"GPIO", "USDHC", "SEMC"} MAX_AF = 10 # AF0 .. AF9 ADC_COL = 11 diff --git a/ports/mimxrt/mimxrt_flash.c b/ports/mimxrt/mimxrt_flash.c index 79c4e676dc..25a11ab7ca 100644 --- a/ports/mimxrt/mimxrt_flash.c +++ b/ports/mimxrt/mimxrt_flash.c @@ -32,8 +32,6 @@ #include "modmimxrt.h" #include BOARD_FLASH_OPS_HEADER_H -// BOARD_FLASH_SIZE is defined in mpconfigport.h - #define SECTOR_SIZE_BYTES (qspiflash_config.sectorSize) #define PAGE_SIZE_BYTES (qspiflash_config.pageSize) diff --git a/ports/mimxrt/mimxrt_sdram.c b/ports/mimxrt/mimxrt_sdram.c new file mode 100644 index 0000000000..8c336bb607 --- /dev/null +++ b/ports/mimxrt/mimxrt_sdram.c @@ -0,0 +1,186 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Philipp Ebensberger + * + * 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. + */ + +#if MICROPY_HW_SDRAM_AVAIL + +#include "modmachine.h" +#include "fsl_semc.h" +#include "fsl_iomuxc.h" + +// Linker symbols +extern uint8_t __sdram_start; + + +void mimxrt_sdram_init(void) { + // Set Clocks + CLOCK_InitSysPfd(kCLOCK_Pfd2, 29); // '29' PLL2 PFD2 frequency = 528MHz * 18 / 29 = 327.72MHz (with 528MHz = PLL2 frequency) + CLOCK_SetMux(kCLOCK_SemcAltMux, 0); // '0' PLL2 PFD2 will be selected as alternative clock for SEMC root clock + CLOCK_SetMux(kCLOCK_SemcMux, 1); // '1' SEMC alternative clock will be used as SEMC clock root + CLOCK_SetDiv(kCLOCK_SemcDiv, 1); // '1' divide by 2 -> SEMC clock = 163.86 MHz + + // Set Pins + + // Data Pins + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA00, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA00, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA01, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA01, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA02, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA02, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA03, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA03, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA04, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA04, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA05, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA05, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA06, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA06, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA07, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA07, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA08, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA08, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA09, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA09, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA10, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA10, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA11, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA11, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA12, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA12, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA13, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA13, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA14, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA14, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DATA15, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DATA15, 0xE1UL); + + // Address Pins + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_ADDR00, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_ADDR00, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_ADDR01, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_ADDR01, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_ADDR02, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_ADDR02, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_ADDR03, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_ADDR03, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_ADDR04, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_ADDR04, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_ADDR05, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_ADDR05, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_ADDR06, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_ADDR06, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_ADDR07, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_ADDR07, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_ADDR08, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_ADDR08, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_ADDR09, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_ADDR09, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_ADDR10, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_ADDR10, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_ADDR11, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_ADDR11, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_ADDR12, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_ADDR12, 0xE1UL); + + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DM00, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DM00, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_BA0, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_BA0, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_BA1, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_BA1, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_CAS, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_CAS, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_RAS, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_RAS, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_CLK, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_CLK, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_CKE, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_CKE, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_WE, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_WE, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DM01, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DM01, 0xE1UL); + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_DQS, 1UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_DQS, 0xE1UL); + + // Chip Select Pins + #ifndef MIMXRT_IOMUXC_SEMC_CS0 + #error No SEMC CS0 defined! + #endif + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_CS0, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_CS0, 0xE1UL); + + #ifdef MIMXRT_IOMUXC_SEMC_CS1 + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_CS1, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_CS1, 0xE1UL); + #endif + + #ifdef MIMXRT_IOMUXC_SEMC_CS2 + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_CS2, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_CS2, 0xE1UL); + #endif + + #ifdef MIMXRT_IOMUXC_SEMC_CS3 + IOMUXC_SetPinMux(MIMXRT_IOMUXC_SEMC_CS3, 0UL); + IOMUXC_SetPinConfig(MIMXRT_IOMUXC_SEMC_CS3, 0xE1UL); + #endif + + // Configure SEMC + semc_config_t semc_cfg; + SEMC_GetDefaultConfig(&semc_cfg); + + semc_cfg.dqsMode = kSEMC_Loopbackdqspad; // For more accurate timing. + SEMC_Init(SEMC, &semc_cfg); + + uint32_t clock_freq = CLOCK_GetFreq(kCLOCK_SemcClk); + semc_sdram_config_t sdram_cfg = { + .csxPinMux = kSEMC_MUXCSX0, + .address = ((uint32_t)&__sdram_start), + .memsize_kbytes = (MICROPY_HW_SDRAM_SIZE >> 10), // Right shift by 10 == division by 1024 + .portSize = kSEMC_PortSize16Bit, + .burstLen = kSEMC_Sdram_BurstLen1, + .columnAddrBitNum = kSEMC_SdramColunm_9bit, + .casLatency = kSEMC_LatencyThree, + .tPrecharge2Act_Ns = 18, // Trp 18ns + .tAct2ReadWrite_Ns = 18, // Trcd 18ns + .tRefreshRecovery_Ns = (60 + 67), + .tWriteRecovery_Ns = 12, // 12ns + .tCkeOff_Ns = 42, // The minimum cycle of SDRAM CLK off state. CKE is off in self refresh at a minimum period tRAS. + .tAct2Prechage_Ns = 42, // Tras 42ns + .tSelfRefRecovery_Ns = 67, + .tRefresh2Refresh_Ns = 60, + .tAct2Act_Ns = 60, + .tPrescalePeriod_Ns = 160 * (1000000000 / clock_freq), + .tIdleTimeout_Ns = 0UL, + .refreshPeriod_nsPerRow = 64 * 1000000 / 8192, // 64ms/8192 + .refreshUrgThreshold = 64 * 1000000 / 8192, // 64ms/8192 + .refreshBurstLen = 1 + }; + + (status_t)SEMC_ConfigureSDRAM(SEMC, kSEMC_SDRAM_CS0, &sdram_cfg, clock_freq); +} + +#endif diff --git a/ports/mimxrt/modmachine.h b/ports/mimxrt/modmachine.h index e1a7ce0b72..90d167843a 100644 --- a/ports/mimxrt/modmachine.h +++ b/ports/mimxrt/modmachine.h @@ -41,5 +41,6 @@ void machine_adc_init(void); void machine_pin_irq_deinit(void); void machine_timer_init_PIT(void); void machine_sdcard_init0(void); +void mimxrt_sdram_init(void); #endif // MICROPY_INCLUDED_MIMXRT_MODMACHINE_H diff --git a/ports/mimxrt/pin.h b/ports/mimxrt/pin.h index 3520ed0f4f..22e7a7e0f5 100644 --- a/ports/mimxrt/pin.h +++ b/ports/mimxrt/pin.h @@ -67,6 +67,7 @@ enum { PIN_AF_MODE_ALT6, PIN_AF_MODE_ALT7, PIN_AF_MODE_ALT8, + PIN_AF_MODE_ALT9, }; enum { From 1866ed7e2ef9a2786aa5cc93dd435ffc8dcce2a3 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 3 Jul 2021 18:39:17 +0200 Subject: [PATCH 094/335] mimxrt/eth: Add LAN support and integrate the network module. This commit implements 10/100 Mbit Ethernet support in the mimxrt port. The following boards are configured without ETH network: - MIMXRT1010_EVK - Teensy 4.0 The following boards are configured with ETH network: - MIMXRT1020_EVK - MIMXRT1050_EVK - MIMXRT1060_EVK - MIMXRT1064_EVK - Teensy 4.1 Ethernet support tested with TEENSY 4.1, MIMRTX1020_EVK and MIMXRT1050_EVK. Build tested with Teensy 4.0 and MIMXRT1010_EVK to be still working. Compiles and builds properly for MIMXRT1060_EVK and MIMXRT1064_EVK, but not tested lacking suitable boards. Tested functions are: - ping works bothway - simple UDP transfer works bothway - ntptime works - the ftp server works - secure socker works - telnet and webrepl works The MAC address is 0x02 plus 5 bytes from the manifacturing info field, which can be considered as unique per device. Some boards do not wire the RESET and INT pin of the PHY transceiver. For operation, these are not required. If they are defined, they will be used. --- ports/mimxrt/Makefile | 48 +- ports/mimxrt/board_init.c | 3 + .../boards/MIMXRT1020_EVK/mpconfigboard.h | 21 + .../boards/MIMXRT1020_EVK/mpconfigboard.mk | 4 + ports/mimxrt/boards/MIMXRT1021.ld | 1 + .../boards/MIMXRT1050_EVK/mpconfigboard.h | 23 +- .../boards/MIMXRT1050_EVK/mpconfigboard.mk | 7 +- .../boards/MIMXRT1060_EVK/mpconfigboard.h | 21 + .../boards/MIMXRT1060_EVK/mpconfigboard.mk | 4 + .../boards/MIMXRT1064_EVK/mpconfigboard.h | 21 + .../boards/MIMXRT1064_EVK/mpconfigboard.mk | 4 + ports/mimxrt/boards/TEENSY41/mpconfigboard.h | 21 + ports/mimxrt/boards/TEENSY41/mpconfigboard.mk | 4 + ports/mimxrt/eth.c | 448 ++++++++++++++++++ ports/mimxrt/eth.h | 41 ++ .../phy/device/phydp83825/fsl_phydp83825.c | 281 +++++++++++ .../phy/device/phydp83825/fsl_phydp83825.h | 163 +++++++ .../phy/device/phyksz8081/fsl_phyksz8081.c | 284 +++++++++++ .../phy/device/phyksz8081/fsl_phyksz8081.h | 163 +++++++ .../phy/device/phylan8720/fsl_phylan8720.c | 271 +++++++++++ .../phy/device/phylan8720/fsl_phylan8720.h | 163 +++++++ ports/mimxrt/hal/phy/fsl_mdio.h | 125 +++++ ports/mimxrt/hal/phy/fsl_phy.h | 258 ++++++++++ .../mimxrt/hal/phy/mdio/enet/fsl_enet_mdio.c | 128 +++++ .../mimxrt/hal/phy/mdio/enet/fsl_enet_mdio.h | 21 + ports/mimxrt/lwip_inc/arch/cc.h | 10 + ports/mimxrt/lwip_inc/arch/sys_arch.h | 1 + ports/mimxrt/lwip_inc/lwipopts.h | 59 +++ ports/mimxrt/main.c | 26 + ports/mimxrt/mbedtls/mbedtls_config.h | 99 ++++ ports/mimxrt/mbedtls/mbedtls_port.c | 93 ++++ ports/mimxrt/moduos.c | 18 + ports/mimxrt/mpconfigport.h | 69 ++- ports/mimxrt/mphalport.c | 42 ++ ports/mimxrt/mphalport.h | 12 + ports/mimxrt/mpnetworkport.c | 64 +++ ports/mimxrt/network_lan.c | 171 +++++++ ports/mimxrt/pendsv.c | 73 +++ ports/mimxrt/pendsv.h | 44 ++ ports/mimxrt/pin.c | 15 + ports/mimxrt/systick.c | 60 +++ ports/mimxrt/systick.h | 60 +++ 42 files changed, 3436 insertions(+), 8 deletions(-) create mode 100644 ports/mimxrt/eth.c create mode 100644 ports/mimxrt/eth.h create mode 100644 ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.c create mode 100644 ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.h create mode 100644 ports/mimxrt/hal/phy/device/phyksz8081/fsl_phyksz8081.c create mode 100644 ports/mimxrt/hal/phy/device/phyksz8081/fsl_phyksz8081.h create mode 100644 ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.c create mode 100644 ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.h create mode 100644 ports/mimxrt/hal/phy/fsl_mdio.h create mode 100644 ports/mimxrt/hal/phy/fsl_phy.h create mode 100644 ports/mimxrt/hal/phy/mdio/enet/fsl_enet_mdio.c create mode 100644 ports/mimxrt/hal/phy/mdio/enet/fsl_enet_mdio.h create mode 100644 ports/mimxrt/lwip_inc/arch/cc.h create mode 100644 ports/mimxrt/lwip_inc/arch/sys_arch.h create mode 100644 ports/mimxrt/lwip_inc/lwipopts.h create mode 100644 ports/mimxrt/mbedtls/mbedtls_config.h create mode 100644 ports/mimxrt/mbedtls/mbedtls_port.c create mode 100644 ports/mimxrt/mpnetworkport.c create mode 100644 ports/mimxrt/network_lan.c create mode 100644 ports/mimxrt/pendsv.c create mode 100644 ports/mimxrt/pendsv.h create mode 100644 ports/mimxrt/systick.c create mode 100644 ports/mimxrt/systick.h diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 1b83f36abf..16aac389d1 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -43,7 +43,7 @@ MICROPY_VFS_FAT ?= 1 # Include py core make definitions include $(TOP)/py/py.mk -GIT_SUBMODULES = lib/tinyusb lib/nxp_driver +GIT_SUBMODULES = lib/tinyusb lib/nxp_driver lib/lwip lib/mbedtls MCU_DIR = lib/nxp_driver/sdk/devices/$(MCU_SERIES) LD_FILES = boards/$(MCU_SERIES).ld boards/common.ld @@ -79,7 +79,7 @@ INC += -I$(TOP)/lib/tinyusb/src CFLAGS_MCU = -mtune=cortex-m7 -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 CFLAGS += $(INC) -Wall -Werror -Wdouble-promotion -Wfloat-conversion -std=c99 -nostdlib -mthumb $(CFLAGS_MCU) -CFLAGS += -DCPU_$(MCU_SERIES) -DCPU_$(MCU_VARIANT) +CFLAGS += -DCPU_$(MCU_SERIES) -DCPU_$(MCU_VARIANT) -DBOARD_$(BOARD) CFLAGS += -DXIP_EXTERNAL_FLASH=1 \ -DXIP_BOOT_HEADER_ENABLE=1 \ -DFSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1 \ @@ -134,6 +134,34 @@ LDFLAGS += --gc-sections CFLAGS += -fdata-sections -ffunction-sections endif +# All settings for Ethernet support are controller by the value of MICROPY_PY_LWIP +ifeq ($(MICROPY_PY_LWIP), 1) + +INC += -Ilwip_inc +INC += -Ihal/phy + +SRC_MOD := $(filter-out %/mbedtls/library/error.c, $(SRC_MOD)) + +SRC_ETH_C += \ + hal/phy/mdio/enet/fsl_enet_mdio.c \ + hal/phy/device/phydp83825/fsl_phydp83825.c \ + hal/phy/device/phyksz8081/fsl_phyksz8081.c \ + hal/phy/device/phylan8720/fsl_phylan8720.c \ + lib/mbedtls_errors/mp_mbedtls_errors.c \ + $(MCU_DIR)/drivers/fsl_enet.c \ + +SRC_QSTR += \ + extmod/modlwip.c \ + extmod/modnetwork.c \ + extmod/moduwebsocket.c \ + extmod/modusocket.c \ + network_lan.c \ + +CFLAGS += -DFSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE=1 \ + -DMBEDTLS_CONFIG_FILE='"mbedtls/mbedtls_config.h"' + +endif + # TinyUSB Stack source SRC_TINYUSB_C += \ lib/tinyusb/src/class/cdc/cdc_device.c \ @@ -164,6 +192,7 @@ SRC_HAL_IMX_C += \ $(MCU_DIR)/drivers/fsl_lpspi.c \ $(MCU_DIR)/drivers/fsl_lpspi_edma.c \ $(MCU_DIR)/drivers/fsl_lpuart.c \ + $(MCU_DIR)/drivers/fsl_ocotp.c \ $(MCU_DIR)/drivers/fsl_pit.c \ $(MCU_DIR)/drivers/fsl_snvs_lp.c \ $(MCU_DIR)/drivers/fsl_trng.c \ @@ -183,7 +212,11 @@ SRC_C += \ board_init.c \ dma_channel.c \ drivers/bus/softspi.c \ + eth.c \ + extmod/modnetwork.c \ extmod/modonewire.c \ + extmod/modusocket.c \ + extmod/uos_dupterm.c \ fatfs_port.c \ led.c \ machine_adc.c \ @@ -197,6 +230,7 @@ SRC_C += \ machine_timer.c \ machine_uart.c \ main.c \ + mbedtls/mbedtls_port.c \ mimxrt_flash.c \ mimxrt_sdram.c \ modmachine.c \ @@ -204,10 +238,16 @@ SRC_C += \ moduos.c \ modutime.c \ mphalport.c \ + mpnetworkport.c \ + network_lan.c \ + pendsv.c \ pin.c \ sdcard.c \ shared/libc/printf.c \ shared/libc/string0.c \ + shared/netutils/netutils.c \ + shared/netutils/trace.c \ + shared/netutils/dhcpserver.c \ shared/readline/readline.c \ shared/runtime/gchelper_native.c \ shared/runtime/mpirq.c \ @@ -215,10 +255,13 @@ SRC_C += \ shared/runtime/stdout_helpers.c \ shared/runtime/sys_stdio_mphal.c \ shared/timeutils/timeutils.c \ + systick.c \ ticks.c \ tusb_port.c \ $(SRC_TINYUSB_C) \ $(SRC_HAL_IMX_C) \ + $(SRC_ETH_C) \ + ifeq ($(MICROPY_HW_FLASH_TYPE), qspi_nor) SRC_C += \ @@ -334,6 +377,7 @@ SRC_S += shared/runtime/gchelper_m3.s \ # List of sources for qstr extraction SRC_QSTR += \ extmod/modonewire.c \ + extmod/uos_dupterm.c \ machine_adc.c \ machine_led.c \ machine_pin.c \ diff --git a/ports/mimxrt/board_init.c b/ports/mimxrt/board_init.c index e37ed1f149..d96645feff 100644 --- a/ports/mimxrt/board_init.c +++ b/ports/mimxrt/board_init.c @@ -56,6 +56,9 @@ void board_init(void) { mimxrt_sdram_init(); #endif + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + // ------------- USB0 ------------- // // Clock CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U); diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h index 4f33bb2087..b546700e7a 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h @@ -117,3 +117,24 @@ #define MIMXRT_IOMUXC_SEMC_WE IOMUXC_GPIO_EMC_09_SEMC_WE #define MIMXRT_IOMUXC_SEMC_CS0 IOMUXC_GPIO_EMC_12_SEMC_CS0 + +// Network definitions +// Transceiver Phy Address +#define ENET_PHY_ADDRESS (2) +#define ENET_PHY_OPS phyksz8081_ops + +// Etherner PIN definitions +#define ENET_RESET_PIN pin_GPIO_AD_B0_04 +#define ENET_INT_PIN pin_GPIO_AD_B1_06 + +#define IOMUX_TABLE_ENET \ + { IOMUXC_GPIO_AD_B0_08_ENET_REF_CLK1, 1, 0xB0E9u }, \ + { IOMUXC_GPIO_AD_B0_09_ENET_RDATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_AD_B0_10_ENET_RDATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_AD_B0_11_ENET_RX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_AD_B0_12_ENET_RX_ER, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_AD_B0_13_ENET_TX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_AD_B0_14_ENET_TDATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_AD_B0_15_ENET_TDATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_EMC_40_ENET_MDIO, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_EMC_41_ENET_MDC, 0, 0xB0E9u }, diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk index e08b3357fd..c1e1678e59 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk @@ -9,6 +9,10 @@ MICROPY_HW_FLASH_SIZE ?= 0x800000 # 8MB MICROPY_HW_SDRAM_AVAIL = 1 MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB +MICROPY_PY_LWIP = 1 +MICROPY_PY_USSL = 1 +MICROPY_SSL_MBEDTLS = 1 + JLINK_PATH ?= /media/RT1020-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink diff --git a/ports/mimxrt/boards/MIMXRT1021.ld b/ports/mimxrt/boards/MIMXRT1021.ld index 8d981a7c61..64f4e537e0 100644 --- a/ports/mimxrt/boards/MIMXRT1021.ld +++ b/ports/mimxrt/boards/MIMXRT1021.ld @@ -42,6 +42,7 @@ _gc_heap_start = ORIGIN(m_sdram); _gc_heap_end = ORIGIN(m_sdram) + LENGTH(m_sdram); #else /* Use second OCRAM bank for GC heap. */ +/* Use all OCRAM for the GC heap. */ _gc_heap_start = ORIGIN(m_ocrm); _gc_heap_end = ORIGIN(m_ocrm) + LENGTH(m_ocrm); #endif diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h index f6021ac788..3837315f7d 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h @@ -1,4 +1,4 @@ -#define MICROPY_HW_BOARD_NAME "i.MX RT1050 EVK" +#define MICROPY_HW_BOARD_NAME "i.MX RT1050 EVKB-A1" #define MICROPY_HW_MCU_NAME "MIMXRT1052DVL6B" // MIMXRT1050_EVKB has 1 user LED @@ -108,3 +108,24 @@ #define MIMXRT_IOMUXC_SEMC_WE IOMUXC_GPIO_EMC_28_SEMC_WE #define MIMXRT_IOMUXC_SEMC_CS0 IOMUXC_GPIO_EMC_29_SEMC_CS0 + +// Network definitions +// Transceiver Phy Address & Type +#define ENET_PHY_ADDRESS (2) +#define ENET_PHY_OPS phyksz8081_ops + +// Etherner PIN definitions +#define ENET_RESET_PIN pin_GPIO_AD_B0_09 +#define ENET_INT_PIN pin_GPIO_AD_B0_10 + +#define IOMUX_TABLE_ENET \ + { IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_06_ENET_RX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_09_ENET_TX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_10_ENET_REF_CLK, 1, 0x71u }, \ + { IOMUXC_GPIO_B1_11_ENET_RX_ER, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_EMC_41_ENET_MDIO, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_EMC_40_ENET_MDC, 0, 0xB0E9u }, diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk index 4165b72c26..65e3d30963 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk @@ -9,7 +9,6 @@ MICROPY_HW_FLASH_SIZE ?= 0x4000000 # 64MB MICROPY_HW_SDRAM_AVAIL = 1 MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB -JLINK_PATH ?= /media/RT1050-EVKB/ - -deploy: $(BUILD)/firmware.bin - cp $< $(JLINK_PATH) +MICROPY_PY_LWIP = 1 +MICROPY_PY_USSL = 1 +MICROPY_SSL_MBEDTLS = 1 diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h index af44010486..a66fcf9ae9 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h @@ -107,3 +107,24 @@ #define MIMXRT_IOMUXC_SEMC_WE IOMUXC_GPIO_EMC_28_SEMC_WE #define MIMXRT_IOMUXC_SEMC_CS0 IOMUXC_GPIO_EMC_29_SEMC_CS0 + +// Network definitions +// Transceiver Phy Address +#define ENET_PHY_ADDRESS (2) +#define ENET_PHY_OPS phyksz8081_ops + +// Etherner PIN definitions +#define ENET_RESET_PIN pin_GPIO_AD_B0_09 +#define ENET_INT_PIN pin_GPIO_AD_B0_10 + +#define IOMUX_TABLE_ENET \ + { IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_06_ENET_RX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_09_ENET_TX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_10_ENET_REF_CLK, 1, 0x71u }, \ + { IOMUXC_GPIO_B1_11_ENET_RX_ER, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_EMC_41_ENET_MDIO, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_EMC_40_ENET_MDC, 0, 0xB0E9u }, diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk index 4c4a2ff980..56ccba6e59 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk @@ -9,6 +9,10 @@ MICROPY_HW_FLASH_SIZE ?= 0x800000 # 8MB MICROPY_HW_SDRAM_AVAIL = 1 MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB +MICROPY_PY_LWIP = 1 +MICROPY_PY_USSL = 1 +MICROPY_SSL_MBEDTLS = 1 + JLINK_PATH ?= /media/RT1060-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h index 17268b0a56..1dcdd378a2 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h @@ -107,3 +107,24 @@ #define MIMXRT_IOMUXC_SEMC_WE IOMUXC_GPIO_EMC_28_SEMC_WE #define MIMXRT_IOMUXC_SEMC_CS0 IOMUXC_GPIO_EMC_29_SEMC_CS0 + +// Network definitions +// Transceiver Phy Address +#define ENET_PHY_ADDRESS (2) +#define ENET_PHY_OPS phyksz8081_ops + +// Etherner PIN definitions +#define ENET_RESET_PIN pin_GPIO_AD_B0_09 +#define ENET_INT_PIN pin_GPIO_AD_B0_10 + +#define IOMUX_TABLE_ENET \ + { IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_06_ENET_RX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_09_ENET_TX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_10_ENET_REF_CLK, 1, 0x71u }, \ + { IOMUXC_GPIO_B1_11_ENET_RX_ER, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_EMC_41_ENET_MDIO, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_EMC_40_ENET_MDC, 0, 0xB0E9u }, diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk index 8bc35dd0dd..5cd7d49abd 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk @@ -9,6 +9,10 @@ MICROPY_HW_FLASH_SIZE ?= 0x4000000 # 64MB MICROPY_HW_SDRAM_AVAIL = 1 MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB +MICROPY_PY_LWIP = 1 +MICROPY_PY_USSL = 1 +MICROPY_SSL_MBEDTLS = 1 + JLINK_PATH ?= /media/RT1064-EVK/ deploy: $(BUILD)/firmware.bin diff --git a/ports/mimxrt/boards/TEENSY41/mpconfigboard.h b/ports/mimxrt/boards/TEENSY41/mpconfigboard.h index 7890ba762c..4ca82d4b65 100644 --- a/ports/mimxrt/boards/TEENSY41/mpconfigboard.h +++ b/ports/mimxrt/boards/TEENSY41/mpconfigboard.h @@ -65,3 +65,24 @@ .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 }, \ .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 }, \ } + +// Network definitions +// Transceiver Phy Address & Type +#define ENET_PHY_ADDRESS (0) +#define ENET_PHY_OPS phydp83825_ops + +// Ethernet PIN definitions +#define ENET_RESET_PIN pin_GPIO_B0_14 +#define ENET_INT_PIN pin_GPIO_B0_15 + +#define IOMUX_TABLE_ENET \ + { IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_06_ENET_RX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_09_ENET_TX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_10_ENET_REF_CLK, 1, 0x71u }, \ + { IOMUXC_GPIO_B1_11_ENET_RX_ER, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_15_ENET_MDIO, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_14_ENET_MDC, 0, 0xB0E9u }, diff --git a/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk b/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk index 27039648b8..a012444caa 100755 --- a/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk +++ b/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk @@ -7,5 +7,9 @@ MICROPY_HW_FLASH_TYPE ?= qspi_nor MICROPY_HW_FLASH_SIZE ?= 0x800000 # 8MB MICROPY_HW_FLASH_RESERVED ?= 0x1000 # 4KB +MICROPY_PY_LWIP = 1 +MICROPY_PY_USSL = 1 +MICROPY_SSL_MBEDTLS = 1 + deploy: $(BUILD)/firmware.hex teensy_loader_cli --mcu=imxrt1062 -v -w $< diff --git a/ports/mimxrt/eth.c b/ports/mimxrt/eth.c new file mode 100644 index 0000000000..414e8d51f2 --- /dev/null +++ b/ports/mimxrt/eth.c @@ -0,0 +1,448 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * Copyright (c) 2021 Robert Hammelrath + * + * 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 +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/mperrno.h" +#include "ticks.h" + +#if defined(MICROPY_HW_ETH_MDC) + +#include "eth.h" +#include "pin.h" +#include "shared/netutils/netutils.h" +#include "extmod/modnetwork.h" + +#include "fsl_iomuxc.h" +#include "fsl_enet.h" +#include "fsl_phy.h" +#include "hal/phy/mdio/enet/fsl_enet_mdio.h" +#include "hal/phy/device/phyksz8081/fsl_phyksz8081.h" +#include "hal/phy/device/phydp83825/fsl_phydp83825.h" +#include "hal/phy/device/phylan8720/fsl_phylan8720.h" + +#include "lwip/etharp.h" +#include "lwip/dns.h" +#include "lwip/dhcp.h" +#include "netif/ethernet.h" + +#include "ticks.h" + +// Configuration values +enet_config_t enet_config; +phy_config_t phyConfig = {0}; + +// Prepare the buffer configuration. + +#define ENET_RXBD_NUM (5) +#define ENET_TXBD_NUM (5) + +AT_NONCACHEABLE_SECTION_ALIGN(enet_rx_bd_struct_t g_rxBuffDescrip[ENET_RXBD_NUM], ENET_BUFF_ALIGNMENT); +AT_NONCACHEABLE_SECTION_ALIGN(enet_tx_bd_struct_t g_txBuffDescrip[ENET_TXBD_NUM], ENET_BUFF_ALIGNMENT); +SDK_ALIGN(uint8_t g_rxDataBuff[ENET_RXBD_NUM][SDK_SIZEALIGN(ENET_FRAME_MAX_FRAMELEN, ENET_BUFF_ALIGNMENT)], + ENET_BUFF_ALIGNMENT); +SDK_ALIGN(uint8_t g_txDataBuff[ENET_TXBD_NUM][SDK_SIZEALIGN(ENET_FRAME_MAX_FRAMELEN, ENET_BUFF_ALIGNMENT)], + ENET_BUFF_ALIGNMENT); + +// ENET Handles & Buffers +enet_handle_t g_handle; + +static mdio_handle_t mdioHandle = {.ops = &enet_ops}; +static phy_handle_t phyHandle = {.phyAddr = ENET_PHY_ADDRESS, .mdioHandle = &mdioHandle, .ops = &ENET_PHY_OPS}; + +enet_buffer_config_t buffConfig[] = {{ + ENET_RXBD_NUM, + ENET_TXBD_NUM, + SDK_SIZEALIGN(ENET_FRAME_MAX_FRAMELEN, ENET_BUFF_ALIGNMENT), + SDK_SIZEALIGN(ENET_FRAME_MAX_FRAMELEN, ENET_BUFF_ALIGNMENT), + &g_rxBuffDescrip[0], + &g_txBuffDescrip[0], + &g_rxDataBuff[0][0], + &g_txDataBuff[0][0], + }}; + +static uint8_t hw_addr[6]; // The MAC address field +eth_t eth_instance; + +#define PHY_INIT_TIMEOUT_MS (10000) +#define PHY_AUTONEGO_TIMEOUT_US (5000000) + +typedef struct _eth_t { + uint32_t trace_flags; + struct netif netif; + struct dhcp dhcp_struct; +} eth_t; + +typedef struct _iomux_table_t { + uint32_t muxRegister; + uint32_t muxMode; + uint32_t inputRegister; + uint32_t inputDaisy; + uint32_t configRegister; + uint32_t inputOnfield; + uint32_t configValue; +} iomux_table_t; + +static const iomux_table_t iomux_table_enet[] = { + IOMUX_TABLE_ENET +}; + +#define IOTE (iomux_table_enet[i]) +#ifndef ENET_TX_CLK_OUTPUT +#define ENET_TX_CLK_OUTPUT true +#endif + +#define TRACE_ASYNC_EV (0x0001) +#define TRACE_ETH_TX (0x0002) +#define TRACE_ETH_RX (0x0004) +#define TRACE_ETH_FULL (0x0008) + + +STATIC void eth_trace(eth_t *self, size_t len, const void *data, unsigned int flags) { + if (((flags & NETUTILS_TRACE_IS_TX) && (self->trace_flags & TRACE_ETH_TX)) + || (!(flags & NETUTILS_TRACE_IS_TX) && (self->trace_flags & TRACE_ETH_RX))) { + const uint8_t *buf; + if (len == (size_t)-1) { + // data is a pbuf + const struct pbuf *pbuf = data; + buf = pbuf->payload; + len = pbuf->len; // restricted to print only the first chunk of the pbuf + } else { + // data is actual data buffer + buf = data; + } + if (self->trace_flags & TRACE_ETH_FULL) { + flags |= NETUTILS_TRACE_PAYLOAD; + } + netutils_ethernet_trace(MP_PYTHON_PRINTER, len, buf, flags); + } +} + +STATIC void eth_process_frame(eth_t *self, uint8_t *buf, size_t length) { + + struct netif *netif = &self->netif; + if (netif->flags & NETIF_FLAG_LINK_UP) { + struct pbuf *p = pbuf_alloc(PBUF_RAW, length, PBUF_POOL); + if (p != NULL) { + // Need to create a local copy first, since ENET_ReadFrame does not + // provide a pointer to the buffer. + pbuf_take(p, buf, length); + if (netif->input(p, netif) != ERR_OK) { + pbuf_free(p); + } + } + } +} + +void eth_irq_handler(ENET_Type *base, enet_handle_t *handle, enet_event_t event, void *userData) { + eth_t *self = (eth_t *)userData; + uint8_t g_rx_frame[ENET_FRAME_MAX_FRAMELEN + 14]; + uint32_t length = 0; + status_t status; + + if (event == kENET_RxEvent) { + do { + status = ENET_GetRxFrameSize(&g_handle, &length); + if (status == kStatus_Success) { + // Get the data + ENET_ReadFrame(ENET, &g_handle, g_rx_frame, length); + eth_process_frame(self, g_rx_frame, length); + } else if (status == kStatus_ENET_RxFrameError) { + ENET_ReadFrame(ENET, &g_handle, NULL, 0); + } + } while (status != kStatus_ENET_RxFrameEmpty); + } else { + ENET_ClearInterruptStatus(ENET, kENET_TxFrameInterrupt); + } +} + +// eth_init: Set up GPIO and the transceiver +void eth_init(eth_t *self, int mac_idx) { + + CLOCK_EnableClock(kCLOCK_Iomuxc); + + gpio_pin_config_t gpio_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode}; + (void)gpio_config; + + #ifdef ENET_RESET_PIN + // Configure the Reset Pin + const machine_pin_obj_t *reset_pin = &ENET_RESET_PIN; + const machine_pin_af_obj_t *af_obj = pin_find_af(reset_pin, PIN_AF_MODE_ALT5); + + IOMUXC_SetPinMux(reset_pin->muxRegister, af_obj->af_mode, 0, 0, reset_pin->configRegister, 0U); + IOMUXC_SetPinConfig(reset_pin->muxRegister, af_obj->af_mode, 0, 0, reset_pin->configRegister, 0xB0A9U); + GPIO_PinInit(reset_pin->gpio, reset_pin->pin, &gpio_config); + #endif + + #ifdef ENET_INT_PIN + // Configure the Int Pin + const machine_pin_obj_t *int_pin = &ENET_INT_PIN; + af_obj = pin_find_af(int_pin, PIN_AF_MODE_ALT5); + + IOMUXC_SetPinMux(int_pin->muxRegister, af_obj->af_mode, 0, 0, int_pin->configRegister, 0U); + IOMUXC_SetPinConfig(int_pin->muxRegister, af_obj->af_mode, 0, 0, int_pin->configRegister, 0xB0A9U); + GPIO_PinInit(int_pin->gpio, int_pin->pin, &gpio_config); + #endif + + // Configure the Transceiver Pins, Settings except for CLK: + // Slew Rate Field: Fast Slew Rate, Drive Strength, R0/5, Speed max(200MHz) + // Open Drain Disabled, Pull Enabled, Pull 100K Ohm Pull Up + // Hysteresis Disabled + + for (int i = 0; i < ARRAY_SIZE(iomux_table_enet); i++) { + IOMUXC_SetPinMux(IOTE.muxRegister, IOTE.muxMode, IOTE.inputRegister, IOTE.inputDaisy, IOTE.configRegister, IOTE.inputOnfield); + IOMUXC_SetPinConfig(IOTE.muxRegister, IOTE.muxMode, IOTE.inputRegister, IOTE.inputDaisy, IOTE.configRegister, IOTE.configValue); + } + + const clock_enet_pll_config_t config = { + .enableClkOutput = true, .enableClkOutput25M = false, .loopDivider = 1 + }; + CLOCK_InitEnetPll(&config); + + IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1RefClkMode, false); // Drive ENET_REF_CLK from PAD + IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, ENET_TX_CLK_OUTPUT); // Enable output driver + + // Reset transceiver + // pull up the ENET_INT before RESET. + #ifdef ENET_INT_PIN + GPIO_WritePinOutput(int_pin->gpio, int_pin->pin, 1); + #endif + + #ifdef ENET_RESET_PIN + GPIO_WritePinOutput(reset_pin->gpio, reset_pin->pin, 0); + mp_hal_delay_us(1000); + GPIO_WritePinOutput(reset_pin->gpio, reset_pin->pin, 1); + mp_hal_delay_us(1000); + #endif + + mp_hal_get_mac(0, hw_addr); + + phyConfig.autoNeg = true; + mdioHandle.resource.base = ENET; + mdioHandle.resource.csrClock_Hz = CLOCK_GetFreq(kCLOCK_IpgClk); + + // Init the PHY interface & negotiate the speed + bool link = false; + bool autonego = false; + phy_speed_t speed = kENET_MiiSpeed100M; + phy_duplex_t duplex = kENET_MiiFullDuplex; + + phyConfig.phyAddr = ENET_PHY_ADDRESS; + + status_t status = PHY_Init(&phyHandle, &phyConfig); + if (status == kStatus_Success) { + if (phyConfig.autoNeg) { + uint64_t t = ticks_us64() + PHY_AUTONEGO_TIMEOUT_US; + // Wait for auto-negotiation success and link up + do { + PHY_GetAutoNegotiationStatus(&phyHandle, &autonego); + PHY_GetLinkStatus(&phyHandle, &link); + if (autonego && link) { + break; + } + } while (ticks_us64() < t); + if (!autonego) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("PHY Auto-negotiation failed.")); + } + PHY_GetLinkSpeedDuplex(&phyHandle, &speed, &duplex); + } else { + PHY_SetLinkSpeedDuplex(&phyHandle, speed, duplex); + } + } else { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("PHY Init failed.")); + } + + ENET_GetDefaultConfig(&enet_config); + enet_config.miiSpeed = (enet_mii_speed_t)speed; + enet_config.miiDuplex = (enet_mii_duplex_t)duplex; + enet_config.miiMode = kENET_RmiiMode; + // Enable checksum generation by the ENET controller + // Note: Disabled due to problems with the checksum on ICMP requests + // Maybe caused by LWIP inserting 0xffff instead of 0x0000 + // Keep the code for now until it may be fixed. + // enet_config.txAccelerConfig = kENET_TxAccelIpCheckEnabled | kENET_TxAccelProtoCheckEnabled; + // Set interrupt + enet_config.interrupt |= ENET_TX_INTERRUPT | ENET_RX_INTERRUPT; + + ENET_Init(ENET, &g_handle, &enet_config, &buffConfig[0], hw_addr, CLOCK_GetFreq(kCLOCK_IpgClk)); + ENET_SetCallback(&g_handle, eth_irq_handler, (void *)self); + ENET_EnableInterrupts(ENET, ENET_RX_INTERRUPT); + ENET_ClearInterruptStatus(ENET, ENET_TX_INTERRUPT | ENET_RX_INTERRUPT | ENET_ERR_INTERRUPT); + ENET_ActiveRead(ENET); +} + +// Initialize the phy interface +STATIC int eth_mac_init(eth_t *self) { + return 0; +} + +// Deinit the interface +STATIC void eth_mac_deinit(eth_t *self) { +} + +void eth_set_trace(eth_t *self, uint32_t value) { + self->trace_flags = value; +} + +/*******************************************************************************/ +// ETH-LwIP bindings + +STATIC err_t eth_netif_output(struct netif *netif, struct pbuf *p) { + // This function should always be called from a context where PendSV-level IRQs are disabled + status_t status; + + LINK_STATS_INC(link.xmit); + eth_trace(netif->state, (size_t)-1, p, NETUTILS_TRACE_IS_TX | NETUTILS_TRACE_NEWLINE); + + if (p->next == NULL) { + status = ENET_SendFrame(ENET, &g_handle, p->payload, p->len); + } else { + // frame consists of several parts. Copy them together and send them + size_t length = 0; + uint8_t tx_frame[ENET_FRAME_MAX_FRAMELEN + 14]; + + while (p) { + memcpy(&tx_frame[length], p->payload, p->len); + length += p->len; + p = p->next; + } + status = ENET_SendFrame(ENET, &g_handle, tx_frame, length); + } + return status == kStatus_Success ? ERR_OK : ERR_BUF; +} + +STATIC err_t eth_netif_init(struct netif *netif) { + netif->linkoutput = eth_netif_output; + netif->output = etharp_output; + netif->mtu = 1500; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP; + // Checksums only need to be checked on incoming frames, not computed on outgoing frames + NETIF_SET_CHECKSUM_CTRL(netif, + NETIF_CHECKSUM_CHECK_IP + | NETIF_CHECKSUM_CHECK_UDP + | NETIF_CHECKSUM_CHECK_TCP + | NETIF_CHECKSUM_CHECK_ICMP + | NETIF_CHECKSUM_CHECK_ICMP6 + | NETIF_CHECKSUM_GEN_IP + | NETIF_CHECKSUM_GEN_UDP + | NETIF_CHECKSUM_GEN_TCP + | NETIF_CHECKSUM_GEN_ICMP + | NETIF_CHECKSUM_GEN_ICMP6 + ); + return ERR_OK; +} + +STATIC void eth_lwip_init(eth_t *self) { + ip_addr_t ipconfig[4]; + IP4_ADDR(&ipconfig[0], 192, 168, 0, 2); + IP4_ADDR(&ipconfig[1], 255, 255, 255, 0); + IP4_ADDR(&ipconfig[2], 192, 168, 0, 1); + IP4_ADDR(&ipconfig[3], 8, 8, 8, 8); + + self->netif.hwaddr_len = 6; + memcpy(self->netif.hwaddr, hw_addr, 6); + + MICROPY_PY_LWIP_ENTER + + struct netif *n = &self->netif; + n->name[0] = 'e'; + n->name[1] = '0'; + netif_add(n, &ipconfig[0], &ipconfig[1], &ipconfig[2], self, eth_netif_init, ethernet_input); + netif_set_hostname(n, "MPY"); + netif_set_default(n); + netif_set_up(n); + + dns_setserver(0, &ipconfig[3]); + dhcp_set_struct(n, &self->dhcp_struct); + dhcp_start(n); + + netif_set_link_up(n); + + MICROPY_PY_LWIP_EXIT +} + +STATIC void eth_lwip_deinit(eth_t *self) { + MICROPY_PY_LWIP_ENTER + for (struct netif *netif = netif_list; netif != NULL; netif = netif->next) { + if (netif == &self->netif) { + netif_remove(netif); + netif->ip_addr.addr = 0; + netif->flags = 0; + } + } + MICROPY_PY_LWIP_EXIT +} + +struct netif *eth_netif(eth_t *self) { + return &self->netif; +} + +int eth_link_status(eth_t *self) { + struct netif *netif = &self->netif; + if ((netif->flags & (NETIF_FLAG_UP | NETIF_FLAG_LINK_UP)) + == (NETIF_FLAG_UP | NETIF_FLAG_LINK_UP)) { + if (netif->ip_addr.addr != 0) { + return 3; // link up + } else { + return 2; // link no-ip; + } + } else { + bool link; + PHY_GetLinkStatus(&phyHandle, &link); + if (link) { + return 1; // link up + } else { + return 0; // link down + } + } +} + +int eth_start(eth_t *self) { + eth_lwip_deinit(self); + + // Make sure Eth is Not in low power mode. + eth_low_power_mode(self, false); + + int ret = eth_mac_init(self); + if (ret < 0) { + return ret; + } + eth_lwip_init(self); + return 0; +} + +int eth_stop(eth_t *self) { + eth_lwip_deinit(self); + eth_mac_deinit(self); + return 0; +} + +void eth_low_power_mode(eth_t *self, bool enable) { + ENET_EnableSleepMode(ENET, enable); +} +#endif // defined(MICROPY_HW_ETH_MDC) diff --git a/ports/mimxrt/eth.h b/ports/mimxrt/eth.h new file mode 100644 index 0000000000..56327d08ae --- /dev/null +++ b/ports/mimxrt/eth.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * Copyright (c) 2021 Robert Hammelrath + * + * 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_MIMXRT_ETH_H +#define MICROPY_INCLUDED_MIMXRT_ETH_H + +typedef struct _eth_t eth_t; +extern eth_t eth_instance; + +void eth_init(eth_t *self, int mac_idx); +void eth_set_trace(eth_t *self, uint32_t value); +struct netif *eth_netif(eth_t *self); +int eth_link_status(eth_t *self); +int eth_start(eth_t *self); +int eth_stop(eth_t *self); +void eth_low_power_mode(eth_t *self, bool enable); + +#endif // MICROPY_INCLUDED_MIMXRT_ETH_H diff --git a/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.c b/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.c new file mode 100644 index 0000000000..2aca609a05 --- /dev/null +++ b/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.c @@ -0,0 +1,281 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_phydp83825.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Defines the PHY PD83825 vendor defined registers. */ +#define PHY_PHYSTS_REG 0x10U // Phy status register +#define PHY_BISCR_REG 0x16U // RMII Config register. +#define PHY_RCSR_REG 0x17U // RMII Config register. +#define PHY_CONTROL2_REG 0x1FU /*!< The PHY control register 2. */ + +/*! @brief Defines the PHY DP82825 ID number. */ +#define PHY_CONTROL_ID1 0x2000U /*!< The PHY ID1 */ + +/*! @brief Defines the mask flag of operation mode in control registers */ +#define PHY_PHYSTS_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */ +#define PHY_PHYSTS_DUPLEX_MASK 0x0004U /*!< The PHY full duplex mask. */ +#define PHY_PHYSTS_100M_MASK 0x0002U /*!< The PHY 100M mask. */ +#define PHY_PHYSTS_LINK_MASK 0x0001U /*!< The PHY link up mask. */ + +#define PYH_RMII_CLOCK_SELECT 0x80 // Select 50MHz clock +#define PHY_BISCR_REMOTELOOP_MASK 0x1FU // !< The PHY remote loopback mask. +#define PHY_BISCR_REMOTELOOP_MODE 0x08U // !< The PHY remote loopback mode. + +/*! @brief Defines the timeout macro. */ +#define PHY_READID_TIMEOUT_COUNT 1000U + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +const phy_operations_t phydp83825_ops = {.phyInit = PHY_DP83825_Init, + .phyWrite = PHY_DP83825_Write, + .phyRead = PHY_DP83825_Read, + .getAutoNegoStatus = PHY_DP83825_GetAutoNegotiationStatus, + .getLinkStatus = PHY_DP83825_GetLinkStatus, + .getLinkSpeedDuplex = PHY_DP83825_GetLinkSpeedDuplex, + .setLinkSpeedDuplex = PHY_DP83825_SetLinkSpeedDuplex, + .enableLoopback = PHY_DP83825_EnableLoopback}; + +/******************************************************************************* + * Code + ******************************************************************************/ + +status_t PHY_DP83825_Init(phy_handle_t *handle, const phy_config_t *config) { + uint32_t counter = PHY_READID_TIMEOUT_COUNT; + status_t result = kStatus_Success; + uint32_t regValue = 0; + + /* Init MDIO interface. */ + MDIO_Init(handle->mdioHandle); + + /* Assign phy address. */ + handle->phyAddr = config->phyAddr; + + /* Check PHY ID. */ + do + { + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_ID1_REG, ®Value); + if (result != kStatus_Success) { + return result; + } + counter--; + } while ((regValue != PHY_CONTROL_ID1) && (counter != 0U)); + + if (counter == 0U) { + return kStatus_Fail; + } + + /* Reset PHY. */ + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK); + if (result == kStatus_Success) { + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_RCSR_REG, ®Value); + if (result != kStatus_Success) { + return result; + } + result = + MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_RCSR_REG, (regValue | PYH_RMII_CLOCK_SELECT)); + if (result != kStatus_Success) { + return result; + } + + if (config->autoNeg) { + /* Set the auto-negotiation then start it. */ + result = + MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_AUTONEG_ADVERTISE_REG, + (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK | + PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | PHY_IEEE802_3_SELECTOR_MASK)); + if (result == kStatus_Success) { + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, + (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK)); + } + } else { + /* This PHY only supports 10/100M speed. */ + assert(config->speed <= kPHY_Speed100M); + + /* Disable isolate mode */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); + if (result != kStatus_Success) { + return result; + } + regValue &= ~PHY_BCTL_ISOLATE_MASK; + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + if (result != kStatus_Success) { + return result; + } + + /* Disable the auto-negotiation and set user-defined speed/duplex configuration. */ + result = PHY_DP83825_SetLinkSpeedDuplex(handle, config->speed, config->duplex); + } + } + return result; +} + +status_t PHY_DP83825_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data) { + return MDIO_Write(handle->mdioHandle, handle->phyAddr, phyReg, data); +} + +status_t PHY_DP83825_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr) { + return MDIO_Read(handle->mdioHandle, handle->phyAddr, phyReg, dataPtr); +} + +status_t PHY_DP83825_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status) { + assert(status); + + status_t result; + uint32_t regValue; + + *status = false; + + /* Check auto negotiation complete. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, ®Value); + if (result == kStatus_Success) { + if ((regValue & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0U) { + *status = true; + } + } + return result; +} + +status_t PHY_DP83825_GetLinkStatus(phy_handle_t *handle, bool *status) { + assert(status); + + status_t result; + uint32_t regValue; + + /* Read the basic status register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, ®Value); + if (result == kStatus_Success) { + if ((PHY_BSTATUS_LINKSTATUS_MASK & regValue) != 0U) { + /* Link up. */ + *status = true; + } else { + /* Link down. */ + *status = false; + } + } + return result; +} + +status_t PHY_DP83825_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex) { + assert(!((speed == NULL) && (duplex == NULL))); + + status_t result; + uint32_t regValue; + uint32_t flag; + + /* Read the control register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_PHYSTS_REG, ®Value); + if (result == kStatus_Success) { + if (speed != NULL) { + flag = regValue & PHY_PHYSTS_100M_MASK; + if (flag) { + *speed = kPHY_Speed10M; + } else { + *speed = kPHY_Speed100M; + } + } + + if (duplex != NULL) { + flag = regValue & PHY_PHYSTS_DUPLEX_MASK; + if (flag) { + *duplex = kPHY_FullDuplex; + } else { + *duplex = kPHY_HalfDuplex; + } + } + } + return result; +} + +status_t PHY_DP83825_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex) { + /* This PHY only supports 10/100M speed. */ + assert(speed <= kPHY_Speed100M); + + status_t result; + uint32_t regValue; + + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); + if (result == kStatus_Success) { + /* Disable the auto-negotiation and set according to user-defined configuration. */ + regValue &= ~PHY_BCTL_AUTONEG_MASK; + if (speed == kPHY_Speed100M) { + regValue |= PHY_BCTL_SPEED0_MASK; + } else { + regValue &= ~PHY_BCTL_SPEED0_MASK; + } + if (duplex == kPHY_FullDuplex) { + regValue |= PHY_BCTL_DUPLEX_MASK; + } else { + regValue &= ~PHY_BCTL_DUPLEX_MASK; + } + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + } + return result; +} +status_t PHY_DP83825_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable) { + /* This PHY only supports local/remote loopback and 10/100M speed. */ + assert(mode <= kPHY_RemoteLoop); + assert(speed <= kPHY_Speed100M); + + status_t result = kStatus_Success; + uint32_t regValue; + + /* Set the loop mode. */ + if (enable) { + if (mode == kPHY_LocalLoop) { + if (speed == kPHY_Speed100M) { + regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + } else { + regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + } + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + } else { + /* Remote loopback only supports 100M full-duplex. */ + assert(speed == kPHY_Speed100M); + + regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + if (result != kStatus_Success) { + return result; + } + /* Set the remote loopback bit. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BISCR_REG, ®Value); + if (result == kStatus_Success) { + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BISCR_REG, + (regValue & ~PHY_BISCR_REMOTELOOP_MASK) | PHY_BISCR_REMOTELOOP_MODE); + } + } + } else { + /* Disable the loop mode. */ + if (mode != kPHY_LocalLoop) { + /* First read the current status in control one register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BISCR_REG, ®Value); + if (result == kStatus_Success) { + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BISCR_REG, + (regValue & ~PHY_BISCR_REMOTELOOP_MASK)); + } + } + /* First read the current status in control register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); + if (result == kStatus_Success) { + regValue &= ~PHY_BCTL_LOOP_MASK; + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, + (regValue | PHY_BCTL_RESTART_AUTONEG_MASK)); + } + } + + return result; +} diff --git a/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.h b/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.h new file mode 100644 index 0000000000..9d6b4fdf78 --- /dev/null +++ b/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.h @@ -0,0 +1,163 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/***************************************************************************** + * PHY DP83825 driver change log + *****************************************************************************/ + +/*! +@page driver_log Driver Change Log + +@section phyksz8081 PHYDP83825 + The current PHYDP83825 driver version is 2.0.0. + + - 2.0.0 + - Initial version. +*/ + +#ifndef _FSL_DP83825_H_ +#define _FSL_DP83825_H_ + +#include "fsl_phy.h" + +/*! + * @addtogroup phy_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief PHY driver version */ +#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) + +/*! @brief PHY operations structure. */ +extern const phy_operations_t phydp83825_ops; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name PHY Driver + * @{ + */ + +/*! + * @brief Initializes PHY. + * + * This function initialize PHY. + * + * @param handle PHY device handle. + * @param config Pointer to structure of phy_config_t. + * @retval kStatus_Success PHY initialization succeeds + * @retval kStatus_Fail PHY initialization fails + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83825_Init(phy_handle_t *handle, const phy_config_t *config); + +/*! + * @brief PHY Write function. This function writes data over the SMI to + * the specified PHY register. This function is called by all PHY interfaces. + * + * @param handle PHY device handle. + * @param phyReg The PHY register. + * @param data The data written to the PHY register. + * @retval kStatus_Success PHY write success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83825_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data); + +/*! + * @brief PHY Read function. This interface read data over the SMI from the + * specified PHY register. This function is called by all PHY interfaces. + * + * @param handle PHY device handle. + * @param phyReg The PHY register. + * @param dataPtr The address to store the data read from the PHY register. + * @retval kStatus_Success PHY read success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83825_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr); + +/*! + * @brief Gets the PHY auto-negotiation status. + * + * @param handle PHY device handle. + * @param status The auto-negotiation status of the PHY. + * - true the auto-negotiation is over. + * - false the auto-negotiation is on-going or not started. + * @retval kStatus_Success PHY gets status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83825_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status); + +/*! + * @brief Gets the PHY link status. + * + * @param handle PHY device handle. + * @param status The link up or down status of the PHY. + * - true the link is up. + * - false the link is down. + * @retval kStatus_Success PHY gets link status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83825_GetLinkStatus(phy_handle_t *handle, bool *status); + +/*! + * @brief Gets the PHY link speed and duplex. + * + * @brief This function gets the speed and duplex mode of PHY. User can give one of speed + * and duplex address paramter and set the other as NULL if only wants to get one of them. + * + * @param handle PHY device handle. + * @param speed The address of PHY link speed. + * @param duplex The link duplex of PHY. + * @retval kStatus_Success PHY gets link speed and duplex success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83825_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex); + +/*! + * @brief Sets the PHY link speed and duplex. + * + * @param handle PHY device handle. + * @param speed Specified PHY link speed. + * @param duplex Specified PHY link duplex. + * @retval kStatus_Success PHY gets status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83825_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex); + +/*! + * @brief Enables/disables PHY loopback. + * + * @param handle PHY device handle. + * @param mode The loopback mode to be enabled, please see "phy_loop_t". + * All loopback modes should not be set together, when one loopback mode is set + * another should be disabled. + * @param speed PHY speed for loopback mode. + * @param enable True to enable, false to disable. + * @retval kStatus_Success PHY loopback success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83825_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_DP83825_H_ */ diff --git a/ports/mimxrt/hal/phy/device/phyksz8081/fsl_phyksz8081.c b/ports/mimxrt/hal/phy/device/phyksz8081/fsl_phyksz8081.c new file mode 100644 index 0000000000..32cabacdb6 --- /dev/null +++ b/ports/mimxrt/hal/phy/device/phyksz8081/fsl_phyksz8081.c @@ -0,0 +1,284 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_phyksz8081.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Defines the PHY KSZ8081 vendor defined registers. */ +#define PHY_CONTROL1_REG 0x1EU /*!< The PHY control one register. */ +#define PHY_CONTROL2_REG 0x1FU /*!< The PHY control two register. */ + +/*! @brief Defines the PHY KSZ8081 ID number. */ +#define PHY_CONTROL_ID1 0x22U /*!< The PHY ID1 */ + +/*! @brief Defines the mask flag of operation mode in control registers */ +#define PHY_CTL2_REMOTELOOP_MASK 0x0004U /*!< The PHY remote loopback mask. */ +#define PHY_CTL2_REFCLK_SELECT_MASK 0x0080U /*!< The PHY RMII reference clock select. */ +#define PHY_CTL1_10HALFDUPLEX_MASK 0x0001U /*!< The PHY 10M half duplex mask. */ +#define PHY_CTL1_100HALFDUPLEX_MASK 0x0002U /*!< The PHY 100M half duplex mask. */ +#define PHY_CTL1_10FULLDUPLEX_MASK 0x0005U /*!< The PHY 10M full duplex mask. */ +#define PHY_CTL1_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */ +#define PHY_CTL1_SPEEDUPLX_MASK 0x0007U /*!< The PHY speed and duplex mask. */ +#define PHY_CTL1_ENERGYDETECT_MASK 0x10U /*!< The PHY signal present on rx differential pair. */ +#define PHY_CTL1_LINKUP_MASK 0x100U /*!< The PHY link up. */ +#define PHY_LINK_READY_MASK (PHY_CTL1_ENERGYDETECT_MASK | PHY_CTL1_LINKUP_MASK) + +/*! @brief Defines the timeout macro. */ +#define PHY_READID_TIMEOUT_COUNT 1000U + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +const phy_operations_t phyksz8081_ops = {.phyInit = PHY_KSZ8081_Init, + .phyWrite = PHY_KSZ8081_Write, + .phyRead = PHY_KSZ8081_Read, + .getAutoNegoStatus = PHY_KSZ8081_GetAutoNegotiationStatus, + .getLinkStatus = PHY_KSZ8081_GetLinkStatus, + .getLinkSpeedDuplex = PHY_KSZ8081_GetLinkSpeedDuplex, + .setLinkSpeedDuplex = PHY_KSZ8081_SetLinkSpeedDuplex, + .enableLoopback = PHY_KSZ8081_EnableLoopback}; + +/******************************************************************************* + * Code + ******************************************************************************/ + +status_t PHY_KSZ8081_Init(phy_handle_t *handle, const phy_config_t *config) { + uint32_t counter = PHY_READID_TIMEOUT_COUNT; + status_t result = kStatus_Success; + uint32_t regValue = 0; + + /* Init MDIO interface. */ + MDIO_Init(handle->mdioHandle); + + /* Assign phy address. */ + handle->phyAddr = config->phyAddr; + + /* Check PHY ID. */ + do + { + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_ID1_REG, ®Value); + if (result != kStatus_Success) { + return result; + } + counter--; + } while ((regValue != PHY_CONTROL_ID1) && (counter != 0U)); + + if (counter == 0U) { + return kStatus_Fail; + } + + /* Reset PHY. */ + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK); + if (result == kStatus_Success) { + #if defined(FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE) + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, ®Value); + if (result != kStatus_Success) { + return result; + } + result = + MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, (regValue | PHY_CTL2_REFCLK_SELECT_MASK)); + if (result != kStatus_Success) { + return result; + } + #endif /* FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE */ + + if (config->autoNeg) { + /* Set the auto-negotiation then start it. */ + result = + MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_AUTONEG_ADVERTISE_REG, + (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK | + PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | PHY_IEEE802_3_SELECTOR_MASK)); + if (result == kStatus_Success) { + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, + (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK)); + } + } else { + /* This PHY only supports 10/100M speed. */ + assert(config->speed <= kPHY_Speed100M); + + /* Disable isolate mode */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); + if (result != kStatus_Success) { + return result; + } + regValue &= ~PHY_BCTL_ISOLATE_MASK; + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + if (result != kStatus_Success) { + return result; + } + + /* Disable the auto-negotiation and set user-defined speed/duplex configuration. */ + result = PHY_KSZ8081_SetLinkSpeedDuplex(handle, config->speed, config->duplex); + } + } + return result; +} + +status_t PHY_KSZ8081_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data) { + return MDIO_Write(handle->mdioHandle, handle->phyAddr, phyReg, data); +} + +status_t PHY_KSZ8081_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr) { + return MDIO_Read(handle->mdioHandle, handle->phyAddr, phyReg, dataPtr); +} + +status_t PHY_KSZ8081_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status) { + assert(status); + + status_t result; + uint32_t regValue; + + *status = false; + + /* Check auto negotiation complete. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, ®Value); + if (result == kStatus_Success) { + if ((regValue & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0U) { + *status = true; + } + } + return result; +} + +status_t PHY_KSZ8081_GetLinkStatus(phy_handle_t *handle, bool *status) { + assert(status); + + status_t result; + uint32_t regValue; + + /* Read the basic status register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, ®Value); + if (result == kStatus_Success) { + if ((PHY_BSTATUS_LINKSTATUS_MASK & regValue) != 0U) { + /* Link up. */ + *status = true; + } else { + /* Link down. */ + *status = false; + } + } + return result; +} + +status_t PHY_KSZ8081_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex) { + assert(!((speed == NULL) && (duplex == NULL))); + + status_t result; + uint32_t regValue; + uint32_t flag; + + /* Read the control register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_CONTROL1_REG, ®Value); + if (result == kStatus_Success) { + if (speed != NULL) { + flag = regValue & PHY_CTL1_SPEEDUPLX_MASK; + if ((PHY_CTL1_100HALFDUPLEX_MASK == flag) || (PHY_CTL1_100FULLDUPLEX_MASK == flag)) { + *speed = kPHY_Speed100M; + } else { + *speed = kPHY_Speed10M; + } + } + + if (duplex != NULL) { + flag = regValue & PHY_CTL1_SPEEDUPLX_MASK; + if ((PHY_CTL1_10FULLDUPLEX_MASK == flag) || (PHY_CTL1_100FULLDUPLEX_MASK == flag)) { + *duplex = kPHY_FullDuplex; + } else { + *duplex = kPHY_HalfDuplex; + } + } + } + return result; +} + +status_t PHY_KSZ8081_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex) { + /* This PHY only supports 10/100M speed. */ + assert(speed <= kPHY_Speed100M); + + status_t result; + uint32_t regValue; + + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); + if (result == kStatus_Success) { + /* Disable the auto-negotiation and set according to user-defined configuration. */ + regValue &= ~PHY_BCTL_AUTONEG_MASK; + if (speed == kPHY_Speed100M) { + regValue |= PHY_BCTL_SPEED0_MASK; + } else { + regValue &= ~PHY_BCTL_SPEED0_MASK; + } + if (duplex == kPHY_FullDuplex) { + regValue |= PHY_BCTL_DUPLEX_MASK; + } else { + regValue &= ~PHY_BCTL_DUPLEX_MASK; + } + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + } + return result; +} + +status_t PHY_KSZ8081_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable) { + /* This PHY only supports local/remote loopback and 10/100M speed. */ + assert(mode <= kPHY_RemoteLoop); + assert(speed <= kPHY_Speed100M); + + status_t result; + uint32_t regValue; + + /* Set the loop mode. */ + if (enable) { + if (mode == kPHY_LocalLoop) { + if (speed == kPHY_Speed100M) { + regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + } else { + regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + } + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + } else { + /* Remote loopback only supports 100M full-duplex. */ + assert(speed == kPHY_Speed100M); + + regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + if (result != kStatus_Success) { + return result; + } + /* Set the remote loopback bit. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, ®Value); + if (result == kStatus_Success) { + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, + (regValue | PHY_CTL2_REMOTELOOP_MASK)); + } + } + } else { + /* Disable the loop mode. */ + if (mode == kPHY_LocalLoop) { + /* First read the current status in control register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); + if (result == kStatus_Success) { + regValue &= ~PHY_BCTL_LOOP_MASK; + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, + (regValue | PHY_BCTL_RESTART_AUTONEG_MASK)); + } + } else { + /* First read the current status in control one register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, ®Value); + if (result == kStatus_Success) { + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, + (regValue & ~PHY_CTL2_REMOTELOOP_MASK)); + } + } + } + return result; +} diff --git a/ports/mimxrt/hal/phy/device/phyksz8081/fsl_phyksz8081.h b/ports/mimxrt/hal/phy/device/phyksz8081/fsl_phyksz8081.h new file mode 100644 index 0000000000..5b93c5698a --- /dev/null +++ b/ports/mimxrt/hal/phy/device/phyksz8081/fsl_phyksz8081.h @@ -0,0 +1,163 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/***************************************************************************** + * PHY KSZ8081 driver change log + *****************************************************************************/ + +/*! +@page driver_log Driver Change Log + +@section phyksz8081 PHYKSZ8081 + The current PHYKSZ8081 driver version is 2.0.0. + + - 2.0.0 + - Initial version. +*/ + +#ifndef _FSL_PHYKSZ8081_H_ +#define _FSL_PHYKSZ8081_H_ + +#include "fsl_phy.h" + +/*! + * @addtogroup phy_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief PHY driver version */ +#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) + +/*! @brief PHY operations structure. */ +extern const phy_operations_t phyksz8081_ops; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name PHY Driver + * @{ + */ + +/*! + * @brief Initializes PHY. + * + * This function initialize PHY. + * + * @param handle PHY device handle. + * @param config Pointer to structure of phy_config_t. + * @retval kStatus_Success PHY initialization succeeds + * @retval kStatus_Fail PHY initialization fails + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_KSZ8081_Init(phy_handle_t *handle, const phy_config_t *config); + +/*! + * @brief PHY Write function. This function writes data over the SMI to + * the specified PHY register. This function is called by all PHY interfaces. + * + * @param handle PHY device handle. + * @param phyReg The PHY register. + * @param data The data written to the PHY register. + * @retval kStatus_Success PHY write success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_KSZ8081_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data); + +/*! + * @brief PHY Read function. This interface read data over the SMI from the + * specified PHY register. This function is called by all PHY interfaces. + * + * @param handle PHY device handle. + * @param phyReg The PHY register. + * @param dataPtr The address to store the data read from the PHY register. + * @retval kStatus_Success PHY read success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_KSZ8081_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr); + +/*! + * @brief Gets the PHY auto-negotiation status. + * + * @param handle PHY device handle. + * @param status The auto-negotiation status of the PHY. + * - true the auto-negotiation is over. + * - false the auto-negotiation is on-going or not started. + * @retval kStatus_Success PHY gets status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_KSZ8081_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status); + +/*! + * @brief Gets the PHY link status. + * + * @param handle PHY device handle. + * @param status The link up or down status of the PHY. + * - true the link is up. + * - false the link is down. + * @retval kStatus_Success PHY gets link status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_KSZ8081_GetLinkStatus(phy_handle_t *handle, bool *status); + +/*! + * @brief Gets the PHY link speed and duplex. + * + * @brief This function gets the speed and duplex mode of PHY. User can give one of speed + * and duplex address paramter and set the other as NULL if only wants to get one of them. + * + * @param handle PHY device handle. + * @param speed The address of PHY link speed. + * @param duplex The link duplex of PHY. + * @retval kStatus_Success PHY gets link speed and duplex success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_KSZ8081_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex); + +/*! + * @brief Sets the PHY link speed and duplex. + * + * @param handle PHY device handle. + * @param speed Specified PHY link speed. + * @param duplex Specified PHY link duplex. + * @retval kStatus_Success PHY gets status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_KSZ8081_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex); + +/*! + * @brief Enables/disables PHY loopback. + * + * @param handle PHY device handle. + * @param mode The loopback mode to be enabled, please see "phy_loop_t". + * All loopback modes should not be set together, when one loopback mode is set + * another should be disabled. + * @param speed PHY speed for loopback mode. + * @param enable True to enable, false to disable. + * @retval kStatus_Success PHY loopback success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_KSZ8081_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_PHYKSZ8081_H_ */ diff --git a/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.c b/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.c new file mode 100644 index 0000000000..b7435c2d05 --- /dev/null +++ b/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.c @@ -0,0 +1,271 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_phylan8720.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Defines the PHY LAN8720 vendor defined registers. */ +#define PHY_PHYSTS_REG 0x1FU // Phy status register +#define PHY_MCSR_REG 0x11U // Mode Control/Status Register for loopback + +/*! @brief Defines the PHY LAN8720 ID number. */ +#define PHY_CONTROL_ID1 0x07U /*!< The PHY ID1 */ + +/*! @brief Defines the mask flag of operation mode in control registers */ +#define PHY_PHYSTS_MASK 0x001CU /*!< The PHY Status mask. */ +#define PHY_PHYSTS_DUPLEX_MASK 0x0010U /*!< The PHY full duplex mask. */ +#define PHY_PHYSTS_100M_MASK 0x000CU /*!< The PHY 100M mask. */ +#define PHY_PHYSTS_100M_FLAG 0x0008U /*!< The PHY 100M flag. */ +#define PHY_PHYSTS_LINK_MASK 0x0001U /*!< The PHY link up mask. */ + +#define PHY_MCSR_REMOTELOOP_MASK 0x100U // !< The PHY remote loopback mask. +#define PHY_MCSR_REMOTELOOP_MODE 0x100U // !< The PHY remote loopback mode. + +/*! @brief Defines the timeout macro. */ +#define PHY_READID_TIMEOUT_COUNT 1000U + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +const phy_operations_t phylan8720_ops = {.phyInit = PHY_LAN8720_Init, + .phyWrite = PHY_LAN8720_Write, + .phyRead = PHY_LAN8720_Read, + .getAutoNegoStatus = PHY_LAN8720_GetAutoNegotiationStatus, + .getLinkStatus = PHY_LAN8720_GetLinkStatus, + .getLinkSpeedDuplex = PHY_LAN8720_GetLinkSpeedDuplex, + .setLinkSpeedDuplex = PHY_LAN8720_SetLinkSpeedDuplex, + .enableLoopback = PHY_LAN8720_EnableLoopback}; + +/******************************************************************************* + * Code + ******************************************************************************/ + +status_t PHY_LAN8720_Init(phy_handle_t *handle, const phy_config_t *config) { + uint32_t counter = PHY_READID_TIMEOUT_COUNT; + status_t result = kStatus_Success; + uint32_t regValue = 0; + + /* Init MDIO interface. */ + MDIO_Init(handle->mdioHandle); + + /* Assign phy address. */ + handle->phyAddr = config->phyAddr; + + /* Check PHY ID. */ + do + { + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_ID1_REG, ®Value); + if (result != kStatus_Success) { + return result; + } + counter--; + } while ((regValue != PHY_CONTROL_ID1) && (counter != 0U)); + + if (counter == 0U) { + return kStatus_Fail; + } + + /* Reset PHY. */ + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK); + if (result == kStatus_Success) { + if (config->autoNeg) { + /* Set the auto-negotiation then start it. */ + result = + MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_AUTONEG_ADVERTISE_REG, + (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK | + PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | PHY_IEEE802_3_SELECTOR_MASK)); + if (result == kStatus_Success) { + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, + (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK)); + } + } else { + /* This PHY only supports 10/100M speed. */ + assert(config->speed <= kPHY_Speed100M); + + /* Disable isolate mode */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); + if (result != kStatus_Success) { + return result; + } + regValue &= ~PHY_BCTL_ISOLATE_MASK; + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + if (result != kStatus_Success) { + return result; + } + + /* Disable the auto-negotiation and set user-defined speed/duplex configuration. */ + result = PHY_LAN8720_SetLinkSpeedDuplex(handle, config->speed, config->duplex); + } + } + return result; +} + +status_t PHY_LAN8720_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data) { + return MDIO_Write(handle->mdioHandle, handle->phyAddr, phyReg, data); +} + +status_t PHY_LAN8720_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr) { + return MDIO_Read(handle->mdioHandle, handle->phyAddr, phyReg, dataPtr); +} + +status_t PHY_LAN8720_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status) { + assert(status); + + status_t result; + uint32_t regValue; + + *status = false; + + /* Check auto negotiation complete. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, ®Value); + if (result == kStatus_Success) { + if ((regValue & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0U) { + *status = true; + } + } + return result; +} + +status_t PHY_LAN8720_GetLinkStatus(phy_handle_t *handle, bool *status) { + assert(status); + + status_t result; + uint32_t regValue; + + /* Read the basic status register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, ®Value); + if (result == kStatus_Success) { + if ((PHY_BSTATUS_LINKSTATUS_MASK & regValue) != 0U) { + /* Link up. */ + *status = true; + } else { + /* Link down. */ + *status = false; + } + } + return result; +} + +status_t PHY_LAN8720_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex) { + assert(!((speed == NULL) && (duplex == NULL))); + + status_t result; + uint32_t regValue; + uint32_t flag; + + /* Read the control register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_PHYSTS_REG, ®Value); + if (result == kStatus_Success) { + regValue &= PHY_PHYSTS_MASK; + if (speed != NULL) { + flag = regValue & PHY_PHYSTS_100M_MASK; + if (flag == PHY_PHYSTS_100M_FLAG) { + *speed = kPHY_Speed100M; + } else { + *speed = kPHY_Speed10M; + } + } + + if (duplex != NULL) { + flag = regValue & PHY_PHYSTS_DUPLEX_MASK; + if (flag) { + *duplex = kPHY_FullDuplex; + } else { + *duplex = kPHY_HalfDuplex; + } + } + } + return result; +} + +status_t PHY_LAN8720_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex) { + /* This PHY only supports 10/100M speed. */ + assert(speed <= kPHY_Speed100M); + + status_t result; + uint32_t regValue; + + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); + if (result == kStatus_Success) { + /* Disable the auto-negotiation and set according to user-defined configuration. */ + regValue &= ~PHY_BCTL_AUTONEG_MASK; + if (speed == kPHY_Speed100M) { + regValue |= PHY_BCTL_SPEED0_MASK; + } else { + regValue &= ~PHY_BCTL_SPEED0_MASK; + } + if (duplex == kPHY_FullDuplex) { + regValue |= PHY_BCTL_DUPLEX_MASK; + } else { + regValue &= ~PHY_BCTL_DUPLEX_MASK; + } + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + } + return result; +} + +status_t PHY_LAN8720_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable) { + /* This PHY only supports local/remote loopback and 10/100M speed. */ + assert(mode <= kPHY_RemoteLoop); + assert(speed <= kPHY_Speed100M); + + status_t result = kStatus_Success; + uint32_t regValue; + + /* Set the loop mode. */ + if (enable) { + if (mode == kPHY_LocalLoop) { + if (speed == kPHY_Speed100M) { + regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + } else { + regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + } + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + } else { + /* Remote loopback only supports 100M full-duplex. */ + assert(speed == kPHY_Speed100M); + + regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + if (result != kStatus_Success) { + return result; + } + /* Set the remote loopback bit. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_MCSR_REG, ®Value); + if (result == kStatus_Success) { + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_MCSR_REG, + (regValue & ~PHY_MCSR_REMOTELOOP_MASK) | PHY_MCSR_REMOTELOOP_MODE); + } + } + } else { + /* Disable the loop mode. */ + if (mode != kPHY_LocalLoop) { + /* First read the current status in control one register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_MCSR_REG, ®Value); + if (result == kStatus_Success) { + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_MCSR_REG, + (regValue & ~PHY_MCSR_REMOTELOOP_MASK)); + } + } + /* First read the current status in control register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); + if (result == kStatus_Success) { + regValue &= ~PHY_BCTL_LOOP_MASK; + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, + (regValue | PHY_BCTL_RESTART_AUTONEG_MASK)); + } + } + + return result; +} diff --git a/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.h b/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.h new file mode 100644 index 0000000000..2e8b4e3631 --- /dev/null +++ b/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.h @@ -0,0 +1,163 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/***************************************************************************** + * PHY KSZ8081 driver change log + *****************************************************************************/ + +/*! +@page driver_log Driver Change Log + +@section phylan8720 PHYLAN8720 + The current PHYLAN8720 driver version is 2.0.0. + + - 2.0.0 + - Initial version. +*/ + +#ifndef _FSL_PHYLAN8720_H_ +#define _FSL_PHYLAN8720_H_ + +#include "fsl_phy.h" + +/*! + * @addtogroup phy_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief PHY driver version */ +#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) + +/*! @brief PHY operations structure. */ +extern const phy_operations_t phylan8720_ops; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name PHY Driver + * @{ + */ + +/*! + * @brief Initializes PHY. + * + * This function initialize PHY. + * + * @param handle PHY device handle. + * @param config Pointer to structure of phy_config_t. + * @retval kStatus_Success PHY initialization succeeds + * @retval kStatus_Fail PHY initialization fails + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_LAN8720_Init(phy_handle_t *handle, const phy_config_t *config); + +/*! + * @brief PHY Write function. This function writes data over the SMI to + * the specified PHY register. This function is called by all PHY interfaces. + * + * @param handle PHY device handle. + * @param phyReg The PHY register. + * @param data The data written to the PHY register. + * @retval kStatus_Success PHY write success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_LAN8720_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data); + +/*! + * @brief PHY Read function. This interface read data over the SMI from the + * specified PHY register. This function is called by all PHY interfaces. + * + * @param handle PHY device handle. + * @param phyReg The PHY register. + * @param dataPtr The address to store the data read from the PHY register. + * @retval kStatus_Success PHY read success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_LAN8720_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr); + +/*! + * @brief Gets the PHY auto-negotiation status. + * + * @param handle PHY device handle. + * @param status The auto-negotiation status of the PHY. + * - true the auto-negotiation is over. + * - false the auto-negotiation is on-going or not started. + * @retval kStatus_Success PHY gets status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_LAN8720_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status); + +/*! + * @brief Gets the PHY link status. + * + * @param handle PHY device handle. + * @param status The link up or down status of the PHY. + * - true the link is up. + * - false the link is down. + * @retval kStatus_Success PHY gets link status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_LAN8720_GetLinkStatus(phy_handle_t *handle, bool *status); + +/*! + * @brief Gets the PHY link speed and duplex. + * + * @brief This function gets the speed and duplex mode of PHY. User can give one of speed + * and duplex address paramter and set the other as NULL if only wants to get one of them. + * + * @param handle PHY device handle. + * @param speed The address of PHY link speed. + * @param duplex The link duplex of PHY. + * @retval kStatus_Success PHY gets link speed and duplex success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_LAN8720_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex); + +/*! + * @brief Sets the PHY link speed and duplex. + * + * @param handle PHY device handle. + * @param speed Specified PHY link speed. + * @param duplex Specified PHY link duplex. + * @retval kStatus_Success PHY gets status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_LAN8720_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex); + +/*! + * @brief Enables/disables PHY loopback. + * + * @param handle PHY device handle. + * @param mode The loopback mode to be enabled, please see "phy_loop_t". + * All loopback modes should not be set together, when one loopback mode is set + * another should be disabled. + * @param speed PHY speed for loopback mode. + * @param enable True to enable, false to disable. + * @retval kStatus_Success PHY loopback success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_LAN8720_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_PHYLAN8720_H_ */ diff --git a/ports/mimxrt/hal/phy/fsl_mdio.h b/ports/mimxrt/hal/phy/fsl_mdio.h new file mode 100644 index 0000000000..6bfee2a244 --- /dev/null +++ b/ports/mimxrt/hal/phy/fsl_mdio.h @@ -0,0 +1,125 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_MDIO_H_ +#define _FSL_MDIO_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Defines the timeout macro. */ +#if defined(MDIO_TIMEOUT_COUNT_NUMBER) && MDIO_TIMEOUT_COUNT_NUMBER +#define MDIO_TIMEOUT_COUNT MDIO_TIMEOUT_COUNT_NUMBER +#endif + +/*! @brief Defines the PHY status. */ +enum _mdio_status +{ + kStatus_PHY_SMIVisitTimeout = MAKE_STATUS(kStatusGroup_PHY, 0), /*!< ENET PHY SMI visit timeout. */ +}; + +typedef struct _mdio_operations mdio_operations_t; + +/*! @brief MDIO resource. */ +typedef struct _mdio_resource +{ + void *base; /*!< ENET Ip register base. */ + uint32_t csrClock_Hz; /*!< ENET CSR clock. */ +} mdio_resource_t; + +/*! @brief MDIO handle. */ +typedef struct _mdio_handle +{ + mdio_resource_t resource; + const mdio_operations_t *ops; +} mdio_handle_t; + +/*! @brief Camera receiver operations. */ +struct _mdio_operations +{ + void (*mdioInit)(mdio_handle_t *handle); /*!< MDIO interface init. */ + status_t (*mdioWrite)(mdio_handle_t *handle, + uint32_t phyAddr, + uint32_t devAddr, + uint32_t data); /*!< MDIO write data. */ + status_t (*mdioRead)(mdio_handle_t *handle, + uint32_t phyAddr, + uint32_t devAddr, + uint32_t *dataPtr); /*!< MDIO read data. */ + status_t (*mdioWriteExt)(mdio_handle_t *handle, + uint32_t phyAddr, + uint32_t devAddr, + uint32_t data); /*!< MDIO write data. */ + status_t (*mdioReadExt)(mdio_handle_t *handle, + uint32_t phyAddr, + uint32_t devAddr, + uint32_t *dataPtr); /*!< MDIO read data. */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif +/*! + * @name MDIO Driver + * @{ + */ + +/*! + * @brief MDIO Write function. This function write data over the SMI to + * the specified MDIO register. This function is called by all MDIO interfaces. + * + * @param handle MDIO device handle. + * @retval kStatus_Success MDIO write success + * @retval kStatus_MDIO_SMIVisitTimeout MDIO SMI visit time out + */ +static inline void MDIO_Init(mdio_handle_t *handle) { + handle->ops->mdioInit(handle); +} + +/*! + * @brief MDIO Write function. This function write data over the SMI to + * the specified MDIO register. This function is called by all MDIO interfaces. + * + * @param handle MDIO device handle. + * @param phyAddr MDIO PHY address handle. + * @param devAddr The PHY device register. + * @param data The data written to the MDIO register. + * @retval kStatus_Success MDIO write success + * @retval kStatus_MDIO_SMIVisitTimeout MDIO SMI visit time out + */ +static inline status_t MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data) { + return handle->ops->mdioWrite(handle, phyAddr, devAddr, data); +} + +/*! + * @brief MDIO Read function. This interface read data over the SMI from the + * specified MDIO register. This function is called by all MDIO interfaces. + * + * @param handle MDIO device handle. + * @param phyAddr MDIO PHY address handle. + * @param devAddr The PHY device register. + * @param dataPtr The address to store the data read from the MDIO register. + * @retval kStatus_Success MDIO read success + * @retval kStatus_MDIO_SMIVisitTimeout MDIO SMI visit time out + */ +static inline status_t MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr) { + return handle->ops->mdioRead(handle, phyAddr, devAddr, dataPtr); +} + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/ports/mimxrt/hal/phy/fsl_phy.h b/ports/mimxrt/hal/phy/fsl_phy.h new file mode 100644 index 0000000000..6a022d4eae --- /dev/null +++ b/ports/mimxrt/hal/phy/fsl_phy.h @@ -0,0 +1,258 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_PHY_H_ +#define _FSL_PHY_H_ + +#include "fsl_mdio.h" + +/*! @note The following PHY registers are the IEEE802.3 standard definition, same register and bit field may + have different names in various PHYs, but the feature they represent should be same or very similar. */ + +/*! @brief Defines the IEEE802.3 standard PHY registers. */ +#define PHY_BASICCONTROL_REG 0x00U /*!< The PHY basic control register. */ +#define PHY_BASICSTATUS_REG 0x01U /*!< The PHY basic status register. */ +#define PHY_ID1_REG 0x02U /*!< The PHY ID one register. */ +#define PHY_ID2_REG 0x03U /*!< The PHY ID two register. */ +#define PHY_AUTONEG_ADVERTISE_REG 0x04U /*!< The PHY auto-negotiate advertise register. */ +#define PHY_AUTONEG_LINKPARTNER_REG 0x05U /*!< The PHY auto negotiation link partner ability register. */ +#define PHY_AUTONEG_EXPANSION_REG 0x06U /*!< The PHY auto negotiation expansion register. */ +#define PHY_1000BASET_CONTROL_REG 0x09U /*!< The PHY 1000BASE-T control register. */ +#define PHY_MMD_ACCESS_CONTROL_REG 0x0DU /*!< The PHY MMD access control register. */ +#define PHY_MMD_ACCESS_DATA_REG 0x0EU /*!< The PHY MMD access data register. */ + +/*! @brief Defines the mask flag in basic control register(Address 0x00). */ +#define PHY_BCTL_SPEED1_MASK 0x0040U /*!< The PHY speed bit mask(MSB).*/ +#define PHY_BCTL_ISOLATE_MASK 0x0400U /*!< The PHY isolate mask.*/ +#define PHY_BCTL_DUPLEX_MASK 0x0100U /*!< The PHY duplex bit mask. */ +#define PHY_BCTL_RESTART_AUTONEG_MASK 0x0200U /*!< The PHY restart auto negotiation mask. */ +#define PHY_BCTL_AUTONEG_MASK 0x1000U /*!< The PHY auto negotiation bit mask. */ +#define PHY_BCTL_SPEED0_MASK 0x2000U /*!< The PHY speed bit mask(LSB). */ +#define PHY_BCTL_LOOP_MASK 0x4000U /*!< The PHY loop bit mask. */ +#define PHY_BCTL_RESET_MASK 0x8000U /*!< The PHY reset bit mask. */ + +/*! @brief Defines the mask flag in basic status register(Address 0x01). */ +#define PHY_BSTATUS_LINKSTATUS_MASK 0x0004U /*!< The PHY link status mask. */ +#define PHY_BSTATUS_AUTONEGABLE_MASK 0x0008U /*!< The PHY auto-negotiation ability mask. */ +#define PHY_BSTATUS_SPEEDUPLX_MASK 0x001CU /*!< The PHY speed and duplex mask. */ +#define PHY_BSTATUS_AUTONEGCOMP_MASK 0x0020U /*!< The PHY auto-negotiation complete mask. */ + +/*! @brief Defines the mask flag in PHY auto-negotiation advertise register(Address 0x04). */ +#define PHY_100BaseT4_ABILITY_MASK 0x200U /*!< The PHY have the T4 ability. */ +#define PHY_100BASETX_FULLDUPLEX_MASK 0x100U /*!< The PHY has the 100M full duplex ability.*/ +#define PHY_100BASETX_HALFDUPLEX_MASK 0x080U /*!< The PHY has the 100M full duplex ability.*/ +#define PHY_10BASETX_FULLDUPLEX_MASK 0x040U /*!< The PHY has the 10M full duplex ability.*/ +#define PHY_10BASETX_HALFDUPLEX_MASK 0x020U /*!< The PHY has the 10M full duplex ability.*/ +#define PHY_IEEE802_3_SELECTOR_MASK 0x001U /*!< The message type being sent by Auto-Nego.*/ + +/*! @brief Defines the mask flag in the 1000BASE-T control register(Address 0x09). */ +#define PHY_1000BASET_FULLDUPLEX_MASK 0x200U /*!< The PHY has the 1000M full duplex ability.*/ +#define PHY_1000BASET_HALFDUPLEX_MASK 0x100U /*!< The PHY has the 1000M half duplex ability.*/ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +typedef struct _phy_handle phy_handle_t; +/*! @brief Defines the PHY link speed. */ +typedef enum _phy_speed +{ + kPHY_Speed10M = 0U, /*!< ENET PHY 10M speed. */ + kPHY_Speed100M, /*!< ENET PHY 100M speed. */ + kPHY_Speed1000M /*!< ENET PHY 1000M speed. */ +} phy_speed_t; + +/*! @brief Defines the PHY link duplex. */ +typedef enum _phy_duplex +{ + kPHY_HalfDuplex = 0U, /*!< ENET PHY half duplex. */ + kPHY_FullDuplex /*!< ENET PHY full duplex. */ +} phy_duplex_t; + +/*! @brief Defines the PHY loopback mode. */ +typedef enum _phy_loop +{ + kPHY_LocalLoop = 0U, /*!< ENET PHY local/digital loopback. */ + kPHY_RemoteLoop, /*!< ENET PHY remote loopback. */ + kPHY_ExternalLoop, /*!< ENET PHY external loopback. */ +} phy_loop_t; + +/*! @brief Defines the PHY MMD data access mode. */ +typedef enum _phy_mmd_access_mode +{ + kPHY_MMDAccessNoPostIncrement = (1U << 14), /*!< ENET PHY MMD access data with no address post increment. */ + kPHY_MMDAccessRdWrPostIncrement = + (2U << 14), /*!< ENET PHY MMD access data with Read/Write address post increment. */ + kPHY_MMDAccessWrPostIncrement = (3U << 14), /*!< ENET PHY MMD access data with Write address post increment. */ +} phy_mmd_access_mode_t; + +/*! @brief Defines PHY configuration. */ +typedef struct _phy_config +{ + uint32_t phyAddr; /*!< PHY address. */ + phy_speed_t speed; /*!< PHY speed configuration. */ + phy_duplex_t duplex; /*!< PHY duplex configuration. */ + bool autoNeg; /*!< PHY auto-negotiation, true: enable, false: disable. */ + bool enableEEE; /*!< PHY Energy Efficient Ethernet. */ +} phy_config_t; + +/*! @brief PHY device operations. */ +typedef struct _phy_operations +{ + status_t (*phyInit)(phy_handle_t *handle, const phy_config_t *config); + status_t (*phyWrite)(phy_handle_t *handle, uint32_t phyReg, uint32_t data); + status_t (*phyRead)(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr); + status_t (*getAutoNegoStatus)(phy_handle_t *handle, bool *status); + status_t (*getLinkStatus)(phy_handle_t *handle, bool *status); + status_t (*getLinkSpeedDuplex)(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex); + status_t (*setLinkSpeedDuplex)(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex); + status_t (*enableLoopback)(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable); +} phy_operations_t; + +/*! @brief PHY device handle. */ + +struct _phy_handle +{ + uint32_t phyAddr; /*!< PHY address. */ + mdio_handle_t *mdioHandle; /*!< The MDIO handle used by the phy device, it is specified by device. */ + const phy_operations_t *ops; /*!< The device related operations. */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name PHY Driver + * @{ + */ + +/*! + * @brief Initializes PHY. + * + * This function initialize PHY. + * + * @param handle PHY device handle. + * @param config Pointer to structure of phy_config_t. + * @retval kStatus_Success PHY initialization succeeds + * @retval kStatus_Fail PHY initialization fails + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +static inline status_t PHY_Init(phy_handle_t *handle, const phy_config_t *config) { + return handle->ops->phyInit(handle, config); +} +/*! + * @brief PHY Write function. This function write data over the SMI to + * the specified PHY register. This function is called by all PHY interfaces. + * + * @param handle PHY device handle. + * @param phyReg The PHY register. + * @param data The data written to the PHY register. + * @retval kStatus_Success PHY write success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +static inline status_t PHY_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data) { + return handle->ops->phyWrite(handle, phyReg, data); +} + +/*! + * @brief PHY Read function. This interface read data over the SMI from the + * specified PHY register. This function is called by all PHY interfaces. + * + * @param handle PHY device handle. + * @param phyReg The PHY register. + * @param dataPtr The address to store the data read from the PHY register. + * @retval kStatus_Success PHY read success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +static inline status_t PHY_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr) { + return handle->ops->phyRead(handle, phyReg, dataPtr); +} + +/*! + * @brief Gets the PHY auto-negotiation status. + * + * @param handle PHY device handle. + * @param status The auto-negotiation status of the PHY. + * - true the auto-negotiation is over. + * - false the auto-negotiation is on-going or not started. + * @retval kStatus_Success PHY gets status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +static inline status_t PHY_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status) { + return handle->ops->getAutoNegoStatus(handle, status); +} + +/*! + * @brief Gets the PHY link status. + * + * @param handle PHY device handle. + * @param status The link up or down status of the PHY. + * - true the link is up. + * - false the link is down. + * @retval kStatus_Success PHY get link status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +static inline status_t PHY_GetLinkStatus(phy_handle_t *handle, bool *status) { + return handle->ops->getLinkStatus(handle, status); +} + +/*! + * @brief Gets the PHY link speed and duplex. + * + * @brief This function gets the speed and duplex mode of PHY. User can give one of speed + * and duplex address paramter and set the other as NULL if only wants to get one of them. + * + * @param handle PHY device handle. + * @param speed The address of PHY link speed. + * @param duplex The link duplex of PHY. + * @retval kStatus_Success PHY get link speed and duplex success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +static inline status_t PHY_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex) { + return handle->ops->getLinkSpeedDuplex(handle, speed, duplex); +} + +/*! + * @brief Sets the PHY link speed and duplex. + * + * @param handle PHY device handle. + * @param speed Specified PHY link speed. + * @param duplex Specified PHY link duplex. + * @retval kStatus_Success PHY gets status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +static inline status_t PHY_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex) { + return handle->ops->setLinkSpeedDuplex(handle, speed, duplex); +} + +/*! + * @brief Enable PHY loopcback mode. + * + * @param handle PHY device handle. + * @param mode The loopback mode to be enabled, please see "phy_loop_t". + * All loopback modes should not be set together, when one loopback mode is set + * another should be disabled. + * @param speed PHY speed for loopback mode. + * @param enable True to enable, false to disable. + * @retval kStatus_Success PHY get link speed and duplex success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +static inline status_t PHY_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable) { + return handle->ops->enableLoopback(handle, mode, speed, enable); +} + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ +#endif diff --git a/ports/mimxrt/hal/phy/mdio/enet/fsl_enet_mdio.c b/ports/mimxrt/hal/phy/mdio/enet/fsl_enet_mdio.c new file mode 100644 index 0000000000..8e679cd989 --- /dev/null +++ b/ports/mimxrt/hal/phy/mdio/enet/fsl_enet_mdio.c @@ -0,0 +1,128 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_enet_mdio.h" +#include "fsl_enet.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +static void ENET_MDIO_Init(mdio_handle_t *handle); +static status_t ENET_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data); +static status_t ENET_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr); + +uint32_t ENET_GetInstance(ENET_Type *base); +extern clock_ip_name_t s_enetClock[]; + +/******************************************************************************* + * Variables + ******************************************************************************/ + +const mdio_operations_t enet_ops = {.mdioInit = ENET_MDIO_Init, + .mdioWrite = ENET_MDIO_Write, + .mdioRead = ENET_MDIO_Read, + .mdioWriteExt = NULL, + .mdioReadExt = NULL}; + +/******************************************************************************* + * Code + ******************************************************************************/ + +static void ENET_MDIO_Init(mdio_handle_t *handle) { + mdio_resource_t *resource = (mdio_resource_t *)&handle->resource; + ENET_Type *base = (ENET_Type *)resource->base; + uint32_t instance = ENET_GetInstance(base); + + #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Set SMI first. */ + (void)CLOCK_EnableClock(s_enetClock[instance]); + #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + ENET_SetSMI(base, resource->csrClock_Hz, false); +} + +static status_t ENET_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data) { + mdio_resource_t *resource = (mdio_resource_t *)&handle->resource; + ENET_Type *base = (ENET_Type *)resource->base; + status_t result = kStatus_Success; + #ifdef MDIO_TIMEOUT_COUNT + uint32_t counter; + #endif + + /* Clear the SMI interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + /* Starts a SMI write command. */ + ENET_StartSMIWrite(base, phyAddr, devAddr, kENET_MiiWriteValidFrame, data); + + /* Wait for SMI complete. */ + #ifdef MDIO_TIMEOUT_COUNT + for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--) + { + if (ENET_EIR_MII_MASK == (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)) { + break; + } + } + /* Check for timeout. */ + if (0U == counter) { + result = kStatus_PHY_SMIVisitTimeout; + } + #else + while (ENET_EIR_MII_MASK != (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)) { + } + #endif + + /* Clear SMI interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + return result; +} + +static status_t ENET_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr) { + assert(dataPtr); + + mdio_resource_t *resource = (mdio_resource_t *)&handle->resource; + ENET_Type *base = (ENET_Type *)resource->base; + #ifdef MDIO_TIMEOUT_COUNT + uint32_t counter; + #endif + + /* Clear the SMI interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + /* Starts a SMI read command operation. */ + ENET_StartSMIRead(base, phyAddr, devAddr, kENET_MiiReadValidFrame); + + /* Wait for SMI complete. */ + #ifdef MDIO_TIMEOUT_COUNT + for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--) + { + if (ENET_EIR_MII_MASK == (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)) { + break; + } + } + /* Check for timeout. */ + if (0U == counter) { + return kStatus_PHY_SMIVisitTimeout; + } + #else + while (ENET_EIR_MII_MASK != (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)) { + } + #endif + + /* Get data from SMI register. */ + *dataPtr = ENET_ReadSMIData(base); + + /* Clear SMI interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + return kStatus_Success; +} diff --git a/ports/mimxrt/hal/phy/mdio/enet/fsl_enet_mdio.h b/ports/mimxrt/hal/phy/mdio/enet/fsl_enet_mdio.h new file mode 100644 index 0000000000..500985d8fd --- /dev/null +++ b/ports/mimxrt/hal/phy/mdio/enet/fsl_enet_mdio.h @@ -0,0 +1,21 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_ENET_MDIO_H_ +#define _FSL_ENET_MDIO_H_ + +#include "fsl_enet.h" +#include "fsl_mdio.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief ENET MDIO operations structure. */ +extern const mdio_operations_t enet_ops; + +#endif diff --git a/ports/mimxrt/lwip_inc/arch/cc.h b/ports/mimxrt/lwip_inc/arch/cc.h new file mode 100644 index 0000000000..c37e62b839 --- /dev/null +++ b/ports/mimxrt/lwip_inc/arch/cc.h @@ -0,0 +1,10 @@ +#ifndef MICROPY_INCLUDED_MIMXRT_LWIP_ARCH_CC_H +#define MICROPY_INCLUDED_MIMXRT_LWIP_ARCH_CC_H + +#include +#define LWIP_PLATFORM_DIAG(x) +#define LWIP_PLATFORM_ASSERT(x) { assert(1); } + +#define LWIP_NO_CTYPE_H 1 + +#endif // MICROPY_INCLUDED_MIMXRT_LWIP_ARCH_CC_H diff --git a/ports/mimxrt/lwip_inc/arch/sys_arch.h b/ports/mimxrt/lwip_inc/arch/sys_arch.h new file mode 100644 index 0000000000..8b1a393741 --- /dev/null +++ b/ports/mimxrt/lwip_inc/arch/sys_arch.h @@ -0,0 +1 @@ +// empty diff --git a/ports/mimxrt/lwip_inc/lwipopts.h b/ports/mimxrt/lwip_inc/lwipopts.h new file mode 100644 index 0000000000..42dc9fc5db --- /dev/null +++ b/ports/mimxrt/lwip_inc/lwipopts.h @@ -0,0 +1,59 @@ +#ifndef MICROPY_INCLUDED_MIMXRT_LWIP_LWIPOPTS_H +#define MICROPY_INCLUDED_MIMXRT_LWIP_LWIPOPTS_H + +#include + +// This protection is not needed, instead we execute all lwIP code at PendSV priority +#define SYS_ARCH_DECL_PROTECT(lev) do { } while (0) +#define SYS_ARCH_PROTECT(lev) do { } while (0) +#define SYS_ARCH_UNPROTECT(lev) do { } while (0) + +#define NO_SYS 1 +#define SYS_LIGHTWEIGHT_PROT 1 +#define MEM_ALIGNMENT 4 + +#define LWIP_CHKSUM_ALGORITHM 3 +// Chksum generaration by HW fails for ICMP +// Maybe caused by LWIP inserting ffff instead of 0000 +// The checksum flags are set in eth.c +#define LWIP_CHECKSUM_CTRL_PER_NETIF 0 +#define LWIP_CHECKSUM_ON_COPY 0 + +#define LWIP_ARP 1 +#define LWIP_ETHERNET 1 +#define LWIP_RAW 1 +#define LWIP_NETCONN 0 +#define LWIP_SOCKET 0 +#define LWIP_STATS 0 +#define LWIP_NETIF_HOSTNAME 1 +#define LWIP_NETIF_EXT_STATUS_CALLBACK 1 + +#define LWIP_IPV6 0 +#define LWIP_DHCP 1 +#define LWIP_DHCP_CHECK_LINK_UP 1 +#define DHCP_DOES_ARP_CHECK 0 // to speed DHCP up +#define LWIP_DNS 1 +#define LWIP_DNS_SUPPORT_MDNS_QUERIES 1 +#define LWIP_MDNS_RESPONDER 1 +#define LWIP_IGMP 1 + +#define LWIP_NUM_NETIF_CLIENT_DATA LWIP_MDNS_RESPONDER +#define MEMP_NUM_UDP_PCB (4 + LWIP_MDNS_RESPONDER) +#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + LWIP_MDNS_RESPONDER) + +#define SO_REUSE 1 +#define TCP_LISTEN_BACKLOG 1 + +extern uint32_t trng_random_u32(void); +#define LWIP_RAND() trng_random_u32() + +// lwip takes 26700 bytes +#define MEM_SIZE (8000) +#define TCP_MSS (800) +#define TCP_WND (8 * TCP_MSS) +#define TCP_SND_BUF (8 * TCP_MSS) +#define MEMP_NUM_TCP_SEG (32) + +typedef uint32_t sys_prot_t; + +#endif // MICROPY_INCLUDED_MIMXRT_LWIP_LWIPOPTS_H diff --git a/ports/mimxrt/main.c b/ports/mimxrt/main.c index e81974afaa..f921f50a0c 100644 --- a/ports/mimxrt/main.c +++ b/ports/mimxrt/main.c @@ -36,8 +36,16 @@ #include "ticks.h" #include "tusb.h" #include "led.h" +#include "pendsv.h" #include "modmachine.h" +#if MICROPY_PY_LWIP +#include "lwip/init.h" +#include "lwip/apps/mdns.h" +#endif +#include "systick.h" +#include "extmod/modnetwork.h" + extern uint8_t _sstack, _estack, _gc_heap_start, _gc_heap_end; void board_init(void); @@ -47,10 +55,22 @@ int main(void) { ticks_init(); tusb_init(); led_init(); + pendsv_init(); mp_stack_set_top(&_estack); mp_stack_set_limit(&_estack - &_sstack - 1024); + #if MICROPY_PY_LWIP + // lwIP doesn't allow to reinitialise itself by subsequent calls to this function + // because the system timeout list (next_timeout) is only ever reset by BSS clearing. + // So for now we only init the lwIP stack once on power-up. + lwip_init(); + #if LWIP_MDNS_RESPONDER + mdns_resp_init(); + #endif + systick_enable_dispatch(SYSTICK_DISPATCH_LWIP, mod_network_lwip_poll_wrapper); + #endif + for (;;) { gc_init(&_gc_heap_start, &_gc_heap_end); mp_init(); @@ -58,6 +78,9 @@ int main(void) { mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); + #if MICROPY_PY_NETWORK + mod_network_init(); + #endif // Initialise sub-systems. readline_init0(); @@ -93,6 +116,9 @@ int main(void) { soft_reset_exit: mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); machine_pin_irq_deinit(); + #if MICROPY_PY_NETWORK + mod_network_deinit(); + #endif gc_sweep_all(); mp_deinit(); } diff --git a/ports/mimxrt/mbedtls/mbedtls_config.h b/ports/mimxrt/mbedtls/mbedtls_config.h new file mode 100644 index 0000000000..1ab748d8e5 --- /dev/null +++ b/ports/mimxrt/mbedtls/mbedtls_config.h @@ -0,0 +1,99 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018-2019 Damien P. George + * + * 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_MBEDTLS_CONFIG_H +#define MICROPY_INCLUDED_MBEDTLS_CONFIG_H + +// Set mbedtls configuration +#define MBEDTLS_PLATFORM_MEMORY +#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS +#define MBEDTLS_DEPRECATED_REMOVED +#define MBEDTLS_ENTROPY_HARDWARE_ALT +#define MBEDTLS_AES_ROM_TABLES +#define MBEDTLS_CIPHER_MODE_CBC +#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +#define MBEDTLS_ECP_DP_SECP224R1_ENABLED +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +#define MBEDTLS_ECP_DP_SECP521R1_ENABLED +#define MBEDTLS_ECP_DP_SECP192K1_ENABLED +#define MBEDTLS_ECP_DP_SECP224K1_ENABLED +#define MBEDTLS_ECP_DP_SECP256K1_ENABLED +#define MBEDTLS_ECP_DP_BP256R1_ENABLED +#define MBEDTLS_ECP_DP_BP384R1_ENABLED +#define MBEDTLS_ECP_DP_BP512R1_ENABLED +#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED +#define MBEDTLS_NO_PLATFORM_ENTROPY +#define MBEDTLS_PKCS1_V15 +#define MBEDTLS_SHA256_SMALLER +#define MBEDTLS_SSL_PROTO_TLS1 +#define MBEDTLS_SSL_PROTO_TLS1_1 +#define MBEDTLS_SSL_PROTO_TLS1_2 +#define MBEDTLS_SSL_SERVER_NAME_INDICATION + +// Use a smaller output buffer to reduce size of SSL context +#define MBEDTLS_SSL_MAX_CONTENT_LEN (16384) +#define MBEDTLS_SSL_IN_CONTENT_LEN (MBEDTLS_SSL_MAX_CONTENT_LEN) +#define MBEDTLS_SSL_OUT_CONTENT_LEN (4096) + +// Enable mbedtls modules +#define MBEDTLS_AES_C +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_CIPHER_C +#define MBEDTLS_CTR_DRBG_C +// #define MBEDTLS_ECP_C +#define MBEDTLS_ENTROPY_C +#define MBEDTLS_ERROR_C +#define MBEDTLS_MD_C +#define MBEDTLS_MD5_C +#define MBEDTLS_OID_C +#define MBEDTLS_PKCS5_C +#define MBEDTLS_PK_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PLATFORM_C +#define MBEDTLS_RSA_C +#define MBEDTLS_SHA1_C +#define MBEDTLS_SHA256_C +#define MBEDTLS_SHA512_C +#define MBEDTLS_SSL_CLI_C +#define MBEDTLS_SSL_SRV_C +#define MBEDTLS_SSL_TLS_C +#define MBEDTLS_X509_CRT_PARSE_C +#define MBEDTLS_X509_USE_C + +// Memory allocation hooks +#include +#include +void *m_calloc_mbedtls(size_t nmemb, size_t size); +void m_free_mbedtls(void *ptr); +#define MBEDTLS_PLATFORM_STD_CALLOC m_calloc_mbedtls +#define MBEDTLS_PLATFORM_STD_FREE m_free_mbedtls +#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf + +#include "mbedtls/check_config.h" + +#endif /* MICROPY_INCLUDED_MBEDTLS_CONFIG_H */ diff --git a/ports/mimxrt/mbedtls/mbedtls_port.c b/ports/mimxrt/mbedtls/mbedtls_port.c new file mode 100644 index 0000000000..eb11f5141b --- /dev/null +++ b/ports/mimxrt/mbedtls/mbedtls_port.c @@ -0,0 +1,93 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * + * 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. + */ + +#ifdef MICROPY_SSL_MBEDTLS + +#include "py/runtime.h" +#include "py/gc.h" +#include "fsl_trng.h" +#include "mbedtls_config.h" + +#define DEBUG (0) + +#if DEBUG +static size_t count_links(uint32_t *nb) { + void **p = MP_STATE_PORT(mbedtls_memory); + size_t n = 0; + *nb = 0; + while (p != NULL) { + ++n; + *nb += gc_nbytes(p); + p = (void **)p[1]; + } + return n; +} +#endif + +void *m_calloc_mbedtls(size_t nmemb, size_t size) { + void **ptr = m_malloc0(nmemb * size + 2 * sizeof(uintptr_t)); + #if DEBUG + uint32_t nb; + size_t n = count_links(&nb); + printf("mbed_alloc(%u, %u) -> (%u;%u) %p\n", nmemb, size, n, (uint)nb, ptr); + #endif + if (MP_STATE_PORT(mbedtls_memory) != NULL) { + MP_STATE_PORT(mbedtls_memory)[0] = ptr; + } + ptr[0] = NULL; + ptr[1] = MP_STATE_PORT(mbedtls_memory); + MP_STATE_PORT(mbedtls_memory) = ptr; + return &ptr[2]; +} + +void m_free_mbedtls(void *ptr_in) { + void **ptr = &((void **)ptr_in)[-2]; + #if DEBUG + uint32_t nb; + size_t n = count_links(&nb); + printf("mbed_free(%p, [%p, %p], nbytes=%u, links=%u;%u)\n", ptr, ptr[0], ptr[1], gc_nbytes(ptr), n, (uint)nb); + #endif + if (ptr[1] != NULL) { + ((void **)ptr[1])[0] = ptr[0]; + } + if (ptr[0] != NULL) { + ((void **)ptr[0])[1] = ptr[1]; + } else { + MP_STATE_PORT(mbedtls_memory) = ptr[1]; + } + m_free(ptr); +} + +int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen) { + + // assumes that TRNG_Init was called during startup + *olen = len; + TRNG_GetRandomData(TRNG, output, len); + + return 0; +} + +#endif diff --git a/ports/mimxrt/moduos.c b/ports/mimxrt/moduos.c index ff0f0824c4..b59a5f4483 100644 --- a/ports/mimxrt/moduos.c +++ b/ports/mimxrt/moduos.c @@ -30,6 +30,8 @@ #include "py/objstr.h" #include "py/runtime.h" +#include "py/mphal.h" +#include "extmod/misc.h" #include "extmod/vfs.h" #include "extmod/vfs_fat.h" #include "extmod/vfs_lfs.h" @@ -96,6 +98,21 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom); +#if MICROPY_PY_OS_DUPTERM +STATIC mp_obj_t os_dupterm_notify(mp_obj_t obj_in) { + (void)obj_in; + for (;;) { + int c = mp_uos_dupterm_rx_chr(); + if (c < 0) { + break; + } + ringbuf_put(&stdin_ringbuf, c); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_dupterm_notify_obj, os_dupterm_notify); +#endif + STATIC const mp_rom_map_elem_t os_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) }, @@ -118,6 +135,7 @@ STATIC const mp_rom_map_elem_t os_module_globals_table[] = { #if MICROPY_PY_OS_DUPTERM { MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mp_uos_dupterm_obj) }, + { MP_ROM_QSTR(MP_QSTR_dupterm_notify), MP_ROM_PTR(&os_dupterm_notify_obj) }, #endif #if MICROPY_VFS diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 0fe6cd1291..f1c38b1fad 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -44,7 +44,6 @@ uint32_t trng_random_u32(void); #define MICROPY_EMIT_INLINE_THUMB (1) // Compiler configuration -#define MICROPY_COMP_CONST (0) // Python internal features #define MICROPY_READER_VFS (1) @@ -118,6 +117,7 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_UBINASCII (1) #define MICROPY_PY_UBINASCII_CRC32 (1) #define MICROPY_PY_UTIME_MP_HAL (1) +#define MICROPY_PY_OS_DUPTERM (3) #define MICROPY_PY_URANDOM (1) #define MICROPY_PY_URANDOM_EXTRA_FUNCS (1) #define MICROPY_PY_URANDOM_SEED_INIT_FUNC (trng_random_u32()) @@ -139,12 +139,38 @@ uint32_t trng_random_u32(void); #define MICROPY_FATFS_MAX_SS (4096) #define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ +// If MICROPY_PY_LWIP is defined, add network support +#if MICROPY_PY_LWIP + +#define MICROPY_PY_NETWORK (1) +#define MICROPY_PY_USOCKET (1) +#define MICROPY_PY_UWEBSOCKET (1) +#define MICROPY_PY_WEBREPL (1) +#define MICROPY_PY_UHASHLIB_SHA1 (1) +#define MICROPY_PY_LWIP_SOCK_RAW (1) +#define MICROPY_HW_ETH_MDC (1) + +// Prevent the "LWIP task" from running. +#define MICROPY_PY_LWIP_ENTER MICROPY_PY_PENDSV_ENTER +#define MICROPY_PY_LWIP_REENTER MICROPY_PY_PENDSV_REENTER +#define MICROPY_PY_LWIP_EXIT MICROPY_PY_PENDSV_EXIT + +#endif + +// For regular code that wants to prevent "background tasks" from running. +// These background tasks (LWIP, Bluetooth) run in PENDSV context. +// TODO: Check for the settings of the STM32 port in irq.h +#define MICROPY_PY_PENDSV_ENTER uint32_t atomic_state = disable_irq(); +#define MICROPY_PY_PENDSV_REENTER atomic_state = disable_irq(); +#define MICROPY_PY_PENDSV_EXIT enable_irq(atomic_state); + // Use VfsLfs2's types for fileio/textio #define mp_type_fileio mp_type_vfs_lfs2_fileio #define mp_type_textio mp_type_vfs_lfs2_textio // Use VFS's functions for import stat and builtin open #define mp_import_stat mp_vfs_import_stat +#define mp_builtin_open mp_vfs_open #define mp_builtin_open_obj mp_vfs_open_obj // Hooks to add builtins @@ -170,6 +196,38 @@ extern const struct _mp_obj_module_t mp_module_mimxrt; extern const struct _mp_obj_module_t mp_module_onewire; extern const struct _mp_obj_module_t mp_module_uos; extern const struct _mp_obj_module_t mp_module_utime; +extern const struct _mp_obj_module_t mp_module_usocket; +extern const struct _mp_obj_module_t mp_module_network; + +#if MICROPY_PY_NETWORK +#define NETWORK_BUILTIN_MODULE { MP_ROM_QSTR(MP_QSTR_network), MP_ROM_PTR(&mp_module_network) }, +#else +#define NETWORK_BUILTIN_MODULE +#endif + +#if MICROPY_PY_USOCKET && MICROPY_PY_LWIP +// usocket implementation provided by lwIP +#define SOCKET_BUILTIN_MODULE { MP_ROM_QSTR(MP_QSTR_usocket), MP_ROM_PTR(&mp_module_lwip) }, +#elif MICROPY_PY_USOCKET +// usocket implementation provided by skeleton wrapper +#define SOCKET_BUILTIN_MODULE { MP_ROM_QSTR(MP_QSTR_usocket), MP_ROM_PTR(&mp_module_usocket) }, +#else +// no usocket module +#define SOCKET_BUILTIN_MODULE +#endif + +#if MICROPY_SSL_MBEDTLS +#define MICROPY_PORT_ROOT_POINTER_MBEDTLS void **mbedtls_memory; +#else +#define MICROPY_PORT_ROOT_POINTER_MBEDTLS +#endif + +#if defined(MICROPY_HW_ETH_MDC) +extern const struct _mp_obj_type_t network_lan_type; +#define MICROPY_HW_NIC_ETH { MP_ROM_QSTR(MP_QSTR_LAN), MP_ROM_PTR(&network_lan_type) }, +#else +#define MICROPY_HW_NIC_ETH +#endif #define MICROPY_PORT_BUILTIN_MODULES \ { MP_ROM_QSTR(MP_QSTR_machine), MP_ROM_PTR(&mp_module_machine) }, \ @@ -177,6 +235,11 @@ extern const struct _mp_obj_module_t mp_module_utime; { MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_uos) }, \ { MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_utime) }, \ { MP_ROM_QSTR(MP_QSTR__onewire), MP_ROM_PTR(&mp_module_onewire) }, \ + SOCKET_BUILTIN_MODULE \ + NETWORK_BUILTIN_MODULE \ + +#define MICROPY_PORT_NETWORK_INTERFACES \ + MICROPY_HW_NIC_ETH \ #define MICROPY_HW_PIT_NUM_CHANNELS 3 @@ -184,6 +247,10 @@ extern const struct _mp_obj_module_t mp_module_utime; const char *readline_hist[8]; \ struct _machine_timer_obj_t *timer_table[MICROPY_HW_PIT_NUM_CHANNELS]; \ void *machine_pin_irq_objects[MICROPY_HW_NUM_PIN_IRQS]; \ + /* list of registered NICs */ \ + mp_obj_list_t mod_network_nic_list; \ + /* root pointers for sub-systems */ \ + MICROPY_PORT_ROOT_POINTER_MBEDTLS \ #define MP_STATE_PORT MP_STATE_VM diff --git a/ports/mimxrt/mphalport.c b/ports/mimxrt/mphalport.c index ff7e988dff..66498d7b27 100644 --- a/ports/mimxrt/mphalport.c +++ b/ports/mimxrt/mphalport.c @@ -29,14 +29,21 @@ #include "py/stream.h" #include "py/mphal.h" #include "shared/timeutils/timeutils.h" +#include "extmod/misc.h" #include "ticks.h" #include "tusb.h" #include "fsl_snvs_lp.h" +#include "fsl_ocotp.h" #include CPU_HEADER_H +STATIC uint8_t stdin_ringbuf_array[260]; +ringbuf_t stdin_ringbuf = {stdin_ringbuf_array, sizeof(stdin_ringbuf_array), 0, 0}; + #if MICROPY_KBD_EXCEPTION +int mp_interrupt_char = -1; + void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { (void)itf; (void)wanted_char; @@ -45,6 +52,7 @@ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { } void mp_hal_set_interrupt_char(int c) { + mp_interrupt_char = c; tud_cdc_set_wanted_char(c); } @@ -52,6 +60,9 @@ void mp_hal_set_interrupt_char(int c) { uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) { uintptr_t ret = 0; + if ((poll_flags & MP_STREAM_POLL_RD) && ringbuf_peek(&stdin_ringbuf) != -1) { + ret |= MP_STREAM_POLL_RD; + } if (tud_cdc_connected() && tud_cdc_available()) { ret |= MP_STREAM_POLL_RD; } @@ -64,6 +75,10 @@ int mp_hal_stdin_rx_chr(void) { // if (USARTx->USART.INTFLAG.bit.RXC) { // return USARTx->USART.DATA.bit.DATA; // } + int c = ringbuf_get(&stdin_ringbuf); + if (c != -1) { + return c; + } if (tud_cdc_connected() && tud_cdc_available()) { uint8_t buf[1]; uint32_t count = tud_cdc_read(buf, sizeof(buf)); @@ -90,6 +105,7 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { i += n2; } } + mp_uos_dupterm_tx_strn(str, len); // TODO // while (len--) { // while (!(USARTx->USART.INTFLAG.bit.DRE)) { } @@ -103,3 +119,29 @@ uint64_t mp_hal_time_ns(void) { uint64_t s = timeutils_seconds_since_epoch(t.year, t.month, t.day, t.hour, t.minute, t.second); return s * 1000000000ULL; } + +/*******************************************************************************/ +// MAC address + +// Generate a random locally administered MAC address (LAA) +void mp_hal_generate_laa_mac(int idx, uint8_t buf[6]) { + // Take the MAC addr from the OTP's Configuration and Manufacturing Info + OCOTP_Init(OCOTP, CLOCK_GetFreq(kCLOCK_IpgClk)); + buf[0] = 0x02; // Locally Administered MAC + *(uint32_t *)&buf[1] = OCOTP->CFG0 ^ (OCOTP->CFG0 >> 8); + *(uint16_t *)&buf[4] = (uint16_t)(OCOTP->CFG1 ^ (OCOTP->CFG1 >> 16)); +} + +// A board can override this if needed +MP_WEAK void mp_hal_get_mac(int idx, uint8_t buf[6]) { + mp_hal_generate_laa_mac(idx, buf); +} + +void mp_hal_get_mac_ascii(int idx, size_t chr_off, size_t chr_len, char *dest) { + static const char hexchr[16] = "0123456789ABCDEF"; + uint8_t mac[6]; + mp_hal_get_mac(idx, mac); + for (; chr_len; ++chr_off, --chr_len) { + *dest++ = hexchr[mac[chr_off >> 1] >> (4 * (1 - (chr_off & 1))) & 0xf]; + } +} diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index 3f0ae51bb6..a98ae5ed79 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -29,10 +29,12 @@ #include #include "ticks.h" +#include "py/ringbuf.h" #include "pin.h" #include "fsl_clock.h" #define MP_HAL_PIN_FMT "%q" +extern ringbuf_t stdin_ringbuf; #define mp_hal_pin_obj_t const machine_pin_obj_t * #define mp_hal_get_pin_obj(o) pin_find(o) @@ -85,5 +87,15 @@ static inline mp_uint_t mp_hal_get_cpu_freq(void) { return CLOCK_GetCpuClkFreq(); } +enum { + MP_HAL_MAC_WLAN0 = 0, + MP_HAL_MAC_WLAN1, + MP_HAL_MAC_BDADDR, + MP_HAL_MAC_ETH0, +}; + +void mp_hal_generate_laa_mac(int idx, uint8_t buf[6]); +void mp_hal_get_mac(int idx, uint8_t buf[6]); +void mp_hal_get_mac_ascii(int idx, size_t chr_off, size_t chr_len, char *dest); #endif // MICROPY_INCLUDED_MIMXRT_MPHALPORT_H diff --git a/ports/mimxrt/mpnetworkport.c b/ports/mimxrt/mpnetworkport.c new file mode 100644 index 0000000000..2e6a49b90e --- /dev/null +++ b/ports/mimxrt/mpnetworkport.c @@ -0,0 +1,64 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * + * 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 +#include +#include + +#include "py/objlist.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "shared/netutils/netutils.h" +#include "systick.h" +#include "pendsv.h" +#include "extmod/modnetwork.h" + +#if MICROPY_PY_LWIP +#include "lwip/netif.h" +#include "lwip/timeouts.h" +#include "lwip/dns.h" +#include "lwip/dhcp.h" +#include "lwip/apps/mdns.h" + +// Poll lwIP every 128ms +#define LWIP_TICK(tick) (((tick) & ~(SYSTICK_DISPATCH_NUM_SLOTS - 1) & 0x7f) == 0) + +u32_t sys_now(void) { + return mp_hal_ticks_ms(); +} + +STATIC void pyb_lwip_poll(void) { + // Run the lwIP internal updates + sys_check_timeouts(); +} + +void mod_network_lwip_poll_wrapper(uint32_t ticks_ms) { + if (LWIP_TICK(ticks_ms)) { + pendsv_schedule_dispatch(PENDSV_DISPATCH_LWIP, pyb_lwip_poll); + } +} + +#endif // MICROPY_PY_LWIP diff --git a/ports/mimxrt/network_lan.c b/ports/mimxrt/network_lan.c new file mode 100644 index 0000000000..c0d6e41362 --- /dev/null +++ b/ports/mimxrt/network_lan.c @@ -0,0 +1,171 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * + * 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/runtime.h" +#include "py/mphal.h" +#include "extmod/modnetwork.h" +#include "eth.h" + +#if defined(MICROPY_HW_ETH_MDC) + +#include "lwip/netif.h" + +typedef struct _network_lan_obj_t { + mp_obj_base_t base; + eth_t *eth; +} network_lan_obj_t; + +STATIC const network_lan_obj_t network_lan_eth0 = { { &network_lan_type }, ð_instance }; + +STATIC void network_lan_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + network_lan_obj_t *self = MP_OBJ_TO_PTR(self_in); + struct netif *netif = eth_netif(self->eth); + int status = eth_link_status(self->eth); + mp_printf(print, "", + status, + netif->ip_addr.addr & 0xff, + netif->ip_addr.addr >> 8 & 0xff, + netif->ip_addr.addr >> 16 & 0xff, + netif->ip_addr.addr >> 24 + ); +} + +STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 0, 0, false); + const network_lan_obj_t *self = &network_lan_eth0; + eth_init(self->eth, MP_HAL_MAC_ETH0); + // register with network module + mod_network_register_nic((mp_obj_t *)self); + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t network_lan_active(size_t n_args, const mp_obj_t *args) { + network_lan_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (n_args == 1) { + return mp_obj_new_bool(eth_link_status(self->eth)); + } else { + int ret; + if (mp_obj_is_true(args[1])) { + ret = eth_start(self->eth); + } else { + ret = eth_stop(self->eth); + } + if (ret < 0) { + mp_raise_OSError(-ret); + } + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_lan_active_obj, 1, 2, network_lan_active); + +STATIC mp_obj_t network_lan_isconnected(mp_obj_t self_in) { + network_lan_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(eth_link_status(self->eth) == 3); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_lan_isconnected_obj, network_lan_isconnected); + +STATIC mp_obj_t network_lan_ifconfig(size_t n_args, const mp_obj_t *args) { + network_lan_obj_t *self = MP_OBJ_TO_PTR(args[0]); + return mod_network_nic_ifconfig(eth_netif(self->eth), n_args - 1, args + 1); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_lan_ifconfig_obj, 1, 2, network_lan_ifconfig); + +STATIC mp_obj_t network_lan_status(size_t n_args, const mp_obj_t *args) { + network_lan_obj_t *self = MP_OBJ_TO_PTR(args[0]); + (void)self; + + if (n_args == 1) { + // No arguments: return link status + return MP_OBJ_NEW_SMALL_INT(eth_link_status(self->eth)); + } + + mp_raise_ValueError(MP_ERROR_TEXT("unknown status param")); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_lan_status_obj, 1, 2, network_lan_status); + +STATIC mp_obj_t network_lan_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + network_lan_obj_t *self = MP_OBJ_TO_PTR(args[0]); + + if (kwargs->used == 0) { + // Get config value + if (n_args != 2) { + mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); + } + + switch (mp_obj_str_get_qstr(args[1])) { + case MP_QSTR_mac: { + return mp_obj_new_bytes(ð_netif(self->eth)->hwaddr[0], 6); + } + default: + mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); + } + } else { + // Set config value(s) + if (n_args != 1) { + mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args")); + } + + for (size_t i = 0; i < kwargs->alloc; ++i) { + if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { + mp_map_elem_t *e = &kwargs->table[i]; + switch (mp_obj_str_get_qstr(e->key)) { + case MP_QSTR_trace: { + eth_set_trace(self->eth, mp_obj_get_int(e->value)); + break; + } + case MP_QSTR_low_power: { + eth_low_power_mode(self->eth, mp_obj_get_int(e->value)); + break; + } + default: + mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); + } + } + } + + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(network_lan_config_obj, 1, network_lan_config); + +STATIC const mp_rom_map_elem_t network_lan_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&network_lan_active_obj) }, + { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&network_lan_isconnected_obj) }, + { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_lan_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_lan_status_obj) }, + { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_lan_config_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(network_lan_locals_dict, network_lan_locals_dict_table); + +const mp_obj_type_t network_lan_type = { + { &mp_type_type }, + .name = MP_QSTR_LAN, + .print = network_lan_print, + .make_new = network_lan_make_new, + .locals_dict = (mp_obj_dict_t *)&network_lan_locals_dict, +}; + +#endif // defined(MICROPY_HW_ETH_MDC) diff --git a/ports/mimxrt/pendsv.c b/ports/mimxrt/pendsv.c new file mode 100644 index 0000000000..7638b160d8 --- /dev/null +++ b/ports/mimxrt/pendsv.c @@ -0,0 +1,73 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * 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 + +#include "py/runtime.h" +#include "shared/runtime/interrupt_char.h" +#include "pendsv.h" +#include "lib/nxp_driver/sdk/CMSIS/Include/core_cm7.h" + +#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) +#define IRQ_PRI_PENDSV NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 15, 0) + +#if defined(PENDSV_DISPATCH_NUM_SLOTS) +uint32_t pendsv_dispatch_active; +pendsv_dispatch_t pendsv_dispatch_table[PENDSV_DISPATCH_NUM_SLOTS]; +#endif + +void pendsv_init(void) { + #if defined(PENDSV_DISPATCH_NUM_SLOTS) + pendsv_dispatch_active = false; + #endif + + // set PendSV interrupt at lowest priority + NVIC_SetPriority(PendSV_IRQn, IRQ_PRI_PENDSV); +} + +#if defined(PENDSV_DISPATCH_NUM_SLOTS) +void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f) { + pendsv_dispatch_table[slot] = f; + pendsv_dispatch_active = true; + SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; +} + +void pendsv_dispatch_handler(void) { + for (size_t i = 0; i < PENDSV_DISPATCH_NUM_SLOTS; ++i) { + if (pendsv_dispatch_table[i] != NULL) { + pendsv_dispatch_t f = pendsv_dispatch_table[i]; + pendsv_dispatch_table[i] = NULL; + f(); + } + } +} + +void PendSV_Handler(void) { + if (pendsv_dispatch_active) { + pendsv_dispatch_handler(); + } +} +#endif diff --git a/ports/mimxrt/pendsv.h b/ports/mimxrt/pendsv.h new file mode 100644 index 0000000000..64883c9031 --- /dev/null +++ b/ports/mimxrt/pendsv.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * 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_STM32_PENDSV_H +#define MICROPY_INCLUDED_STM32_PENDSV_H + +enum { + PENDSV_DISPATCH_SOFT_TIMER, // For later & for having at least one entry + #if MICROPY_PY_NETWORK && MICROPY_PY_LWIP + PENDSV_DISPATCH_LWIP, + #endif + PENDSV_DISPATCH_MAX +}; + +#define PENDSV_DISPATCH_NUM_SLOTS PENDSV_DISPATCH_MAX + +typedef void (*pendsv_dispatch_t)(void); + +void pendsv_init(void); +void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f); + +#endif // MICROPY_INCLUDED_STM32_PENDSV_H diff --git a/ports/mimxrt/pin.c b/ports/mimxrt/pin.c index 7a437661e3..964fb537b8 100644 --- a/ports/mimxrt/pin.c +++ b/ports/mimxrt/pin.c @@ -116,6 +116,21 @@ const machine_pin_af_obj_t *pin_find_af(const machine_pin_obj_t *pin, uint8_t fn return NULL; } +const machine_pin_af_obj_t *pin_find_af_by_base(const machine_pin_obj_t *pin, void *base_ptr[], size_t base_size) { + const machine_pin_af_obj_t *af_obj = NULL; + + for (int i = 0; i < pin->af_list_len; ++i) { + af_obj = &pin->af_list[i]; + for (int j = 0; j < base_size; ++j) { + if (af_obj->instance == base_ptr[j]) { + return af_obj; + } + } + } + + return NULL; +} + const machine_pin_af_obj_t *pin_find_af_by_index(const machine_pin_obj_t *pin, mp_uint_t af_idx) { // TODO: Implement pin_find_af_by_index function return NULL; diff --git a/ports/mimxrt/systick.c b/ports/mimxrt/systick.c new file mode 100644 index 0000000000..086bf16701 --- /dev/null +++ b/ports/mimxrt/systick.c @@ -0,0 +1,60 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * 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/runtime.h" +#include "py/mphal.h" +#include "systick.h" + +volatile uint32_t systick_ms = 0; + +systick_dispatch_t systick_dispatch_table[SYSTICK_DISPATCH_NUM_SLOTS]; + +void SysTick_Handler(void) { + // Instead of calling HAL_IncTick we do the increment here of the counter. + // This is purely for efficiency, since SysTick is called 1000 times per + // second at the highest interrupt priority. + uint32_t uw_tick = systick_ms + 1; + systick_ms = uw_tick; + + // Dispatch to any registered handlers in a cycle + systick_dispatch_t f = systick_dispatch_table[uw_tick & (SYSTICK_DISPATCH_NUM_SLOTS - 1)]; + if (f != NULL) { + f(uw_tick); + } +} + +bool systick_has_passed(uint32_t start_tick, uint32_t delay_ms) { + return systick_ms - start_tick >= delay_ms; +} + +// waits until at least delay_ms milliseconds have passed from the sampling of +// startTick. Handles overflow properly. Assumes stc was taken from +// HAL_GetTick() some time before calling this function. +void systick_wait_at_least(uint32_t start_tick, uint32_t delay_ms) { + while (!systick_has_passed(start_tick, delay_ms)) { + __WFI(); // enter sleep mode, waiting for interrupt + } +} diff --git a/ports/mimxrt/systick.h b/ports/mimxrt/systick.h new file mode 100644 index 0000000000..2638905cd6 --- /dev/null +++ b/ports/mimxrt/systick.h @@ -0,0 +1,60 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * 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_MIMXRT_SYSTICK_H +#define MICROPY_INCLUDED_MIMXRT_SYSTICK_H + +// Works for x between 0 and 16 inclusive +#define POW2_CEIL(x) ((((x) - 1) | ((x) - 1) >> 1 | ((x) - 1) >> 2 | ((x) - 1) >> 3) + 1) + +enum { + SYSTICK_DISPATCH_DMA = 0, + #if MICROPY_HW_ENABLE_STORAGE + SYSTICK_DISPATCH_STORAGE, + #endif + #if MICROPY_PY_NETWORK && MICROPY_PY_LWIP + SYSTICK_DISPATCH_LWIP, + #endif + SYSTICK_DISPATCH_MAX +}; + +#define SYSTICK_DISPATCH_NUM_SLOTS POW2_CEIL(SYSTICK_DISPATCH_MAX) + +typedef void (*systick_dispatch_t)(uint32_t); + +extern systick_dispatch_t systick_dispatch_table[SYSTICK_DISPATCH_NUM_SLOTS]; + +static inline void systick_enable_dispatch(size_t slot, systick_dispatch_t f) { + systick_dispatch_table[slot] = f; +} + +static inline void systick_disable_dispatch(size_t slot) { + systick_dispatch_table[slot] = NULL; +} + +void systick_wait_at_least(uint32_t stc, uint32_t delay_ms); +bool systick_has_passed(uint32_t stc, uint32_t delay_ms); + +#endif // MICROPY_INCLUDED_MIMXRT_SYSTICK_H From c2e4759cfaa4080356424b2602d90085a99bfb2b Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 12 Sep 2021 16:44:24 +0200 Subject: [PATCH 095/335] mimxrt/modmachine: Implement machine.WDT() and machine.reset_cause(). The API follows that of rp2, stm32, esp32, and the docs. wdt=machine.WDT(0, timeout) Timeout is given in ms. The valid range is 500 to 128000 (128 seconds) with 500 ms granularity. Values outside of that range will be silently aligned. wdt.feed() Resets the watchdog timer (feeding). wdt.timeout_ms(value) Sets a new timeout and feeds the watchdog. This is a new, preliminary method which is not yet documented. reset_cause = machine.reset_cause() Values returned: 1 Power On reset 3 Watchdog reset 5 Software reset: state after calling machine.reset() More elaborate API functions are supported by the MCU, like an interrupt called a certain time after feeding. But for port cosistency that is not implemented. --- ports/mimxrt/Makefile | 3 ++ ports/mimxrt/machine_wdt.c | 107 +++++++++++++++++++++++++++++++++++++ ports/mimxrt/modmachine.c | 32 ++++++++++- ports/mimxrt/modmachine.h | 9 ++-- 4 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 ports/mimxrt/machine_wdt.c diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 16aac389d1..239b7cd0c7 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -196,6 +196,7 @@ SRC_HAL_IMX_C += \ $(MCU_DIR)/drivers/fsl_pit.c \ $(MCU_DIR)/drivers/fsl_snvs_lp.c \ $(MCU_DIR)/drivers/fsl_trng.c \ + $(MCU_DIR)/drivers/fsl_wdog.c \ $(MCU_DIR)/project_template/clock_config.c \ $(MCU_DIR)/system_$(MCU_SERIES).c \ $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ @@ -229,6 +230,7 @@ SRC_C += \ machine_spi.c \ machine_timer.c \ machine_uart.c \ + machine_wdt.c \ main.c \ mbedtls/mbedtls_port.c \ mimxrt_flash.c \ @@ -386,6 +388,7 @@ SRC_QSTR += \ machine_spi.c \ machine_timer.c \ machine_uart.c \ + machine_wdt.c \ mimxrt_flash.c \ modmachine.c \ modmimxrt.c \ diff --git a/ports/mimxrt/machine_wdt.c b/ports/mimxrt/machine_wdt.c new file mode 100644 index 0000000000..d09c464f69 --- /dev/null +++ b/ports/mimxrt/machine_wdt.c @@ -0,0 +1,107 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020-2021 Damien P. George + * + * 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/runtime.h" +#include "modmachine.h" + +#include "fsl_wdog.h" + +#define MIN_TIMEOUT (500) +#define MAX_TIMEOUT (128000) + +typedef struct _machine_wdt_obj_t { + mp_obj_base_t base; +} machine_wdt_obj_t; + +STATIC const machine_wdt_obj_t machine_wdt = {{&machine_wdt_type}}; + +STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_id, ARG_timeout }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_timeout, MP_ARG_INT, {.u_int = 5000} }, + }; + + // Parse the arguments. + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Verify the WDT id. + mp_int_t id = args[ARG_id].u_int; + if (id != 0) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("WDT(%d) doesn't exist"), id); + } + + // Start the watchdog (timeout is in milliseconds). + wdog_config_t config; + WDOG_GetDefaultConfig(&config); + uint32_t timeout = args[ARG_timeout].u_int; + // confine to the valid range + if (timeout < MIN_TIMEOUT) { + timeout = MIN_TIMEOUT; + } else if (timeout > MAX_TIMEOUT) { + timeout = MAX_TIMEOUT; + } + config.timeoutValue = (timeout / 500) - 1; + WDOG_Init(WDOG1, &config); + + return MP_OBJ_FROM_PTR(&machine_wdt); +} + +STATIC mp_obj_t machine_wdt_feed(mp_obj_t self_in) { + (void)self_in; + WDOG_Refresh(WDOG1); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_feed_obj, machine_wdt_feed); + +STATIC mp_obj_t machine_wdt_timeout_ms(mp_obj_t self_in, mp_obj_t timout_in) { + uint32_t timeout = mp_obj_get_int(timout_in); + // confine to the valid range + if (timeout < MIN_TIMEOUT) { + timeout = MIN_TIMEOUT; + } else if (timeout > MAX_TIMEOUT) { + timeout = MAX_TIMEOUT; + } + timeout = (timeout / 500) - 1; + WDOG_SetTimeoutValue(WDOG1, (uint16_t)timeout); + WDOG_Refresh(WDOG1); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_wdt_timeout_ms_obj, machine_wdt_timeout_ms); + +STATIC const mp_rom_map_elem_t machine_wdt_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_feed), MP_ROM_PTR(&machine_wdt_feed_obj) }, + { MP_ROM_QSTR(MP_QSTR_timeout_ms), MP_ROM_PTR(&machine_wdt_timeout_ms_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(machine_wdt_locals_dict, machine_wdt_locals_dict_table); + +const mp_obj_type_t machine_wdt_type = { + { &mp_type_type }, + .name = MP_QSTR_WDT, + .make_new = machine_wdt_make_new, + .locals_dict = (mp_obj_dict_t *)&machine_wdt_locals_dict, +}; diff --git a/ports/mimxrt/modmachine.c b/ports/mimxrt/modmachine.c index 2e8753df12..d4078d5660 100644 --- a/ports/mimxrt/modmachine.c +++ b/ports/mimxrt/modmachine.c @@ -36,15 +36,38 @@ #include "pin.h" #include "modmachine.h" #include "fsl_clock.h" +#include "fsl_wdog.h" #include CPU_HEADER_H +typedef enum { + MP_PWRON_RESET = 1, + MP_HARD_RESET, + MP_WDT_RESET, + MP_DEEPSLEEP_RESET, + MP_SOFT_RESET +} reset_reason_t; + STATIC mp_obj_t machine_reset(void) { - NVIC_SystemReset(); + WDOG_TriggerSystemSoftwareReset(WDOG1); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_obj, machine_reset); +STATIC mp_obj_t machine_reset_cause(void) { + uint16_t reset_cause = + WDOG_GetStatusFlags(WDOG1) & (kWDOG_PowerOnResetFlag | kWDOG_TimeoutResetFlag | kWDOG_SoftwareResetFlag); + if (reset_cause == kWDOG_PowerOnResetFlag) { + reset_cause = MP_PWRON_RESET; + } else if (reset_cause == kWDOG_TimeoutResetFlag) { + reset_cause = MP_WDT_RESET; + } else { + reset_cause = MP_SOFT_RESET; + } + return MP_OBJ_NEW_SMALL_INT(reset_cause); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_cause_obj, machine_reset_cause); + STATIC mp_obj_t machine_freq(void) { return MP_OBJ_NEW_SMALL_INT(mp_hal_get_cpu_freq()); } @@ -72,6 +95,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_enable_irq_obj, machine_enable_irq); STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) }, + { MP_ROM_QSTR(MP_QSTR_reset_cause), MP_ROM_PTR(&machine_reset_cause_obj) }, { MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&machine_freq_obj) }, { MP_ROM_QSTR(MP_QSTR_mem8), MP_ROM_PTR(&machine_mem8_obj) }, { MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) }, @@ -92,6 +116,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, + { MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&machine_wdt_type) }, { MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) }, @@ -102,6 +127,11 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_bitstream), MP_ROM_PTR(&machine_bitstream_obj) }, #endif { MP_ROM_QSTR(MP_QSTR_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) }, + + // Reset reasons + { MP_ROM_QSTR(MP_QSTR_PWRON_RESET), MP_ROM_INT(MP_PWRON_RESET) }, + { MP_ROM_QSTR(MP_QSTR_WDT_RESET), MP_ROM_INT(MP_WDT_RESET) }, + { MP_ROM_QSTR(MP_QSTR_SOFT_RESET), MP_ROM_INT(MP_SOFT_RESET) }, }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); diff --git a/ports/mimxrt/modmachine.h b/ports/mimxrt/modmachine.h index 90d167843a..b9949ab784 100644 --- a/ports/mimxrt/modmachine.h +++ b/ports/mimxrt/modmachine.h @@ -30,12 +30,13 @@ #include "py/obj.h" extern const mp_obj_type_t machine_adc_type; -extern const mp_obj_type_t machine_timer_type; -extern const mp_obj_type_t machine_rtc_type; extern const mp_obj_type_t machine_i2c_type; -extern const mp_obj_type_t machine_spi_type; -extern const mp_obj_type_t machine_uart_type; +extern const mp_obj_type_t machine_rtc_type; extern const mp_obj_type_t machine_sdcard_type; +extern const mp_obj_type_t machine_spi_type; +extern const mp_obj_type_t machine_timer_type; +extern const mp_obj_type_t machine_uart_type; +extern const mp_obj_type_t machine_wdt_type; void machine_adc_init(void); void machine_pin_irq_deinit(void); From 68146aa197bbb5b62c671fbc116352a625902394 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 19 Aug 2021 09:09:43 +0200 Subject: [PATCH 096/335] mimxrt/boards: Fix the D14/D15 pin assignment of MIMXRT1050/60/64_EVK. There are several PCB layouts in the market under the same name. --- ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv | 4 ++-- ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv | 4 ++-- ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv b/ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv index 366a141ff8..463079b129 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv @@ -12,8 +12,8 @@ D10,GPIO_SD_B0_01 D11,GPIO_SD_B0_02 D12,GPIO_SD_B0_03 D13,GPIO_SD_B0_00 -D14,GPIO_AD_B1_01 -D15,GPIO_AD_B1_00 +D14,GPIO_AD_B0_01 +D15,GPIO_AD_B0_00 A0,GPIO_AD_B1_10 A1,GPIO_AD_B1_11 A2,GPIO_AD_B1_04 diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv b/ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv index 366a141ff8..463079b129 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv @@ -12,8 +12,8 @@ D10,GPIO_SD_B0_01 D11,GPIO_SD_B0_02 D12,GPIO_SD_B0_03 D13,GPIO_SD_B0_00 -D14,GPIO_AD_B1_01 -D15,GPIO_AD_B1_00 +D14,GPIO_AD_B0_01 +D15,GPIO_AD_B0_00 A0,GPIO_AD_B1_10 A1,GPIO_AD_B1_11 A2,GPIO_AD_B1_04 diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv b/ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv index 366a141ff8..463079b129 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv @@ -12,8 +12,8 @@ D10,GPIO_SD_B0_01 D11,GPIO_SD_B0_02 D12,GPIO_SD_B0_03 D13,GPIO_SD_B0_00 -D14,GPIO_AD_B1_01 -D15,GPIO_AD_B1_00 +D14,GPIO_AD_B0_01 +D15,GPIO_AD_B0_00 A0,GPIO_AD_B1_10 A1,GPIO_AD_B1_11 A2,GPIO_AD_B1_04 From 101d2ddea308d532818fc456d4093941fa01e37b Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 21 Aug 2021 12:24:10 +0200 Subject: [PATCH 097/335] mimxrt/hal: Remove duplicate definitions from flexspi_hyper_flash.h. --- ports/mimxrt/hal/flexspi_hyper_flash.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/ports/mimxrt/hal/flexspi_hyper_flash.h b/ports/mimxrt/hal/flexspi_hyper_flash.h index d51ca3073d..dbd028fd6f 100644 --- a/ports/mimxrt/hal/flexspi_hyper_flash.h +++ b/ports/mimxrt/hal/flexspi_hyper_flash.h @@ -59,12 +59,4 @@ static inline uint32_t flexspi_get_frequency(void) { return fre; } -#define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP 12 - #endif // MICROPY_INCLUDED_MIMXRT_HAL_FLEXSPI_HYPER_FLASH_H From 06d1b02014b37664b5b9ecd3841bb48841c7c44c Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 3 Oct 2021 20:54:18 +0200 Subject: [PATCH 098/335] mimxrt/dma_channel: Fix the DMA channel management. The MIMXRT1011 has only 16 channels, so size the channel list accordingly. --- ports/mimxrt/dma_channel.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/ports/mimxrt/dma_channel.c b/ports/mimxrt/dma_channel.c index 3dd043a66b..c6cae9da9c 100644 --- a/ports/mimxrt/dma_channel.c +++ b/ports/mimxrt/dma_channel.c @@ -27,10 +27,17 @@ #include "dma_channel.h" // List of channel flags: true: channel used, false: channel available -static bool channel_list[32] = { true, true, true, true, false, false, false, false, - false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false }; +static bool channel_list[FSL_FEATURE_DMAMUX_MODULE_CHANNEL] = { + true, true, true, true, false, false, false, false, + false, false, false, false, false, false, false, false, + + #if FSL_FEATURE_DMAMUX_MODULE_CHANNEL > 16 + + false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false + + #endif +}; // allocate_channel(): retrieve an available channel. Return the number or -1 int allocate_dma_channel(void) { From 99221cd1181288ffb86404e348f25e345e863a7b Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 12 Oct 2021 22:49:18 +0200 Subject: [PATCH 099/335] mimxrt: Fix cycle counter for time.ticks_cpu() and machine.bitstream(). Prior to this commit mp_hal_ticks_cpu() was not started properly. It only started when the code was executed with a debugger attached, except for the Teensy (i.MXRT1062) boards. As an additional fix, the CYYCNT timer is now started at boot time. Also rename mp_hal_ticks_cpu_init() to mp_hal_ticks_cpu_enable(). --- ports/mimxrt/machine_bitstream.c | 2 +- ports/mimxrt/mphalport.h | 5 ++++- ports/mimxrt/ticks.c | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ports/mimxrt/machine_bitstream.c b/ports/mimxrt/machine_bitstream.c index c6ff469ea6..cb391a38c5 100644 --- a/ports/mimxrt/machine_bitstream.c +++ b/ports/mimxrt/machine_bitstream.c @@ -48,7 +48,7 @@ void machine_bitstream_high_low(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const } } // Enable the CPU cycle counter, which is not always enabled. - mp_hal_ticks_cpu_init(); + mp_hal_ticks_cpu_enable(); uint32_t irq_state = mp_hal_quiet_timing_enter(); diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index a98ae5ed79..40e929b23b 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -75,7 +75,10 @@ static inline void mp_hal_delay_us(mp_uint_t us) { #define mp_hal_delay_us_fast(us) mp_hal_delay_us(us) -static inline void mp_hal_ticks_cpu_init(void) { +static inline void mp_hal_ticks_cpu_enable(void) { + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + DWT->LAR = 0xc5acce55; + DWT->CYCCNT = 0; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; } diff --git a/ports/mimxrt/ticks.c b/ports/mimxrt/ticks.c index 676f81b30e..a5ee102428 100644 --- a/ports/mimxrt/ticks.c +++ b/ports/mimxrt/ticks.c @@ -56,6 +56,7 @@ void ticks_init(void) { NVIC_EnableIRQ(GPTx_IRQn); GPT_StartTimer(GPTx); + mp_hal_ticks_cpu_enable(); } void GPTx_IRQHandler(void) { From e7572776c3ec3a245c831f3f2aaa595a4dec43a8 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 19 Jun 2021 11:00:55 +0200 Subject: [PATCH 100/335] mimxrt: Add dht_readinto() to the mimxrt module, and freeze dht.py. The change affects dht.py from the drivers directory as well to include the logic for the mimxrt port. --- drivers/dht/dht.py | 8 ++++++-- ports/mimxrt/Makefile | 1 + ports/mimxrt/boards/manifest.py | 1 + ports/mimxrt/modmimxrt.c | 4 ++++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/dht/dht.py b/drivers/dht/dht.py index 1163b382bb..322608990e 100644 --- a/drivers/dht/dht.py +++ b/drivers/dht/dht.py @@ -1,9 +1,13 @@ # DHT11/DHT22 driver for MicroPython on ESP8266 # MIT license; Copyright (c) 2016 Damien P. George -try: +import sys + +if sys.platform.startswith("esp"): from esp import dht_readinto -except: +elif sys.platform == "mimxrt": + from mimxrt import dht_readinto +else: from pyb import dht_readinto diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 239b7cd0c7..7cda558bdc 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -213,6 +213,7 @@ SRC_C += \ board_init.c \ dma_channel.c \ drivers/bus/softspi.c \ + drivers/dht/dht.c \ eth.c \ extmod/modnetwork.c \ extmod/modonewire.c \ diff --git a/ports/mimxrt/boards/manifest.py b/ports/mimxrt/boards/manifest.py index 9df589f126..ccbd33cae8 100644 --- a/ports/mimxrt/boards/manifest.py +++ b/ports/mimxrt/boards/manifest.py @@ -1,3 +1,4 @@ freeze("$(PORT_DIR)/modules") freeze("$(MPY_DIR)/drivers/onewire") +freeze("$(MPY_DIR)/drivers/dht", "dht.py") include("$(MPY_DIR)/extmod/uasyncio/manifest.py") diff --git a/ports/mimxrt/modmimxrt.c b/ports/mimxrt/modmimxrt.c index addd4ba4d2..041a72f7f7 100644 --- a/ports/mimxrt/modmimxrt.c +++ b/ports/mimxrt/modmimxrt.c @@ -24,12 +24,16 @@ * THE SOFTWARE. */ +#include "py/mperrno.h" #include "py/runtime.h" +#include "drivers/dht/dht.h" #include "modmimxrt.h" STATIC const mp_rom_map_elem_t mimxrt_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_mimxrt) }, { MP_ROM_QSTR(MP_QSTR_Flash), MP_ROM_PTR(&mimxrt_flash_type) }, + + { MP_ROM_QSTR(MP_QSTR_dht_readinto), MP_ROM_PTR(&dht_readinto_obj) }, }; STATIC MP_DEFINE_CONST_DICT(mimxrt_module_globals, mimxrt_module_globals_table); From c827d4b7ab418e5299e3d8b9fc8e7520ae42493a Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 9 Aug 2021 18:41:36 +0200 Subject: [PATCH 101/335] mimxrt: Extend the help() message and README.md. --- ports/mimxrt/README.md | 26 ++++++++++++++++++++------ ports/mimxrt/main.c | 14 +++++++++++--- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/ports/mimxrt/README.md b/ports/mimxrt/README.md index c24939f478..c8c5d989b9 100644 --- a/ports/mimxrt/README.md +++ b/ports/mimxrt/README.md @@ -1,17 +1,31 @@ Port of MicroPython to NXP iMX RT 10xx ====================================== -Currently supports Teensy 4.0 and the i.MX RT1010 EVK board. +Currently supports Teensy 4.0, Teensy 4.1, and the +MIMXRT1010_EVK, MIMXRT1020_EVK, MIMXRT1050_EVK, MIMXRT1060_EVK and +MIMXRT1064_EVK boards. Features: - REPL over USB VCP + - machine.ADC + - machine.I2C + - machine.LED - machine.Pin + - machine.PWM + - machine.RTC + - machine.SDCard + - machine.SPI + - machine.Signal + - machine.SoftI2C + - machine.SoftSPI + - machine.Timer + - machine.UART + - LFS2 file system at the internal Flash + - SDCard support (not on MIMXRT1010_EVK) + - Ethernet (not on Teensy 4.0 and MIMXRT1010_EVK) Known issues: - - pyboard.py doesn't work with files larger than 64 bytes - - machine.Pin class currently does not support GPIOMUX option of - i.MX RT101x variants TODO: - - Enable TCM - - Peripherals (LED, Timers, etc) + - More peripherals (Counter, I2S, CAN, etc) + - More Python options diff --git a/ports/mimxrt/main.c b/ports/mimxrt/main.c index f921f50a0c..fa6237ca07 100644 --- a/ports/mimxrt/main.c +++ b/ports/mimxrt/main.c @@ -163,17 +163,25 @@ const char mimxrt_help_text[] = " Pin pull modes are: Pin.PULL_UP, Pin.PULL_UP_47K, Pin.PULL_UP_22K, Pin.PULL_DOWN, Pin.PULL_HOLD\n" " machine.ADC(pin) -- make an analog object from a pin\n" " methods: read_u16()\n" - " machine.UART(id, baudrate=115200) -- create an UART object (id=1 - 8)\n" + " machine.UART(id, baudrate=115200) -- create an UART object (id=1 - 8, board-specific)\n" " methods: init(), write(buf), any()\n" " buf=read(n), readinto(buf), buf=readline()\n" " The RX and TX pins are fixed and board-specific.\n" - " machine.SoftI2C() -- create an Soft I2C object\n" + " machine.SoftI2C() -- create a Soft I2C object\n" + " machine.I2C(id) -- create a HW I2C object\n" " methods: readfrom(addr, buf, stop=True), writeto(addr, buf, stop=True)\n" " readfrom_mem(addr, memaddr, arg), writeto_mem(addr, memaddr, arg)\n" - " machine.SoftSPI(baudrate=1000000) -- create an SPI object ()\n" + " SoftI2C allows to use any pin for sda and scl, HW I2C id's and pins are fixed\n" + " machine.SoftSPI(baudrate=1000000) -- create a Soft SPI object\n" + " machine.SPI(id, baudrate=1000000) -- create a HW SPI object\n" " methods: read(nbytes, write=0x00), write(buf), write_readinto(wr_buf, rd_buf)\n" + " SoftSPI allows to use any pin for SPI, HW SPI id's and pins are fixed\n" " machine.Timer(id, freq, callback) -- create a hardware timer object (id=0,1,2)\n" " eg: machine.Timer(freq=1, callback=lambda t:print(t))\n" + " machine.RTC() -- create a Real Time Clock object\n" + " methods: init(), datetime([dateime_tuple]), now()\n" + " machine.PWM(pin, freq, duty_u16[, kw_opts]) -- create a PWM object\n" + " methods: init(), duty_u16([value]), duty_ns([value]), freq([value])\n" "\n" "Useful control commands:\n" " CTRL-C -- interrupt a running program\n" From dc8be7ccad67f76f35c64c028588c9457ed438a2 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 13 Aug 2021 17:15:48 +0200 Subject: [PATCH 102/335] tools/autobuild: Add the MIMXRT1010_EVK board to autobuild. Having a board now available for testing, this binary can be provided with good confidence. --- tools/autobuild/build-mimxrt-latest.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/autobuild/build-mimxrt-latest.sh b/tools/autobuild/build-mimxrt-latest.sh index f5bc1397a5..fea5da81c5 100755 --- a/tools/autobuild/build-mimxrt-latest.sh +++ b/tools/autobuild/build-mimxrt-latest.sh @@ -33,5 +33,6 @@ fi # build the boards do_build TEENSY40 TEENSY40 hex do_build TEENSY41 TEENSY41 hex +do_build MIMXRT1010_EVK MIMXRT1010_EVK bin do_build MIMXRT1020_EVK MIMXRT1020_EVK bin do_build MIMXRT1050_EVK MIMXRT1050_EVK bin From a12e318948cc422950751f61563b46784eb6b665 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 15 Aug 2021 08:10:19 +0200 Subject: [PATCH 103/335] mimxrt/mpconfigport.h: Enable f-strings. --- ports/mimxrt/mpconfigport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index f1c38b1fad..1d487fb541 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -70,6 +70,7 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_FUNCTION_ATTRS (1) #define MICROPY_PY_DESCRIPTORS (1) #define MICROPY_PY_DELATTR_SETATTR (1) +#define MICROPY_PY_FSTRINGS (1) #define MICROPY_PY_BUILTINS_STR_UNICODE (1) #define MICROPY_PY_BUILTINS_STR_CENTER (1) #define MICROPY_PY_BUILTINS_STR_PARTITION (1) From 6754213a9d54f7c57005794824dd6aabd71855c8 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 12 Sep 2021 17:57:01 +0200 Subject: [PATCH 104/335] mimxrt/modmachine: Implement soft_reset() and unique_id() functions. --- ports/mimxrt/modmachine.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ports/mimxrt/modmachine.c b/ports/mimxrt/modmachine.c index d4078d5660..a05c81a40a 100644 --- a/ports/mimxrt/modmachine.c +++ b/ports/mimxrt/modmachine.c @@ -32,10 +32,12 @@ #include "extmod/machine_pulse.h" #include "extmod/machine_signal.h" #include "extmod/machine_spi.h" +#include "shared/runtime/pyexec.h" #include "led.h" #include "pin.h" #include "modmachine.h" #include "fsl_clock.h" +#include "fsl_ocotp.h" #include "fsl_wdog.h" #include CPU_HEADER_H @@ -48,6 +50,21 @@ typedef enum { MP_SOFT_RESET } reset_reason_t; +STATIC mp_obj_t machine_unique_id(void) { + unsigned char id[8]; + OCOTP_Init(OCOTP, CLOCK_GetFreq(kCLOCK_IpgClk)); + *(uint32_t *)&id[0] = OCOTP->CFG0; + *(uint32_t *)&id[4] = OCOTP->CFG1; + return mp_obj_new_bytes(id, sizeof(id)); +} +MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id); + +STATIC mp_obj_t machine_soft_reset(void) { + pyexec_system_exit = PYEXEC_FORCED_EXIT; + mp_raise_type(&mp_type_SystemExit); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_soft_reset_obj, machine_soft_reset); + STATIC mp_obj_t machine_reset(void) { WDOG_TriggerSystemSoftwareReset(WDOG1); return mp_const_none; @@ -94,6 +111,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_enable_irq_obj, machine_enable_irq); STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) }, + { MP_ROM_QSTR(MP_QSTR_unique_id), MP_ROM_PTR(&machine_unique_id_obj) }, + { MP_ROM_QSTR(MP_QSTR_soft_reset), MP_ROM_PTR(&machine_soft_reset_obj) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) }, { MP_ROM_QSTR(MP_QSTR_reset_cause), MP_ROM_PTR(&machine_reset_cause_obj) }, { MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&machine_freq_obj) }, From 90b45efa6a7efaef80db9b6bbac48690723fb8b9 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 16 Sep 2021 08:40:01 +0200 Subject: [PATCH 105/335] mimxrt/boards/make-pins.py: Allow empty lines and comments in pins.csv. --- ports/mimxrt/boards/make-pins.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ports/mimxrt/boards/make-pins.py b/ports/mimxrt/boards/make-pins.py index aba517127c..e13b9c578f 100644 --- a/ports/mimxrt/boards/make-pins.py +++ b/ports/mimxrt/boards/make-pins.py @@ -180,6 +180,12 @@ class Pins(object): with open(filename, "r") as csvfile: rows = csv.reader(csvfile) for row in rows: + if len(row) == 0 or row[0].startswith("#"): + # Skip empty lines, and lines starting with "#" + continue + if len(row) != 2: + raise ValueError("Expecting two entries in a row") + pin = self.find_pin_by_name(row[1]) if pin and row[0]: # Only add board pins that have a name self.board_pins.append(NamedPin(row[0], pin.pad, pin.idx)) From 4f89c38a6a9ecdda2931e9226c847c4d279d04f6 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 17 Sep 2021 08:25:33 +0200 Subject: [PATCH 106/335] mimxrt: Optimize the runtime speed. By moving code to ITCM, like vm, gc, parse, runtime. The change affects mostly the execution speed of MicroPython code. The speed is increased by up to a factor of 6, especially for MCU with small cache. --- ports/mimxrt/boards/common.ld | 5 +++-- ports/mimxrt/mpconfigport.h | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ports/mimxrt/boards/common.ld b/ports/mimxrt/boards/common.ld index 5dd7097fab..7aee66e2e8 100644 --- a/ports/mimxrt/boards/common.ld +++ b/ports/mimxrt/boards/common.ld @@ -96,7 +96,7 @@ SECTIONS .text : { . = ALIGN(4); - *(EXCLUDE_FILE(*fsl_flexspi.o) .text*) /* .text* sections (code) */ + *(EXCLUDE_FILE(*fsl_flexspi.o *gc*.o *vm.o *parse.o *runtime*.o *mpirq.o *map.o) .text*) /* .text* sections (code) */ *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ *(.glue_7) /* glue arm to thumb code */ @@ -200,8 +200,9 @@ SECTIONS { . = ALIGN(4); __ram_function_start__ = .; - *fsl_flexspi.o(.text*) *(.ram_functions*) + /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */ + *(.text*) . = ALIGN(4); __ram_function_end__ = .; } > m_itcm diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 1d487fb541..35ee9eb648 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -43,7 +43,9 @@ uint32_t trng_random_u32(void); #define MICROPY_EMIT_THUMB (1) #define MICROPY_EMIT_INLINE_THUMB (1) -// Compiler configuration +// Optimisations +#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (1) +#define MICROPY_OPT_MAP_LOOKUP_CACHE (1) // Python internal features #define MICROPY_READER_VFS (1) From 9f6604eb2723c48bfe712a57801d0c7f14c6fbda Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 19 Sep 2021 22:08:51 +0200 Subject: [PATCH 107/335] mimxrt: Enable the platform module. --- ports/mimxrt/mpconfigport.h | 1 + ports/mimxrt/mphalport.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 35ee9eb648..64e991c799 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -135,6 +135,7 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_FRAMEBUF (1) #define MICROPY_PY_ONEWIRE (1) +#define MICROPY_PY_UPLATFORM (1) // fatfs configuration used in ffconf.h #define MICROPY_FATFS_ENABLE_LFN (1) diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index 40e929b23b..c02f561a9d 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -33,6 +33,8 @@ #include "pin.h" #include "fsl_clock.h" +#define MICROPY_HAL_VERSION "2.8.0" + #define MP_HAL_PIN_FMT "%q" extern ringbuf_t stdin_ringbuf; From 64e4bae129263278f72a6c3494f1e67c7895fcdd Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 25 Oct 2021 16:38:25 +1100 Subject: [PATCH 108/335] tools/ci.sh: Use a specific ESP IDF v4.4 commit. There is no release of IDF v4.4 yet but master is now on v5.0-dev so a specific commit must be chosen to stick to v4.4. Signed-off-by: Damien George --- tools/ci.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/ci.sh b/tools/ci.sh index 407ea04579..f9b90b9687 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -107,7 +107,8 @@ function ci_esp32_idf402_setup { } function ci_esp32_idf44_setup { - ci_esp32_setup_helper master + # This commit is just before v5.0-dev + ci_esp32_setup_helper 142bb32c50fa9875b8b69fa539a2d59559460d72 } function ci_esp32_build { From 43467b9c719928ffaf2bc1cb314338bc402914e1 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Mon, 27 Sep 2021 16:27:42 +1000 Subject: [PATCH 109/335] extmod/modbluetooth: Add connection interval to gap_connect. This forwards through directly to the NimBLE and BTStack connect functions. Signed-off-by: Jim Mussared --- docs/library/bluetooth.rst | 11 ++++++++++- extmod/btstack/modbluetooth_btstack.c | 6 +++--- extmod/modbluetooth.c | 14 +++++++++++--- extmod/modbluetooth.h | 2 +- extmod/nimble/modbluetooth_nimble.c | 12 +++++++----- ports/zephyr/modbluetooth_zephyr.c | 2 +- 6 files changed, 33 insertions(+), 14 deletions(-) diff --git a/docs/library/bluetooth.rst b/docs/library/bluetooth.rst index 6ebceeed58..cfec804eaf 100644 --- a/docs/library/bluetooth.rst +++ b/docs/library/bluetooth.rst @@ -359,7 +359,7 @@ Central Role A central device can connect to peripherals that it has discovered using the observer role (see :meth:`gap_scan`) or with a known address. -.. method:: BLE.gap_connect(addr_type, addr, scan_duration_ms=2000, /) +.. method:: BLE.gap_connect(addr_type, addr, scan_duration_ms=2000, min_conn_interval_us=None, max_conn_interval_us=None, /) Connect to a peripheral. @@ -367,6 +367,15 @@ A central device can connect to peripherals that it has discovered using the obs On success, the ``_IRQ_PERIPHERAL_CONNECT`` event will be raised. + The device will wait up to *scan_duration_ms* to receive an advertising + payload from the device. + + The connection interval can be configured in **micro**\ seconds using either + or both of *min_conn_interval_us* and *max_conn_interval_us*. Otherwise a + default interval will be chosen, typically between 30000 and 50000 + microseconds. A shorter interval will increase throughput, at the expense + of power usage. + Peripheral Role --------------- diff --git a/extmod/btstack/modbluetooth_btstack.c b/extmod/btstack/modbluetooth_btstack.c index 4e81e21fe2..cd2ba83d53 100644 --- a/extmod/btstack/modbluetooth_btstack.c +++ b/extmod/btstack/modbluetooth_btstack.c @@ -1265,13 +1265,13 @@ int mp_bluetooth_gap_scan_stop(void) { return 0; } -int mp_bluetooth_gap_peripheral_connect(uint8_t addr_type, const uint8_t *addr, int32_t duration_ms) { +int mp_bluetooth_gap_peripheral_connect(uint8_t addr_type, const uint8_t *addr, int32_t duration_ms, int32_t min_conn_interval_us, int32_t max_conn_interval_us) { DEBUG_printf("mp_bluetooth_gap_peripheral_connect\n"); uint16_t conn_scan_interval = 60000 / 625; uint16_t conn_scan_window = 30000 / 625; - uint16_t conn_interval_min = 10000 / 1250; - uint16_t conn_interval_max = 30000 / 1250; + uint16_t conn_interval_min = (min_conn_interval_us ? min_conn_interval_us : 10000) / 1250; + uint16_t conn_interval_max = (max_conn_interval_us ? max_conn_interval_us : 30000) / 1250; uint16_t conn_latency = 4; uint16_t supervision_timeout = duration_ms / 10; // default = 720 uint16_t min_ce_length = 10000 / 625; diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index cb153f70e9..e3d64b81f1 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -637,14 +637,22 @@ STATIC mp_obj_t bluetooth_ble_gap_connect(size_t n_args, const mp_obj_t *args) { mp_raise_ValueError(MP_ERROR_TEXT("invalid addr")); } mp_int_t scan_duration_ms = MP_BLUETOOTH_CONNECT_DEFAULT_SCAN_DURATION_MS; - if (n_args == 4) { + mp_int_t min_conn_interval_us = 0; + mp_int_t max_conn_interval_us = 0; + if (n_args >= 4 && args[3] != mp_const_none) { scan_duration_ms = mp_obj_get_int(args[3]); } + if (n_args >= 5 && args[4] != mp_const_none) { + min_conn_interval_us = mp_obj_get_int(args[4]); + } + if (n_args >= 6 && args[5] != mp_const_none) { + max_conn_interval_us = mp_obj_get_int(args[5]); + } - int err = mp_bluetooth_gap_peripheral_connect(addr_type, bufinfo.buf, scan_duration_ms); + int err = mp_bluetooth_gap_peripheral_connect(addr_type, bufinfo.buf, scan_duration_ms, min_conn_interval_us, max_conn_interval_us); return bluetooth_handle_errno(err); } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gap_connect_obj, 3, 4, bluetooth_ble_gap_connect); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gap_connect_obj, 3, 6, bluetooth_ble_gap_connect); STATIC mp_obj_t bluetooth_ble_gap_scan(size_t n_args, const mp_obj_t *args) { // Default is indefinite scan, with the NimBLE "background scan" interval and window. diff --git a/extmod/modbluetooth.h b/extmod/modbluetooth.h index 43519e5941..fe41fd5143 100644 --- a/extmod/modbluetooth.h +++ b/extmod/modbluetooth.h @@ -370,7 +370,7 @@ int mp_bluetooth_gap_scan_start(int32_t duration_ms, int32_t interval_us, int32_ int mp_bluetooth_gap_scan_stop(void); // Connect to a found peripheral. -int mp_bluetooth_gap_peripheral_connect(uint8_t addr_type, const uint8_t *addr, int32_t duration_ms); +int mp_bluetooth_gap_peripheral_connect(uint8_t addr_type, const uint8_t *addr, int32_t duration_ms, int32_t min_conn_interval_us, int32_t max_conn_interval_us); #endif #if MICROPY_PY_BLUETOOTH_ENABLE_GATT_CLIENT diff --git a/extmod/nimble/modbluetooth_nimble.c b/extmod/nimble/modbluetooth_nimble.c index e4b4cb68af..6ac31fd4bd 100644 --- a/extmod/nimble/modbluetooth_nimble.c +++ b/extmod/nimble/modbluetooth_nimble.c @@ -1202,7 +1202,7 @@ STATIC int peripheral_gap_event_cb(struct ble_gap_event *event, void *arg) { return commmon_gap_event_cb(event, arg); } -int mp_bluetooth_gap_peripheral_connect(uint8_t addr_type, const uint8_t *addr, int32_t duration_ms) { +int mp_bluetooth_gap_peripheral_connect(uint8_t addr_type, const uint8_t *addr, int32_t duration_ms, int32_t min_conn_interval_us, int32_t max_conn_interval_us) { DEBUG_printf("mp_bluetooth_gap_peripheral_connect\n"); if (!mp_bluetooth_is_active()) { return ERRNO_BLUETOOTH_NOT_ACTIVE; @@ -1211,12 +1211,14 @@ int mp_bluetooth_gap_peripheral_connect(uint8_t addr_type, const uint8_t *addr, mp_bluetooth_gap_scan_stop(); } - // TODO: This is the same as ble_gap_conn_params_dflt (i.e. passing NULL). - STATIC const struct ble_gap_conn_params params = { + uint16_t conn_interval_min = min_conn_interval_us ? min_conn_interval_us / BLE_HCI_CONN_ITVL : BLE_GAP_INITIAL_CONN_ITVL_MIN; + uint16_t conn_interval_max = max_conn_interval_us ? max_conn_interval_us / BLE_HCI_CONN_ITVL : BLE_GAP_INITIAL_CONN_ITVL_MAX; + + const struct ble_gap_conn_params params = { .scan_itvl = 0x0010, .scan_window = 0x0010, - .itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN, - .itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX, + .itvl_min = conn_interval_min, + .itvl_max = conn_interval_max, .latency = BLE_GAP_INITIAL_CONN_LATENCY, .supervision_timeout = BLE_GAP_INITIAL_SUPERVISION_TIMEOUT, .min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN, diff --git a/ports/zephyr/modbluetooth_zephyr.c b/ports/zephyr/modbluetooth_zephyr.c index 5753d71476..f4b6f35590 100644 --- a/ports/zephyr/modbluetooth_zephyr.c +++ b/ports/zephyr/modbluetooth_zephyr.c @@ -400,7 +400,7 @@ int mp_bluetooth_gap_scan_stop(void) { return bt_err_to_errno(err); } -int mp_bluetooth_gap_peripheral_connect(uint8_t addr_type, const uint8_t *addr, int32_t duration_ms) { +int mp_bluetooth_gap_peripheral_connect(uint8_t addr_type, const uint8_t *addr, int32_t duration_ms, int32_t min_conn_interval_us, int32_t max_conn_interval_us) { DEBUG_printf("mp_bluetooth_gap_peripheral_connect\n"); if (!mp_bluetooth_is_active()) { return ERRNO_BLUETOOTH_NOT_ACTIVE; From 1244d7f0bdce6531085f35a36039662147341e74 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 26 Oct 2021 16:39:38 +1100 Subject: [PATCH 110/335] lib/mynewt-nimble: Switch to the MicroPython fork of NimBLE. We will use this fork for adding further features and patches to support MicroPython. Signed-off-by: Jim Mussared --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 9fd45dfecf..474ae9890b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,7 +28,7 @@ url = https://github.com/hathach/tinyusb [submodule "lib/mynewt-nimble"] path = lib/mynewt-nimble - url = https://github.com/apache/mynewt-nimble.git + url = https://github.com/micropython/mynewt-nimble.git [submodule "lib/btstack"] path = lib/btstack url = https://github.com/bluekitchen/btstack.git From 948e3289bf3e86974f1fc399aadb130e9de26401 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 8 Jul 2021 00:43:56 +1000 Subject: [PATCH 111/335] extmod/nimble: Update to NimBLE v1.4. We're using the MicroPython fork of NimBLE, which on the `micropython_1_4_0` branch re-adds support for 64-bit targets and fixes initialisation of g_msys_pool_list. Also updates modbluetooth_nimble.c to suit v1.4. Signed-off-by: Jim Mussared --- extmod/nimble/modbluetooth_nimble.c | 49 +++++++++++++--------------- extmod/nimble/nimble/nimble_npl_os.h | 6 +++- lib/mynewt-nimble | 2 +- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/extmod/nimble/modbluetooth_nimble.c b/extmod/nimble/modbluetooth_nimble.c index 6ac31fd4bd..125e282d0d 100644 --- a/extmod/nimble/modbluetooth_nimble.c +++ b/extmod/nimble/modbluetooth_nimble.c @@ -138,9 +138,9 @@ STATIC int ble_gattc_attr_write_cb(uint16_t conn_handle, const struct ble_gatt_e #if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING // Bonding store. -STATIC int ble_store_ram_read(int obj_type, const union ble_store_key *key, union ble_store_value *value); -STATIC int ble_store_ram_write(int obj_type, const union ble_store_value *val); -STATIC int ble_store_ram_delete(int obj_type, const union ble_store_key *key); +STATIC int ble_secret_store_read(int obj_type, const union ble_store_key *key, union ble_store_value *value); +STATIC int ble_secret_store_write(int obj_type, const union ble_store_value *val); +STATIC int ble_secret_store_delete(int obj_type, const union ble_store_key *key); #endif STATIC int ble_hs_err_to_errno(int err) { @@ -604,6 +604,12 @@ int mp_bluetooth_init(void) { ble_hs_cfg.gatts_register_cb = gatts_register_cb; ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + #if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING + ble_hs_cfg.store_read_cb = ble_secret_store_read; + ble_hs_cfg.store_write_cb = ble_secret_store_write; + ble_hs_cfg.store_delete_cb = ble_secret_store_delete; + #endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING + MP_STATE_PORT(bluetooth_nimble_root_pointers) = m_new0(mp_bluetooth_nimble_root_pointers_t, 1); mp_bluetooth_gatts_db_create(&MP_STATE_PORT(bluetooth_nimble_root_pointers)->gatts_db); @@ -1826,8 +1832,8 @@ int mp_bluetooth_hci_cmd(uint16_t ogf, uint16_t ocf, const uint8_t *req, size_t #if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING -STATIC int ble_store_ram_read(int obj_type, const union ble_store_key *key, union ble_store_value *value) { - DEBUG_printf("ble_store_ram_read: %d\n", obj_type); +STATIC int ble_secret_store_read(int obj_type, const union ble_store_key *key, union ble_store_value *value) { + DEBUG_printf("ble_secret_store_read: %d\n", obj_type); const uint8_t *key_data; size_t key_data_len; @@ -1861,7 +1867,7 @@ STATIC int ble_store_ram_read(int obj_type, const union ble_store_key *key, unio } case BLE_STORE_OBJ_TYPE_CCCD: { // TODO: Implement CCCD persistence. - DEBUG_printf("ble_store_ram_read: CCCD not supported.\n"); + DEBUG_printf("ble_secret_store_read: CCCD not supported.\n"); return -1; } default: @@ -1871,18 +1877,18 @@ STATIC int ble_store_ram_read(int obj_type, const union ble_store_key *key, unio const uint8_t *value_data; size_t value_data_len; if (!mp_bluetooth_gap_on_get_secret(obj_type, key->sec.idx, key_data, key_data_len, &value_data, &value_data_len)) { - DEBUG_printf("ble_store_ram_read: Key not found: type=%d, index=%u, key=0x%p, len=" UINT_FMT "\n", obj_type, key->sec.idx, key_data, key_data_len); + DEBUG_printf("ble_secret_store_read: Key not found: type=%d, index=%u, key=0x%p, len=" UINT_FMT "\n", obj_type, key->sec.idx, key_data, key_data_len); return BLE_HS_ENOENT; } if (value_data_len != sizeof(struct ble_store_value_sec)) { - DEBUG_printf("ble_store_ram_read: Invalid key data: actual=" UINT_FMT " expected=" UINT_FMT "\n", value_data_len, sizeof(struct ble_store_value_sec)); + DEBUG_printf("ble_secret_store_read: Invalid key data: actual=" UINT_FMT " expected=" UINT_FMT "\n", value_data_len, sizeof(struct ble_store_value_sec)); return BLE_HS_ENOENT; } memcpy((uint8_t *)&value->sec, value_data, sizeof(struct ble_store_value_sec)); - DEBUG_printf("ble_store_ram_read: found secret\n"); + DEBUG_printf("ble_secret_store_read: found secret\n"); if (obj_type == BLE_STORE_OBJ_TYPE_OUR_SEC) { // TODO: Verify ediv_rand matches. @@ -1891,8 +1897,8 @@ STATIC int ble_store_ram_read(int obj_type, const union ble_store_key *key, unio return 0; } -STATIC int ble_store_ram_write(int obj_type, const union ble_store_value *val) { - DEBUG_printf("ble_store_ram_write: %d\n", obj_type); +STATIC int ble_secret_store_write(int obj_type, const union ble_store_value *val) { + DEBUG_printf("ble_secret_store_write: %d\n", obj_type); switch (obj_type) { case BLE_STORE_OBJ_TYPE_PEER_SEC: case BLE_STORE_OBJ_TYPE_OUR_SEC: { @@ -1910,13 +1916,13 @@ STATIC int ble_store_ram_write(int obj_type, const union ble_store_value *val) { return BLE_HS_ESTORE_CAP; } - DEBUG_printf("ble_store_ram_write: wrote secret\n"); + DEBUG_printf("ble_secret_store_write: wrote secret\n"); return 0; } case BLE_STORE_OBJ_TYPE_CCCD: { // TODO: Implement CCCD persistence. - DEBUG_printf("ble_store_ram_write: CCCD not supported.\n"); + DEBUG_printf("ble_secret_store_write: CCCD not supported.\n"); // Just pretend we wrote it. return 0; } @@ -1925,8 +1931,8 @@ STATIC int ble_store_ram_write(int obj_type, const union ble_store_value *val) { } } -STATIC int ble_store_ram_delete(int obj_type, const union ble_store_key *key) { - DEBUG_printf("ble_store_ram_delete: %d\n", obj_type); +STATIC int ble_secret_store_delete(int obj_type, const union ble_store_key *key) { + DEBUG_printf("ble_secret_store_delete: %d\n", obj_type); switch (obj_type) { case BLE_STORE_OBJ_TYPE_PEER_SEC: case BLE_STORE_OBJ_TYPE_OUR_SEC: { @@ -1940,13 +1946,13 @@ STATIC int ble_store_ram_delete(int obj_type, const union ble_store_key *key) { return BLE_HS_ENOENT; } - DEBUG_printf("ble_store_ram_delete: deleted secret\n"); + DEBUG_printf("ble_secret_store_delete: deleted secret\n"); return 0; } case BLE_STORE_OBJ_TYPE_CCCD: { // TODO: Implement CCCD persistence. - DEBUG_printf("ble_store_ram_delete: CCCD not supported.\n"); + DEBUG_printf("ble_secret_store_delete: CCCD not supported.\n"); // Just pretend it wasn't there. return BLE_HS_ENOENT; } @@ -1955,15 +1961,6 @@ STATIC int ble_store_ram_delete(int obj_type, const union ble_store_key *key) { } } -// nimble_port_init always calls ble_store_ram_init. We provide this alternative -// implementation rather than the one in nimble/store/ram/src/ble_store_ram.c. -// TODO: Consider re-implementing nimble_port_init instead. -void ble_store_ram_init(void) { - ble_hs_cfg.store_read_cb = ble_store_ram_read; - ble_hs_cfg.store_write_cb = ble_store_ram_write; - ble_hs_cfg.store_delete_cb = ble_store_ram_delete; -} - #endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING #endif // MICROPY_PY_BLUETOOTH && MICROPY_BLUETOOTH_NIMBLE diff --git a/extmod/nimble/nimble/nimble_npl_os.h b/extmod/nimble/nimble/nimble_npl_os.h index d0803f7e2e..3205baa032 100644 --- a/extmod/nimble/nimble/nimble_npl_os.h +++ b/extmod/nimble/nimble/nimble_npl_os.h @@ -35,7 +35,11 @@ // --- Configuration of NimBLE data structures -------------------------------- // This is used at runtime to align allocations correctly. -#define BLE_NPL_OS_ALIGNMENT (sizeof(uintptr_t)) +#if __WORDSIZE == 64 +#define BLE_NPL_OS_ALIGNMENT 8 +#else +#define BLE_NPL_OS_ALIGNMENT 4 +#endif #define BLE_NPL_TIME_FOREVER (0xffffffff) // This is used at compile time to force struct member alignment. See diff --git a/lib/mynewt-nimble b/lib/mynewt-nimble index 97ce3eacaa..42849560ba 160000 --- a/lib/mynewt-nimble +++ b/lib/mynewt-nimble @@ -1 +1 @@ -Subproject commit 97ce3eacaaa79e8ed6cf71717149ced4f5328ee7 +Subproject commit 42849560ba7906f023f61e5f7ff3709ba2c1dfca From 9519484c564de8408d001ebbf45de27ef78bb60a Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 21 Sep 2021 13:36:06 +1000 Subject: [PATCH 112/335] extmod/nimble: Remove workaround for OS_ENOMEM. This was fixed in NimBLE 1.4. Signed-off-by: Jim Mussared --- extmod/nimble/modbluetooth_nimble.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/extmod/nimble/modbluetooth_nimble.c b/extmod/nimble/modbluetooth_nimble.c index 125e282d0d..919841c243 100644 --- a/extmod/nimble/modbluetooth_nimble.c +++ b/extmod/nimble/modbluetooth_nimble.c @@ -1747,12 +1747,6 @@ int mp_bluetooth_l2cap_send(uint16_t conn_handle, uint16_t cid, const uint8_t *b *stalled = true; } - // Sometimes we see what looks like BLE_HS_EAGAIN (but it's actually - // OS_ENOMEM in disguise). Fixed in NimBLE v1.4. - if (err == OS_ENOMEM) { - err = BLE_HS_ENOMEM; - } - // Other error codes such as BLE_HS_EBUSY (we're stalled) or BLE_HS_EBADDATA (bigger than MTU). return ble_hs_err_to_errno(err); } From e359b077dd9b44fea17ae8fa46177ccee36f1fd2 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 2 Sep 2021 00:08:30 +1000 Subject: [PATCH 113/335] ports: Add board.json for all boards. This will be used by https://micropython.org/download/ to generate the full listing of boards and firmware files. Optionally supports a board.md for additional customisation of the download page, as well as deploy.md for flashing instructions. Signed-off-by: Jim Mussared --- ports/cc3200/boards/WIPY/board.json | 16 ++++++++++ ports/cc3200/boards/WIPY/deploy.md | 2 ++ ports/esp32/boards/ESP32_S2_WROVER/board.json | 13 ++++++++ ports/esp32/boards/GENERIC/board.json | 20 ++++++++++++ ports/esp32/boards/GENERIC/board.md | 3 ++ ports/esp32/boards/GENERIC_C3/board.json | 14 +++++++++ ports/esp32/boards/GENERIC_C3_USB/board.json | 14 +++++++++ ports/esp32/boards/GENERIC_D2WD/board.json | 14 +++++++++ ports/esp32/boards/GENERIC_OTA/board.json | 14 +++++++++ ports/esp32/boards/GENERIC_S2/board.json | 13 ++++++++ ports/esp32/boards/GENERIC_S3/board.json | 13 ++++++++ ports/esp32/boards/GENERIC_SPIRAM/board.json | 21 +++++++++++++ ports/esp32/boards/GENERIC_SPIRAM/board.md | 3 ++ ports/esp32/boards/LOLIN_S2_MINI/board.json | 13 ++++++++ ports/esp32/boards/M5STACK_ATOM/board.json | 13 ++++++++ ports/esp32/boards/SIL_WESP32/board.json | 14 +++++++++ ports/esp32/boards/UM_FEATHERS2/board.json | 23 ++++++++++++++ ports/esp32/boards/UM_FEATHERS2NEO/board.json | 22 +++++++++++++ ports/esp32/boards/UM_TINYPICO/board.json | 19 ++++++++++++ ports/esp32/boards/UM_TINYS2/board.json | 16 ++++++++++ ports/esp32/boards/deploy.md | 13 ++++++++ ports/esp8266/boards/GENERIC/board.json | 17 ++++++++++ ports/esp8266/boards/GENERIC/board.md | 19 ++++++++++++ ports/esp8266/boards/GENERIC_1M/board.json | 14 +++++++++ ports/esp8266/boards/GENERIC_1M/board.md | 5 +++ ports/esp8266/boards/GENERIC_512K/board.json | 14 +++++++++ ports/esp8266/boards/GENERIC_512K/board.md | 3 ++ ports/esp8266/boards/deploy.md | 1 + ports/mimxrt/boards/MIMXRT1010_EVK/board.json | 13 ++++++++ ports/mimxrt/boards/MIMXRT1020_EVK/board.json | 13 ++++++++ ports/mimxrt/boards/MIMXRT1050_EVK/board.json | 13 ++++++++ ports/mimxrt/boards/MIMXRT1060_EVK/board.json | 13 ++++++++ ports/mimxrt/boards/MIMXRT1064_EVK/board.json | 13 ++++++++ ports/mimxrt/boards/TEENSY40/board.json | 13 ++++++++ ports/mimxrt/boards/TEENSY41/board.json | 13 ++++++++ ports/mimxrt/boards/deploy.md | 0 ports/nrf/boards/actinius_icarus/board.json | 13 ++++++++ ports/nrf/boards/arduino_primo/board.json | 13 ++++++++ ports/nrf/boards/blueio_tag_evim/board.json | 13 ++++++++ ports/nrf/boards/deploy.md | 0 ports/nrf/boards/dvk_bl652/board.json | 13 ++++++++ ports/nrf/boards/evk_nina_b1/board.json | 13 ++++++++ ports/nrf/boards/evk_nina_b3/board.json | 13 ++++++++ ports/nrf/boards/feather52/board.json | 15 +++++++++ ports/nrf/boards/ibk_blyst_nano/board.json | 13 ++++++++ ports/nrf/boards/idk_blyst_nano/board.json | 13 ++++++++ ports/nrf/boards/microbit/board.json | 13 ++++++++ .../boards/nrf52840-mdk-usb-dongle/board.json | 13 ++++++++ ports/nrf/boards/particle_xenon/board.json | 13 ++++++++ ports/nrf/boards/pca10000/board.json | 13 ++++++++ ports/nrf/boards/pca10001/board.json | 13 ++++++++ ports/nrf/boards/pca10028/board.json | 13 ++++++++ ports/nrf/boards/pca10031/board.json | 13 ++++++++ ports/nrf/boards/pca10040/board.json | 13 ++++++++ ports/nrf/boards/pca10056/board.json | 13 ++++++++ ports/nrf/boards/pca10059/board.json | 15 +++++++++ ports/nrf/boards/pca10090/board.json | 13 ++++++++ ports/nrf/boards/wt51822_s4at/board.json | 13 ++++++++ .../boards/ADAFRUIT_FEATHER_RP2040/board.json | 15 +++++++++ .../ADAFRUIT_ITSYBITSY_RP2040/board.json | 15 +++++++++ .../boards/ADAFRUIT_QTPY_RP2040/board.json | 15 +++++++++ ports/rp2/boards/PICO/board.json | 16 ++++++++++ .../boards/PIMORONI_PICOLIPO_16MB/board.json | 15 +++++++++ .../boards/PIMORONI_PICOLIPO_4MB/board.json | 15 +++++++++ ports/rp2/boards/PIMORONI_TINY2040/board.json | 15 +++++++++ ports/rp2/boards/SPARKFUN_PROMICRO/board.json | 15 +++++++++ .../rp2/boards/SPARKFUN_THINGPLUS/board.json | 15 +++++++++ ports/rp2/boards/deploy.md | 8 +++++ .../ADAFRUIT_FEATHER_M0_EXPRESS/board.json | 15 +++++++++ .../ADAFRUIT_ITSYBITSY_M4_EXPRESS/board.json | 15 +++++++++ .../boards/ADAFRUIT_TRINKET_M0/board.json | 15 +++++++++ ports/samd/boards/MINISAM_M4/board.json | 15 +++++++++ .../boards/SAMD21_XPLAINED_PRO/board.json | 13 ++++++++ ports/samd/boards/deploy.md | 0 .../boards/ADAFRUIT_F405_EXPRESS/board.json | 13 ++++++++ ports/stm32/boards/B_L072Z_LRWAN1/board.json | 13 ++++++++ ports/stm32/boards/B_L475E_IOT01A/board.json | 13 ++++++++ ports/stm32/boards/CERB40/board.json | 13 ++++++++ ports/stm32/boards/ESPRUINO_PICO/board.json | 15 +++++++++ ports/stm32/boards/ESPRUINO_PICO/deploy.md | 1 + ports/stm32/boards/HYDRABUS/board.json | 13 ++++++++ ports/stm32/boards/LEGO_HUB_NO6/board.json | 13 ++++++++ ports/stm32/boards/LIMIFROG/board.json | 13 ++++++++ .../boards/MIKROE_CLICKER2_STM32/board.json | 13 ++++++++ ports/stm32/boards/NADHAT_PYBF405/board.json | 13 ++++++++ ports/stm32/boards/NETDUINO_PLUS_2/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_F091RC/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_F401RE/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_F411RE/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_F412ZG/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_F413ZH/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_F429ZI/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_F439ZI/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_F446RE/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_F722ZE/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_F746ZG/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_F767ZI/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_H743ZI/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_H743ZI2/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_L073RZ/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_L432KC/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_L452RE/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_L476RG/board.json | 13 ++++++++ ports/stm32/boards/NUCLEO_WB55/board.json | 13 ++++++++ ports/stm32/boards/OLIMEX_E407/board.json | 13 ++++++++ ports/stm32/boards/OLIMEX_H407/board.json | 13 ++++++++ ports/stm32/boards/PYBD_SF2/board.json | 21 +++++++++++++ ports/stm32/boards/PYBD_SF2/board.md | 1 + ports/stm32/boards/PYBD_SF2/deploy.md | 3 ++ ports/stm32/boards/PYBD_SF3/board.json | 21 +++++++++++++ ports/stm32/boards/PYBD_SF3/board.md | 1 + ports/stm32/boards/PYBD_SF6/board.json | 24 ++++++++++++++ ports/stm32/boards/PYBD_SF6/board.md | 1 + ports/stm32/boards/PYBLITEV10/board.json | 24 ++++++++++++++ ports/stm32/boards/PYBLITEV10/board.md | 1 + ports/stm32/boards/PYBV10/board.json | 22 +++++++++++++ ports/stm32/boards/PYBV10/board.md | 1 + ports/stm32/boards/PYBV10/deploy.md | 6 ++++ ports/stm32/boards/PYBV11/board.json | 24 ++++++++++++++ ports/stm32/boards/PYBV11/board.md | 1 + .../boards/SPARKFUN_MICROMOD_STM32/board.json | 13 ++++++++ ports/stm32/boards/STM32F411DISC/board.json | 13 ++++++++ ports/stm32/boards/STM32F429DISC/board.json | 13 ++++++++ ports/stm32/boards/STM32F439/board.json | 13 ++++++++ ports/stm32/boards/STM32F4DISC/board.json | 13 ++++++++ ports/stm32/boards/STM32F769DISC/board.json | 13 ++++++++ ports/stm32/boards/STM32F7DISC/board.json | 13 ++++++++ ports/stm32/boards/STM32H7B3I_DK/board.json | 13 ++++++++ ports/stm32/boards/STM32L476DISC/board.json | 13 ++++++++ ports/stm32/boards/STM32L496GDISC/board.json | 13 ++++++++ ports/stm32/boards/USBDONGLE_WB55/board.json | 13 ++++++++ ports/stm32/boards/VCC_GND_F407VE/board.json | 13 ++++++++ ports/stm32/boards/VCC_GND_F407ZG/board.json | 13 ++++++++ ports/stm32/boards/VCC_GND_H743VI/board.json | 13 ++++++++ ports/stm32/boards/deploy.md | 31 +++++++++++++++++++ 135 files changed, 1721 insertions(+) create mode 100644 ports/cc3200/boards/WIPY/board.json create mode 100644 ports/cc3200/boards/WIPY/deploy.md create mode 100644 ports/esp32/boards/ESP32_S2_WROVER/board.json create mode 100644 ports/esp32/boards/GENERIC/board.json create mode 100644 ports/esp32/boards/GENERIC/board.md create mode 100644 ports/esp32/boards/GENERIC_C3/board.json create mode 100644 ports/esp32/boards/GENERIC_C3_USB/board.json create mode 100644 ports/esp32/boards/GENERIC_D2WD/board.json create mode 100644 ports/esp32/boards/GENERIC_OTA/board.json create mode 100644 ports/esp32/boards/GENERIC_S2/board.json create mode 100644 ports/esp32/boards/GENERIC_S3/board.json create mode 100644 ports/esp32/boards/GENERIC_SPIRAM/board.json create mode 100644 ports/esp32/boards/GENERIC_SPIRAM/board.md create mode 100644 ports/esp32/boards/LOLIN_S2_MINI/board.json create mode 100644 ports/esp32/boards/M5STACK_ATOM/board.json create mode 100644 ports/esp32/boards/SIL_WESP32/board.json create mode 100644 ports/esp32/boards/UM_FEATHERS2/board.json create mode 100644 ports/esp32/boards/UM_FEATHERS2NEO/board.json create mode 100644 ports/esp32/boards/UM_TINYPICO/board.json create mode 100644 ports/esp32/boards/UM_TINYS2/board.json create mode 100644 ports/esp32/boards/deploy.md create mode 100644 ports/esp8266/boards/GENERIC/board.json create mode 100644 ports/esp8266/boards/GENERIC/board.md create mode 100644 ports/esp8266/boards/GENERIC_1M/board.json create mode 100644 ports/esp8266/boards/GENERIC_1M/board.md create mode 100644 ports/esp8266/boards/GENERIC_512K/board.json create mode 100644 ports/esp8266/boards/GENERIC_512K/board.md create mode 100644 ports/esp8266/boards/deploy.md create mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/board.json create mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/board.json create mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/board.json create mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/board.json create mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/board.json create mode 100644 ports/mimxrt/boards/TEENSY40/board.json create mode 100644 ports/mimxrt/boards/TEENSY41/board.json create mode 100644 ports/mimxrt/boards/deploy.md create mode 100644 ports/nrf/boards/actinius_icarus/board.json create mode 100644 ports/nrf/boards/arduino_primo/board.json create mode 100644 ports/nrf/boards/blueio_tag_evim/board.json create mode 100644 ports/nrf/boards/deploy.md create mode 100644 ports/nrf/boards/dvk_bl652/board.json create mode 100644 ports/nrf/boards/evk_nina_b1/board.json create mode 100644 ports/nrf/boards/evk_nina_b3/board.json create mode 100644 ports/nrf/boards/feather52/board.json create mode 100644 ports/nrf/boards/ibk_blyst_nano/board.json create mode 100644 ports/nrf/boards/idk_blyst_nano/board.json create mode 100644 ports/nrf/boards/microbit/board.json create mode 100644 ports/nrf/boards/nrf52840-mdk-usb-dongle/board.json create mode 100644 ports/nrf/boards/particle_xenon/board.json create mode 100644 ports/nrf/boards/pca10000/board.json create mode 100644 ports/nrf/boards/pca10001/board.json create mode 100644 ports/nrf/boards/pca10028/board.json create mode 100644 ports/nrf/boards/pca10031/board.json create mode 100644 ports/nrf/boards/pca10040/board.json create mode 100644 ports/nrf/boards/pca10056/board.json create mode 100644 ports/nrf/boards/pca10059/board.json create mode 100644 ports/nrf/boards/pca10090/board.json create mode 100644 ports/nrf/boards/wt51822_s4at/board.json create mode 100644 ports/rp2/boards/ADAFRUIT_FEATHER_RP2040/board.json create mode 100644 ports/rp2/boards/ADAFRUIT_ITSYBITSY_RP2040/board.json create mode 100644 ports/rp2/boards/ADAFRUIT_QTPY_RP2040/board.json create mode 100644 ports/rp2/boards/PICO/board.json create mode 100644 ports/rp2/boards/PIMORONI_PICOLIPO_16MB/board.json create mode 100644 ports/rp2/boards/PIMORONI_PICOLIPO_4MB/board.json create mode 100644 ports/rp2/boards/PIMORONI_TINY2040/board.json create mode 100644 ports/rp2/boards/SPARKFUN_PROMICRO/board.json create mode 100644 ports/rp2/boards/SPARKFUN_THINGPLUS/board.json create mode 100644 ports/rp2/boards/deploy.md create mode 100644 ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/board.json create mode 100644 ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/board.json create mode 100644 ports/samd/boards/ADAFRUIT_TRINKET_M0/board.json create mode 100644 ports/samd/boards/MINISAM_M4/board.json create mode 100644 ports/samd/boards/SAMD21_XPLAINED_PRO/board.json create mode 100644 ports/samd/boards/deploy.md create mode 100644 ports/stm32/boards/ADAFRUIT_F405_EXPRESS/board.json create mode 100644 ports/stm32/boards/B_L072Z_LRWAN1/board.json create mode 100644 ports/stm32/boards/B_L475E_IOT01A/board.json create mode 100644 ports/stm32/boards/CERB40/board.json create mode 100644 ports/stm32/boards/ESPRUINO_PICO/board.json create mode 100644 ports/stm32/boards/ESPRUINO_PICO/deploy.md create mode 100644 ports/stm32/boards/HYDRABUS/board.json create mode 100644 ports/stm32/boards/LEGO_HUB_NO6/board.json create mode 100644 ports/stm32/boards/LIMIFROG/board.json create mode 100644 ports/stm32/boards/MIKROE_CLICKER2_STM32/board.json create mode 100644 ports/stm32/boards/NADHAT_PYBF405/board.json create mode 100644 ports/stm32/boards/NETDUINO_PLUS_2/board.json create mode 100644 ports/stm32/boards/NUCLEO_F091RC/board.json create mode 100644 ports/stm32/boards/NUCLEO_F401RE/board.json create mode 100644 ports/stm32/boards/NUCLEO_F411RE/board.json create mode 100644 ports/stm32/boards/NUCLEO_F412ZG/board.json create mode 100644 ports/stm32/boards/NUCLEO_F413ZH/board.json create mode 100644 ports/stm32/boards/NUCLEO_F429ZI/board.json create mode 100644 ports/stm32/boards/NUCLEO_F439ZI/board.json create mode 100644 ports/stm32/boards/NUCLEO_F446RE/board.json create mode 100644 ports/stm32/boards/NUCLEO_F722ZE/board.json create mode 100644 ports/stm32/boards/NUCLEO_F746ZG/board.json create mode 100644 ports/stm32/boards/NUCLEO_F767ZI/board.json create mode 100644 ports/stm32/boards/NUCLEO_H743ZI/board.json create mode 100644 ports/stm32/boards/NUCLEO_H743ZI2/board.json create mode 100644 ports/stm32/boards/NUCLEO_L073RZ/board.json create mode 100644 ports/stm32/boards/NUCLEO_L432KC/board.json create mode 100644 ports/stm32/boards/NUCLEO_L452RE/board.json create mode 100644 ports/stm32/boards/NUCLEO_L476RG/board.json create mode 100644 ports/stm32/boards/NUCLEO_WB55/board.json create mode 100644 ports/stm32/boards/OLIMEX_E407/board.json create mode 100644 ports/stm32/boards/OLIMEX_H407/board.json create mode 100644 ports/stm32/boards/PYBD_SF2/board.json create mode 100644 ports/stm32/boards/PYBD_SF2/board.md create mode 100644 ports/stm32/boards/PYBD_SF2/deploy.md create mode 100644 ports/stm32/boards/PYBD_SF3/board.json create mode 100644 ports/stm32/boards/PYBD_SF3/board.md create mode 100644 ports/stm32/boards/PYBD_SF6/board.json create mode 100644 ports/stm32/boards/PYBD_SF6/board.md create mode 100644 ports/stm32/boards/PYBLITEV10/board.json create mode 100644 ports/stm32/boards/PYBLITEV10/board.md create mode 100644 ports/stm32/boards/PYBV10/board.json create mode 100644 ports/stm32/boards/PYBV10/board.md create mode 100644 ports/stm32/boards/PYBV10/deploy.md create mode 100644 ports/stm32/boards/PYBV11/board.json create mode 100644 ports/stm32/boards/PYBV11/board.md create mode 100644 ports/stm32/boards/SPARKFUN_MICROMOD_STM32/board.json create mode 100644 ports/stm32/boards/STM32F411DISC/board.json create mode 100644 ports/stm32/boards/STM32F429DISC/board.json create mode 100644 ports/stm32/boards/STM32F439/board.json create mode 100644 ports/stm32/boards/STM32F4DISC/board.json create mode 100644 ports/stm32/boards/STM32F769DISC/board.json create mode 100644 ports/stm32/boards/STM32F7DISC/board.json create mode 100644 ports/stm32/boards/STM32H7B3I_DK/board.json create mode 100644 ports/stm32/boards/STM32L476DISC/board.json create mode 100644 ports/stm32/boards/STM32L496GDISC/board.json create mode 100644 ports/stm32/boards/USBDONGLE_WB55/board.json create mode 100644 ports/stm32/boards/VCC_GND_F407VE/board.json create mode 100644 ports/stm32/boards/VCC_GND_F407ZG/board.json create mode 100644 ports/stm32/boards/VCC_GND_H743VI/board.json create mode 100644 ports/stm32/boards/deploy.md diff --git a/ports/cc3200/boards/WIPY/board.json b/ports/cc3200/boards/WIPY/board.json new file mode 100644 index 0000000000..fcc895b7f5 --- /dev/null +++ b/ports/cc3200/boards/WIPY/board.json @@ -0,0 +1,16 @@ +{ + "deploy": [ + "deploy.md" + ], + "docs": "https://docs.pycom.io/datasheets/development/wipy3/", + "features": [], + "id": "wipy", + "images": [ + "wipy.jpg" + ], + "mcu": "cc3200", + "product": "WiPy Module", + "thumbnail": "", + "url": "https://pycom.io/product/wipy-3-0/", + "vendor": "Pycom" +} diff --git a/ports/cc3200/boards/WIPY/deploy.md b/ports/cc3200/boards/WIPY/deploy.md new file mode 100644 index 0000000000..19dcfc158f --- /dev/null +++ b/ports/cc3200/boards/WIPY/deploy.md @@ -0,0 +1,2 @@ +The following files are firmware for the WiPy. The zip file contains mcuimg.bin +which should be copied via ftp to the /flash/sys directory on the WiPy. diff --git a/ports/esp32/boards/ESP32_S2_WROVER/board.json b/ports/esp32/boards/ESP32_S2_WROVER/board.json new file mode 100644 index 0000000000..8f2aff7346 --- /dev/null +++ b/ports/esp32/boards/ESP32_S2_WROVER/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "esp32s2", + "product": "ESP32-S2 WROVER", + "thumbnail": "", + "url": "", + "vendor": "Espressif" +} diff --git a/ports/esp32/boards/GENERIC/board.json b/ports/esp32/boards/GENERIC/board.json new file mode 100644 index 0000000000..eadf70dd12 --- /dev/null +++ b/ports/esp32/boards/GENERIC/board.json @@ -0,0 +1,20 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "WiFi", + "BLE" + ], + "id": "esp32", + "images": [], + "mcu": "esp32", + "product": "ESP32", + "thumbnail": "", + "url": "", + "variants": { + "idf3": "Compiled with IDF 3.x" + }, + "vendor": "Espressif" +} diff --git a/ports/esp32/boards/GENERIC/board.md b/ports/esp32/boards/GENERIC/board.md new file mode 100644 index 0000000000..576ea80450 --- /dev/null +++ b/ports/esp32/boards/GENERIC/board.md @@ -0,0 +1,3 @@ +The following files are daily firmware for ESP32-based boards without external SPIRAM. + +This firmware is compiled using ESP-IDF v4.x. Some older releases are also provided that are compiled with ESP-IDF v3.x. diff --git a/ports/esp32/boards/GENERIC_C3/board.json b/ports/esp32/boards/GENERIC_C3/board.json new file mode 100644 index 0000000000..3c360e64c7 --- /dev/null +++ b/ports/esp32/boards/GENERIC_C3/board.json @@ -0,0 +1,14 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "id": "esp32c3", + "images": [], + "mcu": "esp32c3", + "product": "ESP32-C3", + "thumbnail": "", + "url": "", + "vendor": "Espressif" +} diff --git a/ports/esp32/boards/GENERIC_C3_USB/board.json b/ports/esp32/boards/GENERIC_C3_USB/board.json new file mode 100644 index 0000000000..cf9f63b90c --- /dev/null +++ b/ports/esp32/boards/GENERIC_C3_USB/board.json @@ -0,0 +1,14 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "id": "esp32c3-usb", + "images": [], + "mcu": "esp32c3", + "product": "ESP32-C3 with USB", + "thumbnail": "", + "url": "", + "vendor": "Espressif" +} diff --git a/ports/esp32/boards/GENERIC_D2WD/board.json b/ports/esp32/boards/GENERIC_D2WD/board.json new file mode 100644 index 0000000000..63fbbfb2f9 --- /dev/null +++ b/ports/esp32/boards/GENERIC_D2WD/board.json @@ -0,0 +1,14 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "id": "esp32-d2wd", + "images": [], + "mcu": "esp32", + "product": "ESP32 D2WD", + "thumbnail": "", + "url": "", + "vendor": "Espressif" +} diff --git a/ports/esp32/boards/GENERIC_OTA/board.json b/ports/esp32/boards/GENERIC_OTA/board.json new file mode 100644 index 0000000000..529f0acdee --- /dev/null +++ b/ports/esp32/boards/GENERIC_OTA/board.json @@ -0,0 +1,14 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "id": "esp32-ota", + "images": [], + "mcu": "esp32", + "product": "ESP32 with OTA support", + "thumbnail": "", + "url": "", + "vendor": "Espressif" +} diff --git a/ports/esp32/boards/GENERIC_S2/board.json b/ports/esp32/boards/GENERIC_S2/board.json new file mode 100644 index 0000000000..4ecb90a48a --- /dev/null +++ b/ports/esp32/boards/GENERIC_S2/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "esp32s2", + "product": "ESP32-S2", + "thumbnail": "", + "url": "", + "vendor": "Espressif" +} diff --git a/ports/esp32/boards/GENERIC_S3/board.json b/ports/esp32/boards/GENERIC_S3/board.json new file mode 100644 index 0000000000..a2652ea46a --- /dev/null +++ b/ports/esp32/boards/GENERIC_S3/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "esp32s3", + "product": "ESP32-S3", + "thumbnail": "", + "url": "", + "vendor": "Espressif" +} diff --git a/ports/esp32/boards/GENERIC_SPIRAM/board.json b/ports/esp32/boards/GENERIC_SPIRAM/board.json new file mode 100644 index 0000000000..307555b501 --- /dev/null +++ b/ports/esp32/boards/GENERIC_SPIRAM/board.json @@ -0,0 +1,21 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "WiFi", + "BLE", + "SPIRAM" + ], + "id": "esp32spiram", + "images": [], + "mcu": "esp32", + "product": "ESP32 with SPIRAM", + "thumbnail": "", + "url": "", + "variants": { + "idf3": "Compiled with IDF 3.x" + }, + "vendor": "Espressif" +} diff --git a/ports/esp32/boards/GENERIC_SPIRAM/board.md b/ports/esp32/boards/GENERIC_SPIRAM/board.md new file mode 100644 index 0000000000..3b02b902cd --- /dev/null +++ b/ports/esp32/boards/GENERIC_SPIRAM/board.md @@ -0,0 +1,3 @@ +The following files are daily firmware for ESP32-based boards with external SPIRAM (also known as PSRAM). + +This firmware is compiled using ESP-IDF v4.x. Some older releases are also provided that are compiled with ESP-IDF v3.x. diff --git a/ports/esp32/boards/LOLIN_S2_MINI/board.json b/ports/esp32/boards/LOLIN_S2_MINI/board.json new file mode 100644 index 0000000000..5e866f0e59 --- /dev/null +++ b/ports/esp32/boards/LOLIN_S2_MINI/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "esp32s2", + "product": "S2 mini", + "thumbnail": "", + "url": "https://www.wemos.cc/en/latest/s2/s2_mini.html", + "vendor": "Wemos" +} diff --git a/ports/esp32/boards/M5STACK_ATOM/board.json b/ports/esp32/boards/M5STACK_ATOM/board.json new file mode 100644 index 0000000000..b61d6d9e16 --- /dev/null +++ b/ports/esp32/boards/M5STACK_ATOM/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "esp32", + "product": "M5 Stack Atom", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/esp32/boards/SIL_WESP32/board.json b/ports/esp32/boards/SIL_WESP32/board.json new file mode 100644 index 0000000000..73382c1565 --- /dev/null +++ b/ports/esp32/boards/SIL_WESP32/board.json @@ -0,0 +1,14 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "id": "wesp32", + "images": [], + "mcu": "esp32", + "product": "SIL WESP32", + "thumbnail": "", + "url": "", + "vendor": "Espressif" +} diff --git a/ports/esp32/boards/UM_FEATHERS2/board.json b/ports/esp32/boards/UM_FEATHERS2/board.json new file mode 100644 index 0000000000..bbfd389004 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2/board.json @@ -0,0 +1,23 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "BLE", + "WiFi", + "Feather", + "Battery Charging", + "STEMMA QT/QWIIC", + "USB-C" + ], + "id": "featherS2", + "images": [ + "unexpectedmaker_feathers2.jpg" + ], + "mcu": "esp32s2", + "product": "Feather S2", + "thumbnail": "", + "url": "https://feathers2.io/", + "vendor": "Unexpected Maker" +} diff --git a/ports/esp32/boards/UM_FEATHERS2NEO/board.json b/ports/esp32/boards/UM_FEATHERS2NEO/board.json new file mode 100644 index 0000000000..1bcc2a4b22 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2NEO/board.json @@ -0,0 +1,22 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "BLE", + "WiFi", + "Feather", + "Battery Charging", + "STEMMA QT/QWIIC", + "USB-C", + "Neopixels" + ], + "id": "featherS2neo", + "images": [], + "mcu": "esp32s2", + "product": "Feather S2 Neo", + "thumbnail": "", + "url": "https://unexpectedmaker.com/feathers2-neo", + "vendor": "Unexpected Maker" +} diff --git a/ports/esp32/boards/UM_TINYPICO/board.json b/ports/esp32/boards/UM_TINYPICO/board.json new file mode 100644 index 0000000000..6b5a01d57f --- /dev/null +++ b/ports/esp32/boards/UM_TINYPICO/board.json @@ -0,0 +1,19 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "id": "tinypico", + "images": [ + "tinypico-v2-both.jpg" + ], + "mcu": "esp32", + "product": "TinyPICO", + "thumbnail": "", + "url": "https://www.tinypico.com/", + "variants": { + "idf3": "Compiled with IDF 3.x" + }, + "vendor": "Unexpected Maker" +} diff --git a/ports/esp32/boards/UM_TINYS2/board.json b/ports/esp32/boards/UM_TINYS2/board.json new file mode 100644 index 0000000000..bc694c2cca --- /dev/null +++ b/ports/esp32/boards/UM_TINYS2/board.json @@ -0,0 +1,16 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "id": "tinys2", + "images": [ + "TinyS2+Product+Shot.jpg" + ], + "mcu": "esp32s2", + "product": "Tiny S2", + "thumbnail": "", + "url": "https://unexpectedmaker.com/tinys2", + "vendor": "Unexpected Maker" +} diff --git a/ports/esp32/boards/deploy.md b/ports/esp32/boards/deploy.md new file mode 100644 index 0000000000..c8740a8dd4 --- /dev/null +++ b/ports/esp32/boards/deploy.md @@ -0,0 +1,13 @@ +Program your board using the esptool.py program, found [here](https://github.com/espressif/esptool). +If you are putting MicroPython on your board for the first time then you should +first erase the entire flash using: + +```bash +esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash +``` + +From then on program the firmware starting at address 0x1000: + +```bash +esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 esp32-20190125-v1.10.bin +``` diff --git a/ports/esp8266/boards/GENERIC/board.json b/ports/esp8266/boards/GENERIC/board.json new file mode 100644 index 0000000000..d8f4cba083 --- /dev/null +++ b/ports/esp8266/boards/GENERIC/board.json @@ -0,0 +1,17 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "id": "esp8266", + "images": [], + "mcu": "esp8266", + "product": "ESP8266 with 2MiB+ flash", + "thumbnail": "", + "url": "", + "variants": { + "ota": "OTA compatible" + }, + "vendor": "Espressif" +} diff --git a/ports/esp8266/boards/GENERIC/board.md b/ports/esp8266/boards/GENERIC/board.md new file mode 100644 index 0000000000..b93ca509f8 --- /dev/null +++ b/ports/esp8266/boards/GENERIC/board.md @@ -0,0 +1,19 @@ +The following are daily builds of the ESP8266 firmware for boards with at +least 2MiB of flash. They have the latest features and bug fixes, WebREPL is +not automatically started, and debugging is enabled by default. + +Note: v1.12-334 and newer (including v1.13) require an ESP8266 module with +2MiB of flash or more, and use littlefs as the filesystem by default. When +upgrading from older firmware please backup your files first, and either +erase all flash before upgrading, or after upgrading execute +`uos.VfsLfs2.mkfs(bdev)`. + +### OTA builds +Over-The-Air (OTA) builds of the ESP8266 firmware are also provided. + +The first time you use this build you need to flash one of the "initial image" +images using esptool.py as described above. After that, you can update the +firmware over the air using the "OTA update" file in conjunction with the +ota-client script from yaota8266. The "OTA update" files are digitally signed +and will only work with the provided "initial image" files, and vice versa. +(Note: this feature is work-in-progress.) diff --git a/ports/esp8266/boards/GENERIC_1M/board.json b/ports/esp8266/boards/GENERIC_1M/board.json new file mode 100644 index 0000000000..6279d3fee0 --- /dev/null +++ b/ports/esp8266/boards/GENERIC_1M/board.json @@ -0,0 +1,14 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "id": "esp8266-1m", + "images": [], + "mcu": "esp8266", + "product": "ESP8266 with 1MiB flash", + "thumbnail": "", + "url": "", + "vendor": "Espressif" +} diff --git a/ports/esp8266/boards/GENERIC_1M/board.md b/ports/esp8266/boards/GENERIC_1M/board.md new file mode 100644 index 0000000000..4a0e677078 --- /dev/null +++ b/ports/esp8266/boards/GENERIC_1M/board.md @@ -0,0 +1,5 @@ +The following are daily builds of the ESP8266 firmware tailored for modules with +only 1MiB of flash. This firmware uses littlefs as the filesystem. +When upgrading from older firmware that uses a FAT filesystem please backup your files +first, and either erase all flash before upgrading, or after upgrading execute +`uos.VfsLfs2.mkfs(bdev)`. diff --git a/ports/esp8266/boards/GENERIC_512K/board.json b/ports/esp8266/boards/GENERIC_512K/board.json new file mode 100644 index 0000000000..da15a39d51 --- /dev/null +++ b/ports/esp8266/boards/GENERIC_512K/board.json @@ -0,0 +1,14 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "id": "esp8266-512k", + "images": [], + "mcu": "esp8266", + "product": "ESP8266 with 512kiB flash", + "thumbnail": "", + "url": "", + "vendor": "Espressif" +} diff --git a/ports/esp8266/boards/GENERIC_512K/board.md b/ports/esp8266/boards/GENERIC_512K/board.md new file mode 100644 index 0000000000..1f6e2c7907 --- /dev/null +++ b/ports/esp8266/boards/GENERIC_512K/board.md @@ -0,0 +1,3 @@ +The following are daily builds of the ESP8266 firmware tailored for modules with +only 512kiB of flash. Certain features are disabled to get the firmware down +to this size. diff --git a/ports/esp8266/boards/deploy.md b/ports/esp8266/boards/deploy.md new file mode 100644 index 0000000000..520316367c --- /dev/null +++ b/ports/esp8266/boards/deploy.md @@ -0,0 +1 @@ +Program your board using the esptool.py program as described [the tutorial](http://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/intro.html#deploying-the-firmware). diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/board.json b/ports/mimxrt/boards/MIMXRT1010_EVK/board.json new file mode 100644 index 0000000000..c865e74f4a --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "mimxrt", + "product": "MIMXRT1010_EVK", + "thumbnail": "", + "url": "", + "vendor": "NXP" +} diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/board.json b/ports/mimxrt/boards/MIMXRT1020_EVK/board.json new file mode 100644 index 0000000000..7930f702b4 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "mimxrt", + "product": "MIMXRT1020_EVK", + "thumbnail": "", + "url": "", + "vendor": "NXP" +} diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/board.json b/ports/mimxrt/boards/MIMXRT1050_EVK/board.json new file mode 100644 index 0000000000..5f04fb29b5 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "mimxrt", + "product": "MIMXRT1050_EVK", + "thumbnail": "", + "url": "", + "vendor": "NXP" +} diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/board.json b/ports/mimxrt/boards/MIMXRT1060_EVK/board.json new file mode 100644 index 0000000000..602b50d7f2 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "mimxrt", + "product": "MIMXRT1060_EVK", + "thumbnail": "", + "url": "", + "vendor": "NXP" +} diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/board.json b/ports/mimxrt/boards/MIMXRT1064_EVK/board.json new file mode 100644 index 0000000000..5830a39f2e --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "mimxrt", + "product": "MIMXRT1064_EVK", + "thumbnail": "", + "url": "", + "vendor": "NXP" +} diff --git a/ports/mimxrt/boards/TEENSY40/board.json b/ports/mimxrt/boards/TEENSY40/board.json new file mode 100644 index 0000000000..25f7690fc0 --- /dev/null +++ b/ports/mimxrt/boards/TEENSY40/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "mimxrt", + "product": "Teensy 4.0", + "thumbnail": "", + "url": "https://www.pjrc.com/store/teensy40.html", + "vendor": "PJRC" +} diff --git a/ports/mimxrt/boards/TEENSY41/board.json b/ports/mimxrt/boards/TEENSY41/board.json new file mode 100644 index 0000000000..9c5c4709a9 --- /dev/null +++ b/ports/mimxrt/boards/TEENSY41/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "mimxrt", + "product": "Teensy 4.1", + "thumbnail": "", + "url": "https://www.pjrc.com/store/teensy41.html", + "vendor": "PJRC" +} diff --git a/ports/mimxrt/boards/deploy.md b/ports/mimxrt/boards/deploy.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ports/nrf/boards/actinius_icarus/board.json b/ports/nrf/boards/actinius_icarus/board.json new file mode 100644 index 0000000000..86e7bd3508 --- /dev/null +++ b/ports/nrf/boards/actinius_icarus/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf91", + "product": "actinius_icarus", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/nrf/boards/arduino_primo/board.json b/ports/nrf/boards/arduino_primo/board.json new file mode 100644 index 0000000000..05439fdfee --- /dev/null +++ b/ports/nrf/boards/arduino_primo/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf52", + "product": "arduino_primo", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/nrf/boards/blueio_tag_evim/board.json b/ports/nrf/boards/blueio_tag_evim/board.json new file mode 100644 index 0000000000..ed178d11da --- /dev/null +++ b/ports/nrf/boards/blueio_tag_evim/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf52", + "product": "blueio_tag_evim", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/nrf/boards/deploy.md b/ports/nrf/boards/deploy.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ports/nrf/boards/dvk_bl652/board.json b/ports/nrf/boards/dvk_bl652/board.json new file mode 100644 index 0000000000..1e2491010f --- /dev/null +++ b/ports/nrf/boards/dvk_bl652/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf52", + "product": "dvk_bl652", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/nrf/boards/evk_nina_b1/board.json b/ports/nrf/boards/evk_nina_b1/board.json new file mode 100644 index 0000000000..a81e961fcc --- /dev/null +++ b/ports/nrf/boards/evk_nina_b1/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf52", + "product": "evk_nina_b1", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/nrf/boards/evk_nina_b3/board.json b/ports/nrf/boards/evk_nina_b3/board.json new file mode 100644 index 0000000000..f71a6eff71 --- /dev/null +++ b/ports/nrf/boards/evk_nina_b3/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf52", + "product": "evk_nina_b3", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/nrf/boards/feather52/board.json b/ports/nrf/boards/feather52/board.json new file mode 100644 index 0000000000..344b880ba5 --- /dev/null +++ b/ports/nrf/boards/feather52/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "4062-02.jpg" + ], + "mcu": "nrf52", + "product": "Feather nRF52840 Express", + "thumbnail": "", + "url": "https://www.adafruit.com/product/4062", + "vendor": "Adafruit" +} diff --git a/ports/nrf/boards/ibk_blyst_nano/board.json b/ports/nrf/boards/ibk_blyst_nano/board.json new file mode 100644 index 0000000000..f641f6b7d2 --- /dev/null +++ b/ports/nrf/boards/ibk_blyst_nano/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf52", + "product": "ibk_blyst_nano", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/nrf/boards/idk_blyst_nano/board.json b/ports/nrf/boards/idk_blyst_nano/board.json new file mode 100644 index 0000000000..07b2748a76 --- /dev/null +++ b/ports/nrf/boards/idk_blyst_nano/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf52", + "product": "idk_blyst_nano", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/nrf/boards/microbit/board.json b/ports/nrf/boards/microbit/board.json new file mode 100644 index 0000000000..b7a041ad4d --- /dev/null +++ b/ports/nrf/boards/microbit/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf51", + "product": "micro:bit v1", + "thumbnail": "", + "url": "https://microbit.org/", + "vendor": "BBC" +} diff --git a/ports/nrf/boards/nrf52840-mdk-usb-dongle/board.json b/ports/nrf/boards/nrf52840-mdk-usb-dongle/board.json new file mode 100644 index 0000000000..bbe03618da --- /dev/null +++ b/ports/nrf/boards/nrf52840-mdk-usb-dongle/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf52", + "product": "nrf52840-mdk-usb-dongle", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/nrf/boards/particle_xenon/board.json b/ports/nrf/boards/particle_xenon/board.json new file mode 100644 index 0000000000..ed1522be5b --- /dev/null +++ b/ports/nrf/boards/particle_xenon/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf52", + "product": "Xenon", + "thumbnail": "", + "url": "", + "vendor": "Particle" +} diff --git a/ports/nrf/boards/pca10000/board.json b/ports/nrf/boards/pca10000/board.json new file mode 100644 index 0000000000..6cae711f07 --- /dev/null +++ b/ports/nrf/boards/pca10000/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf51", + "product": "pca10000", + "thumbnail": "", + "url": "", + "vendor": "Nordic Semiconductor" +} diff --git a/ports/nrf/boards/pca10001/board.json b/ports/nrf/boards/pca10001/board.json new file mode 100644 index 0000000000..9f073b8190 --- /dev/null +++ b/ports/nrf/boards/pca10001/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf51", + "product": "pca10001", + "thumbnail": "", + "url": "", + "vendor": "Nordic Semiconductor" +} diff --git a/ports/nrf/boards/pca10028/board.json b/ports/nrf/boards/pca10028/board.json new file mode 100644 index 0000000000..bda2c4d757 --- /dev/null +++ b/ports/nrf/boards/pca10028/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf51", + "product": "pca10028", + "thumbnail": "", + "url": "", + "vendor": "Nordic Semiconductor" +} diff --git a/ports/nrf/boards/pca10031/board.json b/ports/nrf/boards/pca10031/board.json new file mode 100644 index 0000000000..caba44f328 --- /dev/null +++ b/ports/nrf/boards/pca10031/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf51", + "product": "pca10031", + "thumbnail": "", + "url": "", + "vendor": "Nordic Semiconductor" +} diff --git a/ports/nrf/boards/pca10040/board.json b/ports/nrf/boards/pca10040/board.json new file mode 100644 index 0000000000..55cef41862 --- /dev/null +++ b/ports/nrf/boards/pca10040/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf52", + "product": "pca10040", + "thumbnail": "", + "url": "", + "vendor": "Nordic Semiconductor" +} diff --git a/ports/nrf/boards/pca10056/board.json b/ports/nrf/boards/pca10056/board.json new file mode 100644 index 0000000000..ed9b65baa3 --- /dev/null +++ b/ports/nrf/boards/pca10056/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf52", + "product": "pca10056", + "thumbnail": "", + "url": "", + "vendor": "Nordic Semiconductor" +} diff --git a/ports/nrf/boards/pca10059/board.json b/ports/nrf/boards/pca10059/board.json new file mode 100644 index 0000000000..7b883c007e --- /dev/null +++ b/ports/nrf/boards/pca10059/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "pca10059.jpg" + ], + "mcu": "nrf52", + "product": "pca10059", + "thumbnail": "", + "url": "", + "vendor": "Nordic Semiconductor" +} diff --git a/ports/nrf/boards/pca10090/board.json b/ports/nrf/boards/pca10090/board.json new file mode 100644 index 0000000000..dd2e928e4c --- /dev/null +++ b/ports/nrf/boards/pca10090/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf91", + "product": "pca10090", + "thumbnail": "", + "url": "", + "vendor": "Nordic Semiconductor" +} diff --git a/ports/nrf/boards/wt51822_s4at/board.json b/ports/nrf/boards/wt51822_s4at/board.json new file mode 100644 index 0000000000..3917265a9a --- /dev/null +++ b/ports/nrf/boards/wt51822_s4at/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "nrf51", + "product": "wt51822_s4at", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/rp2/boards/ADAFRUIT_FEATHER_RP2040/board.json b/ports/rp2/boards/ADAFRUIT_FEATHER_RP2040/board.json new file mode 100644 index 0000000000..a4caba335d --- /dev/null +++ b/ports/rp2/boards/ADAFRUIT_FEATHER_RP2040/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "4884-06.jpg" + ], + "mcu": "rp2040", + "product": "Feather RP2040", + "thumbnail": "", + "url": "https://www.adafruit.com/product/4884", + "vendor": "Adafruit" +} diff --git a/ports/rp2/boards/ADAFRUIT_ITSYBITSY_RP2040/board.json b/ports/rp2/boards/ADAFRUIT_ITSYBITSY_RP2040/board.json new file mode 100644 index 0000000000..1dcb999a86 --- /dev/null +++ b/ports/rp2/boards/ADAFRUIT_ITSYBITSY_RP2040/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "4888-05.jpg" + ], + "mcu": "rp2040", + "product": "ItsyBitsy RP2040", + "thumbnail": "", + "url": "https://www.adafruit.com/product/4888", + "vendor": "Adafruit" +} diff --git a/ports/rp2/boards/ADAFRUIT_QTPY_RP2040/board.json b/ports/rp2/boards/ADAFRUIT_QTPY_RP2040/board.json new file mode 100644 index 0000000000..d8efa83be4 --- /dev/null +++ b/ports/rp2/boards/ADAFRUIT_QTPY_RP2040/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "4900-12.jpg" + ], + "mcu": "rp2040", + "product": "QT Py RP2040", + "thumbnail": "", + "url": "https://www.adafruit.com/product/4900", + "vendor": "Adafruit" +} diff --git a/ports/rp2/boards/PICO/board.json b/ports/rp2/boards/PICO/board.json new file mode 100644 index 0000000000..cc933c5a92 --- /dev/null +++ b/ports/rp2/boards/PICO/board.json @@ -0,0 +1,16 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "id": "rp2-pico", + "images": [ + "rp2-pico.jpg" + ], + "mcu": "rp2040", + "product": "Pico", + "thumbnail": "", + "url": "https://www.raspberrypi.org/products/raspberry-pi-pico/", + "vendor": "Raspberry Pi" +} diff --git a/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/board.json b/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/board.json new file mode 100644 index 0000000000..35e18cc8dc --- /dev/null +++ b/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "PimoroniPicoLipo_1of3_1024x1024.jpg" + ], + "mcu": "rp2040", + "product": "Pico LiPo (16MiB)", + "thumbnail": "", + "url": "https://shop.pimoroni.com/products/pimoroni-pico-lipo", + "vendor": "Pimoroni" +} diff --git a/ports/rp2/boards/PIMORONI_PICOLIPO_4MB/board.json b/ports/rp2/boards/PIMORONI_PICOLIPO_4MB/board.json new file mode 100644 index 0000000000..5a8273cb5c --- /dev/null +++ b/ports/rp2/boards/PIMORONI_PICOLIPO_4MB/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "PimoroniPicoLipo_1of3_1024x1024.jpg" + ], + "mcu": "rp2040", + "product": "Pico LiPo (4MiB)", + "thumbnail": "", + "url": "https://shop.pimoroni.com/products/pimoroni-pico-lipo", + "vendor": "Pimoroni" +} diff --git a/ports/rp2/boards/PIMORONI_TINY2040/board.json b/ports/rp2/boards/PIMORONI_TINY2040/board.json new file mode 100644 index 0000000000..cc7e643f41 --- /dev/null +++ b/ports/rp2/boards/PIMORONI_TINY2040/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "tiny-2040-on-white-1_1024x1024.jpg" + ], + "mcu": "rp2040", + "product": "Tiny2040", + "thumbnail": "", + "url": "https://shop.pimoroni.com/products/tiny-2040", + "vendor": "Pimoroni" +} diff --git a/ports/rp2/boards/SPARKFUN_PROMICRO/board.json b/ports/rp2/boards/SPARKFUN_PROMICRO/board.json new file mode 100644 index 0000000000..28e9764fe4 --- /dev/null +++ b/ports/rp2/boards/SPARKFUN_PROMICRO/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "17745-SparkFun_Thing_Plus_-_RP2040-01a.jpg" + ], + "mcu": "rp2040", + "product": "Pro Micro RP2040", + "thumbnail": "", + "url": "https://www.sparkfun.com/products/17717", + "vendor": "Sparkfun" +} diff --git a/ports/rp2/boards/SPARKFUN_THINGPLUS/board.json b/ports/rp2/boards/SPARKFUN_THINGPLUS/board.json new file mode 100644 index 0000000000..d864f67c11 --- /dev/null +++ b/ports/rp2/boards/SPARKFUN_THINGPLUS/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "17745-SparkFun_Thing_Plus_-_RP2040-01a.jpg" + ], + "mcu": "rp2040", + "product": "Thing Plus RP2040", + "thumbnail": "", + "url": "https://www.sparkfun.com/products/17745", + "vendor": "Sparkfun" +} diff --git a/ports/rp2/boards/deploy.md b/ports/rp2/boards/deploy.md new file mode 100644 index 0000000000..4e76dfa290 --- /dev/null +++ b/ports/rp2/boards/deploy.md @@ -0,0 +1,8 @@ +### Flashing via UF2 bootloader + +To get the board in bootloader mode ready for the firmware update, execute +`machine.bootloader()` at the MicroPython REPL. Alternatively, hold +down the BOOTSEL button while plugging the board into USB. The uf2 file below +should then be copied to the USB mass storage device that appears. Once +programming of the new firmware is complete the device will automatically reset +and be ready for use. diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/board.json b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/board.json new file mode 100644 index 0000000000..8b91398e12 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "feather_m0_express.jpg" + ], + "mcu": "samd21", + "product": "Feather M0 Express", + "thumbnail": "", + "url": "https://www.adafruit.com/product/3403", + "vendor": "Adafruit" +} diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/board.json b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/board.json new file mode 100644 index 0000000000..74b278b15b --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "itsybitsy_m4_express.jpg" + ], + "mcu": "samd51", + "product": "ItsyBitsy M4 Express", + "thumbnail": "", + "url": "https://www.adafruit.com/product/3800", + "vendor": "Adafruit" +} diff --git a/ports/samd/boards/ADAFRUIT_TRINKET_M0/board.json b/ports/samd/boards/ADAFRUIT_TRINKET_M0/board.json new file mode 100644 index 0000000000..6d104fac18 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_TRINKET_M0/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "trinket_m0.jpg" + ], + "mcu": "samd21", + "product": "Trinket M0", + "thumbnail": "", + "url": "https://www.adafruit.com/product/3500", + "vendor": "Adafruit" +} diff --git a/ports/samd/boards/MINISAM_M4/board.json b/ports/samd/boards/MINISAM_M4/board.json new file mode 100644 index 0000000000..df63ec64b7 --- /dev/null +++ b/ports/samd/boards/MINISAM_M4/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "mini_sam_m4.jpg" + ], + "mcu": "samd51", + "product": "Mini SAM M4", + "thumbnail": "", + "url": "https://minifigboards.com/products/mini-sam-m4", + "vendor": "MiniFig Boards" +} diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/board.json b/ports/samd/boards/SAMD21_XPLAINED_PRO/board.json new file mode 100644 index 0000000000..0564e3f82a --- /dev/null +++ b/ports/samd/boards/SAMD21_XPLAINED_PRO/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": ["2033-atsamd21-xpro.jpg"], + "mcu": "samd21", + "product": "SAMD21 Xplained Pro", + "thumbnail": "", + "url": "https://www.microchip.com/en-us/development-tool/atsamd21-xpro", + "vendor": "Microchip" +} diff --git a/ports/samd/boards/deploy.md b/ports/samd/boards/deploy.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/board.json b/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/board.json new file mode 100644 index 0000000000..a2cc8b327d --- /dev/null +++ b/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "F405 Express", + "thumbnail": "", + "url": "https://www.adafruit.com/product/4382", + "vendor": "Adafruit" +} diff --git a/ports/stm32/boards/B_L072Z_LRWAN1/board.json b/ports/stm32/boards/B_L072Z_LRWAN1/board.json new file mode 100644 index 0000000000..7eb6981ff3 --- /dev/null +++ b/ports/stm32/boards/B_L072Z_LRWAN1/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32l0", + "product": "B_L072Z_LRWAN1", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/B_L475E_IOT01A/board.json b/ports/stm32/boards/B_L475E_IOT01A/board.json new file mode 100644 index 0000000000..91e76bc08e --- /dev/null +++ b/ports/stm32/boards/B_L475E_IOT01A/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32l4", + "product": "B_L475E_IOT01A", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/CERB40/board.json b/ports/stm32/boards/CERB40/board.json new file mode 100644 index 0000000000..600ccdf2a4 --- /dev/null +++ b/ports/stm32/boards/CERB40/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "CERB40", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/stm32/boards/ESPRUINO_PICO/board.json b/ports/stm32/boards/ESPRUINO_PICO/board.json new file mode 100644 index 0000000000..554687edba --- /dev/null +++ b/ports/stm32/boards/ESPRUINO_PICO/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "Pico_angled.jpg" + ], + "mcu": "stm32f4", + "product": "Pico", + "thumbnail": "", + "url": "https://www.espruino.com/Pico", + "vendor": "Espruino" +} diff --git a/ports/stm32/boards/ESPRUINO_PICO/deploy.md b/ports/stm32/boards/ESPRUINO_PICO/deploy.md new file mode 100644 index 0000000000..5c85668f24 --- /dev/null +++ b/ports/stm32/boards/ESPRUINO_PICO/deploy.md @@ -0,0 +1 @@ +For programming an Espruino Pico see the "Advanced Reflashing" section of [this page](http://www.espruino.com/Pico). diff --git a/ports/stm32/boards/HYDRABUS/board.json b/ports/stm32/boards/HYDRABUS/board.json new file mode 100644 index 0000000000..c3f398f28e --- /dev/null +++ b/ports/stm32/boards/HYDRABUS/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "HYDRABUS", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/stm32/boards/LEGO_HUB_NO6/board.json b/ports/stm32/boards/LEGO_HUB_NO6/board.json new file mode 100644 index 0000000000..c11b9f1818 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "Hub No.6", + "thumbnail": "", + "url": "", + "vendor": "Lego" +} diff --git a/ports/stm32/boards/LIMIFROG/board.json b/ports/stm32/boards/LIMIFROG/board.json new file mode 100644 index 0000000000..d4ce3f41cd --- /dev/null +++ b/ports/stm32/boards/LIMIFROG/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32l4", + "product": "LIMIFROG", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/stm32/boards/MIKROE_CLICKER2_STM32/board.json b/ports/stm32/boards/MIKROE_CLICKER2_STM32/board.json new file mode 100644 index 0000000000..3d7d4904fc --- /dev/null +++ b/ports/stm32/boards/MIKROE_CLICKER2_STM32/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "MIKROE_CLICKER2_STM32", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/stm32/boards/NADHAT_PYBF405/board.json b/ports/stm32/boards/NADHAT_PYBF405/board.json new file mode 100644 index 0000000000..fd4e67c61a --- /dev/null +++ b/ports/stm32/boards/NADHAT_PYBF405/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "PYBF405", + "thumbnail": "", + "url": "", + "vendor": "Nadhat" +} diff --git a/ports/stm32/boards/NETDUINO_PLUS_2/board.json b/ports/stm32/boards/NETDUINO_PLUS_2/board.json new file mode 100644 index 0000000000..88b135bc08 --- /dev/null +++ b/ports/stm32/boards/NETDUINO_PLUS_2/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "NETDUINO_PLUS_2", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/stm32/boards/NUCLEO_F091RC/board.json b/ports/stm32/boards/NUCLEO_F091RC/board.json new file mode 100644 index 0000000000..1cabbce5c8 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_F091RC/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f0", + "product": "Nucleo F091RC", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_F401RE/board.json b/ports/stm32/boards/NUCLEO_F401RE/board.json new file mode 100644 index 0000000000..91ae8b49cf --- /dev/null +++ b/ports/stm32/boards/NUCLEO_F401RE/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "Nucleo F401RE", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_F411RE/board.json b/ports/stm32/boards/NUCLEO_F411RE/board.json new file mode 100644 index 0000000000..c2d4ad4e2f --- /dev/null +++ b/ports/stm32/boards/NUCLEO_F411RE/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "Nucleo F411RE", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_F412ZG/board.json b/ports/stm32/boards/NUCLEO_F412ZG/board.json new file mode 100644 index 0000000000..bddc1e6d67 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_F412ZG/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "Nucleo F412ZG", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_F413ZH/board.json b/ports/stm32/boards/NUCLEO_F413ZH/board.json new file mode 100644 index 0000000000..4a08c9f5e2 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_F413ZH/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "Nucleo F413ZH", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_F429ZI/board.json b/ports/stm32/boards/NUCLEO_F429ZI/board.json new file mode 100644 index 0000000000..7c2767da4d --- /dev/null +++ b/ports/stm32/boards/NUCLEO_F429ZI/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "Nucleo F429ZI", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_F439ZI/board.json b/ports/stm32/boards/NUCLEO_F439ZI/board.json new file mode 100644 index 0000000000..8daac091f1 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_F439ZI/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "Nucleo F439ZI", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_F446RE/board.json b/ports/stm32/boards/NUCLEO_F446RE/board.json new file mode 100644 index 0000000000..3cbf34d6aa --- /dev/null +++ b/ports/stm32/boards/NUCLEO_F446RE/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "Nucleo F446RE", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_F722ZE/board.json b/ports/stm32/boards/NUCLEO_F722ZE/board.json new file mode 100644 index 0000000000..fe318edfa3 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_F722ZE/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f7", + "product": "Nucleo F722ZE", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_F746ZG/board.json b/ports/stm32/boards/NUCLEO_F746ZG/board.json new file mode 100644 index 0000000000..7aee7b05a6 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_F746ZG/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f7", + "product": "Nucleo F746ZG", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_F767ZI/board.json b/ports/stm32/boards/NUCLEO_F767ZI/board.json new file mode 100644 index 0000000000..936ad53dd7 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_F767ZI/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f7", + "product": "Nucleo F767ZI", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_H743ZI/board.json b/ports/stm32/boards/NUCLEO_H743ZI/board.json new file mode 100644 index 0000000000..27b8e901ce --- /dev/null +++ b/ports/stm32/boards/NUCLEO_H743ZI/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32h7", + "product": "Nucleo H743ZI", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_H743ZI2/board.json b/ports/stm32/boards/NUCLEO_H743ZI2/board.json new file mode 100644 index 0000000000..30361e6f15 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_H743ZI2/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32", + "product": "Nucleo H743ZI2", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_L073RZ/board.json b/ports/stm32/boards/NUCLEO_L073RZ/board.json new file mode 100644 index 0000000000..c11bad6d94 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_L073RZ/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32l0", + "product": "Nucleo L073RZ", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_L432KC/board.json b/ports/stm32/boards/NUCLEO_L432KC/board.json new file mode 100644 index 0000000000..3300603885 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_L432KC/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32l4", + "product": "Nucleo L432KC", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_L452RE/board.json b/ports/stm32/boards/NUCLEO_L452RE/board.json new file mode 100644 index 0000000000..e8c31c5023 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_L452RE/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32l4", + "product": "Nucleo L452RE", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_L476RG/board.json b/ports/stm32/boards/NUCLEO_L476RG/board.json new file mode 100644 index 0000000000..d776f6615e --- /dev/null +++ b/ports/stm32/boards/NUCLEO_L476RG/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32l4", + "product": "Nucleo L476RG", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_WB55/board.json b/ports/stm32/boards/NUCLEO_WB55/board.json new file mode 100644 index 0000000000..2456b0b3a0 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_WB55/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32wb", + "product": "Nucleo WB55", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/OLIMEX_E407/board.json b/ports/stm32/boards/OLIMEX_E407/board.json new file mode 100644 index 0000000000..d4e0fda98c --- /dev/null +++ b/ports/stm32/boards/OLIMEX_E407/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "E407", + "thumbnail": "", + "url": "", + "vendor": "OLIMEX" +} diff --git a/ports/stm32/boards/OLIMEX_H407/board.json b/ports/stm32/boards/OLIMEX_H407/board.json new file mode 100644 index 0000000000..d4e0fda98c --- /dev/null +++ b/ports/stm32/boards/OLIMEX_H407/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "E407", + "thumbnail": "", + "url": "", + "vendor": "OLIMEX" +} diff --git a/ports/stm32/boards/PYBD_SF2/board.json b/ports/stm32/boards/PYBD_SF2/board.json new file mode 100644 index 0000000000..534a048ff0 --- /dev/null +++ b/ports/stm32/boards/PYBD_SF2/board.json @@ -0,0 +1,21 @@ +{ + "deploy": [ + "deploy.md" + ], + "docs": "", + "features": [], + "id": "PYBD-SF2", + "images": [ + "PYBD_SF2_W4F2.jpg", + "PYBD_SF2_W4F2_top.jpg", + "PYBD_SF2_W4F2_bot.jpg", + "PYBD_SF2_W4F2_ds1.jpg", + "PYBD_SF2_W4F2_ds2.jpg", + "PYBD_SF2_W4F2_ds3.jpg" + ], + "mcu": "stm32f7", + "product": "Pyboard D-series SF2", + "thumbnail": "", + "url": "https://store.micropython.org/product/PYBD-SF2-W4F2", + "vendor": "George Robotics" +} diff --git a/ports/stm32/boards/PYBD_SF2/board.md b/ports/stm32/boards/PYBD_SF2/board.md new file mode 100644 index 0000000000..f1074df1a5 --- /dev/null +++ b/ports/stm32/boards/PYBD_SF2/board.md @@ -0,0 +1 @@ +Firmware can be found in the sections below, which is built daily from the ports/stm32/ directory of MicroPython. Check which model you have by the sticker on the top. diff --git a/ports/stm32/boards/PYBD_SF2/deploy.md b/ports/stm32/boards/PYBD_SF2/deploy.md new file mode 100644 index 0000000000..afef7b148d --- /dev/null +++ b/ports/stm32/boards/PYBD_SF2/deploy.md @@ -0,0 +1,3 @@ +### Pyboard-D via mboot + +For the pyboard D-series you can enter the mboot DFU bootloader by executing `machine.bootloader()` at the MicroPython REPL. Alternatively, mboot can be entered by holding down the USR button, pressing and releasing the RST button, and continuing to hold down USR until the LED is white (4th in the cycle), then let go of USR while the LED is white. The LED will then flash red once per second to indicate it is in USB DFU mode. You can then program the firmware using a DFU programmer, eg [dfu-util](http://dfu-util.sourceforge.net/) or [pydfu.py](https://github.com/micropython/micropython/blob/master/tools/pydfu.py). diff --git a/ports/stm32/boards/PYBD_SF3/board.json b/ports/stm32/boards/PYBD_SF3/board.json new file mode 100644 index 0000000000..3e4731b3d2 --- /dev/null +++ b/ports/stm32/boards/PYBD_SF3/board.json @@ -0,0 +1,21 @@ +{ + "deploy": [ + "../PYBD_SF2/deploy.md" + ], + "docs": "", + "features": [], + "id": "PYBD-SF3", + "images": [ + "PYBD_SF3_W4F2.jpg", + "PYBD_SF3_W4F2_top.jpg", + "PYBD_SF2_W4F2_bot.jpg", + "PYBD_SF3_W4F2_ds1.jpg", + "PYBD_SF3_W4F2_ds2.jpg", + "PYBD_SF3_W4F2_ds3.jpg" + ], + "mcu": "stm32f7", + "product": "Pyboard D-series SF3", + "thumbnail": "", + "url": "https://store.micropython.org/product/PYBD-SF3-W4F2", + "vendor": "George Robotics" +} diff --git a/ports/stm32/boards/PYBD_SF3/board.md b/ports/stm32/boards/PYBD_SF3/board.md new file mode 100644 index 0000000000..f1074df1a5 --- /dev/null +++ b/ports/stm32/boards/PYBD_SF3/board.md @@ -0,0 +1 @@ +Firmware can be found in the sections below, which is built daily from the ports/stm32/ directory of MicroPython. Check which model you have by the sticker on the top. diff --git a/ports/stm32/boards/PYBD_SF6/board.json b/ports/stm32/boards/PYBD_SF6/board.json new file mode 100644 index 0000000000..3e689d69be --- /dev/null +++ b/ports/stm32/boards/PYBD_SF6/board.json @@ -0,0 +1,24 @@ +{ + "deploy": [ + "../PYBD_SF2/deploy.md" + ], + "docs": "", + "features": [ + "WiFi", + "BLE" + ], + "id": "PYBD-SF6", + "images": [ + "PYBD_SF6_W4F2.jpg", + "PYBD_SF6_W4F2_top.jpg", + "PYBD_SF2_W4F2_bot.jpg", + "PYBD_SF6_W4F2_ds1.jpg", + "PYBD_SF6_W4F2_ds2.jpg", + "PYBD_SF6_W4F2_ds3.jpg" + ], + "mcu": "stm32f7", + "product": "Pyboard D-series SF6", + "thumbnail": "", + "url": "https://store.micropython.org/product/PYBD-SF6-W4F2", + "vendor": "George Robotics" +} diff --git a/ports/stm32/boards/PYBD_SF6/board.md b/ports/stm32/boards/PYBD_SF6/board.md new file mode 100644 index 0000000000..f1074df1a5 --- /dev/null +++ b/ports/stm32/boards/PYBD_SF6/board.md @@ -0,0 +1 @@ +Firmware can be found in the sections below, which is built daily from the ports/stm32/ directory of MicroPython. Check which model you have by the sticker on the top. diff --git a/ports/stm32/boards/PYBLITEV10/board.json b/ports/stm32/boards/PYBLITEV10/board.json new file mode 100644 index 0000000000..ce98ba7de7 --- /dev/null +++ b/ports/stm32/boards/PYBLITEV10/board.json @@ -0,0 +1,24 @@ +{ + "deploy": [ + "../PYBV10/deploy.md" + ], + "docs": "", + "features": [], + "id": "pyblitev10", + "images": [ + "PYBLITEv1_0.jpg", + "PYBLITEv1_0-B.jpg", + "PYBLITEv1_0-C.jpg" + ], + "mcu": "stm32f4", + "product": "Pyboard Lite v1.0", + "thumbnail": "", + "url": "https://store.micropython.org/product/PYBLITEv1.0", + "variants": { + "dp": "Double-precision float", + "dp-thread": "Double precision float + Threads", + "network": "Wiznet 5200 Driver", + "thread": "Threading" + }, + "vendor": "George Robotics" +} diff --git a/ports/stm32/boards/PYBLITEV10/board.md b/ports/stm32/boards/PYBLITEV10/board.md new file mode 100644 index 0000000000..1511ffcf51 --- /dev/null +++ b/ports/stm32/boards/PYBLITEV10/board.md @@ -0,0 +1 @@ +The "standard" build is listed first and is the default firmware that the pyboards are shipped with. Use this firmware if you are uncertain. The "double FP" builds use double-precision floating point instead of the standard single precision. The "threading" builds contain the \_thread module and allow multithreading. The "network" builds have network drivers for CC3000 and WIZ820io included. All these different firmware are completely interchangeable and you can freely change from one to the other without losing the filesystem on your pyboard. diff --git a/ports/stm32/boards/PYBV10/board.json b/ports/stm32/boards/PYBV10/board.json new file mode 100644 index 0000000000..2907b8fc45 --- /dev/null +++ b/ports/stm32/boards/PYBV10/board.json @@ -0,0 +1,22 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "id": "pybv10", + "images": [ + "PYBv1_0-C.jpg" + ], + "mcu": "stm32f4", + "product": "Pyboard v1.0", + "thumbnail": "", + "url": "", + "variants": { + "dp": "Double-precision float", + "dp-thread": "Double precision float + Threads", + "network": "Wiznet 5200 Driver", + "thread": "Threading" + }, + "vendor": "George Robotics" +} diff --git a/ports/stm32/boards/PYBV10/board.md b/ports/stm32/boards/PYBV10/board.md new file mode 100644 index 0000000000..1511ffcf51 --- /dev/null +++ b/ports/stm32/boards/PYBV10/board.md @@ -0,0 +1 @@ +The "standard" build is listed first and is the default firmware that the pyboards are shipped with. Use this firmware if you are uncertain. The "double FP" builds use double-precision floating point instead of the standard single precision. The "threading" builds contain the \_thread module and allow multithreading. The "network" builds have network drivers for CC3000 and WIZ820io included. All these different firmware are completely interchangeable and you can freely change from one to the other without losing the filesystem on your pyboard. diff --git a/ports/stm32/boards/PYBV10/deploy.md b/ports/stm32/boards/PYBV10/deploy.md new file mode 100644 index 0000000000..d7c21999e7 --- /dev/null +++ b/ports/stm32/boards/PYBV10/deploy.md @@ -0,0 +1,6 @@ +### Pyboard v1.x via DFU + +One you have downloaded the appropriate DFU file it can be flashed directly to your pyboard +using a DFU programmer. You can enter the DFU bootloader on the pyboard by executing `machine.bootloader()` at the MicroPython REPL. + +Alternatively, connect 3V3 with BOOT0 and reset the board. For information about DFU programming on Windows see [this PDF](http://micropython.org/resources/Micro-Python-Windows-setup.pdf). For Linux and Mac see [here](https://github.com/micropython/micropython/wiki/Pyboard-Firmware-Update). diff --git a/ports/stm32/boards/PYBV11/board.json b/ports/stm32/boards/PYBV11/board.json new file mode 100644 index 0000000000..fe59a7b16d --- /dev/null +++ b/ports/stm32/boards/PYBV11/board.json @@ -0,0 +1,24 @@ +{ + "deploy": [ + "../PYBV10/deploy.md" + ], + "docs": "", + "features": [], + "id": "pybv11", + "images": [ + "PYBv1_1.jpg", + "PYBv1_1-C.jpg", + "PYBv1_1-E.jpg" + ], + "mcu": "stm32f4", + "product": "Pyboard v1.1", + "thumbnail": "", + "url": "https://store.micropython.org/product/PYBv1.1", + "variants": { + "dp": "Double-precision float", + "dp-thread": "Double precision float + Threads", + "network": "Wiznet 5200 Driver", + "thread": "Threading" + }, + "vendor": "George Robotics" +} diff --git a/ports/stm32/boards/PYBV11/board.md b/ports/stm32/boards/PYBV11/board.md new file mode 100644 index 0000000000..1511ffcf51 --- /dev/null +++ b/ports/stm32/boards/PYBV11/board.md @@ -0,0 +1 @@ +The "standard" build is listed first and is the default firmware that the pyboards are shipped with. Use this firmware if you are uncertain. The "double FP" builds use double-precision floating point instead of the standard single precision. The "threading" builds contain the \_thread module and allow multithreading. The "network" builds have network drivers for CC3000 and WIZ820io included. All these different firmware are completely interchangeable and you can freely change from one to the other without losing the filesystem on your pyboard. diff --git a/ports/stm32/boards/SPARKFUN_MICROMOD_STM32/board.json b/ports/stm32/boards/SPARKFUN_MICROMOD_STM32/board.json new file mode 100644 index 0000000000..0c1bba8ee7 --- /dev/null +++ b/ports/stm32/boards/SPARKFUN_MICROMOD_STM32/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "Micromod STM32", + "thumbnail": "", + "url": "", + "vendor": "Sparkfun" +} diff --git a/ports/stm32/boards/STM32F411DISC/board.json b/ports/stm32/boards/STM32F411DISC/board.json new file mode 100644 index 0000000000..42516178a0 --- /dev/null +++ b/ports/stm32/boards/STM32F411DISC/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "Discovery F411", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/STM32F429DISC/board.json b/ports/stm32/boards/STM32F429DISC/board.json new file mode 100644 index 0000000000..8842e004d1 --- /dev/null +++ b/ports/stm32/boards/STM32F429DISC/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "Discovery F429", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/STM32F439/board.json b/ports/stm32/boards/STM32F439/board.json new file mode 100644 index 0000000000..e941244e7e --- /dev/null +++ b/ports/stm32/boards/STM32F439/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "STM32F439", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/stm32/boards/STM32F4DISC/board.json b/ports/stm32/boards/STM32F4DISC/board.json new file mode 100644 index 0000000000..7c4fea38b2 --- /dev/null +++ b/ports/stm32/boards/STM32F4DISC/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "Discovery F4", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/STM32F769DISC/board.json b/ports/stm32/boards/STM32F769DISC/board.json new file mode 100644 index 0000000000..68584e9501 --- /dev/null +++ b/ports/stm32/boards/STM32F769DISC/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f7", + "product": "Discovery F769", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/STM32F7DISC/board.json b/ports/stm32/boards/STM32F7DISC/board.json new file mode 100644 index 0000000000..4b83f20f2d --- /dev/null +++ b/ports/stm32/boards/STM32F7DISC/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f7", + "product": "Discovery F7", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/STM32H7B3I_DK/board.json b/ports/stm32/boards/STM32H7B3I_DK/board.json new file mode 100644 index 0000000000..4d03c72917 --- /dev/null +++ b/ports/stm32/boards/STM32H7B3I_DK/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32h7", + "product": "Discovery Kit H7", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/STM32L476DISC/board.json b/ports/stm32/boards/STM32L476DISC/board.json new file mode 100644 index 0000000000..b8a4f92efd --- /dev/null +++ b/ports/stm32/boards/STM32L476DISC/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32l4", + "product": "Discovery L476", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/STM32L496GDISC/board.json b/ports/stm32/boards/STM32L496GDISC/board.json new file mode 100644 index 0000000000..b152948c1a --- /dev/null +++ b/ports/stm32/boards/STM32L496GDISC/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32l4", + "product": "Discovery L496G", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/USBDONGLE_WB55/board.json b/ports/stm32/boards/USBDONGLE_WB55/board.json new file mode 100644 index 0000000000..00d9121881 --- /dev/null +++ b/ports/stm32/boards/USBDONGLE_WB55/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32wb", + "product": "USBDONGLE_WB55", + "thumbnail": "", + "url": "", + "vendor": "" +} diff --git a/ports/stm32/boards/VCC_GND_F407VE/board.json b/ports/stm32/boards/VCC_GND_F407VE/board.json new file mode 100644 index 0000000000..1b2d02b9f2 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407VE/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "F407VE", + "thumbnail": "", + "url": "http://vcc-gnd.com/", + "vendor": "VCC-GND Studio" +} diff --git a/ports/stm32/boards/VCC_GND_F407ZG/board.json b/ports/stm32/boards/VCC_GND_F407ZG/board.json new file mode 100644 index 0000000000..0d3cbdb6e0 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407ZG/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "F407ZG", + "thumbnail": "", + "url": "http://vcc-gnd.com/", + "vendor": "VCC-GND Studio" +} diff --git a/ports/stm32/boards/VCC_GND_H743VI/board.json b/ports/stm32/boards/VCC_GND_H743VI/board.json new file mode 100644 index 0000000000..3dfd138ed9 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_H743VI/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32h7", + "product": "H743VI", + "thumbnail": "", + "url": "http://vcc-gnd.com/", + "vendor": "VCC-GND Studio" +} diff --git a/ports/stm32/boards/deploy.md b/ports/stm32/boards/deploy.md new file mode 100644 index 0000000000..db2b4ef3ab --- /dev/null +++ b/ports/stm32/boards/deploy.md @@ -0,0 +1,31 @@ +### STM32 via ST-Link + +Nucleo and Discovery boards typically include a built-in ST-Link programmer. + +A `.bin` or `.hex` file can be flashed using [st-flash](https://github.com/stlink-org/stlink). + +```bash +# Optional erase to clear existing filesystem. +st-flash erase + +# Flash .bin +st-flash write firmware.bin 0x08000000 +# or, flash .hex +st-flash --format ihex write firmware.hex +``` + +A `.hex` file can be flashed using [STM32 Cube Programmer](https://www.st.com/en/development-tools/stm32cubeprog.html). + +```bash +STM32_Programmer.sh -c port=SWD -d firmware.hex -hardRst +``` + +### STM32 via DFU + +Boards with USB support can also be programmed via the ST DFU bootloader, using e.g. [dfu-util](http://dfu-util.sourceforge.net/) or [pydfu.py](https://github.com/micropython/micropython/blob/master/tools/pydfu.py). + +To enter the bootloader the `BOOT0` pin can be connected to `VCC` during reset, or you can use `machine.bootloader()` from the MicroPython REPL. + +```bash +dfu-util --alt 0 -D firmware.dfu +``` From ab754d5924168d027bfc2eeed7881b9b2e469535 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 19 Oct 2021 16:34:09 +1100 Subject: [PATCH 114/335] tools/autobuild: Add script to generate website board metadata. Signed-off-by: Jim Mussared --- tools/autobuild/build-downloads.py | 58 ++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100755 tools/autobuild/build-downloads.py diff --git a/tools/autobuild/build-downloads.py b/tools/autobuild/build-downloads.py new file mode 100755 index 0000000000..0f532e8bf0 --- /dev/null +++ b/tools/autobuild/build-downloads.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +import glob +import json +import os +import sys + + +def main(repo_path, output_path): + boards_index = [] + board_ids = set() + + for board_json in glob.glob(os.path.join(repo_path, "ports/*/boards/*/board.json")): + # Relative path to the board directory (e.g. "ports/stm32/boards/PYBV11"). + board_dir = os.path.dirname(board_json) + # Relative path to the port (e.g. "ports/stm32") + port_dir = os.path.dirname(os.path.dirname(board_dir)) + + with open(board_json, "r") as f: + blob = json.load(f) + + # Use "id" if specified, otherwise default to board dir (e.g. "PYBV11"). + # We allow boards to override ID for the historical build names. + blob["id"] = blob.get("id", os.path.basename(board_dir)) + + # Check for duplicate board IDs. + if blob["id"] in board_ids: + print("Duplicate board ID: '{}'".format(blob["id"]), file=sys.stderr) + board_ids.add(blob["id"]) + + # Add in default fields. + blob["port"] = os.path.basename(port_dir) + blob["build"] = os.path.basename(board_dir) + boards_index.append(blob) + + # Create the board markdown, which is the concatenation of the + # default "board.md" file (if exists), as well as any flashing + # instructions. + board_markdown = os.path.join(board_dir, "board.md") + with open(os.path.join(output_path, blob["id"] + ".md"), "w") as f: + if os.path.exists(board_markdown): + with open(board_markdown, "r") as fin: + f.write(fin.read()) + + if blob["deploy"]: + f.write("\n\n## Installation instructions\n") + for deploy in blob["deploy"]: + with open(os.path.join(board_dir, deploy), "r") as fin: + f.write(fin.read()) + + # Write the full index for the website to load. + with open(os.path.join(output_path, "index.json"), "w") as f: + json.dump(boards_index, f, indent=4, sort_keys=True) + f.write("\n") + + +if __name__ == "__main__": + main(sys.argv[1], sys.argv[2]) From 910e9f9111606b32165b3c57eb54384d8367c4c2 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 27 Oct 2021 14:56:59 +1100 Subject: [PATCH 115/335] esp32: Add specific deploy_s2.md instructions for esp32-s2. In particular the UM S2 boards (and update the features list). Signed-off-by: Jim Mussared --- ports/esp32/boards/GENERIC_S2/board.json | 2 +- ports/esp32/boards/LOLIN_S2_MINI/board.json | 2 +- ports/esp32/boards/UM_FEATHERS2/board.json | 3 +-- ports/esp32/boards/UM_FEATHERS2NEO/board.json | 3 +-- ports/esp32/boards/UM_TINYS2/board.json | 7 +++++-- ports/esp32/boards/deploy.md | 1 + ports/esp32/boards/deploy_s2.md | 14 ++++++++++++++ 7 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 ports/esp32/boards/deploy_s2.md diff --git a/ports/esp32/boards/GENERIC_S2/board.json b/ports/esp32/boards/GENERIC_S2/board.json index 4ecb90a48a..5e1758b86a 100644 --- a/ports/esp32/boards/GENERIC_S2/board.json +++ b/ports/esp32/boards/GENERIC_S2/board.json @@ -1,6 +1,6 @@ { "deploy": [ - "../deploy.md" + "../deploy_s2.md" ], "docs": "", "features": [], diff --git a/ports/esp32/boards/LOLIN_S2_MINI/board.json b/ports/esp32/boards/LOLIN_S2_MINI/board.json index 5e866f0e59..a84a3098bf 100644 --- a/ports/esp32/boards/LOLIN_S2_MINI/board.json +++ b/ports/esp32/boards/LOLIN_S2_MINI/board.json @@ -1,6 +1,6 @@ { "deploy": [ - "../deploy.md" + "../deploy_s2.md" ], "docs": "", "features": [], diff --git a/ports/esp32/boards/UM_FEATHERS2/board.json b/ports/esp32/boards/UM_FEATHERS2/board.json index bbfd389004..d2da16a6ee 100644 --- a/ports/esp32/boards/UM_FEATHERS2/board.json +++ b/ports/esp32/boards/UM_FEATHERS2/board.json @@ -1,10 +1,9 @@ { "deploy": [ - "../deploy.md" + "../deploy_s2.md" ], "docs": "", "features": [ - "BLE", "WiFi", "Feather", "Battery Charging", diff --git a/ports/esp32/boards/UM_FEATHERS2NEO/board.json b/ports/esp32/boards/UM_FEATHERS2NEO/board.json index 1bcc2a4b22..1e3e2c0e3b 100644 --- a/ports/esp32/boards/UM_FEATHERS2NEO/board.json +++ b/ports/esp32/boards/UM_FEATHERS2NEO/board.json @@ -1,10 +1,9 @@ { "deploy": [ - "../deploy.md" + "../deploy_s2.md" ], "docs": "", "features": [ - "BLE", "WiFi", "Feather", "Battery Charging", diff --git a/ports/esp32/boards/UM_TINYS2/board.json b/ports/esp32/boards/UM_TINYS2/board.json index bc694c2cca..d378f6b9d8 100644 --- a/ports/esp32/boards/UM_TINYS2/board.json +++ b/ports/esp32/boards/UM_TINYS2/board.json @@ -1,9 +1,12 @@ { "deploy": [ - "../deploy.md" + "../deploy_s2.md" ], "docs": "", - "features": [], + "features": [ + "WiFi", + "USB-C" + ], "id": "tinys2", "images": [ "TinyS2+Product+Shot.jpg" diff --git a/ports/esp32/boards/deploy.md b/ports/esp32/boards/deploy.md index c8740a8dd4..64e683edfc 100644 --- a/ports/esp32/boards/deploy.md +++ b/ports/esp32/boards/deploy.md @@ -1,4 +1,5 @@ Program your board using the esptool.py program, found [here](https://github.com/espressif/esptool). + If you are putting MicroPython on your board for the first time then you should first erase the entire flash using: diff --git a/ports/esp32/boards/deploy_s2.md b/ports/esp32/boards/deploy_s2.md new file mode 100644 index 0000000000..5b3057087d --- /dev/null +++ b/ports/esp32/boards/deploy_s2.md @@ -0,0 +1,14 @@ +Program your board using the esptool.py program, found [here](https://github.com/espressif/esptool). + +If you are putting MicroPython on your board for the first time then you should +first erase the entire flash using: + +```bash +esptool.py --chip esp32s2 --port /dev/ttyACM0 erase_flash +``` + +From then on program the firmware starting at address 0x1000: + +```bash +esptool.py --chip esp32s2 --port /dev/ttyACM0 write_flash -z 0x1000 board-20210902-v1.17.bin +``` From 5bb14c4e461932230e572e6baa9aafd1eea26e91 Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Wed, 27 Oct 2021 16:19:01 +1100 Subject: [PATCH 116/335] esp32/boards/LOLIN_S2_MINI: Add image to board.json. --- ports/esp32/boards/LOLIN_S2_MINI/board.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ports/esp32/boards/LOLIN_S2_MINI/board.json b/ports/esp32/boards/LOLIN_S2_MINI/board.json index a84a3098bf..50e24ff3f9 100644 --- a/ports/esp32/boards/LOLIN_S2_MINI/board.json +++ b/ports/esp32/boards/LOLIN_S2_MINI/board.json @@ -4,7 +4,9 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "lolin_s2_mini.jpg" + ], "mcu": "esp32s2", "product": "S2 mini", "thumbnail": "", From 590ec2ca6e2404129c5b4568feeee69bd28d5bfa Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Wed, 27 Oct 2021 16:18:27 +1100 Subject: [PATCH 117/335] stm32/boards: Add images to board.json for Adafruit and VCC_GND boards. --- ports/stm32/boards/ADAFRUIT_F405_EXPRESS/board.json | 4 +++- ports/stm32/boards/VCC_GND_F407VE/board.json | 4 +++- ports/stm32/boards/VCC_GND_F407ZG/board.json | 4 +++- ports/stm32/boards/VCC_GND_H743VI/board.json | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/board.json b/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/board.json index a2cc8b327d..698e666f29 100644 --- a/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/board.json +++ b/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/board.json @@ -4,7 +4,9 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "4382-09.jpg" + ], "mcu": "stm32f4", "product": "F405 Express", "thumbnail": "", diff --git a/ports/stm32/boards/VCC_GND_F407VE/board.json b/ports/stm32/boards/VCC_GND_F407VE/board.json index 1b2d02b9f2..11e12ff97b 100644 --- a/ports/stm32/boards/VCC_GND_F407VE/board.json +++ b/ports/stm32/boards/VCC_GND_F407VE/board.json @@ -4,7 +4,9 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "STM32F407VET6.jpg" + ], "mcu": "stm32f4", "product": "F407VE", "thumbnail": "", diff --git a/ports/stm32/boards/VCC_GND_F407ZG/board.json b/ports/stm32/boards/VCC_GND_F407ZG/board.json index 0d3cbdb6e0..bf0352b2d0 100644 --- a/ports/stm32/boards/VCC_GND_F407ZG/board.json +++ b/ports/stm32/boards/VCC_GND_F407ZG/board.json @@ -4,7 +4,9 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "STM32F407ZGT6.jpg" + ], "mcu": "stm32f4", "product": "F407ZG", "thumbnail": "", diff --git a/ports/stm32/boards/VCC_GND_H743VI/board.json b/ports/stm32/boards/VCC_GND_H743VI/board.json index 3dfd138ed9..f7539ac9f9 100644 --- a/ports/stm32/boards/VCC_GND_H743VI/board.json +++ b/ports/stm32/boards/VCC_GND_H743VI/board.json @@ -4,7 +4,9 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "STM32H743VIT6.jpg" + ], "mcu": "stm32h7", "product": "H743VI", "thumbnail": "", From 5b9c9cd0971fda60e7e6375c17bda32d3a3407d6 Mon Sep 17 00:00:00 2001 From: Seon Rozenblum Date: Wed, 27 Oct 2021 16:10:16 +1100 Subject: [PATCH 118/335] esp32/boards: Update board and deploy metadata for UM_xxx boards. --- ports/esp32/boards/UM_FEATHERS2/board.json | 9 +++- ports/esp32/boards/UM_FEATHERS2/board.md | 2 + ports/esp32/boards/UM_FEATHERS2/deploy.md | 50 +++++++++++++++++++ ports/esp32/boards/UM_FEATHERS2NEO/board.json | 12 +++-- ports/esp32/boards/UM_FEATHERS2NEO/board.md | 2 + ports/esp32/boards/UM_FEATHERS2NEO/deploy.md | 50 +++++++++++++++++++ ports/esp32/boards/UM_TINYPICO/board.json | 14 +++++- ports/esp32/boards/UM_TINYPICO/board.md | 3 ++ ports/esp32/boards/UM_TINYPICO/deploy.md | 46 +++++++++++++++++ ports/esp32/boards/UM_TINYS2/board.json | 10 +++- ports/esp32/boards/UM_TINYS2/board.md | 2 + ports/esp32/boards/UM_TINYS2/deploy.md | 50 +++++++++++++++++++ 12 files changed, 242 insertions(+), 8 deletions(-) create mode 100644 ports/esp32/boards/UM_FEATHERS2/board.md create mode 100644 ports/esp32/boards/UM_FEATHERS2/deploy.md create mode 100644 ports/esp32/boards/UM_FEATHERS2NEO/board.md create mode 100644 ports/esp32/boards/UM_FEATHERS2NEO/deploy.md create mode 100644 ports/esp32/boards/UM_TINYPICO/board.md create mode 100644 ports/esp32/boards/UM_TINYPICO/deploy.md create mode 100644 ports/esp32/boards/UM_TINYS2/board.md create mode 100644 ports/esp32/boards/UM_TINYS2/deploy.md diff --git a/ports/esp32/boards/UM_FEATHERS2/board.json b/ports/esp32/boards/UM_FEATHERS2/board.json index d2da16a6ee..19d7219ec5 100644 --- a/ports/esp32/boards/UM_FEATHERS2/board.json +++ b/ports/esp32/boards/UM_FEATHERS2/board.json @@ -1,6 +1,6 @@ { "deploy": [ - "../deploy_s2.md" + "deploy.md" ], "docs": "", "features": [ @@ -8,7 +8,12 @@ "Feather", "Battery Charging", "STEMMA QT/QWIIC", - "USB-C" + "USB-C", + "RGB LED", + "SPIRAM" + ], + "features_non_filterable": [ + "Second LDO" ], "id": "featherS2", "images": [ diff --git a/ports/esp32/boards/UM_FEATHERS2/board.md b/ports/esp32/boards/UM_FEATHERS2/board.md new file mode 100644 index 0000000000..e04a8936c8 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2/board.md @@ -0,0 +1,2 @@ +The following files are daily firmware for the FeatherS2. This firmware is +compiled using ESP-IDF v4.3 or later. diff --git a/ports/esp32/boards/UM_FEATHERS2/deploy.md b/ports/esp32/boards/UM_FEATHERS2/deploy.md new file mode 100644 index 0000000000..24bced3cda --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2/deploy.md @@ -0,0 +1,50 @@ +Program your board using the esptool.py program, found [here](https://github.com/espressif/esptool). + +To flash or erase your FeatherS2, you have to first put it into download mode. +To do this, follow these steps: + +- Press and hold the [BOOT] button +- Press and release the [RESET] button +- Release the [BOOT] button + +Now the board is in download mode and the native USB will have enumerated as a serial device. + +If you are putting MicroPython on your board for the first time then you should +first erase the entire flash using: + +### Linux +```bash +esptool.py --chip esp32s2 --port /dev/ttyACM0 erase_flash +``` + +### Mac +```bash +esptool.py --chip esp32s2 --port /dev/cu.usbmodem01 erase_flash +``` + +### Windows +Change (X) to whatever COM port is being used by the board +```bash +esptool --chip esp32s2 --port COM(X) erase_flash +``` + +Now download the version of the firmware you would like to install from the options +below, then use the following command to program the firmware starting at address +0x1000, remembering to replace `feathers2-micropython-firmware-version.bin` with the +name of the firmware you just downloaded: + +### Linux +```bash +esptool.py --chip esp32s2 --port /dev/ttyACM0 write_flash -z 0x1000 feathers2-micropython-firmware-version.bin +``` + +### Mac +```bash +esptool.py --chip esp32s2 --port /dev/cu.usbmodem01 write_flash -z 0x1000 feathers2-micropython-firmware-version.bin +``` + +### Windows +Change (X) to whatever COM port is being used by the board +```bash +esptool --chip esp32s2 --port COM(X) write_flash -z 0x1000 feathers2-micropython-firmware-version.bin +``` diff --git a/ports/esp32/boards/UM_FEATHERS2NEO/board.json b/ports/esp32/boards/UM_FEATHERS2NEO/board.json index 1e3e2c0e3b..be7a1371fa 100644 --- a/ports/esp32/boards/UM_FEATHERS2NEO/board.json +++ b/ports/esp32/boards/UM_FEATHERS2NEO/board.json @@ -1,6 +1,6 @@ { "deploy": [ - "../deploy_s2.md" + "deploy.md" ], "docs": "", "features": [ @@ -9,10 +9,16 @@ "Battery Charging", "STEMMA QT/QWIIC", "USB-C", - "Neopixels" + "RGB LED", + "SPIRAM" + ], + "features_non_filterable": [ + "5x5 RGB LED Matrix" ], "id": "featherS2neo", - "images": [], + "images": [ + "FeatherS2_Neo_White_Product2.jpg" + ], "mcu": "esp32s2", "product": "Feather S2 Neo", "thumbnail": "", diff --git a/ports/esp32/boards/UM_FEATHERS2NEO/board.md b/ports/esp32/boards/UM_FEATHERS2NEO/board.md new file mode 100644 index 0000000000..60ee024a12 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2NEO/board.md @@ -0,0 +1,2 @@ +The following files are daily firmware for the FeatherS2 Neo. This firmware is +compiled using ESP-IDF v4.3 or later. diff --git a/ports/esp32/boards/UM_FEATHERS2NEO/deploy.md b/ports/esp32/boards/UM_FEATHERS2NEO/deploy.md new file mode 100644 index 0000000000..b1a116e807 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2NEO/deploy.md @@ -0,0 +1,50 @@ +Program your board using the esptool.py program, found [here](https://github.com/espressif/esptool). + +To flash or erase your FeatherS2 Neo, you have to first put it into download mode. +To do this, follow these steps: + +- Press and hold the [BOOT] button +- Press and release the [RESET] button +- Release the [BOOT] button + +Now the board is in download mode and the native USB will have enumerated as a serial device. + +If you are putting MicroPython on your board for the first time then you should +first erase the entire flash using: + +### Linux +```bash +esptool.py --chip esp32s2 --port /dev/ttyACM0 erase_flash +``` + +### Mac +```bash +esptool.py --chip esp32s2 --port /dev/cu.usbmodem01 erase_flash +``` + +### Windows +Change (X) to whatever COM port is being used by the board +```bash +esptool --chip esp32s2 --port COM(X) erase_flash +``` + +Now download the version of the firmware you would like to install from the options below, +then use the following command to program the firmware starting at address 0x1000, +remembering to replace `feathers2neo-micropython-firmware-version.bin` with the name of +the firmware you just downloaded: + +### Linux +```bash +esptool.py --chip esp32s2 --port /dev/ttyACM0 write_flash -z 0x1000 feathers2neo-micropython-firmware-version.bin +``` + +### Mac +```bash +esptool.py --chip esp32s2 --port /dev/cu.usbmodem01 write_flash -z 0x1000 feathers2neo-micropython-firmware-version.bin +``` + +### Windows +Change (X) to whatever COM port is being used by the board +```bash +esptool --chip esp32s2 --port COM(X) write_flash -z 0x1000 feathers2-feathers2neo-firmware-version.bin +``` diff --git a/ports/esp32/boards/UM_TINYPICO/board.json b/ports/esp32/boards/UM_TINYPICO/board.json index 6b5a01d57f..6fb7803fe2 100644 --- a/ports/esp32/boards/UM_TINYPICO/board.json +++ b/ports/esp32/boards/UM_TINYPICO/board.json @@ -1,9 +1,19 @@ { "deploy": [ - "../deploy.md" + "deploy.md" ], "docs": "", - "features": [], + "features": [ + "BLE", + "WiFi", + "Battery Charging", + "USB-C", + "RGB LED", + "SPIRAM" + ], + "features_non_filterable": [ + "TinyPICO Compatible" + ], "id": "tinypico", "images": [ "tinypico-v2-both.jpg" diff --git a/ports/esp32/boards/UM_TINYPICO/board.md b/ports/esp32/boards/UM_TINYPICO/board.md new file mode 100644 index 0000000000..d0b1266d2e --- /dev/null +++ b/ports/esp32/boards/UM_TINYPICO/board.md @@ -0,0 +1,3 @@ +The following files are daily firmware for the TinyPICO. This firmware is compiled +using ESP-IDF v4.2 or later. Some older releases are also provided that are +compiled with ESP-IDF v3.x. diff --git a/ports/esp32/boards/UM_TINYPICO/deploy.md b/ports/esp32/boards/UM_TINYPICO/deploy.md new file mode 100644 index 0000000000..ed29478675 --- /dev/null +++ b/ports/esp32/boards/UM_TINYPICO/deploy.md @@ -0,0 +1,46 @@ +Program your board using the esptool.py program, found [here](https://github.com/espressif/esptool). + +Your TinyPICO has an auto-reset circuit on it, so there is no need to put it into a +download mode first to erase or flash it. + +If you are putting MicroPython on your board for the first time then you should +first erase the entire flash using: + +### Linux +```bash +esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash +``` + +### Mac +```bash +esptool.py --chip esp32 --port /dev/tty.SLAB_USBtoUART erase_flash +``` + +### Windows +Change (X) to whatever COM port is being used by the board +```bash +esptool --chip esp32 --port COM(X) erase_flash +``` + +Now download the version of the firmware you would like to install from the options below, +then use the following command to program the firmware starting at address 0x1000, +remembering to replace `tinypico-micropython-firmware-version.bin` with the name of the +firmware you just downloaded: + +From then on program the firmware starting at address 0x1000: + +### Linux +```bash +esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 912600 write_flash -z 0x1000 tinypico-micropython-firmware-version.bin +``` + +### Mac +```bash +esptool.py --chip esp32 --port /dev/tty.SLAB_USBtoUART --baud 912600 write_flash -z 0x1000 tinypico-micropython-firmware-version.bin +``` + +### Windows +Change (X) to whatever COM port is being used by the board +```bash +esptool --chip esp32 --port COM(X) --baud 912600 write_flash -z 0x1000 tinypico-micropython-firmware-version.bin +``` diff --git a/ports/esp32/boards/UM_TINYS2/board.json b/ports/esp32/boards/UM_TINYS2/board.json index d378f6b9d8..20c1c6d847 100644 --- a/ports/esp32/boards/UM_TINYS2/board.json +++ b/ports/esp32/boards/UM_TINYS2/board.json @@ -1,11 +1,19 @@ { "deploy": [ - "../deploy_s2.md" + "deploy.md" ], "docs": "", "features": [ "WiFi", "USB-C" + "Battery Charging", + "STEMMA QT/QWIIC", + "USB-C", + "RGB LED", + "SPIRAM" + ], + "features_non_filterable": [ + "TinyPICO Compatible" ], "id": "tinys2", "images": [ diff --git a/ports/esp32/boards/UM_TINYS2/board.md b/ports/esp32/boards/UM_TINYS2/board.md new file mode 100644 index 0000000000..9a61374edf --- /dev/null +++ b/ports/esp32/boards/UM_TINYS2/board.md @@ -0,0 +1,2 @@ +The following files are daily firmware for the TinyS2. This firmware is compiled +using ESP-IDF v4.3 or later. diff --git a/ports/esp32/boards/UM_TINYS2/deploy.md b/ports/esp32/boards/UM_TINYS2/deploy.md new file mode 100644 index 0000000000..a46bc9bd1a --- /dev/null +++ b/ports/esp32/boards/UM_TINYS2/deploy.md @@ -0,0 +1,50 @@ +Program your board using the esptool.py program, found [here](https://github.com/espressif/esptool). + +To flash or erase your TinyS2, you have to first put it into download mode. +To do this, follow these steps: + +- Press and hold the [BOOT] button +- Press and release the [RESET] button +- Release the [BOOT] button + +Now the board is in download mode and the native USB will have enumerated as a serial device. + +If you are putting MicroPython on your board for the first time then you should +first erase the entire flash using: + +### Linux +```bash +esptool.py --chip esp32s2 --port /dev/ttyACM0 erase_flash +``` + +### Mac +```bash +esptool.py --chip esp32s2 --port /dev/cu.usbmodem01 erase_flash +``` + +#### Windows +Change (X) to whatever COM port is being used by the board +```bash +esptool --chip esp32s2 --port COM(X) erase_flash +``` + +Now download the version of the firmware you would like to install from the options below, +then use the following command to program the firmware starting at address 0x1000, +remembering to replace `tinys2-micropython-firmware-version.bin` with the name of the +firmware you just downloaded: + +#### Linux +```bash +esptool.py --chip esp32s2 --port /dev/ttyACM0 write_flash -z 0x1000 tinys2-micropython-firmware-version.bin +``` + +#### Mac +```bash +esptool.py --chip esp32s2 --port /dev/cu.usbmodem01 write_flash -z 0x1000 tinys2-micropython-firmware-version.bin +``` + +#### Windows +Change (X) to whatever COM port is being used by the board +```bash +esptool --chip esp32s2 --port COM(X) write_flash -z 0x1000 tinys2-micropython-firmware-version.bin +``` From 1e4849557d23f3b194f3a056e28f7a8c14dac050 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 27 Oct 2021 20:15:04 +1100 Subject: [PATCH 119/335] esp32/usb: Further improve speed of USB CDC output. Following on from ba940250a5b630018c8d9b0e21c5ed858a20450f, the change here makes output about 15 times faster (now up to about 550 kbytes/sec). tinyusb_cdcacm_write_queue will return the number of bytes written, so there's no need to use tud_cdc_n_write_available. Signed-off-by: Damien George --- ports/esp32/usb.c | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/ports/esp32/usb.c b/ports/esp32/usb.c index 95c8277299..5a613d2441 100644 --- a/ports/esp32/usb.c +++ b/ports/esp32/usb.c @@ -87,34 +87,13 @@ void usb_init(void) { } void usb_tx_strn(const char *str, size_t len) { - // If no HOST is connected, we can exit this early. - if (usb_cdc_connected == 0) { - return; - } - - while (len) { - // Get amount of CDC output buffer space available, making sure - // there is at least one byte available. - size_t avail = tud_cdc_n_write_available(CDC_ITF); - if (avail == 0) { - if (tinyusb_cdcacm_write_flush(CDC_ITF, pdMS_TO_TICKS(1000)) != ESP_OK) { - return; - } - avail = tud_cdc_n_write_available(CDC_ITF); - } - - // Write as much data as possible. - size_t l = len; - if (l > avail) { - l = avail; - } - tud_cdc_n_write(CDC_ITF, (uint8_t *)str, l); + // Write out the data to the CDC interface, but only while the USB host is connected. + while (usb_cdc_connected && len) { + size_t l = tinyusb_cdcacm_write_queue(CDC_ITF, (uint8_t *)str, len); str += l; len -= l; + tud_cdc_n_write_flush(CDC_ITF); } - - // Queue a flush to write out the data in the CDC buffer (if any). - tud_cdc_n_write_flush(CDC_ITF); } #endif // CONFIG_USB_ENABLED From 3ace779e8e353b697606712b9d25f5288a685c80 Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Wed, 27 Oct 2021 19:01:18 +1100 Subject: [PATCH 120/335] esp32/boards/LOLIN_S2_PICO: Add LOLIN_S2_PICO board definition files. --- ports/esp32/boards/LOLIN_S2_PICO/board.json | 18 +++++++ ports/esp32/boards/LOLIN_S2_PICO/manifest.py | 4 ++ .../boards/LOLIN_S2_PICO/modules/s2pico.py | 38 +++++++++++++++ .../LOLIN_S2_PICO/modules/s2pico_oled.py | 48 +++++++++++++++++++ .../boards/LOLIN_S2_PICO/mpconfigboard.cmake | 11 +++++ .../boards/LOLIN_S2_PICO/mpconfigboard.h | 12 +++++ .../boards/LOLIN_S2_PICO/sdkconfig.board | 6 +++ 7 files changed, 137 insertions(+) create mode 100644 ports/esp32/boards/LOLIN_S2_PICO/board.json create mode 100644 ports/esp32/boards/LOLIN_S2_PICO/manifest.py create mode 100644 ports/esp32/boards/LOLIN_S2_PICO/modules/s2pico.py create mode 100644 ports/esp32/boards/LOLIN_S2_PICO/modules/s2pico_oled.py create mode 100644 ports/esp32/boards/LOLIN_S2_PICO/mpconfigboard.cmake create mode 100644 ports/esp32/boards/LOLIN_S2_PICO/mpconfigboard.h create mode 100644 ports/esp32/boards/LOLIN_S2_PICO/sdkconfig.board diff --git a/ports/esp32/boards/LOLIN_S2_PICO/board.json b/ports/esp32/boards/LOLIN_S2_PICO/board.json new file mode 100644 index 0000000000..df760ace4e --- /dev/null +++ b/ports/esp32/boards/LOLIN_S2_PICO/board.json @@ -0,0 +1,18 @@ +{ + "deploy": [ + "../deploy_s2.md" + ], + "docs": "", + "features": [ + "WiFi", + "USB-C" + ], + "images": [ + "lolin_s2_pico.jpg" + ], + "mcu": "esp32s2", + "product": "S2 pico", + "thumbnail": "", + "url": "https://www.wemos.cc/en/latest/s2/s2_pico.html", + "vendor": "Wemos" +} diff --git a/ports/esp32/boards/LOLIN_S2_PICO/manifest.py b/ports/esp32/boards/LOLIN_S2_PICO/manifest.py new file mode 100644 index 0000000000..98d4247c60 --- /dev/null +++ b/ports/esp32/boards/LOLIN_S2_PICO/manifest.py @@ -0,0 +1,4 @@ +include("$(PORT_DIR)/boards/manifest.py") +freeze("./modules") + +freeze("$(MPY_DIR)/drivers/display", "ssd1306.py") diff --git a/ports/esp32/boards/LOLIN_S2_PICO/modules/s2pico.py b/ports/esp32/boards/LOLIN_S2_PICO/modules/s2pico.py new file mode 100644 index 0000000000..be59db715e --- /dev/null +++ b/ports/esp32/boards/LOLIN_S2_PICO/modules/s2pico.py @@ -0,0 +1,38 @@ +# LOLIN S2 PICO MicroPython Helper Library + +from micropython import const +from machine import Pin, I2C, Signal +from s2pico_oled import OLED + +# Pin Assignments + +# SPI +SPI_MOSI = const(35) +SPI_MISO = const(36) +SPI_CLK = const(37) + +# I2C +I2C_SDA = const(8) +I2C_SCL = const(9) + +# DAC +DAC1 = const(17) +DAC2 = const(18) + +# LED +LED = const(10) + +# OLED +OLED_RST = const(18) + +# BUTTON +BUTTON = const(0) + +# Helper methods for built in sensors + +led = Signal(LED, Pin.OUT, value=0, invert=True) + +button = Pin(BUTTON, Pin.IN, Pin.PULL_UP) + +i2c = I2C(0) +oled = OLED(i2c, Pin(OLED_RST)) diff --git a/ports/esp32/boards/LOLIN_S2_PICO/modules/s2pico_oled.py b/ports/esp32/boards/LOLIN_S2_PICO/modules/s2pico_oled.py new file mode 100644 index 0000000000..37dc5a340f --- /dev/null +++ b/ports/esp32/boards/LOLIN_S2_PICO/modules/s2pico_oled.py @@ -0,0 +1,48 @@ +from time import sleep_ms +from ssd1306 import SSD1306_I2C +import network + + +class OLED(SSD1306_I2C): + def __init__(self, i2c, reset): + reset.init(reset.OUT, value=1) + self._reset = reset + self.reset(False) + super().__init__(128, 32, i2c) + + def reset(self, reinit=True): + self._reset(1) + sleep_ms(1) + self._reset(0) + sleep_ms(10) + self._reset(1) + if reinit: + self.init_display() + + def test(self): + self.fill(0) + self.fill_rect(0, 0, 32, 32, 1) + self.fill_rect(2, 2, 28, 28, 0) + self.vline(9, 8, 22, 1) + self.vline(16, 2, 22, 1) + self.vline(23, 8, 22, 1) + self.fill_rect(26, 24, 2, 4, 1) + self.text("MicroPython", 40, 0, 1) + self.text("SSD1306", 40, 12, 1) + self.text("OLED 128x32", 40, 24, 1) + self.show() + + def display_wifi(self): + self.fill(0) + self.text("Scan...", 0, 0, 1) + self.show() + + sta_if = network.WLAN(network.STA_IF) + sta_if.active(True) + _wifi = sta_if.scan() + + self.fill(0) + self.text(str(len(_wifi)) + " Networks", 0, 0, 1) + self.text(str(_wifi[0][3]) + " " + (_wifi[0][0]).decode("utf-8"), 0, 12, 1) + self.text(str(_wifi[1][3]) + " " + (_wifi[1][0]).decode("utf-8"), 0, 24, 1) + self.show() diff --git a/ports/esp32/boards/LOLIN_S2_PICO/mpconfigboard.cmake b/ports/esp32/boards/LOLIN_S2_PICO/mpconfigboard.cmake new file mode 100644 index 0000000000..5f157e7e77 --- /dev/null +++ b/ports/esp32/boards/LOLIN_S2_PICO/mpconfigboard.cmake @@ -0,0 +1,11 @@ +set(IDF_TARGET esp32s2) + +set(SDKCONFIG_DEFAULTS + boards/sdkconfig.base + boards/sdkconfig.spiram_sx + boards/sdkconfig.usb +) + +if(NOT MICROPY_FROZEN_MANIFEST) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) +endif() diff --git a/ports/esp32/boards/LOLIN_S2_PICO/mpconfigboard.h b/ports/esp32/boards/LOLIN_S2_PICO/mpconfigboard.h new file mode 100644 index 0000000000..549dd9847c --- /dev/null +++ b/ports/esp32/boards/LOLIN_S2_PICO/mpconfigboard.h @@ -0,0 +1,12 @@ +#define MICROPY_HW_BOARD_NAME "LOLIN_S2_PICO" +#define MICROPY_HW_MCU_NAME "ESP32-S2FN4R2" + +#define MICROPY_PY_BLUETOOTH (0) +#define MICROPY_HW_ENABLE_SDCARD (0) + +#define MICROPY_HW_I2C0_SCL (9) +#define MICROPY_HW_I2C0_SDA (8) + +#define MICROPY_HW_SPI1_MOSI (35) +#define MICROPY_HW_SPI1_MISO (36) +#define MICROPY_HW_SPI1_SCK (37) diff --git a/ports/esp32/boards/LOLIN_S2_PICO/sdkconfig.board b/ports/esp32/boards/LOLIN_S2_PICO/sdkconfig.board new file mode 100644 index 0000000000..bf0f3e780e --- /dev/null +++ b/ports/esp32/boards/LOLIN_S2_PICO/sdkconfig.board @@ -0,0 +1,6 @@ +CONFIG_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_USB_AND_UART=y +# LWIP +CONFIG_LWIP_LOCAL_HOSTNAME="LOLIN_S2_PICO" +# end of LWIP From 07ea1afe747fa4eaca15a64d8f73574abc2533e9 Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Thu, 28 Oct 2021 12:35:13 +1100 Subject: [PATCH 121/335] esp32/boards/ESP32_S2_WROVER: Link to specific deploy_s2 instructions. --- ports/esp32/boards/ESP32_S2_WROVER/board.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/esp32/boards/ESP32_S2_WROVER/board.json b/ports/esp32/boards/ESP32_S2_WROVER/board.json index 8f2aff7346..eb2c40aeee 100644 --- a/ports/esp32/boards/ESP32_S2_WROVER/board.json +++ b/ports/esp32/boards/ESP32_S2_WROVER/board.json @@ -1,6 +1,6 @@ { "deploy": [ - "../deploy.md" + "../deploy_s2.md" ], "docs": "", "features": [], From 83827e8e63f18f6437f0569c49cb697896fa58c7 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 28 Oct 2021 12:36:45 +1100 Subject: [PATCH 122/335] stm32/uart: Fix race conditions and clearing status in IRQ handler. Prior to this commit IRQs on STM32F4 could be lost because SR is cleared by reading SR then reading DR. For example, if both RXNE and IDLE IRQs were active upon entry to the IRQ handler, then IDLE is lost because the code that handles RXNE comes first and accidentally clears SR (by reading SR then DR to get the incoming character). This commit fixes this problem by making the IRQ handler more atomic in the following operations: - get current IRQ status flags - deal with RX character - clear remaining status flags - call user handler On the STM32F4 it's very hard to get this right because the only way to clear IRQ status flags is to read SR then DR, but the read of DR may read some data which should remain in the register until the user wants to read it. And it won't work to cache the read because RTS/CTS flow control will then not work. So instead the new code disables interrupts if the DR is full and waits for the user to read it before reenabling the interrupts. Fixes issue mentioned in #4599 and #6082. Signed-off-by: Damien George --- ports/stm32/uart.c | 79 +++++++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 26 deletions(-) diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c index 627c33397d..2c08257f32 100644 --- a/ports/stm32/uart.c +++ b/ports/stm32/uart.c @@ -40,11 +40,13 @@ #if defined(STM32F4) #define UART_RXNE_IS_SET(uart) ((uart)->SR & USART_SR_RXNE) -#elif defined(STM32H7) -#define UART_RXNE_IS_SET(uart) ((uart)->ISR & USART_ISR_RXNE_RXFNE) #else +#if defined(STM32H7) +#define USART_ISR_RXNE USART_ISR_RXNE_RXFNE +#endif #define UART_RXNE_IS_SET(uart) ((uart)->ISR & USART_ISR_RXNE) #endif + #define UART_RXNE_IT_EN(uart) do { (uart)->CR1 |= USART_CR1_RXNEIE; } while (0) #define UART_RXNE_IT_DIS(uart) do { (uart)->CR1 &= ~USART_CR1_RXNEIE; } while (0) @@ -877,7 +879,17 @@ int uart_rx_char(pyb_uart_obj_t *self) { self->uartx->ICR = USART_ICR_ORECF; // clear ORE if it was set return data; #else - return self->uartx->DR & self->char_mask; + int data = self->uartx->DR & self->char_mask; + // Re-enable any IRQs that were disabled in uart_irq_handler because SR couldn't + // be cleared there (clearing SR in uart_irq_handler required reading DR which + // may have lost a character). + if (self->mp_irq_trigger & UART_FLAG_RXNE) { + self->uartx->CR1 |= USART_CR1_RXNEIE; + } + if (self->mp_irq_trigger & UART_FLAG_IDLE) { + self->uartx->CR1 |= USART_CR1_IDLEIE; + } + return data; #endif } } @@ -982,7 +994,10 @@ void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len) { uart_tx_data(uart_obj, str, len, &errcode); } -// this IRQ handler is set up to handle RXNE interrupts only +// This IRQ handler is set up to handle RXNE, IDLE and ORE interrupts only. +// Notes: +// - ORE (overrun error) is tied to the RXNE IRQ line. +// - On STM32F4 the IRQ flags are cleared by reading SR then DR. void uart_irq_handler(mp_uint_t uart_id) { // get the uart object pyb_uart_obj_t *self = MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1]; @@ -993,16 +1008,28 @@ void uart_irq_handler(mp_uint_t uart_id) { return; } - if (UART_RXNE_IS_SET(self->uartx)) { + // Capture IRQ status flags. + #if defined(STM32F4) + self->mp_irq_flags = self->uartx->SR; + bool rxne_is_set = self->mp_irq_flags & USART_SR_RXNE; + bool did_clear_sr = false; + #else + self->mp_irq_flags = self->uartx->ISR; + bool rxne_is_set = self->mp_irq_flags & USART_ISR_RXNE; + #endif + + // Process RXNE flag, either read the character or disable the interrupt. + if (rxne_is_set) { if (self->read_buf_len != 0) { uint16_t next_head = (self->read_buf_head + 1) % self->read_buf_len; if (next_head != self->read_buf_tail) { // only read data if room in buf #if defined(STM32F0) || defined(STM32F7) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) int data = self->uartx->RDR; // clears UART_FLAG_RXNE - self->uartx->ICR = USART_ICR_ORECF; // clear ORE if it was set #else + self->mp_irq_flags = self->uartx->SR; // resample to get any new flags since next read of DR will clear SR int data = self->uartx->DR; // clears UART_FLAG_RXNE + did_clear_sr = true; #endif data &= self->char_mask; if (self->attached_to_repl && data == mp_interrupt_char) { @@ -1019,32 +1046,32 @@ void uart_irq_handler(mp_uint_t uart_id) { } else { // No room: leave char in buf, disable interrupt UART_RXNE_IT_DIS(self->uartx); } + } else { + // No buffering, disable interrupt. + UART_RXNE_IT_DIS(self->uartx); } } - // If RXNE is clear but ORE set then clear the ORE flag (it's tied to RXNE IRQ) - #if defined(STM32F4) - else if (self->uartx->SR & USART_SR_ORE) { - (void)self->uartx->DR; - } - #else - else if (self->uartx->ISR & USART_ISR_ORE) { - self->uartx->ICR = USART_ICR_ORECF; - } - #endif - // Set user IRQ flags - self->mp_irq_flags = 0; + // Clear other interrupt flags that can trigger this IRQ handler. #if defined(STM32F4) - if (self->uartx->SR & USART_SR_IDLE) { - (void)self->uartx->SR; - (void)self->uartx->DR; - self->mp_irq_flags |= UART_FLAG_IDLE; + if (did_clear_sr) { + // SR was cleared above. Re-enable IDLE if it should be enabled. + if (self->mp_irq_trigger & UART_FLAG_IDLE) { + self->uartx->CR1 |= USART_CR1_IDLEIE; + } + } else { + // On STM32F4 the only way to clear flags is to read SR then DR, but that may + // lead to a loss of data in DR. So instead the IRQs are disabled. + if (self->mp_irq_flags & USART_SR_IDLE) { + self->uartx->CR1 &= ~USART_CR1_IDLEIE; + } + if (self->mp_irq_flags & USART_SR_ORE) { + // ORE is tied to RXNE so that must be disabled. + self->uartx->CR1 &= ~USART_CR1_RXNEIE; + } } #else - if (self->uartx->ISR & USART_ISR_IDLE) { - self->uartx->ICR = USART_ICR_IDLECF; - self->mp_irq_flags |= UART_FLAG_IDLE; - } + self->uartx->ICR = self->mp_irq_flags & (USART_ICR_IDLECF | USART_ICR_ORECF); #endif // Check the flags to see if the user handler should be called From 7f143444283528101d9b48e1f2e908c12648f2f1 Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Thu, 28 Oct 2021 13:53:10 +1100 Subject: [PATCH 123/335] ports: Add images, features and urls to board.json. --- ports/cc3200/boards/WIPY/board.json | 9 ++++++++- ports/esp32/boards/ESP32_S2_WROVER/board.json | 12 +++++++++--- ports/esp32/boards/GENERIC/board.json | 6 +++--- ports/esp32/boards/GENERIC_C3/board.json | 7 +++++-- ports/esp32/boards/GENERIC_C3_USB/board.json | 7 +++++-- ports/esp32/boards/GENERIC_D2WD/board.json | 7 +++++-- ports/esp32/boards/GENERIC_OTA/board.json | 7 +++++-- ports/esp32/boards/GENERIC_S2/board.json | 7 +++++-- ports/esp32/boards/GENERIC_S3/board.json | 7 +++++-- ports/esp32/boards/GENERIC_SPIRAM/board.json | 6 +++--- ports/esp32/boards/LOLIN_S2_MINI/board.json | 6 +++++- ports/esp32/boards/LOLIN_S2_PICO/board.json | 8 ++++++-- ports/esp32/boards/M5STACK_ATOM/board.json | 13 ++++++++++--- ports/esp32/boards/SIL_WESP32/board.json | 11 ++++++++--- ports/esp32/boards/UM_FEATHERS2/board.json | 8 ++++---- ports/esp32/boards/UM_FEATHERS2NEO/board.json | 8 ++++---- ports/esp32/boards/UM_TINYPICO/board.json | 8 ++++---- ports/esp32/boards/UM_TINYS2/board.json | 7 +++---- ports/esp8266/boards/GENERIC/board.json | 6 ++++-- ports/esp8266/boards/GENERIC_1M/board.json | 6 ++++-- ports/esp8266/boards/GENERIC_512K/board.json | 6 ++++-- ports/mimxrt/boards/MIMXRT1010_EVK/board.json | 6 ++++-- ports/mimxrt/boards/MIMXRT1020_EVK/board.json | 6 ++++-- ports/mimxrt/boards/MIMXRT1050_EVK/board.json | 6 ++++-- ports/mimxrt/boards/MIMXRT1060_EVK/board.json | 6 ++++-- ports/mimxrt/boards/MIMXRT1064_EVK/board.json | 6 ++++-- ports/mimxrt/boards/TEENSY40/board.json | 4 +++- ports/mimxrt/boards/TEENSY41/board.json | 4 +++- ports/nrf/boards/actinius_icarus/board.json | 8 +++++--- ports/nrf/boards/blueio_tag_evim/board.json | 8 +++++--- ports/nrf/boards/dvk_bl652/board.json | 8 +++++--- ports/nrf/boards/evk_nina_b1/board.json | 10 ++++++---- ports/nrf/boards/evk_nina_b3/board.json | 8 +++++--- ports/nrf/boards/ibk_blyst_nano/board.json | 8 +++++--- ports/nrf/boards/idk_blyst_nano/board.json | 8 +++++--- ports/nrf/boards/microbit/board.json | 4 +++- ports/nrf/boards/nrf52840-mdk-usb-dongle/board.json | 6 ++++-- ports/nrf/boards/particle_xenon/board.json | 6 ++++-- ports/nrf/boards/pca10000/board.json | 6 ++++-- ports/nrf/boards/pca10001/board.json | 6 ++++-- ports/nrf/boards/pca10028/board.json | 6 ++++-- ports/nrf/boards/pca10031/board.json | 6 ++++-- ports/nrf/boards/pca10040/board.json | 6 ++++-- ports/nrf/boards/pca10056/board.json | 6 ++++-- ports/nrf/boards/pca10059/board.json | 2 +- ports/nrf/boards/pca10090/board.json | 6 ++++-- ports/nrf/boards/wt51822_s4at/board.json | 10 ++++++---- ports/rp2/boards/ADAFRUIT_FEATHER_RP2040/board.json | 10 +++++++++- .../rp2/boards/ADAFRUIT_ITSYBITSY_RP2040/board.json | 7 ++++++- ports/rp2/boards/ADAFRUIT_QTPY_RP2040/board.json | 9 ++++++++- ports/rp2/boards/PICO/board.json | 6 +++++- ports/rp2/boards/PIMORONI_PICOLIPO_16MB/board.json | 9 ++++++++- ports/rp2/boards/PIMORONI_PICOLIPO_4MB/board.json | 9 ++++++++- ports/rp2/boards/PIMORONI_TINY2040/board.json | 7 ++++++- ports/rp2/boards/SPARKFUN_PROMICRO/board.json | 10 ++++++++-- ports/rp2/boards/SPARKFUN_THINGPLUS/board.json | 11 ++++++++++- .../boards/ADAFRUIT_FEATHER_M0_EXPRESS/board.json | 9 ++++++++- .../boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/board.json | 7 ++++++- ports/samd/boards/ADAFRUIT_TRINKET_M0/board.json | 6 +++++- ports/samd/boards/MINISAM_M4/board.json | 6 +++++- ports/samd/boards/SAMD21_XPLAINED_PRO/board.json | 5 ++++- 61 files changed, 313 insertions(+), 126 deletions(-) diff --git a/ports/cc3200/boards/WIPY/board.json b/ports/cc3200/boards/WIPY/board.json index fcc895b7f5..d8293b2481 100644 --- a/ports/cc3200/boards/WIPY/board.json +++ b/ports/cc3200/boards/WIPY/board.json @@ -3,7 +3,14 @@ "deploy.md" ], "docs": "https://docs.pycom.io/datasheets/development/wipy3/", - "features": [], + "features": [ + "BLE", + "Breadboard Friendly", + "MicroSD", + "RGB LED", + "SPI Flash", + "WiFi" + ], "id": "wipy", "images": [ "wipy.jpg" diff --git a/ports/esp32/boards/ESP32_S2_WROVER/board.json b/ports/esp32/boards/ESP32_S2_WROVER/board.json index eb2c40aeee..7ebc84415c 100644 --- a/ports/esp32/boards/ESP32_S2_WROVER/board.json +++ b/ports/esp32/boards/ESP32_S2_WROVER/board.json @@ -3,11 +3,17 @@ "../deploy_s2.md" ], "docs": "", - "features": [], - "images": [], + "features": [ + "BLE", + "SPIRAM", + "WiFi" + ], + "images": [ + "ESP32-S2-WROVER_L_0.jpg" + ], "mcu": "esp32s2", "product": "ESP32-S2 WROVER", "thumbnail": "", - "url": "", + "url": "https://www.espressif.com/en/products/modules", "vendor": "Espressif" } diff --git a/ports/esp32/boards/GENERIC/board.json b/ports/esp32/boards/GENERIC/board.json index eadf70dd12..95447dd8e1 100644 --- a/ports/esp32/boards/GENERIC/board.json +++ b/ports/esp32/boards/GENERIC/board.json @@ -4,15 +4,15 @@ ], "docs": "", "features": [ - "WiFi", - "BLE" + "BLE", + "WiFi" ], "id": "esp32", "images": [], "mcu": "esp32", "product": "ESP32", "thumbnail": "", - "url": "", + "url": "https://www.espressif.com/en/products/modules", "variants": { "idf3": "Compiled with IDF 3.x" }, diff --git a/ports/esp32/boards/GENERIC_C3/board.json b/ports/esp32/boards/GENERIC_C3/board.json index 3c360e64c7..325843a72d 100644 --- a/ports/esp32/boards/GENERIC_C3/board.json +++ b/ports/esp32/boards/GENERIC_C3/board.json @@ -3,12 +3,15 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "BLE", + "WiFi" + ], "id": "esp32c3", "images": [], "mcu": "esp32c3", "product": "ESP32-C3", "thumbnail": "", - "url": "", + "url": "https://www.espressif.com/en/products/modules", "vendor": "Espressif" } diff --git a/ports/esp32/boards/GENERIC_C3_USB/board.json b/ports/esp32/boards/GENERIC_C3_USB/board.json index cf9f63b90c..f719a2b63a 100644 --- a/ports/esp32/boards/GENERIC_C3_USB/board.json +++ b/ports/esp32/boards/GENERIC_C3_USB/board.json @@ -3,12 +3,15 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "BLE", + "WiFi" + ], "id": "esp32c3-usb", "images": [], "mcu": "esp32c3", "product": "ESP32-C3 with USB", "thumbnail": "", - "url": "", + "url": "https://www.espressif.com/en/products/modules", "vendor": "Espressif" } diff --git a/ports/esp32/boards/GENERIC_D2WD/board.json b/ports/esp32/boards/GENERIC_D2WD/board.json index 63fbbfb2f9..d20922907d 100644 --- a/ports/esp32/boards/GENERIC_D2WD/board.json +++ b/ports/esp32/boards/GENERIC_D2WD/board.json @@ -3,12 +3,15 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "BLE", + "WiFi" + ], "id": "esp32-d2wd", "images": [], "mcu": "esp32", "product": "ESP32 D2WD", "thumbnail": "", - "url": "", + "url": "https://www.espressif.com/en/products/modules", "vendor": "Espressif" } diff --git a/ports/esp32/boards/GENERIC_OTA/board.json b/ports/esp32/boards/GENERIC_OTA/board.json index 529f0acdee..e656497fc6 100644 --- a/ports/esp32/boards/GENERIC_OTA/board.json +++ b/ports/esp32/boards/GENERIC_OTA/board.json @@ -3,12 +3,15 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "BLE", + "WiFi" + ], "id": "esp32-ota", "images": [], "mcu": "esp32", "product": "ESP32 with OTA support", "thumbnail": "", - "url": "", + "url": "https://www.espressif.com/en/products/modules", "vendor": "Espressif" } diff --git a/ports/esp32/boards/GENERIC_S2/board.json b/ports/esp32/boards/GENERIC_S2/board.json index 5e1758b86a..16b19ad206 100644 --- a/ports/esp32/boards/GENERIC_S2/board.json +++ b/ports/esp32/boards/GENERIC_S2/board.json @@ -3,11 +3,14 @@ "../deploy_s2.md" ], "docs": "", - "features": [], + "features": [ + "BLE", + "WiFi" + ], "images": [], "mcu": "esp32s2", "product": "ESP32-S2", "thumbnail": "", - "url": "", + "url": "https://www.espressif.com/en/products/modules", "vendor": "Espressif" } diff --git a/ports/esp32/boards/GENERIC_S3/board.json b/ports/esp32/boards/GENERIC_S3/board.json index a2652ea46a..f5fb8e9015 100644 --- a/ports/esp32/boards/GENERIC_S3/board.json +++ b/ports/esp32/boards/GENERIC_S3/board.json @@ -3,11 +3,14 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "BLE", + "WiFi" + ], "images": [], "mcu": "esp32s3", "product": "ESP32-S3", "thumbnail": "", - "url": "", + "url": "https://www.espressif.com/en/products/modules", "vendor": "Espressif" } diff --git a/ports/esp32/boards/GENERIC_SPIRAM/board.json b/ports/esp32/boards/GENERIC_SPIRAM/board.json index 307555b501..c0efc22e3f 100644 --- a/ports/esp32/boards/GENERIC_SPIRAM/board.json +++ b/ports/esp32/boards/GENERIC_SPIRAM/board.json @@ -4,16 +4,16 @@ ], "docs": "", "features": [ - "WiFi", "BLE", - "SPIRAM" + "SPIRAM", + "WiFi" ], "id": "esp32spiram", "images": [], "mcu": "esp32", "product": "ESP32 with SPIRAM", "thumbnail": "", - "url": "", + "url": "https://www.espressif.com/en/products/modules", "variants": { "idf3": "Compiled with IDF 3.x" }, diff --git a/ports/esp32/boards/LOLIN_S2_MINI/board.json b/ports/esp32/boards/LOLIN_S2_MINI/board.json index 50e24ff3f9..41e62a0228 100644 --- a/ports/esp32/boards/LOLIN_S2_MINI/board.json +++ b/ports/esp32/boards/LOLIN_S2_MINI/board.json @@ -3,7 +3,11 @@ "../deploy_s2.md" ], "docs": "", - "features": [], + "features": [ + "SPIRAM", + "USB-C", + "WiFi" + ], "images": [ "lolin_s2_mini.jpg" ], diff --git a/ports/esp32/boards/LOLIN_S2_PICO/board.json b/ports/esp32/boards/LOLIN_S2_PICO/board.json index df760ace4e..43322b87b0 100644 --- a/ports/esp32/boards/LOLIN_S2_PICO/board.json +++ b/ports/esp32/boards/LOLIN_S2_PICO/board.json @@ -4,8 +4,12 @@ ], "docs": "", "features": [ - "WiFi", - "USB-C" + "Breadboard Friendly", + "OLED", + "SPIRAM", + "STEMMA QT/QWIIC", + "USB-C", + "WiFi" ], "images": [ "lolin_s2_pico.jpg" diff --git a/ports/esp32/boards/M5STACK_ATOM/board.json b/ports/esp32/boards/M5STACK_ATOM/board.json index b61d6d9e16..1d499ad4bf 100644 --- a/ports/esp32/boards/M5STACK_ATOM/board.json +++ b/ports/esp32/boards/M5STACK_ATOM/board.json @@ -3,11 +3,18 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Grove", + "IMU", + "Infrared", + "RGB LED", + "USB-C", + "WiFi" + ], "images": [], "mcu": "esp32", "product": "M5 Stack Atom", "thumbnail": "", - "url": "", - "vendor": "" + "url": "https://m5stack.com/", + "vendor": "M5 Stack" } diff --git a/ports/esp32/boards/SIL_WESP32/board.json b/ports/esp32/boards/SIL_WESP32/board.json index 73382c1565..65a4fde182 100644 --- a/ports/esp32/boards/SIL_WESP32/board.json +++ b/ports/esp32/boards/SIL_WESP32/board.json @@ -3,12 +3,17 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "BLE", + "Ethernet", + "PoE", + "WiFi" + ], "id": "wesp32", "images": [], "mcu": "esp32", "product": "SIL WESP32", "thumbnail": "", - "url": "", - "vendor": "Espressif" + "url": "https://wesp32.com/", + "vendor": "Silicognition LLC" } diff --git a/ports/esp32/boards/UM_FEATHERS2/board.json b/ports/esp32/boards/UM_FEATHERS2/board.json index 19d7219ec5..fa5b213db0 100644 --- a/ports/esp32/boards/UM_FEATHERS2/board.json +++ b/ports/esp32/boards/UM_FEATHERS2/board.json @@ -4,13 +4,13 @@ ], "docs": "", "features": [ - "WiFi", - "Feather", "Battery Charging", + "Feather", + "RGB LED", + "SPIRAM", "STEMMA QT/QWIIC", "USB-C", - "RGB LED", - "SPIRAM" + "WiFi" ], "features_non_filterable": [ "Second LDO" diff --git a/ports/esp32/boards/UM_FEATHERS2NEO/board.json b/ports/esp32/boards/UM_FEATHERS2NEO/board.json index be7a1371fa..d809485e86 100644 --- a/ports/esp32/boards/UM_FEATHERS2NEO/board.json +++ b/ports/esp32/boards/UM_FEATHERS2NEO/board.json @@ -4,13 +4,13 @@ ], "docs": "", "features": [ - "WiFi", - "Feather", "Battery Charging", + "Feather", + "RGB LED", + "SPIRAM", "STEMMA QT/QWIIC", "USB-C", - "RGB LED", - "SPIRAM" + "WiFi" ], "features_non_filterable": [ "5x5 RGB LED Matrix" diff --git a/ports/esp32/boards/UM_TINYPICO/board.json b/ports/esp32/boards/UM_TINYPICO/board.json index 6fb7803fe2..9f1783a9f1 100644 --- a/ports/esp32/boards/UM_TINYPICO/board.json +++ b/ports/esp32/boards/UM_TINYPICO/board.json @@ -4,12 +4,12 @@ ], "docs": "", "features": [ - "BLE", - "WiFi", "Battery Charging", - "USB-C", + "BLE", "RGB LED", - "SPIRAM" + "SPIRAM", + "USB-C", + "WiFi" ], "features_non_filterable": [ "TinyPICO Compatible" diff --git a/ports/esp32/boards/UM_TINYS2/board.json b/ports/esp32/boards/UM_TINYS2/board.json index 20c1c6d847..e7068170cb 100644 --- a/ports/esp32/boards/UM_TINYS2/board.json +++ b/ports/esp32/boards/UM_TINYS2/board.json @@ -4,13 +4,12 @@ ], "docs": "", "features": [ - "WiFi", - "USB-C" "Battery Charging", + "RGB LED", + "SPIRAM", "STEMMA QT/QWIIC", "USB-C", - "RGB LED", - "SPIRAM" + "WiFi" ], "features_non_filterable": [ "TinyPICO Compatible" diff --git a/ports/esp8266/boards/GENERIC/board.json b/ports/esp8266/boards/GENERIC/board.json index d8f4cba083..46c2659d8a 100644 --- a/ports/esp8266/boards/GENERIC/board.json +++ b/ports/esp8266/boards/GENERIC/board.json @@ -3,13 +3,15 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "WiFi" + ], "id": "esp8266", "images": [], "mcu": "esp8266", "product": "ESP8266 with 2MiB+ flash", "thumbnail": "", - "url": "", + "url": "https://www.espressif.com/en/products/modules", "variants": { "ota": "OTA compatible" }, diff --git a/ports/esp8266/boards/GENERIC_1M/board.json b/ports/esp8266/boards/GENERIC_1M/board.json index 6279d3fee0..2ef4bd99fa 100644 --- a/ports/esp8266/boards/GENERIC_1M/board.json +++ b/ports/esp8266/boards/GENERIC_1M/board.json @@ -3,12 +3,14 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "WiFi" + ], "id": "esp8266-1m", "images": [], "mcu": "esp8266", "product": "ESP8266 with 1MiB flash", "thumbnail": "", - "url": "", + "url": "https://www.espressif.com/en/products/modules", "vendor": "Espressif" } diff --git a/ports/esp8266/boards/GENERIC_512K/board.json b/ports/esp8266/boards/GENERIC_512K/board.json index da15a39d51..10050592cf 100644 --- a/ports/esp8266/boards/GENERIC_512K/board.json +++ b/ports/esp8266/boards/GENERIC_512K/board.json @@ -3,12 +3,14 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "WiFi" + ], "id": "esp8266-512k", "images": [], "mcu": "esp8266", "product": "ESP8266 with 512kiB flash", "thumbnail": "", - "url": "", + "url": "https://www.espressif.com/en/products/modules", "vendor": "Espressif" } diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/board.json b/ports/mimxrt/boards/MIMXRT1010_EVK/board.json index c865e74f4a..048430bead 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/board.json +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "i.MXRT1010-TOP.jpg" + ], "mcu": "mimxrt", "product": "MIMXRT1010_EVK", "thumbnail": "", - "url": "", + "url": "https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/i-mx-rt1010-evaluation-kit:MIMXRT1010-EVK", "vendor": "NXP" } diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/board.json b/ports/mimxrt/boards/MIMXRT1020_EVK/board.json index 7930f702b4..4dd3fed269 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/board.json +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "MIMXRT-1020-EVKBD.jpg" + ], "mcu": "mimxrt", "product": "MIMXRT1020_EVK", "thumbnail": "", - "url": "", + "url": "https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/i-mx-rt1020-evaluation-kit:MIMXRT1020-EVK", "vendor": "NXP" } diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/board.json b/ports/mimxrt/boards/MIMXRT1050_EVK/board.json index 5f04fb29b5..9c0e22b373 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/board.json +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "IMX_RT1050-EVKB_TOP-LR.jpg" + ], "mcu": "mimxrt", "product": "MIMXRT1050_EVK", "thumbnail": "", - "url": "", + "url": "https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/i-mx-rt1050-evaluation-kit:MIMXRT1050-EVK", "vendor": "NXP" } diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/board.json b/ports/mimxrt/boards/MIMXRT1060_EVK/board.json index 602b50d7f2..14e8942de2 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/board.json +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "X-MIMXRT1060-EVK-BOARD-BOTTOM.jpg" + ], "mcu": "mimxrt", "product": "MIMXRT1060_EVK", "thumbnail": "", - "url": "", + "url": "https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/i-mx-rt1060-evaluation-kit:MIMXRT1060-EVK", "vendor": "NXP" } diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/board.json b/ports/mimxrt/boards/MIMXRT1064_EVK/board.json index 5830a39f2e..ff7f3f722e 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/board.json +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "MIMXRT1064EVK-TOP.jpg" + ], "mcu": "mimxrt", "product": "MIMXRT1064_EVK", "thumbnail": "", - "url": "", + "url": "https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/i-mx-rt1064-evaluation-kit:MIMXRT1064-EVK", "vendor": "NXP" } diff --git a/ports/mimxrt/boards/TEENSY40/board.json b/ports/mimxrt/boards/TEENSY40/board.json index 25f7690fc0..dfc0ca96b3 100644 --- a/ports/mimxrt/boards/TEENSY40/board.json +++ b/ports/mimxrt/boards/TEENSY40/board.json @@ -4,7 +4,9 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "teensy40_front.jpg" + ], "mcu": "mimxrt", "product": "Teensy 4.0", "thumbnail": "", diff --git a/ports/mimxrt/boards/TEENSY41/board.json b/ports/mimxrt/boards/TEENSY41/board.json index 9c5c4709a9..cbb397c727 100644 --- a/ports/mimxrt/boards/TEENSY41/board.json +++ b/ports/mimxrt/boards/TEENSY41/board.json @@ -4,7 +4,9 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "teensy41_4.jpg" + ], "mcu": "mimxrt", "product": "Teensy 4.1", "thumbnail": "", diff --git a/ports/nrf/boards/actinius_icarus/board.json b/ports/nrf/boards/actinius_icarus/board.json index 86e7bd3508..c1d9f1c4ef 100644 --- a/ports/nrf/boards/actinius_icarus/board.json +++ b/ports/nrf/boards/actinius_icarus/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "icarus-v1.4-front-shadow-p-800.jpg" + ], "mcu": "nrf91", "product": "actinius_icarus", "thumbnail": "", - "url": "", - "vendor": "" + "url": "https://www.actinius.com/icarus", + "vendor": "Actinius" } diff --git a/ports/nrf/boards/blueio_tag_evim/board.json b/ports/nrf/boards/blueio_tag_evim/board.json index ed178d11da..5b6e5747d5 100644 --- a/ports/nrf/boards/blueio_tag_evim/board.json +++ b/ports/nrf/boards/blueio_tag_evim/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "blyst-nano-mod-4_jpg_project-body.jpg" + ], "mcu": "nrf52", "product": "blueio_tag_evim", "thumbnail": "", - "url": "", - "vendor": "" + "url": "https://www.i-syst.com/index.php/products/blyst-nano", + "vendor": "I-SYST" } diff --git a/ports/nrf/boards/dvk_bl652/board.json b/ports/nrf/boards/dvk_bl652/board.json index 1e2491010f..5c9cfad26e 100644 --- a/ports/nrf/boards/dvk_bl652/board.json +++ b/ports/nrf/boards/dvk_bl652/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "BL652-SA_JPG-500.jpg" + ], "mcu": "nrf52", "product": "dvk_bl652", "thumbnail": "", - "url": "", - "vendor": "" + "url": "https://www.lairdconnect.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl652-series-bluetooth-v5-nfc-module", + "vendor": "Laird Connectivity" } diff --git a/ports/nrf/boards/evk_nina_b1/board.json b/ports/nrf/boards/evk_nina_b1/board.json index a81e961fcc..657b0fa06d 100644 --- a/ports/nrf/boards/evk_nina_b1/board.json +++ b/ports/nrf/boards/evk_nina_b1/board.json @@ -2,12 +2,14 @@ "deploy": [ "../deploy.md" ], - "docs": "", + "docs": "https://www.u-blox.com/sites/default/files/EVK-NINA-B1_UserGuide_%28UBX-15028120%29.pdf", "features": [], - "images": [], + "images": [ + "EVK-NINA-B1_.jpg" + ], "mcu": "nrf52", "product": "evk_nina_b1", "thumbnail": "", - "url": "", - "vendor": "" + "url": "https://www.u-blox.com/en/product/evk-nina-b1", + "vendor": "u-blox" } diff --git a/ports/nrf/boards/evk_nina_b3/board.json b/ports/nrf/boards/evk_nina_b3/board.json index f71a6eff71..54e3dc3585 100644 --- a/ports/nrf/boards/evk_nina_b3/board.json +++ b/ports/nrf/boards/evk_nina_b3/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "EVK-NINA-B3-top.jpg" + ], "mcu": "nrf52", "product": "evk_nina_b3", "thumbnail": "", - "url": "", - "vendor": "" + "url": "https://www.u-blox.com/en/product/evk-nina-b3", + "vendor": "u-blox" } diff --git a/ports/nrf/boards/ibk_blyst_nano/board.json b/ports/nrf/boards/ibk_blyst_nano/board.json index f641f6b7d2..562c33607b 100644 --- a/ports/nrf/boards/ibk_blyst_nano/board.json +++ b/ports/nrf/boards/ibk_blyst_nano/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "blyst-nano-fingertip-close_jpg_content-body-gallery.jpg" + ], "mcu": "nrf52", "product": "ibk_blyst_nano", "thumbnail": "", - "url": "", - "vendor": "" + "url": "https://www.i-syst.com/products/blyst-nano", + "vendor": "I-SYST" } diff --git a/ports/nrf/boards/idk_blyst_nano/board.json b/ports/nrf/boards/idk_blyst_nano/board.json index 07b2748a76..199721698d 100644 --- a/ports/nrf/boards/idk_blyst_nano/board.json +++ b/ports/nrf/boards/idk_blyst_nano/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "blyst-nano-fingertip-close_jpg_content-body-gallery.jpg" + ], "mcu": "nrf52", "product": "idk_blyst_nano", "thumbnail": "", - "url": "", - "vendor": "" + "url": "https://www.i-syst.com/products/blyst-nano", + "vendor": "I-SYST" } diff --git a/ports/nrf/boards/microbit/board.json b/ports/nrf/boards/microbit/board.json index b7a041ad4d..872727bb97 100644 --- a/ports/nrf/boards/microbit/board.json +++ b/ports/nrf/boards/microbit/board.json @@ -4,7 +4,9 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "AF-3362-1.jpg" + ], "mcu": "nrf51", "product": "micro:bit v1", "thumbnail": "", diff --git a/ports/nrf/boards/nrf52840-mdk-usb-dongle/board.json b/ports/nrf/boards/nrf52840-mdk-usb-dongle/board.json index bbe03618da..853c375710 100644 --- a/ports/nrf/boards/nrf52840-mdk-usb-dongle/board.json +++ b/ports/nrf/boards/nrf52840-mdk-usb-dongle/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "dongle_pcba_case.jpg" + ], "mcu": "nrf52", "product": "nrf52840-mdk-usb-dongle", "thumbnail": "", - "url": "", + "url": "https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle", "vendor": "" } diff --git a/ports/nrf/boards/particle_xenon/board.json b/ports/nrf/boards/particle_xenon/board.json index ed1522be5b..1f6b90b753 100644 --- a/ports/nrf/boards/particle_xenon/board.json +++ b/ports/nrf/boards/particle_xenon/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "xenon-top.jpg" + ], "mcu": "nrf52", "product": "Xenon", "thumbnail": "", - "url": "", + "url": "https://docs.particle.io/xenon/", "vendor": "Particle" } diff --git a/ports/nrf/boards/pca10000/board.json b/ports/nrf/boards/pca10000/board.json index 6cae711f07..1f6e738697 100644 --- a/ports/nrf/boards/pca10000/board.json +++ b/ports/nrf/boards/pca10000/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "nRF51-Dongle.jpg" + ], "mcu": "nrf51", "product": "pca10000", "thumbnail": "", - "url": "", + "url": "https://www.nordicsemi.com/Products/Development-hardware/nRF51-Dongle", "vendor": "Nordic Semiconductor" } diff --git a/ports/nrf/boards/pca10001/board.json b/ports/nrf/boards/pca10001/board.json index 9f073b8190..ca1a42df7b 100644 --- a/ports/nrf/boards/pca10001/board.json +++ b/ports/nrf/boards/pca10001/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "nRF51-DK.jpg" + ], "mcu": "nrf51", "product": "pca10001", "thumbnail": "", - "url": "", + "url": "https://www.nordicsemi.com/Products/Development-hardware/nrf51-dk", "vendor": "Nordic Semiconductor" } diff --git a/ports/nrf/boards/pca10028/board.json b/ports/nrf/boards/pca10028/board.json index bda2c4d757..f80cea4699 100644 --- a/ports/nrf/boards/pca10028/board.json +++ b/ports/nrf/boards/pca10028/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "nRF51-DK.jpg" + ], "mcu": "nrf51", "product": "pca10028", "thumbnail": "", - "url": "", + "url": "https://www.nordicsemi.com/Products/Development-hardware/nRF51-DK", "vendor": "Nordic Semiconductor" } diff --git a/ports/nrf/boards/pca10031/board.json b/ports/nrf/boards/pca10031/board.json index caba44f328..fb7c774ca5 100644 --- a/ports/nrf/boards/pca10031/board.json +++ b/ports/nrf/boards/pca10031/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "nRF51-Dongle.jpg" + ], "mcu": "nrf51", "product": "pca10031", "thumbnail": "", - "url": "", + "url": "https://www.nordicsemi.com/Products/Development-hardware/nRF51-Dongle", "vendor": "Nordic Semiconductor" } diff --git a/ports/nrf/boards/pca10040/board.json b/ports/nrf/boards/pca10040/board.json index 55cef41862..d1680e53ad 100644 --- a/ports/nrf/boards/pca10040/board.json +++ b/ports/nrf/boards/pca10040/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "nRF52-DK-prod-page.jpg" + ], "mcu": "nrf52", "product": "pca10040", "thumbnail": "", - "url": "", + "url": "https://www.nordicsemi.com/Products/Development-hardware/nRF52-DK", "vendor": "Nordic Semiconductor" } diff --git a/ports/nrf/boards/pca10056/board.json b/ports/nrf/boards/pca10056/board.json index ed9b65baa3..763d8d824b 100644 --- a/ports/nrf/boards/pca10056/board.json +++ b/ports/nrf/boards/pca10056/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "nRF52840-DK-prod-page.jpg" + ], "mcu": "nrf52", "product": "pca10056", "thumbnail": "", - "url": "", + "url": "https://www.nordicsemi.com/Products/Development-hardware/nRF52840-DK", "vendor": "Nordic Semiconductor" } diff --git a/ports/nrf/boards/pca10059/board.json b/ports/nrf/boards/pca10059/board.json index 7b883c007e..14bd8bf7e8 100644 --- a/ports/nrf/boards/pca10059/board.json +++ b/ports/nrf/boards/pca10059/board.json @@ -10,6 +10,6 @@ "mcu": "nrf52", "product": "pca10059", "thumbnail": "", - "url": "", + "url": "https://www.nordicsemi.com/Products/Development-hardware/nRF52840-Dongle", "vendor": "Nordic Semiconductor" } diff --git a/ports/nrf/boards/pca10090/board.json b/ports/nrf/boards/pca10090/board.json index dd2e928e4c..56525ef3ac 100644 --- a/ports/nrf/boards/pca10090/board.json +++ b/ports/nrf/boards/pca10090/board.json @@ -4,10 +4,12 @@ ], "docs": "", "features": [], - "images": [], + "images": [ + "nRF59160-DK-prod-page.jpg" + ], "mcu": "nrf91", "product": "pca10090", "thumbnail": "", - "url": "", + "url": "https://www.nordicsemi.com/Products/Development-hardware/nrf9160-dk", "vendor": "Nordic Semiconductor" } diff --git a/ports/nrf/boards/wt51822_s4at/board.json b/ports/nrf/boards/wt51822_s4at/board.json index 3917265a9a..89d008c6f5 100644 --- a/ports/nrf/boards/wt51822_s4at/board.json +++ b/ports/nrf/boards/wt51822_s4at/board.json @@ -2,12 +2,14 @@ "deploy": [ "../deploy.md" ], - "docs": "", + "docs": "https://4tronix.co.uk/picobot2/WT51822-S4AT.pdf", "features": [], - "images": [], + "images": [ + "WT51822-S4AT.jpg" + ], "mcu": "nrf51", "product": "wt51822_s4at", "thumbnail": "", - "url": "", - "vendor": "" + "url": "http://www.wireless-tag.com/portfolio/wt51822-s4at-2/", + "vendor": "Wireless-Tag" } diff --git a/ports/rp2/boards/ADAFRUIT_FEATHER_RP2040/board.json b/ports/rp2/boards/ADAFRUIT_FEATHER_RP2040/board.json index a4caba335d..a7db469389 100644 --- a/ports/rp2/boards/ADAFRUIT_FEATHER_RP2040/board.json +++ b/ports/rp2/boards/ADAFRUIT_FEATHER_RP2040/board.json @@ -3,7 +3,15 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Battery Charging", + "Breadboard Friendly", + "Feather", + "RGB LED", + "SPI Flash", + "STEMMA QT/QWIIC", + "USB-C" + ], "images": [ "4884-06.jpg" ], diff --git a/ports/rp2/boards/ADAFRUIT_ITSYBITSY_RP2040/board.json b/ports/rp2/boards/ADAFRUIT_ITSYBITSY_RP2040/board.json index 1dcb999a86..7ca0db0698 100644 --- a/ports/rp2/boards/ADAFRUIT_ITSYBITSY_RP2040/board.json +++ b/ports/rp2/boards/ADAFRUIT_ITSYBITSY_RP2040/board.json @@ -3,7 +3,12 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Breadboard Friendly", + "Micro USB", + "RGB LED", + "SPI Flash" + ], "images": [ "4888-05.jpg" ], diff --git a/ports/rp2/boards/ADAFRUIT_QTPY_RP2040/board.json b/ports/rp2/boards/ADAFRUIT_QTPY_RP2040/board.json index d8efa83be4..d63166616f 100644 --- a/ports/rp2/boards/ADAFRUIT_QTPY_RP2040/board.json +++ b/ports/rp2/boards/ADAFRUIT_QTPY_RP2040/board.json @@ -3,7 +3,14 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Breadboard Friendly", + "Castellated Pads", + "RGB LED", + "SPI Flash", + "STEMMA QT/QWIIC", + "USB-C" + ], "images": [ "4900-12.jpg" ], diff --git a/ports/rp2/boards/PICO/board.json b/ports/rp2/boards/PICO/board.json index cc933c5a92..b8ccb3ba53 100644 --- a/ports/rp2/boards/PICO/board.json +++ b/ports/rp2/boards/PICO/board.json @@ -3,7 +3,11 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Breadboard friendly", + "Castellated Pads", + "Micro USB" + ], "id": "rp2-pico", "images": [ "rp2-pico.jpg" diff --git a/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/board.json b/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/board.json index 35e18cc8dc..9121154d81 100644 --- a/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/board.json +++ b/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/board.json @@ -3,7 +3,14 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Battery Charging", + "Breadboard Friendly", + "Castellated Pads", + "SPI Flash", + "STEMMA QT/QWIIC", + "USB-C" + ], "images": [ "PimoroniPicoLipo_1of3_1024x1024.jpg" ], diff --git a/ports/rp2/boards/PIMORONI_PICOLIPO_4MB/board.json b/ports/rp2/boards/PIMORONI_PICOLIPO_4MB/board.json index 5a8273cb5c..69d8532397 100644 --- a/ports/rp2/boards/PIMORONI_PICOLIPO_4MB/board.json +++ b/ports/rp2/boards/PIMORONI_PICOLIPO_4MB/board.json @@ -3,7 +3,14 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Battery Charging", + "Breadboard Friendly", + "Castellated Pads", + "SPI Flash", + "STEMMA QT/QWIIC", + "USB-C" + ], "images": [ "PimoroniPicoLipo_1of3_1024x1024.jpg" ], diff --git a/ports/rp2/boards/PIMORONI_TINY2040/board.json b/ports/rp2/boards/PIMORONI_TINY2040/board.json index cc7e643f41..753a25beae 100644 --- a/ports/rp2/boards/PIMORONI_TINY2040/board.json +++ b/ports/rp2/boards/PIMORONI_TINY2040/board.json @@ -3,7 +3,12 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Breadboard Friendly", + "Castellated Pads", + "RGB LED", + "USB-C" + ], "images": [ "tiny-2040-on-white-1_1024x1024.jpg" ], diff --git a/ports/rp2/boards/SPARKFUN_PROMICRO/board.json b/ports/rp2/boards/SPARKFUN_PROMICRO/board.json index 28e9764fe4..a0d39165af 100644 --- a/ports/rp2/boards/SPARKFUN_PROMICRO/board.json +++ b/ports/rp2/boards/SPARKFUN_PROMICRO/board.json @@ -3,13 +3,19 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Breadboard Friendly", + "Castellated Pads", + "RGB LED", + "STEMMA QT/QWIIC", + "USB-C" + ], "images": [ "17745-SparkFun_Thing_Plus_-_RP2040-01a.jpg" ], "mcu": "rp2040", "product": "Pro Micro RP2040", "thumbnail": "", - "url": "https://www.sparkfun.com/products/17717", + "url": "https://www.sparkfun.com/products/18288", "vendor": "Sparkfun" } diff --git a/ports/rp2/boards/SPARKFUN_THINGPLUS/board.json b/ports/rp2/boards/SPARKFUN_THINGPLUS/board.json index d864f67c11..871a411b5b 100644 --- a/ports/rp2/boards/SPARKFUN_THINGPLUS/board.json +++ b/ports/rp2/boards/SPARKFUN_THINGPLUS/board.json @@ -3,7 +3,16 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Battery Charging", + "Breadboard Friendly", + "Feather", + "MicroSD", + "RGB LED", + "SPI Flash", + "STEMMA QT/QWIIC", + "USB-C" + ], "images": [ "17745-SparkFun_Thing_Plus_-_RP2040-01a.jpg" ], diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/board.json b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/board.json index 8b91398e12..b0cb02cd4f 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/board.json +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/board.json @@ -3,7 +3,14 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Battery Charging", + "Breadboard Friendly", + "Feather", + "Micro USB", + "RGB LED", + "SPI Flash" + ], "images": [ "feather_m0_express.jpg" ], diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/board.json b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/board.json index 74b278b15b..83db285b4d 100644 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/board.json +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/board.json @@ -3,7 +3,12 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Breadboard Friendly", + "Micro USB", + "RGB LED", + "SPI Flash" + ], "images": [ "itsybitsy_m4_express.jpg" ], diff --git a/ports/samd/boards/ADAFRUIT_TRINKET_M0/board.json b/ports/samd/boards/ADAFRUIT_TRINKET_M0/board.json index 6d104fac18..9112bc06ef 100644 --- a/ports/samd/boards/ADAFRUIT_TRINKET_M0/board.json +++ b/ports/samd/boards/ADAFRUIT_TRINKET_M0/board.json @@ -3,7 +3,11 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Breadboard Friendly", + "Micro USB", + "RGB LED" + ], "images": [ "trinket_m0.jpg" ], diff --git a/ports/samd/boards/MINISAM_M4/board.json b/ports/samd/boards/MINISAM_M4/board.json index df63ec64b7..126e036400 100644 --- a/ports/samd/boards/MINISAM_M4/board.json +++ b/ports/samd/boards/MINISAM_M4/board.json @@ -3,7 +3,11 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Micro USB", + "RGB LED", + "SPI Flash" + ], "images": [ "mini_sam_m4.jpg" ], diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/board.json b/ports/samd/boards/SAMD21_XPLAINED_PRO/board.json index 0564e3f82a..4d22c42bad 100644 --- a/ports/samd/boards/SAMD21_XPLAINED_PRO/board.json +++ b/ports/samd/boards/SAMD21_XPLAINED_PRO/board.json @@ -3,7 +3,10 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "Micro USB", + "SPI Flash" + ], "images": ["2033-atsamd21-xpro.jpg"], "mcu": "samd21", "product": "SAMD21 Xplained Pro", From 3b011d5ef9f8f965ef1792e358976ba5e33b8182 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 28 Oct 2021 15:08:46 +1100 Subject: [PATCH 124/335] github/workflows: Add new workflow to build ports download metadata. Signed-off-by: Damien George --- .github/workflows/ports.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/ports.yml diff --git a/.github/workflows/ports.yml b/.github/workflows/ports.yml new file mode 100644 index 0000000000..e9e6de284c --- /dev/null +++ b/.github/workflows/ports.yml @@ -0,0 +1,18 @@ +name: Build ports metadata + +on: + push: + pull_request: + paths: + - '.github/workflows/*.yml' + - 'tools/**' + - ports/** + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Build ports download metadata + run: mkdir boards && ./tools/autobuild/build-downloads.py . ./boards From b4de39c43c85a63037422e4246c69320f50ad67f Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 1 Nov 2021 14:17:22 +1100 Subject: [PATCH 125/335] bare-arm/mpconfigport.h: Use MICROPY_CONFIG_ROM_LEVEL_MINIMUM. To simplify the config. This commit does not change the build. Signed-off-by: Damien George --- ports/bare-arm/mpconfigport.h | 37 ++++++++++++----------------------- 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/ports/bare-arm/mpconfigport.h b/ports/bare-arm/mpconfigport.h index 3bebc31594..1a6466ccf4 100644 --- a/ports/bare-arm/mpconfigport.h +++ b/ports/bare-arm/mpconfigport.h @@ -28,38 +28,27 @@ // Options to control how MicroPython is built +// Use the minimal starting configuration (disables all optional features). +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_MINIMUM) + // Memory allocation policy -#define MICROPY_QSTR_BYTES_IN_HASH (1) +#define MICROPY_GC_ALLOC_THRESHOLD (1) // Compiler configuration -#define MICROPY_COMP_CONST (0) -#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0) +#define MICROPY_ENABLE_COMPILER (1) +#define MICROPY_COMP_CONST_FOLDING (1) +#define MICROPY_COMP_CONST_LITERAL (1) // Python internal features -#define MICROPY_ENABLE_EXTERNAL_IMPORT (0) #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NONE) -#define MICROPY_CPYTHON_COMPAT (0) -#define MICROPY_MODULE_GETATTR (0) -#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) +#define MICROPY_FULL_CHECKS (1) // Fine control over Python builtins, classes, modules, etc -#define MICROPY_PY_ASYNC_AWAIT (0) -#define MICROPY_PY_ASSIGN_EXPR (0) -#define MICROPY_PY_BUILTINS_STR_COUNT (0) -#define MICROPY_PY_BUILTINS_STR_OP_MODULO (0) -#define MICROPY_PY_BUILTINS_BYTEARRAY (0) -#define MICROPY_PY_BUILTINS_DICT_FROMKEYS (0) -#define MICROPY_PY_BUILTINS_SET (0) -#define MICROPY_PY_BUILTINS_SLICE (0) -#define MICROPY_PY_BUILTINS_PROPERTY (0) -#define MICROPY_PY_BUILTINS_ENUMERATE (0) -#define MICROPY_PY_BUILTINS_REVERSED (0) -#define MICROPY_PY___FILE__ (0) -#define MICROPY_PY_ARRAY (0) -#define MICROPY_PY_COLLECTIONS (0) -#define MICROPY_PY_IO (0) -#define MICROPY_PY_STRUCT (0) -#define MICROPY_PY_SYS (0) +#define MICROPY_MULTIPLE_INHERITANCE (1) +#define MICROPY_PY_GENERATOR_PEND_THROW (1) +#define MICROPY_PY_BUILTINS_RANGE_ATTRS (1) +#define MICROPY_PY_BUILTINS_FILTER (1) +#define MICROPY_PY_BUILTINS_MIN_MAX (1) // Type definitions for the specific machine From ad17d9f0014bff0aab54365f6decc70bad42b138 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 1 Nov 2021 14:23:06 +1100 Subject: [PATCH 126/335] bare-arm/mpconfigport.h: Disable remaining optional features. Signed-off-by: Damien George --- ports/bare-arm/README.md | 2 +- ports/bare-arm/mpconfigport.h | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/ports/bare-arm/README.md b/ports/bare-arm/README.md index dfa5534d59..37e373e2b6 100644 --- a/ports/bare-arm/README.md +++ b/ports/bare-arm/README.md @@ -18,4 +18,4 @@ compiled and executed when the firmware starts. They produce output on the system's stdout. The size of the firmware (the machine code that is programmed to the -microcontroller's flash/ROM) is currently around 57900 bytes. +microcontroller's flash/ROM) is currently around 56500 bytes. diff --git a/ports/bare-arm/mpconfigport.h b/ports/bare-arm/mpconfigport.h index 1a6466ccf4..65bb67f7b9 100644 --- a/ports/bare-arm/mpconfigport.h +++ b/ports/bare-arm/mpconfigport.h @@ -31,24 +31,11 @@ // Use the minimal starting configuration (disables all optional features). #define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_MINIMUM) -// Memory allocation policy -#define MICROPY_GC_ALLOC_THRESHOLD (1) - // Compiler configuration #define MICROPY_ENABLE_COMPILER (1) -#define MICROPY_COMP_CONST_FOLDING (1) -#define MICROPY_COMP_CONST_LITERAL (1) // Python internal features #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NONE) -#define MICROPY_FULL_CHECKS (1) - -// Fine control over Python builtins, classes, modules, etc -#define MICROPY_MULTIPLE_INHERITANCE (1) -#define MICROPY_PY_GENERATOR_PEND_THROW (1) -#define MICROPY_PY_BUILTINS_RANGE_ATTRS (1) -#define MICROPY_PY_BUILTINS_FILTER (1) -#define MICROPY_PY_BUILTINS_MIN_MAX (1) // Type definitions for the specific machine From 0e236eef083ce36cf821a663cf0b3092055cf084 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 15 Sep 2021 23:18:23 +1000 Subject: [PATCH 127/335] py/mpconfig.h: Define the "extra" feature level. Some of these will later be moved to CORE or BASIC, but EXTRA is a good starting point based on what stm32 uses. Signed-off-by: Jim Mussared --- py/mpconfig.h | 142 +++++++++++++++++++++++++------------------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/py/mpconfig.h b/py/mpconfig.h index d20ad04480..4aea8f7ba9 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -440,7 +440,7 @@ // Whether to enable lookup of constants in modules; eg module.CONST #ifndef MICROPY_COMP_MODULE_CONST -#define MICROPY_COMP_MODULE_CONST (0) +#define MICROPY_COMP_MODULE_CONST (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to enable constant optimisation; id = const(value) @@ -457,13 +457,13 @@ // Whether to enable optimisation of: a, b, c = d, e, f // Requires MICROPY_COMP_DOUBLE_TUPLE_ASSIGN and costs 68 bytes (Thumb2) #ifndef MICROPY_COMP_TRIPLE_TUPLE_ASSIGN -#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0) +#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to enable optimisation of: return a if b else c // Costs about 80 bytes (Thumb2) and saves 2 bytes of bytecode for each use #ifndef MICROPY_COMP_RETURN_IF_EXPR -#define MICROPY_COMP_RETURN_IF_EXPR (0) +#define MICROPY_COMP_RETURN_IF_EXPR (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif /*****************************************************************************/ @@ -521,7 +521,7 @@ // Optimise the fast path for loading attributes from instance types. Increases // Thumb2 code size by about 48 bytes. #ifndef MICROPY_OPT_LOAD_ATTR_FAST_PATH -#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (0) +#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Use extra RAM to cache map lookups by remembering the likely location of @@ -530,7 +530,7 @@ // performance improvement on benchmarks involving lots of attribute access // or dictionary lookup. #ifndef MICROPY_OPT_MAP_LOOKUP_CACHE -#define MICROPY_OPT_MAP_LOOKUP_CACHE (0) +#define MICROPY_OPT_MAP_LOOKUP_CACHE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // How much RAM (in bytes) to use for the map lookup cache. @@ -541,13 +541,13 @@ // Whether to use fast versions of bitwise operations (and, or, xor) when the // arguments are both positive. Increases Thumb2 code size by about 250 bytes. #ifndef MICROPY_OPT_MPZ_BITWISE -#define MICROPY_OPT_MPZ_BITWISE (0) +#define MICROPY_OPT_MPZ_BITWISE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether math.factorial is large, fast and recursive (1) or small and slow (0). #ifndef MICROPY_OPT_MATH_FACTORIAL -#define MICROPY_OPT_MATH_FACTORIAL (0) +#define MICROPY_OPT_MATH_FACTORIAL (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif /*****************************************************************************/ @@ -604,7 +604,7 @@ // Whether to enable finalisers in the garbage collector (ie call __del__) #ifndef MICROPY_ENABLE_FINALISER -#define MICROPY_ENABLE_FINALISER (0) +#define MICROPY_ENABLE_FINALISER (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to enable a separate allocator for the Python stack. @@ -621,7 +621,7 @@ // Whether to check C stack usage. C stack used for calling Python functions, // etc. Not checking means segfault on overflow. #ifndef MICROPY_STACK_CHECK -#define MICROPY_STACK_CHECK (0) +#define MICROPY_STACK_CHECK (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to have an emergency exception buffer @@ -636,7 +636,7 @@ // Whether to provide the mp_kbd_exception object, and micropython.kbd_intr function #ifndef MICROPY_KBD_EXCEPTION -#define MICROPY_KBD_EXCEPTION (0) +#define MICROPY_KBD_EXCEPTION (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Prefer to raise KeyboardInterrupt asynchronously (from signal or interrupt @@ -647,17 +647,17 @@ // Whether to include REPL helper function #ifndef MICROPY_HELPER_REPL -#define MICROPY_HELPER_REPL (0) +#define MICROPY_HELPER_REPL (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Allow enabling debug prints after each REPL line #ifndef MICROPY_REPL_INFO -#define MICROPY_REPL_INFO (0) +#define MICROPY_REPL_INFO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to include emacs-style readline behavior in REPL #ifndef MICROPY_REPL_EMACS_KEYS -#define MICROPY_REPL_EMACS_KEYS (0) +#define MICROPY_REPL_EMACS_KEYS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to include emacs-style word movement/kill readline behavior in REPL. @@ -677,7 +677,7 @@ // Whether to implement auto-indent in REPL #ifndef MICROPY_REPL_AUTO_INDENT -#define MICROPY_REPL_AUTO_INDENT (0) +#define MICROPY_REPL_AUTO_INDENT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether port requires event-driven REPL functions @@ -706,7 +706,7 @@ typedef long long mp_longint_impl_t; // Whether to include information in the byte code to determine source // line number (increases RAM usage, but doesn't slow byte code execution) #ifndef MICROPY_ENABLE_SOURCE_LINE -#define MICROPY_ENABLE_SOURCE_LINE (0) +#define MICROPY_ENABLE_SOURCE_LINE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to include doc strings (increases RAM usage) @@ -800,7 +800,7 @@ typedef double mp_float_t; // Whether POSIX-semantics non-blocking streams are supported #ifndef MICROPY_STREAMS_NON_BLOCK -#define MICROPY_STREAMS_NON_BLOCK (0) +#define MICROPY_STREAMS_NON_BLOCK (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide stream functions with POSIX-like signatures @@ -811,7 +811,7 @@ typedef double mp_float_t; // Whether to call __init__ when importing builtin modules for the first time #ifndef MICROPY_MODULE_BUILTIN_INIT -#define MICROPY_MODULE_BUILTIN_INIT (0) +#define MICROPY_MODULE_BUILTIN_INIT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support module-level __getattr__ (see PEP 562) @@ -821,7 +821,7 @@ typedef double mp_float_t; // Whether module weak links are supported #ifndef MICROPY_MODULE_WEAK_LINKS -#define MICROPY_MODULE_WEAK_LINKS (0) +#define MICROPY_MODULE_WEAK_LINKS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether frozen modules are supported in the form of strings @@ -841,7 +841,7 @@ typedef double mp_float_t; // Whether you can override builtins in the builtins module #ifndef MICROPY_CAN_OVERRIDE_BUILTINS -#define MICROPY_CAN_OVERRIDE_BUILTINS (0) +#define MICROPY_CAN_OVERRIDE_BUILTINS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to check that the "self" argument of a builtin method has the @@ -865,7 +865,7 @@ typedef double mp_float_t; // Support for internal scheduler #ifndef MICROPY_ENABLE_SCHEDULER -#define MICROPY_ENABLE_SCHEDULER (0) +#define MICROPY_ENABLE_SCHEDULER (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Maximum number of entries in the scheduler @@ -900,21 +900,21 @@ typedef double mp_float_t; // Whether to implement attributes on functions #ifndef MICROPY_PY_FUNCTION_ATTRS -#define MICROPY_PY_FUNCTION_ATTRS (0) +#define MICROPY_PY_FUNCTION_ATTRS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support the descriptors __get__, __set__, __delete__ // This costs some code size and makes load/store/delete of instance // attributes slower for the classes that use this feature #ifndef MICROPY_PY_DESCRIPTORS -#define MICROPY_PY_DESCRIPTORS (0) +#define MICROPY_PY_DESCRIPTORS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support class __delattr__ and __setattr__ methods // This costs some code size and makes store/delete of instance // attributes slower for the classes that use this feature #ifndef MICROPY_PY_DELATTR_SETATTR -#define MICROPY_PY_DELATTR_SETATTR (0) +#define MICROPY_PY_DELATTR_SETATTR (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Support for async/await/async for/async with @@ -924,7 +924,7 @@ typedef double mp_float_t; // Support for literal string interpolation, f-strings (see PEP 498, Python 3.6+) #ifndef MICROPY_PY_FSTRINGS -#define MICROPY_PY_FSTRINGS (0) +#define MICROPY_PY_FSTRINGS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Support for assignment expressions with := (see PEP 572, Python 3.8+) @@ -948,7 +948,7 @@ typedef double mp_float_t; // Whether str object is proper unicode #ifndef MICROPY_PY_BUILTINS_STR_UNICODE -#define MICROPY_PY_BUILTINS_STR_UNICODE (0) +#define MICROPY_PY_BUILTINS_STR_UNICODE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to check for valid UTF-8 when converting bytes to str @@ -958,7 +958,7 @@ typedef double mp_float_t; // Whether str.center() method provided #ifndef MICROPY_PY_BUILTINS_STR_CENTER -#define MICROPY_PY_BUILTINS_STR_CENTER (0) +#define MICROPY_PY_BUILTINS_STR_CENTER (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether str.count() method provided @@ -973,12 +973,12 @@ typedef double mp_float_t; // Whether str.partition()/str.rpartition() method provided #ifndef MICROPY_PY_BUILTINS_STR_PARTITION -#define MICROPY_PY_BUILTINS_STR_PARTITION (0) +#define MICROPY_PY_BUILTINS_STR_PARTITION (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether str.splitlines() method provided #ifndef MICROPY_PY_BUILTINS_STR_SPLITLINES -#define MICROPY_PY_BUILTINS_STR_SPLITLINES (0) +#define MICROPY_PY_BUILTINS_STR_SPLITLINES (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support bytearray object @@ -993,7 +993,7 @@ typedef double mp_float_t; // Whether to support memoryview object #ifndef MICROPY_PY_BUILTINS_MEMORYVIEW -#define MICROPY_PY_BUILTINS_MEMORYVIEW (0) +#define MICROPY_PY_BUILTINS_MEMORYVIEW (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support memoryview.itemsize attribute @@ -1014,17 +1014,17 @@ typedef double mp_float_t; // Whether to support slice attribute read access, // i.e. slice.start, slice.stop, slice.step #ifndef MICROPY_PY_BUILTINS_SLICE_ATTRS -#define MICROPY_PY_BUILTINS_SLICE_ATTRS (0) +#define MICROPY_PY_BUILTINS_SLICE_ATTRS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support the .indices(len) method on slice objects #ifndef MICROPY_PY_BUILTINS_SLICE_INDICES -#define MICROPY_PY_BUILTINS_SLICE_INDICES (0) +#define MICROPY_PY_BUILTINS_SLICE_INDICES (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support frozenset object #ifndef MICROPY_PY_BUILTINS_FROZENSET -#define MICROPY_PY_BUILTINS_FROZENSET (0) +#define MICROPY_PY_BUILTINS_FROZENSET (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support property object @@ -1053,7 +1053,7 @@ typedef double mp_float_t; // Whether to support rounding of integers (incl bignum); eg round(123,-1)=120 #ifndef MICROPY_PY_BUILTINS_ROUND_INT -#define MICROPY_PY_BUILTINS_ROUND_INT (0) +#define MICROPY_PY_BUILTINS_ROUND_INT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support complete set of special methods for user @@ -1062,7 +1062,7 @@ typedef double mp_float_t; // "Reverse" methods are controlled by // MICROPY_PY_REVERSE_SPECIAL_METHODS below. #ifndef MICROPY_PY_ALL_SPECIAL_METHODS -#define MICROPY_PY_ALL_SPECIAL_METHODS (0) +#define MICROPY_PY_ALL_SPECIAL_METHODS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support all inplace arithmetic operarion methods @@ -1075,12 +1075,12 @@ typedef double mp_float_t; // (__radd__, etc.). Additionally gated by // MICROPY_PY_ALL_SPECIAL_METHODS. #ifndef MICROPY_PY_REVERSE_SPECIAL_METHODS -#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0) +#define MICROPY_PY_REVERSE_SPECIAL_METHODS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support compile function #ifndef MICROPY_PY_BUILTINS_COMPILE -#define MICROPY_PY_BUILTINS_COMPILE (0) +#define MICROPY_PY_BUILTINS_COMPILE (MICROPY_ENABLE_COMPILER && MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support enumerate function(type) @@ -1096,7 +1096,7 @@ typedef double mp_float_t; // Whether to support the Python 2 execfile function #ifndef MICROPY_PY_BUILTINS_EXECFILE -#define MICROPY_PY_BUILTINS_EXECFILE (0) +#define MICROPY_PY_BUILTINS_EXECFILE (MICROPY_ENABLE_COMPILER && MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support filter function(type) @@ -1111,13 +1111,13 @@ typedef double mp_float_t; // Whether to define "NotImplemented" special constant #ifndef MICROPY_PY_BUILTINS_NOTIMPLEMENTED -#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) +#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide the built-in input() function. The implementation of this // uses shared/readline, so can only be enabled if the port uses this readline. #ifndef MICROPY_PY_BUILTINS_INPUT -#define MICROPY_PY_BUILTINS_INPUT (0) +#define MICROPY_PY_BUILTINS_INPUT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support min/max functions @@ -1127,12 +1127,12 @@ typedef double mp_float_t; // Support for calls to pow() with 3 integer arguments #ifndef MICROPY_PY_BUILTINS_POW3 -#define MICROPY_PY_BUILTINS_POW3 (0) +#define MICROPY_PY_BUILTINS_POW3 (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide the help function #ifndef MICROPY_PY_BUILTINS_HELP -#define MICROPY_PY_BUILTINS_HELP (0) +#define MICROPY_PY_BUILTINS_HELP (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Use this to configure the help text shown for help(). It should be a @@ -1143,7 +1143,7 @@ typedef double mp_float_t; // Add the ability to list the available modules when executing help('modules') #ifndef MICROPY_PY_BUILTINS_HELP_MODULES -#define MICROPY_PY_BUILTINS_HELP_MODULES (0) +#define MICROPY_PY_BUILTINS_HELP_MODULES (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to set __file__ for imported modules @@ -1153,7 +1153,7 @@ typedef double mp_float_t; // Whether to provide mem-info related functions in micropython module #ifndef MICROPY_PY_MICROPYTHON_MEM_INFO -#define MICROPY_PY_MICROPYTHON_MEM_INFO (0) +#define MICROPY_PY_MICROPYTHON_MEM_INFO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide "micropython.stack_use" function @@ -1176,7 +1176,7 @@ typedef double mp_float_t; // Whether to support slice assignments for array (and bytearray). // This is rarely used, but adds ~0.5K of code. #ifndef MICROPY_PY_ARRAY_SLICE_ASSIGN -#define MICROPY_PY_ARRAY_SLICE_ASSIGN (0) +#define MICROPY_PY_ARRAY_SLICE_ASSIGN (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support attrtuple type (MicroPython extension) @@ -1192,12 +1192,12 @@ typedef double mp_float_t; // Whether to provide "ucollections.deque" type #ifndef MICROPY_PY_COLLECTIONS_DEQUE -#define MICROPY_PY_COLLECTIONS_DEQUE (0) +#define MICROPY_PY_COLLECTIONS_DEQUE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide "collections.OrderedDict" type #ifndef MICROPY_PY_COLLECTIONS_ORDEREDDICT -#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (0) +#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide the _asdict function for namedtuple @@ -1212,17 +1212,17 @@ typedef double mp_float_t; // Whether to provide special math functions: math.{erf,erfc,gamma,lgamma} #ifndef MICROPY_PY_MATH_SPECIAL_FUNCTIONS -#define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (0) +#define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide math.factorial function #ifndef MICROPY_PY_MATH_FACTORIAL -#define MICROPY_PY_MATH_FACTORIAL (0) +#define MICROPY_PY_MATH_FACTORIAL (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide math.isclose function #ifndef MICROPY_PY_MATH_ISCLOSE -#define MICROPY_PY_MATH_ISCLOSE (0) +#define MICROPY_PY_MATH_ISCLOSE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide fix for atan2 Inf handling. @@ -1247,7 +1247,7 @@ typedef double mp_float_t; // Whether to provide "cmath" module #ifndef MICROPY_PY_CMATH -#define MICROPY_PY_CMATH (0) +#define MICROPY_PY_CMATH (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide "gc" module @@ -1267,7 +1267,7 @@ typedef double mp_float_t; // Whether to provide "io.IOBase" class to support user streams #ifndef MICROPY_PY_IO_IOBASE -#define MICROPY_PY_IO_IOBASE (0) +#define MICROPY_PY_IO_IOBASE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide "uio.resource_stream()" function with @@ -1283,7 +1283,7 @@ typedef double mp_float_t; // Whether to provide "io.FileIO" class #ifndef MICROPY_PY_IO_FILEIO -#define MICROPY_PY_IO_FILEIO (0) +#define MICROPY_PY_IO_FILEIO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide "io.BytesIO" class @@ -1308,7 +1308,7 @@ typedef double mp_float_t; // Whether to provide "sys.maxsize" constant #ifndef MICROPY_PY_SYS_MAXSIZE -#define MICROPY_PY_SYS_MAXSIZE (0) +#define MICROPY_PY_SYS_MAXSIZE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide "sys.modules" dictionary @@ -1344,18 +1344,18 @@ typedef double mp_float_t; // Whether to provide sys.{stdin,stdout,stderr} objects #ifndef MICROPY_PY_SYS_STDFILES -#define MICROPY_PY_SYS_STDFILES (0) +#define MICROPY_PY_SYS_STDFILES (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide sys.{stdin,stdout,stderr}.buffer object // This is implemented per-port #ifndef MICROPY_PY_SYS_STDIO_BUFFER -#define MICROPY_PY_SYS_STDIO_BUFFER (0) +#define MICROPY_PY_SYS_STDIO_BUFFER (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide "uerrno" module #ifndef MICROPY_PY_UERRNO -#define MICROPY_PY_UERRNO (0) +#define MICROPY_PY_UERRNO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide the uerrno.errorcode dict @@ -1365,7 +1365,7 @@ typedef double mp_float_t; // Whether to provide "uselect" module (baremetal implementation) #ifndef MICROPY_PY_USELECT -#define MICROPY_PY_USELECT (0) +#define MICROPY_PY_USELECT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to enable the select() function in the "uselect" module (baremetal @@ -1411,11 +1411,11 @@ typedef double mp_float_t; // Extended modules #ifndef MICROPY_PY_UASYNCIO -#define MICROPY_PY_UASYNCIO (0) +#define MICROPY_PY_UASYNCIO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif #ifndef MICROPY_PY_UCTYPES -#define MICROPY_PY_UCTYPES (0) +#define MICROPY_PY_UCTYPES (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to provide SHORT, INT, LONG, etc. types in addition to @@ -1425,11 +1425,11 @@ typedef double mp_float_t; #endif #ifndef MICROPY_PY_UZLIB -#define MICROPY_PY_UZLIB (0) +#define MICROPY_PY_UZLIB (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif #ifndef MICROPY_PY_UJSON -#define MICROPY_PY_UJSON (0) +#define MICROPY_PY_UJSON (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to support the "separators" argument to dump, dumps @@ -1438,7 +1438,7 @@ typedef double mp_float_t; #endif #ifndef MICROPY_PY_URE -#define MICROPY_PY_URE (0) +#define MICROPY_PY_URE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif #ifndef MICROPY_PY_URE_DEBUG @@ -1454,20 +1454,20 @@ typedef double mp_float_t; #endif #ifndef MICROPY_PY_URE_SUB -#define MICROPY_PY_URE_SUB (0) +#define MICROPY_PY_URE_SUB (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif #ifndef MICROPY_PY_UHEAPQ -#define MICROPY_PY_UHEAPQ (0) +#define MICROPY_PY_UHEAPQ (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif -// Optimized heap queue for relative timestamps +// Optimized heap queue for relative timestamps (only used by uasyncio v2) #ifndef MICROPY_PY_UTIMEQ #define MICROPY_PY_UTIMEQ (0) #endif #ifndef MICROPY_PY_UHASHLIB -#define MICROPY_PY_UHASHLIB (0) +#define MICROPY_PY_UHASHLIB (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif #ifndef MICROPY_PY_UHASHLIB_MD5 @@ -1496,21 +1496,21 @@ typedef double mp_float_t; #endif #ifndef MICROPY_PY_UBINASCII -#define MICROPY_PY_UBINASCII (0) +#define MICROPY_PY_UBINASCII (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Depends on MICROPY_PY_UZLIB #ifndef MICROPY_PY_UBINASCII_CRC32 -#define MICROPY_PY_UBINASCII_CRC32 (0) +#define MICROPY_PY_UBINASCII_CRC32 (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif #ifndef MICROPY_PY_URANDOM -#define MICROPY_PY_URANDOM (0) +#define MICROPY_PY_URANDOM (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif // Whether to include: randrange, randint, choice, random, uniform #ifndef MICROPY_PY_URANDOM_EXTRA_FUNCS -#define MICROPY_PY_URANDOM_EXTRA_FUNCS (0) +#define MICROPY_PY_URANDOM_EXTRA_FUNCS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif #ifndef MICROPY_PY_MACHINE @@ -1556,7 +1556,7 @@ typedef double mp_float_t; #endif #ifndef MICROPY_PY_FRAMEBUF -#define MICROPY_PY_FRAMEBUF (0) +#define MICROPY_PY_FRAMEBUF (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif #ifndef MICROPY_PY_BTREE From 30418813530ee3239c7d7a649ee9fafa8af1f783 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 15 Sep 2021 23:18:35 +1000 Subject: [PATCH 128/335] stm32/mpconfigport.h: Use the "extra" feature level. This commit is a no-op change. Future improvements can come from making individual boards use CORE or BASIC. Signed-off-by: Jim Mussared --- ports/stm32/mpconfigport.h | 122 +++++-------------------------------- 1 file changed, 14 insertions(+), 108 deletions(-) diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 6a9e8bf414..f96d175748 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -31,6 +31,10 @@ #include "mpconfigboard.h" #include "mpconfigboard_common.h" +#ifndef MICROPY_CONFIG_ROM_LEVEL +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES) +#endif + // memory allocation policies #ifndef MICROPY_GC_STACK_ENTRY_TYPE #if MICROPY_HW_SDRAM_SIZE @@ -41,6 +45,16 @@ #endif #define MICROPY_ALLOC_PATH_MAX (128) +// optimisations +#ifndef MICROPY_OPT_COMPUTED_GOTO +#define MICROPY_OPT_COMPUTED_GOTO (1) +#endif + +// Don't enable lookup cache on M0 (low RAM) +#ifndef MICROPY_OPT_MAP_LOOKUP_CACHE +#define MICROPY_OPT_MAP_LOOKUP_CACHE (__CORTEX_M > 0) +#endif + // emitters #define MICROPY_PERSISTENT_CODE_LOAD (1) #ifndef MICROPY_EMIT_THUMB @@ -50,146 +64,41 @@ #define MICROPY_EMIT_INLINE_THUMB (1) #endif -// compiler configuration -#define MICROPY_COMP_MODULE_CONST (1) -#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (1) -#define MICROPY_COMP_RETURN_IF_EXPR (1) - -// optimisations -#ifndef MICROPY_OPT_COMPUTED_GOTO -#define MICROPY_OPT_COMPUTED_GOTO (1) -#endif -#ifndef MICROPY_OPT_LOAD_ATTR_FAST_PATH -#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (1) -#endif -#ifndef MICROPY_OPT_MAP_LOOKUP_CACHE -#define MICROPY_OPT_MAP_LOOKUP_CACHE (__CORTEX_M > 0) -#endif -#define MICROPY_OPT_MPZ_BITWISE (1) -#define MICROPY_OPT_MATH_FACTORIAL (1) - // Python internal features #define MICROPY_READER_VFS (1) #define MICROPY_ENABLE_GC (1) -#define MICROPY_ENABLE_FINALISER (1) -#define MICROPY_STACK_CHECK (1) #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) #define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0) -#define MICROPY_KBD_EXCEPTION (1) -#define MICROPY_HELPER_REPL (1) -#define MICROPY_REPL_INFO (1) -#define MICROPY_REPL_EMACS_KEYS (1) -#define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) -#define MICROPY_ENABLE_SOURCE_LINE (1) #ifndef MICROPY_FLOAT_IMPL // can be configured by each board via mpconfigboard.mk #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) #endif -#define MICROPY_STREAMS_NON_BLOCK (1) -#define MICROPY_MODULE_BUILTIN_INIT (1) -#define MICROPY_MODULE_WEAK_LINKS (1) -#define MICROPY_CAN_OVERRIDE_BUILTINS (1) #define MICROPY_USE_INTERNAL_ERRNO (1) -#define MICROPY_ENABLE_SCHEDULER (1) #define MICROPY_SCHEDULER_DEPTH (8) #define MICROPY_VFS (1) // control over Python builtins -#define MICROPY_PY_FUNCTION_ATTRS (1) -#define MICROPY_PY_DESCRIPTORS (1) -#define MICROPY_PY_DELATTR_SETATTR (1) -#ifndef MICROPY_PY_FSTRINGS -#define MICROPY_PY_FSTRINGS (1) -#endif -#define MICROPY_PY_BUILTINS_STR_UNICODE (1) -#define MICROPY_PY_BUILTINS_STR_CENTER (1) -#define MICROPY_PY_BUILTINS_STR_PARTITION (1) -#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1) -#define MICROPY_PY_BUILTINS_MEMORYVIEW (1) -#define MICROPY_PY_BUILTINS_FROZENSET (1) -#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) -#define MICROPY_PY_BUILTINS_SLICE_INDICES (1) -#define MICROPY_PY_BUILTINS_ROUND_INT (1) -#define MICROPY_PY_ALL_SPECIAL_METHODS (1) -#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) -#define MICROPY_PY_BUILTINS_COMPILE (MICROPY_ENABLE_COMPILER) -#define MICROPY_PY_BUILTINS_EXECFILE (MICROPY_ENABLE_COMPILER) -#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) -#define MICROPY_PY_BUILTINS_INPUT (1) -#define MICROPY_PY_BUILTINS_POW3 (1) -#define MICROPY_PY_BUILTINS_HELP (1) #ifndef MICROPY_PY_BUILTINS_HELP_TEXT #define MICROPY_PY_BUILTINS_HELP_TEXT stm32_help_text #endif -#define MICROPY_PY_BUILTINS_HELP_MODULES (1) -#define MICROPY_PY_MICROPYTHON_MEM_INFO (1) -#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) -#define MICROPY_PY_COLLECTIONS_DEQUE (1) -#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) -#define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1) -#define MICROPY_PY_MATH_ISCLOSE (1) -#define MICROPY_PY_MATH_FACTORIAL (1) -#define MICROPY_PY_CMATH (1) -#define MICROPY_PY_IO (1) -#define MICROPY_PY_IO_IOBASE (1) #define MICROPY_PY_IO_FILEIO (MICROPY_VFS_FAT || MICROPY_VFS_LFS1 || MICROPY_VFS_LFS2) -#define MICROPY_PY_SYS_MAXSIZE (1) -#define MICROPY_PY_SYS_EXIT (1) -#define MICROPY_PY_SYS_STDFILES (1) -#define MICROPY_PY_SYS_STDIO_BUFFER (1) #ifndef MICROPY_PY_SYS_PLATFORM // let boards override it if they want #define MICROPY_PY_SYS_PLATFORM "pyboard" #endif -#define MICROPY_PY_UERRNO (1) #ifndef MICROPY_PY_THREAD #define MICROPY_PY_THREAD (0) #endif // extended modules -#ifndef MICROPY_PY_UASYNCIO -#define MICROPY_PY_UASYNCIO (1) -#endif -#ifndef MICROPY_PY_UCTYPES -#define MICROPY_PY_UCTYPES (1) -#endif -#ifndef MICROPY_PY_UZLIB -#define MICROPY_PY_UZLIB (1) -#endif -#ifndef MICROPY_PY_UJSON -#define MICROPY_PY_UJSON (1) -#endif -#ifndef MICROPY_PY_URE -#define MICROPY_PY_URE (1) -#endif -#ifndef MICROPY_PY_URE_SUB -#define MICROPY_PY_URE_SUB (1) -#endif -#ifndef MICROPY_PY_UHEAPQ -#define MICROPY_PY_UHEAPQ (1) -#endif -#ifndef MICROPY_PY_UHASHLIB -#define MICROPY_PY_UHASHLIB (1) -#endif #define MICROPY_PY_UHASHLIB_MD5 (MICROPY_PY_USSL) #define MICROPY_PY_UHASHLIB_SHA1 (MICROPY_PY_USSL) #define MICROPY_PY_UCRYPTOLIB (MICROPY_PY_USSL) -#ifndef MICROPY_PY_UBINASCII -#define MICROPY_PY_UBINASCII (1) -#define MICROPY_PY_UBINASCII_CRC32 (1) -#endif #ifndef MICROPY_PY_UOS #define MICROPY_PY_UOS (1) #endif #define MICROPY_PY_OS_DUPTERM (3) #define MICROPY_PY_UOS_DUPTERM_BUILTIN_STREAM (1) -#ifndef MICROPY_PY_URANDOM -#define MICROPY_PY_URANDOM (1) #define MICROPY_PY_URANDOM_SEED_INIT_FUNC (rng_get()) -#endif -#ifndef MICROPY_PY_URANDOM_EXTRA_FUNCS -#define MICROPY_PY_URANDOM_EXTRA_FUNCS (1) -#endif -#define MICROPY_PY_USELECT (1) #ifndef MICROPY_PY_UTIME #define MICROPY_PY_UTIME (1) #endif @@ -216,9 +125,6 @@ #define MICROPY_HW_SOFTSPI_MAX_BAUDRATE (HAL_RCC_GetSysClockFreq() / 48) #define MICROPY_PY_UWEBSOCKET (MICROPY_PY_LWIP) #define MICROPY_PY_WEBREPL (MICROPY_PY_LWIP) -#ifndef MICROPY_PY_FRAMEBUF -#define MICROPY_PY_FRAMEBUF (1) -#endif #ifndef MICROPY_PY_USOCKET #define MICROPY_PY_USOCKET (1) #endif From b1a0ce46d10e29d8d630d70bcbeabfe36ce3b0bc Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 15 Sep 2021 23:41:40 +1000 Subject: [PATCH 129/335] rp2/mpconfigport.h: Use the "extra" feature level. This commit is a no-op change to simplify existing config. Signed-off-by: Jim Mussared --- ports/rp2/mpconfigport.h | 78 ++++++++++------------------------------ 1 file changed, 19 insertions(+), 59 deletions(-) diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index cc979b5c30..57fedc724e 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -38,6 +38,10 @@ #define MICROPY_HW_ENABLE_UART_REPL (0) // useful if there is no USB #define MICROPY_HW_ENABLE_USBDEV (1) +#ifndef MICROPY_CONFIG_ROM_LEVEL +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES) +#endif + // Memory allocation policies #define MICROPY_GC_STACK_ENTRY_TYPE uint16_t #define MICROPY_ALLOC_PATH_MAX (128) @@ -51,84 +55,41 @@ #define MICROPY_EMIT_INLINE_THUMB_FLOAT (0) #define MICROPY_EMIT_INLINE_THUMB_ARMV7M (0) +// Features currently overriden for rp2, planned to be brought in line with +// other ports +#define MICROPY_COMP_MODULE_CONST (0) +#define MICROPY_COMP_RETURN_IF_EXPR (0) +#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0) +#define MICROPY_OPT_COMPUTED_GOTO (0) +#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (0) +#define MICROPY_OPT_MAP_LOOKUP_CACHE (0) +#define MICROPY_OPT_MATH_FACTORIAL (0) +#define MICROPY_OPT_MPZ_BITWISE (0) +#define MICROPY_PY_BUILTINS_EXECFILE (0) +#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) +#define MICROPY_REPL_EMACS_KEYS (0) +#define MICROPY_REPL_INFO (0) + // Python internal features #define MICROPY_READER_VFS (1) #define MICROPY_ENABLE_GC (1) -#define MICROPY_ENABLE_FINALISER (1) -#define MICROPY_STACK_CHECK (1) #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) -#define MICROPY_KBD_EXCEPTION (1) -#define MICROPY_HELPER_REPL (1) -#define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) -#define MICROPY_ENABLE_SOURCE_LINE (1) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) -#define MICROPY_STREAMS_NON_BLOCK (1) -#define MICROPY_MODULE_BUILTIN_INIT (1) -#define MICROPY_MODULE_WEAK_LINKS (1) -#define MICROPY_CAN_OVERRIDE_BUILTINS (1) -#define MICROPY_ENABLE_SCHEDULER (1) #define MICROPY_SCHEDULER_DEPTH (8) // Fine control over Python builtins, classes, modules, etc -#define MICROPY_PY_FUNCTION_ATTRS (1) -#define MICROPY_PY_DESCRIPTORS (1) -#define MICROPY_PY_DELATTR_SETATTR (1) -#define MICROPY_PY_FSTRINGS (1) -#define MICROPY_PY_BUILTINS_STR_UNICODE (1) -#define MICROPY_PY_BUILTINS_STR_CENTER (1) -#define MICROPY_PY_BUILTINS_STR_PARTITION (1) -#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1) -#define MICROPY_PY_BUILTINS_MEMORYVIEW (1) -#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) -#define MICROPY_PY_BUILTINS_SLICE_INDICES (1) -#define MICROPY_PY_BUILTINS_FROZENSET (1) -#define MICROPY_PY_BUILTINS_ROUND_INT (1) -#define MICROPY_PY_ALL_SPECIAL_METHODS (1) -#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) -#define MICROPY_PY_BUILTINS_COMPILE (1) -#define MICROPY_PY_BUILTINS_INPUT (1) -#define MICROPY_PY_BUILTINS_POW3 (1) -#define MICROPY_PY_BUILTINS_HELP (1) #define MICROPY_PY_BUILTINS_HELP_TEXT rp2_help_text -#define MICROPY_PY_BUILTINS_HELP_MODULES (1) -#define MICROPY_PY_MICROPYTHON_MEM_INFO (1) -#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) -#define MICROPY_PY_COLLECTIONS_DEQUE (1) -#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) -#define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1) -#define MICROPY_PY_MATH_FACTORIAL (1) -#define MICROPY_PY_MATH_ISCLOSE (1) -#define MICROPY_PY_CMATH (1) -#define MICROPY_PY_IO_IOBASE (1) -#define MICROPY_PY_IO_FILEIO (1) -#define MICROPY_PY_SYS_MAXSIZE (1) -#define MICROPY_PY_SYS_STDFILES (1) -#define MICROPY_PY_SYS_STDIO_BUFFER (1) #define MICROPY_PY_SYS_PLATFORM "rp2" -#define MICROPY_PY_UERRNO (1) #define MICROPY_PY_THREAD (1) #define MICROPY_PY_THREAD_GIL (0) // Extended modules #define MICROPY_EPOCH_IS_1970 (1) -#define MICROPY_PY_UASYNCIO (1) -#define MICROPY_PY_UCTYPES (1) -#define MICROPY_PY_UZLIB (1) -#define MICROPY_PY_UJSON (1) -#define MICROPY_PY_URE (1) #define MICROPY_PY_URE_MATCH_GROUPS (1) #define MICROPY_PY_URE_MATCH_SPAN_START_END (1) -#define MICROPY_PY_URE_SUB (1) -#define MICROPY_PY_UHEAPQ (1) -#define MICROPY_PY_UHASHLIB (1) -#define MICROPY_PY_UBINASCII (1) -#define MICROPY_PY_UBINASCII_CRC32 (1) #define MICROPY_PY_UTIME_MP_HAL (1) -#define MICROPY_PY_URANDOM (1) -#define MICROPY_PY_URANDOM_EXTRA_FUNCS (1) #define MICROPY_PY_URANDOM_SEED_INIT_FUNC (rosc_random_u32()) -#define MICROPY_PY_USELECT (1) #define MICROPY_PY_MACHINE (1) #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new #define MICROPY_PY_MACHINE_PULSE (1) @@ -141,7 +102,6 @@ #define MICROPY_PY_MACHINE_SPI_MSB (SPI_MSB_FIRST) #define MICROPY_PY_MACHINE_SPI_LSB (SPI_LSB_FIRST) #define MICROPY_PY_MACHINE_SOFTSPI (1) -#define MICROPY_PY_FRAMEBUF (1) #define MICROPY_PY_ONEWIRE (1) #define MICROPY_VFS (1) #define MICROPY_VFS_LFS2 (1) From c62351fbd67e0f32e33e2066b7c07a79ac52481d Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 1 Nov 2021 15:18:22 +1100 Subject: [PATCH 130/335] py/mpconfig.h: Revert MICROPY_REPL_INFO to disabled at all levels. This is an stm32-specific feature that's accessed via the pyb module, so not something that will be widely enabled. Signed-off-by: Damien George --- ports/rp2/mpconfigport.h | 1 - ports/stm32/mpconfigport.h | 1 + py/mpconfig.h | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index 57fedc724e..788aeb1638 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -68,7 +68,6 @@ #define MICROPY_PY_BUILTINS_EXECFILE (0) #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) #define MICROPY_REPL_EMACS_KEYS (0) -#define MICROPY_REPL_INFO (0) // Python internal features #define MICROPY_READER_VFS (1) diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index f96d175748..9a1b525202 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -69,6 +69,7 @@ #define MICROPY_ENABLE_GC (1) #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) #define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0) +#define MICROPY_REPL_INFO (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) #ifndef MICROPY_FLOAT_IMPL // can be configured by each board via mpconfigboard.mk #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) diff --git a/py/mpconfig.h b/py/mpconfig.h index 4aea8f7ba9..596bab8d89 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -652,7 +652,7 @@ // Allow enabling debug prints after each REPL line #ifndef MICROPY_REPL_INFO -#define MICROPY_REPL_INFO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) +#define MICROPY_REPL_INFO (0) #endif // Whether to include emacs-style readline behavior in REPL From 693b927687c3ac18726a5eb7b64127fc347a3c41 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Mon, 20 Sep 2021 22:43:39 +1000 Subject: [PATCH 131/335] rp2: Enable optimisations (comp goto, map cache, fast attr). Computed goto costs 1800 bytes for 5-10% performance. Map caching and attr fast path costs 130 bytes for up to 30%. Net effect of those three optimisations: bm_chaos.py +16.059% (+/-0.09%) bm_fannkuch.py +11.145% (+/-0.01%) bm_fft.py +14.604% (+/-0.01%) bm_float.py +26.849% (+/-0.08%) bm_hexiom.py +34.039% (+/-0.03%) bm_nqueens.py +18.333% (+/-0.06%) bm_pidigits.py +4.472% (+/-0.03%) misc_aes.py +28.765% (+/-0.09%) misc_mandel.py +27.116% (+/-0.05%) misc_pystone.py +40.299% (+/-0.20%) misc_raytrace.py +22.812% (+/-0.07%) Also enable other EXTRA-level optimisations (module const, return_if_expr, triple_tuple_assign, factorial, mpz bitwise). Signed-off-by: Jim Mussared --- ports/rp2/mpconfigport.h | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index 788aeb1638..2794fda2e1 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -55,16 +55,11 @@ #define MICROPY_EMIT_INLINE_THUMB_FLOAT (0) #define MICROPY_EMIT_INLINE_THUMB_ARMV7M (0) +// Optimisations +#define MICROPY_OPT_COMPUTED_GOTO (1) + // Features currently overriden for rp2, planned to be brought in line with // other ports -#define MICROPY_COMP_MODULE_CONST (0) -#define MICROPY_COMP_RETURN_IF_EXPR (0) -#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0) -#define MICROPY_OPT_COMPUTED_GOTO (0) -#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (0) -#define MICROPY_OPT_MAP_LOOKUP_CACHE (0) -#define MICROPY_OPT_MATH_FACTORIAL (0) -#define MICROPY_OPT_MPZ_BITWISE (0) #define MICROPY_PY_BUILTINS_EXECFILE (0) #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) #define MICROPY_REPL_EMACS_KEYS (0) From fe120484b67bdc114dbbc2b9bd913fab98c82778 Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Tue, 26 Oct 2021 10:47:04 +0200 Subject: [PATCH 132/335] py/gc: Add hook to run code during time consuming GC operations. This makes it possible for cooperative multitasking systems to keep running event loops during garbage collector operations. For example, this can be used to ensure that a motor control loop runs approximately each 5 ms. Without this hook, the loop time can jump to about 15 ms. Addresses #3475. Signed-off-by: Laurens Valk --- py/gc.c | 5 +++++ py/mpconfig.h | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/py/gc.c b/py/gc.c index 8284c435ba..a01d81abdc 100644 --- a/py/gc.c +++ b/py/gc.c @@ -213,6 +213,7 @@ STATIC void gc_mark_subtree(size_t block) { // Start with the block passed in the argument. size_t sp = 0; for (;;) { + MICROPY_GC_HOOK_LOOP // work out number of consecutive blocks in the chain starting with this one size_t n_blocks = 0; do { @@ -222,6 +223,7 @@ STATIC void gc_mark_subtree(size_t block) { // check this block's children void **ptrs = (void **)PTR_FROM_BLOCK(block); for (size_t i = n_blocks * BYTES_PER_BLOCK / sizeof(void *); i > 0; i--, ptrs++) { + MICROPY_GC_HOOK_LOOP void *ptr = *ptrs; if (VERIFY_PTR(ptr)) { // Mark and push this pointer @@ -255,6 +257,7 @@ STATIC void gc_deal_with_stack_overflow(void) { // scan entire memory looking for blocks which have been marked but not their children for (size_t block = 0; block < MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB; block++) { + MICROPY_GC_HOOK_LOOP // trace (again) if mark bit set if (ATB_GET_KIND(block) == AT_MARK) { gc_mark_subtree(block); @@ -270,6 +273,7 @@ STATIC void gc_sweep(void) { // free unmarked heads and their tails int free_tail = 0; for (size_t block = 0; block < MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB; block++) { + MICROPY_GC_HOOK_LOOP switch (ATB_GET_KIND(block)) { case AT_HEAD: #if MICROPY_ENABLE_FINALISER @@ -354,6 +358,7 @@ static void *gc_get_ptr(void **ptrs, int i) { void gc_collect_root(void **ptrs, size_t len) { for (size_t i = 0; i < len; i++) { + MICROPY_GC_HOOK_LOOP void *ptr = gc_get_ptr(ptrs, i); if (VERIFY_PTR(ptr)) { size_t block = BLOCK_FROM_PTR(ptr); diff --git a/py/mpconfig.h b/py/mpconfig.h index 596bab8d89..06c46b8c73 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -602,6 +602,11 @@ #define MICROPY_ENABLE_GC (0) #endif +// Hook to run code during time consuming garbage collector operations +#ifndef MICROPY_GC_HOOK_LOOP +#define MICROPY_GC_HOOK_LOOP +#endif + // Whether to enable finalisers in the garbage collector (ie call __del__) #ifndef MICROPY_ENABLE_FINALISER #define MICROPY_ENABLE_FINALISER (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) From 0adea4071608e6e6b266cccd0a7fce9bc190fb95 Mon Sep 17 00:00:00 2001 From: Andrew Scheller Date: Thu, 23 Sep 2021 10:53:51 +0100 Subject: [PATCH 133/335] docs/rp2/general.rst: Fix typo with missing spaces. --- docs/rp2/general.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/rp2/general.rst b/docs/rp2/general.rst index 7042d0d25b..9a31d20671 100644 --- a/docs/rp2/general.rst +++ b/docs/rp2/general.rst @@ -22,9 +22,9 @@ QFN-56 SMD package. The key features include: firmware from either the external flash memory or USB bus into internal SRAM) * QSPI bus controller, which supports up to 16 MB of external Flash memory -* On-chip programmable LDO togenerate core voltage +* On-chip programmable LDO to generate core voltage * 2 on-chip PLLs to generate USB and core clocks -* 30 GPIOpins, of which 4 can optionally be used as analog inputs +* 30 GPIO pins, of which 4 can optionally be used as analog inputs The peripherals include: From cb99ca9862827f57c370555841810e98701ecfa2 Mon Sep 17 00:00:00 2001 From: Dave Hylands Date: Mon, 25 Oct 2021 10:41:32 -0700 Subject: [PATCH 134/335] tools/dfu.py: Make tool work with python3 when parsing DFU files. --- tools/dfu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dfu.py b/tools/dfu.py index 6591436e9e..39d68f3b66 100755 --- a/tools/dfu.py +++ b/tools/dfu.py @@ -20,7 +20,7 @@ def consume(fmt, data, names): def cstring(string): - return string.split("\0", 1)[0] + return string.split(b"\0", 1)[0] def compute_crc(data): From c9c55032dc29ba8dc75a211cdbb930e7eaf31844 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 4 Nov 2021 15:28:09 +1100 Subject: [PATCH 135/335] minimal/Makefile: Don't force a 32-bit build. Word-size specific configuration is now done automatically, so it no longer requires this to match the ARM configuration. Also it's less common to have 32-bit compilation support installed, so this will make it work "out of the box" for more people. Signed-off-by: Jim Mussared --- ports/minimal/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/minimal/Makefile b/ports/minimal/Makefile index 21e3fe3f76..fc3730e700 100644 --- a/ports/minimal/Makefile +++ b/ports/minimal/Makefile @@ -27,8 +27,8 @@ CFLAGS = $(INC) -Wall -Werror -std=c99 -nostdlib $(CFLAGS_CORTEX_M4) $(COPT) LDFLAGS = -nostdlib -T stm32f405.ld -Map=$@.map --cref --gc-sections else LD = gcc -CFLAGS = -m32 $(INC) -Wall -Werror -Wdouble-promotion -Wfloat-conversion -std=c99 $(COPT) -LDFLAGS = -m32 -Wl,-Map=$@.map,--cref -Wl,--gc-sections +CFLAGS = $(INC) -Wall -Werror -Wdouble-promotion -Wfloat-conversion -std=c99 $(COPT) +LDFLAGS = -Wl,-Map=$@.map,--cref -Wl,--gc-sections endif CSUPEROPT = -Os # save some code space From fa873ce67c52d04ad6ccea26c7c6366c97daa637 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 5 Nov 2021 13:12:18 +1100 Subject: [PATCH 136/335] minimal/mpconfigport.h: Disable features that are not needed. Now that there are feature levels, and that this port uses MICROPY_CONFIG_ROM_LEVEL_MINIMUM, it's easy to see what optional features can be disabled. And this commit disables them. Signed-off-by: Damien George --- ports/minimal/mpconfigport.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/ports/minimal/mpconfigport.h b/ports/minimal/mpconfigport.h index b83e0c2704..c9f3998762 100644 --- a/ports/minimal/mpconfigport.h +++ b/ports/minimal/mpconfigport.h @@ -15,18 +15,10 @@ #define MICROPY_HELPER_REPL (1) #define MICROPY_MODULE_FROZEN_MPY (1) #define MICROPY_ENABLE_EXTERNAL_IMPORT (1) -#define MICROPY_PY_MATH (1) #define MICROPY_ALLOC_PATH_MAX (256) #define MICROPY_ALLOC_PARSE_CHUNK_INIT (16) -#define MICROPY_COMP_CONST_FOLDING (1) -#define MICROPY_COMP_CONST_LITERAL (1) -#define MICROPY_FULL_CHECKS (1) -#define MICROPY_MULTIPLE_INHERITANCE (1) -#define MICROPY_PY_GENERATOR_PEND_THROW (1) -#define MICROPY_PY_BUILTINS_RANGE_ATTRS (1) - // type definitions for the specific machine typedef intptr_t mp_int_t; // must be pointer size From 1bd47db6881ce9fef5a787e9f4dfe74244c8d3cb Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 5 Nov 2021 11:02:30 +1100 Subject: [PATCH 137/335] tools/autobuild: Automatically build all mimxrt, rp2 and samd boards. Any board with a board.json file will be automatically built. Signed-off-by: Damien George --- tools/autobuild/autobuild.sh | 12 ++++-- tools/autobuild/build-boards.sh | 53 ++++++++++++++++++++++++++ tools/autobuild/build-mimxrt-latest.sh | 38 ------------------ tools/autobuild/build-rp2-latest.sh | 32 ---------------- 4 files changed, 62 insertions(+), 73 deletions(-) create mode 100755 tools/autobuild/build-boards.sh delete mode 100755 tools/autobuild/build-mimxrt-latest.sh delete mode 100755 tools/autobuild/build-rp2-latest.sh diff --git a/tools/autobuild/autobuild.sh b/tools/autobuild/autobuild.sh index a14c7890f7..bb77b178b9 100755 --- a/tools/autobuild/autobuild.sh +++ b/tools/autobuild/autobuild.sh @@ -39,6 +39,9 @@ fi # get directory of this script for access to other build scripts AUTODIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +# source additional functions +source ${AUTODIR}/build-boards.sh + # make local directory to put firmware LOCAL_FIRMWARE=/tmp/autobuild-firmware-$$ mkdir -p ${LOCAL_FIRMWARE} @@ -71,10 +74,13 @@ ${AUTODIR}/build-esp8266-latest.sh ${FW_TAG} ${LOCAL_FIRMWARE} cd ../esp32 ${AUTODIR}/build-esp32-latest.sh ${IDF_PATH_V42} ${FW_TAG} ${LOCAL_FIRMWARE} ${AUTODIR}/build-esp32-latest.sh ${IDF_PATH_V43} ${FW_TAG} ${LOCAL_FIRMWARE} -cd ../rp2 -${AUTODIR}/build-rp2-latest.sh ${FW_TAG} ${LOCAL_FIRMWARE} + cd ../mimxrt -${AUTODIR}/build-mimxrt-latest.sh ${FW_TAG} ${LOCAL_FIRMWARE} +build_mimxrt_boards ${FW_TAG} ${LOCAL_FIRMWARE} +cd ../rp2 +build_rp2_boards ${FW_TAG} ${LOCAL_FIRMWARE} +cd ../samd +build_samd_boards ${FW_TAG} ${LOCAL_FIRMWARE} popd diff --git a/tools/autobuild/build-boards.sh b/tools/autobuild/build-boards.sh new file mode 100755 index 0000000000..1ae795a7a7 --- /dev/null +++ b/tools/autobuild/build-boards.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# +# The functions in this file can be run independently to build boards. +# For example: +# +# $ source build-boards.sh +# $ MICROPY_AUTOBUILD_MAKE=make build_rp2_boards -latest /tmp + +function build_boards { + # check/get parameters + if [ $# -lt 4 ]; then + echo "usage: $0 " + return 1 + fi + + fw_tag=$1 + dest_dir=$2 + check_file=$3 + shift + shift + shift + + # check we are in the correct directory + if [ ! -r $check_file ]; then + echo "must be in directory containing $check_file" + return 1 + fi + + for board_json in $(find boards/ -name board.json); do + board=$(echo $board_json | awk -F '/' '{ print $2 }') + descr=$(cat $board_json | python3 -c "import json,sys; print(json.load(sys.stdin).get('id', '$board'))") + build_dir=/tmp/micropython-build-$board + + echo "building $descr $board" + $MICROPY_AUTOBUILD_MAKE BOARD=$board BUILD=$build_dir || return 1 + for ext in $@; do + mv $build_dir/firmware.$ext $dest_dir/$descr$fw_tag.$ext + done + rm -rf $build_dir + done +} + +function build_mimxrt_boards { + build_boards $1 $2 modmimxrt.c bin hex +} + +function build_rp2_boards { + build_boards $1 $2 modrp2.c uf2 +} + +function build_samd_boards { + build_boards $1 $2 samd_soc.c uf2 +} diff --git a/tools/autobuild/build-mimxrt-latest.sh b/tools/autobuild/build-mimxrt-latest.sh deleted file mode 100755 index fea5da81c5..0000000000 --- a/tools/autobuild/build-mimxrt-latest.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -# function for building firmware -function do_build() { - descr=$1 - board=$2 - ext=$3 - shift - shift - shift - echo "building $descr $board" - build_dir=/tmp/mimxrt-build-$board - $MICROPY_AUTOBUILD_MAKE $@ BOARD=$board BUILD=$build_dir || exit 1 - mv $build_dir/firmware.$ext $dest_dir/$descr$fw_tag.$ext - rm -rf $build_dir -} - -# check/get parameters -if [ $# != 2 ]; then - echo "usage: $0 " - exit 1 -fi - -fw_tag=$1 -dest_dir=$2 - -# check we are in the correct directory -if [ ! -r modmimxrt.c ]; then - echo "must be in mimxrt directory" - exit 1 -fi - -# build the boards -do_build TEENSY40 TEENSY40 hex -do_build TEENSY41 TEENSY41 hex -do_build MIMXRT1010_EVK MIMXRT1010_EVK bin -do_build MIMXRT1020_EVK MIMXRT1020_EVK bin -do_build MIMXRT1050_EVK MIMXRT1050_EVK bin diff --git a/tools/autobuild/build-rp2-latest.sh b/tools/autobuild/build-rp2-latest.sh deleted file mode 100755 index 5124686e21..0000000000 --- a/tools/autobuild/build-rp2-latest.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -# function for building firmware -function do_build() { - descr=$1 - board=$2 - shift - shift - echo "building $descr $board" - build_dir=/tmp/rp2-build-$board - $MICROPY_AUTOBUILD_MAKE $@ BOARD=$board BUILD=$build_dir || exit 1 - mv $build_dir/firmware.uf2 $dest_dir/$descr$fw_tag.uf2 - rm -rf $build_dir -} - -# check/get parameters -if [ $# != 2 ]; then - echo "usage: $0 " - exit 1 -fi - -fw_tag=$1 -dest_dir=$2 - -# check we are in the correct directory -if [ ! -r modrp2.c ]; then - echo "must be in rp2 directory" - exit 1 -fi - -# build the boards -do_build rp2-pico PICO From ff4f1f3ab395a6be426cc1b6ce0839bf65574f45 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 1 Nov 2021 12:47:32 +1100 Subject: [PATCH 138/335] esp8266/boards/GENERIC: Enable f-strings. Costs 612 bytes of code space. Signed-off-by: Damien George --- ports/esp8266/boards/GENERIC/mpconfigboard.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/esp8266/boards/GENERIC/mpconfigboard.h b/ports/esp8266/boards/GENERIC/mpconfigboard.h index d33943df80..e4991ba970 100644 --- a/ports/esp8266/boards/GENERIC/mpconfigboard.h +++ b/ports/esp8266/boards/GENERIC/mpconfigboard.h @@ -11,6 +11,7 @@ #define MICROPY_READER_VFS (MICROPY_VFS) #define MICROPY_VFS (1) +#define MICROPY_PY_FSTRINGS (1) #define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) #define MICROPY_PY_ALL_SPECIAL_METHODS (1) #define MICROPY_PY_IO_FILEIO (1) From 6d9da27c21bcc687f868d77ffca42e4dfc234248 Mon Sep 17 00:00:00 2001 From: Magnus von Wachenfeldt Date: Thu, 4 Nov 2021 14:50:39 +0100 Subject: [PATCH 139/335] esp32: Support building with latest IDF v5. The latest ESP-IDF v5.0-dev declares MAJOR_VERSION 5 and MINOR_VERSION 0. timer_ll_set_alarm_enable() is also changed to timer_ll_set_alarm_value(). --- ports/esp32/machine_timer.c | 6 +++++- ports/esp32/main/CMakeLists.txt | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ports/esp32/machine_timer.c b/ports/esp32/machine_timer.c index 020ba4447d..ea8b5965d8 100644 --- a/ports/esp32/machine_timer.c +++ b/ports/esp32/machine_timer.c @@ -134,7 +134,7 @@ STATIC void machine_timer_isr(void *self_in) { #if HAVE_TIMER_LL - #if CONFIG_IDF_TARGET_ESP32 + #if CONFIG_IDF_TARGET_ESP32 && ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) device->hw_timer[self->index].update = 1; #else #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) @@ -148,7 +148,11 @@ STATIC void machine_timer_isr(void *self_in) { #endif #endif timer_ll_clear_intr_status(device, self->index); + #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) timer_ll_set_alarm_enable(device, self->index, self->repeat); + #else + timer_ll_set_alarm_value(device, self->index, self->repeat); + #endif #else diff --git a/ports/esp32/main/CMakeLists.txt b/ports/esp32/main/CMakeLists.txt index 3294ca7c04..68a4815d7e 100644 --- a/ports/esp32/main/CMakeLists.txt +++ b/ports/esp32/main/CMakeLists.txt @@ -121,16 +121,16 @@ set(IDF_COMPONENTS xtensa ) -if(IDF_VERSION_MINOR GREATER_EQUAL 1) +if(IDF_VERSION_MINOR GREATER_EQUAL 1 OR IDF_VERSION_MAJOR GREATER_EQUAL 5) list(APPEND IDF_COMPONENTS esp_netif) endif() -if(IDF_VERSION_MINOR GREATER_EQUAL 2) +if(IDF_VERSION_MINOR GREATER_EQUAL 2 OR IDF_VERSION_MAJOR GREATER_EQUAL 5) list(APPEND IDF_COMPONENTS esp_system) list(APPEND IDF_COMPONENTS esp_timer) endif() -if(IDF_VERSION_MINOR GREATER_EQUAL 3) +if(IDF_VERSION_MINOR GREATER_EQUAL 3 OR IDF_VERSION_MAJOR GREATER_EQUAL 5) list(APPEND IDF_COMPONENTS esp_hw_support) list(APPEND IDF_COMPONENTS esp_pm) list(APPEND IDF_COMPONENTS hal) @@ -203,7 +203,7 @@ foreach(comp ${IDF_COMPONENTS}) micropy_gather_target_properties(__idf_${comp}) endforeach() -if(IDF_VERSION_MINOR GREATER_EQUAL 2) +if(IDF_VERSION_MINOR GREATER_EQUAL 2 OR IDF_VERSION_MAJOR GREATER_EQUAL 5) # These paths cannot currently be found by the IDF_COMPONENTS search loop above, # so add them explicitly. list(APPEND MICROPY_CPP_INC_EXTRA ${IDF_PATH}/components/soc/soc/${IDF_TARGET}/include) From 0be3b91f11e81ff18a0554c31326ac9df20a2091 Mon Sep 17 00:00:00 2001 From: MikeTeachman Date: Fri, 24 Sep 2021 20:06:10 -0700 Subject: [PATCH 140/335] stm32,esp32: In machine_i2s, send null samples in underflow situations. Eliminate noise data from being sent to the I2S peripheral when the transmitted sample stream is stopped. Signed-off-by: Mike Teachman --- ports/esp32/machine_i2s.c | 1 + ports/stm32/machine_i2s.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/ports/esp32/machine_i2s.c b/ports/esp32/machine_i2s.c index dc583e8e96..390b01e5eb 100644 --- a/ports/esp32/machine_i2s.c +++ b/ports/esp32/machine_i2s.c @@ -448,6 +448,7 @@ STATIC void machine_i2s_init_helper(machine_i2s_obj_t *self, size_t n_pos_args, i2s_config.dma_buf_count = get_dma_buf_count(mode, bits, format, self->ibuf); i2s_config.dma_buf_len = DMA_BUF_LEN_IN_I2S_FRAMES; i2s_config.use_apll = false; + i2s_config.tx_desc_auto_clear = true; // I2S queue size equals the number of DMA buffers check_esp_err(i2s_driver_install(self->port, &i2s_config, i2s_config.dma_buf_count, &self->i2s_event_queue)); diff --git a/ports/stm32/machine_i2s.c b/ports/stm32/machine_i2s.c index 32167cf4e9..266dd45e84 100644 --- a/ports/stm32/machine_i2s.c +++ b/ports/stm32/machine_i2s.c @@ -509,6 +509,9 @@ STATIC void feed_dma(machine_i2s_obj_t *self, ping_pong_t dma_ping_pong) { if (self->bits == 32) { reformat_32_bit_samples((int32_t *)dma_buffer_p, SIZEOF_HALF_DMA_BUFFER_IN_BYTES / (sizeof(uint32_t))); } + } else { + // underflow. clear buffer to transmit "silence" on the I2S bus + memset(dma_buffer_p, 0, SIZEOF_HALF_DMA_BUFFER_IN_BYTES); } // flush cache to RAM so DMA can read the sample data From 6d5296e65e8eb2330dbddd21b167088abf93f57a Mon Sep 17 00:00:00 2001 From: MikeTeachman Date: Tue, 9 Nov 2021 20:41:34 -0800 Subject: [PATCH 141/335] stm32,esp32: In machine_i2s, make object reference arrays root pointers. This change eliminates the risk of the IRQ callback accessing invalid data. Discussed here: https://github.com/micropython/micropython/pull/7183#discussion_r660209875 Signed-off-by: Mike Teachman --- ports/esp32/machine_i2s.c | 10 +++---- ports/esp32/mpconfigport.h | 3 +++ ports/stm32/boards/PYBD_SF2/mpconfigboard.h | 1 - ports/stm32/boards/PYBV10/mpconfigboard.h | 1 - ports/stm32/boards/PYBV11/mpconfigboard.h | 1 - ports/stm32/machine_i2s.c | 30 +++++++++------------ ports/stm32/mpconfigboard_common.h | 9 +++++++ ports/stm32/mpconfigport.h | 3 +++ 8 files changed, 32 insertions(+), 26 deletions(-) diff --git a/ports/esp32/machine_i2s.c b/ports/esp32/machine_i2s.c index 390b01e5eb..71d3ad1163 100644 --- a/ports/esp32/machine_i2s.c +++ b/ports/esp32/machine_i2s.c @@ -147,11 +147,9 @@ STATIC const int8_t i2s_frame_map[NUM_I2S_USER_FORMATS][I2S_RX_FRAME_SIZE_IN_BYT { 4, 5, 6, 7, 0, 1, 2, 3 }, // Stereo, 32-bits }; -STATIC machine_i2s_obj_t *machine_i2s_obj[I2S_NUM_MAX]; - void machine_i2s_init0() { for (i2s_port_t p = 0; p < I2S_NUM_MAX; p++) { - machine_i2s_obj[p] = NULL; + MP_STATE_PORT(machine_i2s_obj)[p] = NULL; } } @@ -507,13 +505,13 @@ STATIC mp_obj_t machine_i2s_make_new(const mp_obj_type_t *type, size_t n_pos_arg } machine_i2s_obj_t *self; - if (machine_i2s_obj[port] == NULL) { + if (MP_STATE_PORT(machine_i2s_obj)[port] == NULL) { self = m_new_obj(machine_i2s_obj_t); - machine_i2s_obj[port] = self; + MP_STATE_PORT(machine_i2s_obj)[port] = self; self->base.type = &machine_i2s_type; self->port = port; } else { - self = machine_i2s_obj[port]; + self = MP_STATE_PORT(machine_i2s_obj)[port]; machine_i2s_deinit(self); } diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 53d706be3f..82bef87880 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -7,6 +7,8 @@ #include #include #include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "driver/i2s.h" // object representation and NLR handling #define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_A) @@ -249,6 +251,7 @@ struct mp_bluetooth_nimble_root_pointers_t; const char *readline_hist[8]; \ mp_obj_t machine_pin_irq_handler[40]; \ struct _machine_timer_obj_t *machine_timer_obj_head; \ + struct _machine_i2s_obj_t *machine_i2s_obj[I2S_NUM_MAX]; \ MICROPY_PORT_ROOT_POINTER_BLUETOOTH_NIMBLE // type definitions for the specific machine diff --git a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h index ed76b3f971..4afa037c4c 100644 --- a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h +++ b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h @@ -40,7 +40,6 @@ #define MICROPY_HW_ENABLE_SDCARD (1) #define MICROPY_HW_ENABLE_MMCARD (1) #define MICROPY_HW_ENABLE_RF_SWITCH (1) -#define MICROPY_HW_ENABLE_I2S (1) #define MICROPY_BOARD_EARLY_INIT board_early_init #define MICROPY_BOARD_ENTER_STOP board_sleep(1); diff --git a/ports/stm32/boards/PYBV10/mpconfigboard.h b/ports/stm32/boards/PYBV10/mpconfigboard.h index 50ef3ae269..6219862be4 100644 --- a/ports/stm32/boards/PYBV10/mpconfigboard.h +++ b/ports/stm32/boards/PYBV10/mpconfigboard.h @@ -11,7 +11,6 @@ #define MICROPY_HW_ENABLE_DAC (1) #define MICROPY_HW_ENABLE_USB (1) #define MICROPY_HW_ENABLE_SDCARD (1) -#define MICROPY_HW_ENABLE_I2S (1) // HSE is 8MHz #define MICROPY_HW_CLK_PLLM (8) diff --git a/ports/stm32/boards/PYBV11/mpconfigboard.h b/ports/stm32/boards/PYBV11/mpconfigboard.h index aec83d1349..c8f660c8fb 100644 --- a/ports/stm32/boards/PYBV11/mpconfigboard.h +++ b/ports/stm32/boards/PYBV11/mpconfigboard.h @@ -11,7 +11,6 @@ #define MICROPY_HW_ENABLE_DAC (1) #define MICROPY_HW_ENABLE_USB (1) #define MICROPY_HW_ENABLE_SDCARD (1) -#define MICROPY_HW_ENABLE_I2S (1) // HSE is 12MHz #define MICROPY_HW_CLK_PLLM (12) diff --git a/ports/stm32/machine_i2s.c b/ports/stm32/machine_i2s.c index 266dd45e84..31b7d14bfd 100644 --- a/ports/stm32/machine_i2s.c +++ b/ports/stm32/machine_i2s.c @@ -81,8 +81,6 @@ // 32 byte address boundary. Not all STM32 devices have a D-Cache. Buffer alignment // will still happen on these devices to keep this code simple. -#define MAX_I2S_STM32 (2) - // DMA ping-pong buffer size was empirically determined. It is a tradeoff between: // 1. memory use (smaller buffer size desirable to reduce memory footprint) // 2. interrupt frequency (larger buffer size desirable to reduce interrupt frequency) @@ -164,11 +162,9 @@ STATIC const int8_t i2s_frame_map[NUM_I2S_USER_FORMATS][I2S_RX_FRAME_SIZE_IN_BYT { 2, 3, 0, 1, 6, 7, 4, 5 }, // Stereo, 32-bits }; -STATIC machine_i2s_obj_t *machine_i2s_obj[MAX_I2S_STM32]; - void machine_i2s_init0() { - for (uint8_t i = 0; i < MAX_I2S_STM32; i++) { - machine_i2s_obj[i] = NULL; + for (uint8_t i = 0; i < MICROPY_HW_MAX_I2S; i++) { + MP_STATE_PORT(machine_i2s_obj)[i] = NULL; } } @@ -601,9 +597,9 @@ void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s) { void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s) { machine_i2s_obj_t *self; if (hi2s->Instance == I2S1) { - self = machine_i2s_obj[0]; + self = MP_STATE_PORT(machine_i2s_obj)[0]; } else { - self = machine_i2s_obj[1]; + self = MP_STATE_PORT(machine_i2s_obj)[1]; } // bottom half of buffer now filled, @@ -620,9 +616,9 @@ void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s) { void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s) { machine_i2s_obj_t *self; if (hi2s->Instance == I2S1) { - self = machine_i2s_obj[0]; + self = MP_STATE_PORT(machine_i2s_obj)[0]; } else { - self = machine_i2s_obj[1]; + self = MP_STATE_PORT(machine_i2s_obj)[1]; } // top half of buffer now filled, @@ -640,9 +636,9 @@ void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) { machine_i2s_obj_t *self; if (hi2s->Instance == I2S1) { - self = machine_i2s_obj[0]; + self = MP_STATE_PORT(machine_i2s_obj)[0]; } else { - self = machine_i2s_obj[1]; + self = MP_STATE_PORT(machine_i2s_obj)[1]; } // for non-blocking operation, this IRQ-based callback handles @@ -659,9 +655,9 @@ void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) { void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s) { machine_i2s_obj_t *self; if (hi2s->Instance == I2S1) { - self = machine_i2s_obj[0]; + self = MP_STATE_PORT(machine_i2s_obj)[0]; } else { - self = machine_i2s_obj[1]; + self = MP_STATE_PORT(machine_i2s_obj)[1]; } // for non-blocking operation, this IRQ-based callback handles @@ -859,13 +855,13 @@ STATIC mp_obj_t machine_i2s_make_new(const mp_obj_type_t *type, size_t n_pos_arg } machine_i2s_obj_t *self; - if (machine_i2s_obj[i2s_id_zero_base] == NULL) { + if (MP_STATE_PORT(machine_i2s_obj)[i2s_id_zero_base] == NULL) { self = m_new_obj(machine_i2s_obj_t); - machine_i2s_obj[i2s_id_zero_base] = self; + MP_STATE_PORT(machine_i2s_obj)[i2s_id_zero_base] = self; self->base.type = &machine_i2s_type; self->i2s_id = i2s_id; } else { - self = machine_i2s_obj[i2s_id_zero_base]; + self = MP_STATE_PORT(machine_i2s_obj)[i2s_id_zero_base]; machine_i2s_deinit(MP_OBJ_FROM_PTR(self)); } diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h index bd00bae9c3..6dd51e913f 100644 --- a/ports/stm32/mpconfigboard_common.h +++ b/ports/stm32/mpconfigboard_common.h @@ -490,6 +490,15 @@ #define MICROPY_HW_MAX_CAN (1) #endif +// Enable I2S if there are any peripherals defined +#if defined(MICROPY_HW_I2S1) || defined(MICROPY_HW_I2S2) +#define MICROPY_HW_ENABLE_I2S (1) +#define MICROPY_HW_MAX_I2S (2) +#else +#define MICROPY_HW_ENABLE_I2S (0) +#define MICROPY_HW_MAX_I2S (0) +#endif + // Define MICROPY_HW_SDMMCx_CK values if that peripheral is used, so that make-pins.py // generates the relevant AF constants. #if MICROPY_HW_SDCARD_SDMMC == 1 || MICROPY_HW_SDIO_SDMMC == 1 diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 9a1b525202..6639b92413 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -342,6 +342,9 @@ struct _mp_bluetooth_btstack_root_pointers_t; /* pointers to all CAN objects (if they have been created) */ \ struct _pyb_can_obj_t *pyb_can_obj_all[MICROPY_HW_MAX_CAN]; \ \ + /* pointers to all I2S objects (if they have been created) */ \ + struct _machine_i2s_obj_t *machine_i2s_obj[MICROPY_HW_MAX_I2S]; \ + \ /* USB_VCP IRQ callbacks (if they have been set) */ \ mp_obj_t pyb_usb_vcp_irq[MICROPY_HW_USB_CDC_NUM]; \ \ From b6dbbbe82f7114cb5b56c54e916e304f416cd47a Mon Sep 17 00:00:00 2001 From: Mike Teachman Date: Fri, 3 Sep 2021 20:34:53 -0700 Subject: [PATCH 142/335] rp2/machine_i2s: Add I2S protocol support. This commit adds I2S protocol support for the rp2 port: - I2S API is consistent with STM32 and ESP32 ports - I2S configurations supported: - master transmit and master receive - 16-bit and 32-bit sample sizes - mono and stereo formats - sampling frequency - 3 modes of operation: - blocking - non-blocking with callback - uasyncio - internal ring buffer size can be tuned - DMA IRQs are managed on an I2S object basis, allowing other RP2 entities to use DMA IRQs when I2S is not being used - MicroPython documentation - tested on Raspberry Pi Pico development board - build metric changes for this commit: text(+4552), data(0), bss(+8) Signed-off-by: Mike Teachman --- docs/rp2/quickref.rst | 20 + ports/rp2/CMakeLists.txt | 2 + ports/rp2/machine_i2s.c | 1150 ++++++++++++++++++++++++++++++++++++++ ports/rp2/main.c | 1 + ports/rp2/modmachine.c | 1 + ports/rp2/modmachine.h | 2 + ports/rp2/mpconfigport.h | 1 + 7 files changed, 1177 insertions(+) create mode 100644 ports/rp2/machine_i2s.c diff --git a/docs/rp2/quickref.rst b/docs/rp2/quickref.rst index ac9cdb86cb..63b8928280 100644 --- a/docs/rp2/quickref.rst +++ b/docs/rp2/quickref.rst @@ -219,6 +219,26 @@ has the same methods as software I2C above:: i2c = I2C(0) # default assignment: scl=Pin(9), sda=Pin(8) i2c = I2C(1, scl=Pin(3), sda=Pin(2), freq=400_000) +I2S bus +------- + +See :ref:`machine.I2S `. :: + + from machine import I2S, Pin + + i2s = I2S(0, sck=Pin(16), ws=Pin(17), sd=Pin(18), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=44100, ibuf=40000) # create I2S object + i2s.write(buf) # write buffer of audio samples to I2S device + + i2s = I2S(1, sck=Pin(0), ws=Pin(1), sd=Pin(2), mode=I2S.RX, bits=16, format=I2S.MONO, rate=22050, ibuf=40000) # create I2S object + i2s.readinto(buf) # fill buffer with audio samples from I2S device + +The ``ws`` pin number must be one greater than the ``sck`` pin number. + +The I2S class is currently available as a Technical Preview. During the preview period, feedback from +users is encouraged. Based on this feedback, the I2S class API and implementation may be changed. + +Two I2S buses are supported with id=0 and id=1. + Real time clock (RTC) --------------------- diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index 14f4e33ebe..e38cd8032d 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -85,6 +85,7 @@ set(MICROPY_SOURCE_PORT fatfs_port.c machine_adc.c machine_i2c.c + machine_i2s.c machine_pin.c machine_rtc.c machine_spi.c @@ -112,6 +113,7 @@ set(MICROPY_SOURCE_QSTR ${MICROPY_DIR}/shared/runtime/sys_stdio_mphal.c ${PROJECT_SOURCE_DIR}/machine_adc.c ${PROJECT_SOURCE_DIR}/machine_i2c.c + ${PROJECT_SOURCE_DIR}/machine_i2s.c ${PROJECT_SOURCE_DIR}/machine_pin.c ${PROJECT_SOURCE_DIR}/machine_rtc.c ${PROJECT_SOURCE_DIR}/machine_spi.c diff --git a/ports/rp2/machine_i2s.c b/ports/rp2/machine_i2s.c new file mode 100644 index 0000000000..ec64f72ec0 --- /dev/null +++ b/ports/rp2/machine_i2s.c @@ -0,0 +1,1150 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Mike Teachman + * + * 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 +#include +#include +#include +#include + +#include "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/misc.h" +#include "py/stream.h" +#include "py/objstr.h" +#include "modmachine.h" + +#include "hardware/pio.h" +#include "hardware/clocks.h" +#include "hardware/gpio.h" +#include "hardware/dma.h" +#include "hardware/irq.h" + +// The I2S class has 3 modes of operation: +// +// Mode1: Blocking +// - readinto() and write() methods block until the supplied buffer is filled (read) or emptied (write) +// - this is the default mode of operation +// +// Mode2: Non-Blocking +// - readinto() and write() methods return immediately +// - buffer filling and emptying happens asynchronously to the main MicroPython task +// - a callback function is called when the supplied buffer has been filled (read) or emptied (write) +// - non-blocking mode is enabled when a callback is set with the irq() method +// - the DMA IRQ handler is used to implement the asynchronous background operations +// +// Mode3: Uasyncio +// - implements the stream protocol +// - uasyncio mode is enabled when the ioctl() function is called +// - the state of the internal ring buffer is used to detect that I2S samples can be read or written +// +// The samples contained in the app buffer supplied for the readinto() and write() methods have the following convention: +// Mono: little endian format +// Stereo: little endian format, left channel first +// +// I2S terms: +// "frame": consists of two audio samples (Left audio sample + Right audio sample) +// +// Misc: +// - for Mono configuration: +// - readinto method: samples are gathered from the L channel only +// - write method: every sample is output to both the L and R channels +// - for readinto method the I2S hardware is read using 8-byte frames +// (this is standard for almost all I2S hardware, such as MEMS microphones) +// - the PIO is used to drive the I2S bus signals +// - all sample data transfers use non-blocking DMA +// - the DMA controller is configured with 2 DMA channels in chained mode + +#define MAX_I2S_RP2 (2) + +// The DMA buffer size was empirically determined. It is a tradeoff between: +// 1. memory use (smaller buffer size desirable to reduce memory footprint) +// 2. interrupt frequency (larger buffer size desirable to reduce interrupt frequency) +#define SIZEOF_DMA_BUFFER_IN_BYTES (256) +#define SIZEOF_HALF_DMA_BUFFER_IN_BYTES (SIZEOF_DMA_BUFFER_IN_BYTES / 2) +#define I2S_NUM_DMA_CHANNELS (2) + +// For non-blocking mode, to avoid underflow/overflow, sample data is written/read to/from the ring buffer at a rate faster +// than the DMA transfer rate +#define NON_BLOCKING_RATE_MULTIPLIER (4) +#define SIZEOF_NON_BLOCKING_COPY_IN_BYTES (SIZEOF_HALF_DMA_BUFFER_IN_BYTES * NON_BLOCKING_RATE_MULTIPLIER) + +#define NUM_I2S_USER_FORMATS (4) +#define I2S_RX_FRAME_SIZE_IN_BYTES (8) + +#define SAMPLES_PER_FRAME (2) +#define PIO_INSTRUCTIONS_PER_BIT (2) + +typedef enum { + RX, + TX +} i2s_mode_t; + +typedef enum { + MONO, + STEREO +} format_t; + +typedef enum { + BLOCKING, + NON_BLOCKING, + UASYNCIO +} io_mode_t; + +typedef enum { + GP_INPUT = 0, + GP_OUTPUT = 1 +} gpio_dir_t; + +typedef struct _ring_buf_t { + uint8_t *buffer; + size_t head; + size_t tail; + size_t size; +} ring_buf_t; + +typedef struct _non_blocking_descriptor_t { + mp_buffer_info_t appbuf; + uint32_t index; + bool copy_in_progress; +} non_blocking_descriptor_t; + +typedef struct _machine_i2s_obj_t { + mp_obj_base_t base; + uint8_t i2s_id; + mp_hal_pin_obj_t sck; + mp_hal_pin_obj_t ws; + mp_hal_pin_obj_t sd; + i2s_mode_t mode; + int8_t bits; + format_t format; + int32_t rate; + int32_t ibuf; + mp_obj_t callback_for_non_blocking; + io_mode_t io_mode; + PIO pio; + uint8_t sm; + const pio_program_t *pio_program; + uint prog_offset; + int dma_channel[I2S_NUM_DMA_CHANNELS]; + uint8_t dma_buffer[SIZEOF_DMA_BUFFER_IN_BYTES]; + ring_buf_t ring_buffer; + uint8_t *ring_buffer_storage; + non_blocking_descriptor_t non_blocking_descriptor; +} machine_i2s_obj_t; + +// The frame map is used with the readinto() method to transform the audio sample data coming +// from DMA memory (32-bit stereo) to the format specified +// in the I2S constructor. e.g. 16-bit mono +STATIC const int8_t i2s_frame_map[NUM_I2S_USER_FORMATS][I2S_RX_FRAME_SIZE_IN_BYTES] = { + {-1, -1, 0, 1, -1, -1, -1, -1 }, // Mono, 16-bits + { 0, 1, 2, 3, -1, -1, -1, -1 }, // Mono, 32-bits + {-1, -1, 0, 1, -1, -1, 2, 3 }, // Stereo, 16-bits + { 0, 1, 2, 3, 4, 5, 6, 7 }, // Stereo, 32-bits +}; + +STATIC const PIO pio_instances[NUM_PIOS] = {pio0, pio1}; + +// PIO program for 16-bit write +// set(x, 14) .side(0b01) +// label('left_channel') +// out(pins, 1) .side(0b00) +// jmp(x_dec, "left_channel") .side(0b01) +// out(pins, 1) .side(0b10) +// set(x, 14) .side(0b11) +// label('right_channel') +// out(pins, 1) .side(0b10) +// jmp(x_dec, "right_channel") .side(0b11) +// out(pins, 1) .side(0b00) +STATIC const uint16_t pio_instructions_write_16[] = {59438, 24577, 2113, 28673, 63534, 28673, 6213, 24577}; +STATIC const pio_program_t pio_write_16 = { + pio_instructions_write_16, + sizeof(pio_instructions_write_16) / sizeof(uint16_t), + -1 +}; + +// PIO program for 32-bit write +// set(x, 30) .side(0b01) +// label('left_channel') +// out(pins, 1) .side(0b00) +// jmp(x_dec, "left_channel") .side(0b01) +// out(pins, 1) .side(0b10) +// set(x, 30) .side(0b11) +// label('right_channel') +// out(pins, 1) .side(0b10) +// jmp(x_dec, "right_channel") .side(0b11) +// out(pins, 1) .side(0b00) +STATIC const uint16_t pio_instructions_write_32[] = {59454, 24577, 2113, 28673, 63550, 28673, 6213, 24577}; +STATIC const pio_program_t pio_write_32 = { + pio_instructions_write_32, + sizeof(pio_instructions_write_32) / sizeof(uint16_t), + -1 +}; + +// PIO program for 32-bit read +// set(x, 30) .side(0b00) +// label('left_channel') +// in_(pins, 1) .side(0b01) +// jmp(x_dec, "left_channel") .side(0b00) +// in_(pins, 1) .side(0b11) +// set(x, 30) .side(0b10) +// label('right_channel') +// in_(pins, 1) .side(0b11) +// jmp(x_dec, "right_channel") .side(0b10) +// in_(pins, 1) .side(0b01) +STATIC const uint16_t pio_instructions_read_32[] = {57406, 18433, 65, 22529, 61502, 22529, 4165, 18433}; +STATIC const pio_program_t pio_read_32 = { + pio_instructions_read_32, + sizeof(pio_instructions_read_32) / sizeof(uint16_t), + -1 +}; + +STATIC uint8_t dma_get_bits(i2s_mode_t mode, int8_t bits); +STATIC void dma_irq0_handler(void); +STATIC void dma_irq1_handler(void); +STATIC mp_obj_t machine_i2s_deinit(mp_obj_t self_in); + +void machine_i2s_init0(void) { + for (uint8_t i = 0; i < MAX_I2S_RP2; i++) { + MP_STATE_PORT(machine_i2s_obj[i]) = NULL; + } +} + +// Ring Buffer +// Thread safe when used with these constraints: +// - Single Producer, Single Consumer +// - Sequential atomic operations +// One byte of capacity is used to detect buffer empty/full + +STATIC void ringbuf_init(ring_buf_t *rbuf, uint8_t *buffer, size_t size) { + rbuf->buffer = buffer; + rbuf->size = size; + rbuf->head = 0; + rbuf->tail = 0; +} + +STATIC bool ringbuf_push(ring_buf_t *rbuf, uint8_t data) { + size_t next_tail = (rbuf->tail + 1) % rbuf->size; + + if (next_tail != rbuf->head) { + rbuf->buffer[rbuf->tail] = data; + rbuf->tail = next_tail; + return true; + } + + // full + return false; +} + +STATIC bool ringbuf_pop(ring_buf_t *rbuf, uint8_t *data) { + if (rbuf->head == rbuf->tail) { + // empty + return false; + } + + *data = rbuf->buffer[rbuf->head]; + rbuf->head = (rbuf->head + 1) % rbuf->size; + return true; +} + +STATIC bool ringbuf_is_empty(ring_buf_t *rbuf) { + return rbuf->head == rbuf->tail; +} + +STATIC bool ringbuf_is_full(ring_buf_t *rbuf) { + return ((rbuf->tail + 1) % rbuf->size) == rbuf->head; +} + +STATIC size_t ringbuf_available_data(ring_buf_t *rbuf) { + return (rbuf->tail - rbuf->head + rbuf->size) % rbuf->size; +} + +STATIC size_t ringbuf_available_space(ring_buf_t *rbuf) { + return rbuf->size - ringbuf_available_data(rbuf) - 1; +} + +STATIC int8_t get_frame_mapping_index(int8_t bits, format_t format) { + if (format == MONO) { + if (bits == 16) { + return 0; + } else { // 32 bits + return 1; + } + } else { // STEREO + if (bits == 16) { + return 2; + } else { // 32 bits + return 3; + } + } +} + +STATIC uint32_t fill_appbuf_from_ringbuf(machine_i2s_obj_t *self, mp_buffer_info_t *appbuf) { + + // copy audio samples from the ring buffer to the app buffer + // loop, copying samples until the app buffer is filled + // For uasyncio mode, the loop will make an early exit if the ring buffer becomes empty + // Example: + // a MicroPython I2S object is configured for 16-bit mono (2 bytes per audio sample). + // For every frame coming from the ring buffer (8 bytes), 2 bytes are "cherry picked" and + // copied to the supplied app buffer. + // Thus, for every 1 byte copied to the app buffer, 4 bytes are read from the ring buffer. + // If a 8kB app buffer is supplied, 32kB of audio samples is read from the ring buffer. + + uint32_t num_bytes_copied_to_appbuf = 0; + uint8_t *app_p = (uint8_t *)appbuf->buf; + uint8_t appbuf_sample_size_in_bytes = (self->bits == 16? 2 : 4) * (self->format == STEREO ? 2: 1); + uint32_t num_bytes_needed_from_ringbuf = appbuf->len * (I2S_RX_FRAME_SIZE_IN_BYTES / appbuf_sample_size_in_bytes); + uint8_t discard_byte; + while (num_bytes_needed_from_ringbuf) { + + uint8_t f_index = get_frame_mapping_index(self->bits, self->format); + + for (uint8_t i = 0; i < I2S_RX_FRAME_SIZE_IN_BYTES; i++) { + int8_t r_to_a_mapping = i2s_frame_map[f_index][i]; + if (r_to_a_mapping != -1) { + if (self->io_mode == BLOCKING) { + // poll the ringbuf until a sample becomes available, copy into appbuf using the mapping transform + while (ringbuf_pop(&self->ring_buffer, app_p + r_to_a_mapping) == false) { + ; + } + num_bytes_copied_to_appbuf++; + } else if (self->io_mode == UASYNCIO) { + if (ringbuf_pop(&self->ring_buffer, app_p + r_to_a_mapping) == false) { + // ring buffer is empty, exit + goto exit; + } else { + num_bytes_copied_to_appbuf++; + } + } else { + return 0; // should never get here (non-blocking mode does not use this function) + } + } else { // r_a_mapping == -1 + // discard unused byte from ring buffer + if (self->io_mode == BLOCKING) { + // poll the ringbuf until a sample becomes available + while (ringbuf_pop(&self->ring_buffer, &discard_byte) == false) { + ; + } + } else if (self->io_mode == UASYNCIO) { + if (ringbuf_pop(&self->ring_buffer, &discard_byte) == false) { + // ring buffer is empty, exit + goto exit; + } + } else { + return 0; // should never get here (non-blocking mode does not use this function) + } + } + num_bytes_needed_from_ringbuf--; + } + app_p += appbuf_sample_size_in_bytes; + } +exit: + return num_bytes_copied_to_appbuf; +} + +// function is used in IRQ context +STATIC void fill_appbuf_from_ringbuf_non_blocking(machine_i2s_obj_t *self) { + + // attempt to copy a block of audio samples from the ring buffer to the supplied app buffer. + // audio samples will be formatted as part of the copy operation + + uint32_t num_bytes_copied_to_appbuf = 0; + uint8_t *app_p = &(((uint8_t *)self->non_blocking_descriptor.appbuf.buf)[self->non_blocking_descriptor.index]); + + uint8_t appbuf_sample_size_in_bytes = (self->bits == 16? 2 : 4) * (self->format == STEREO ? 2: 1); + uint32_t num_bytes_remaining_to_copy_to_appbuf = self->non_blocking_descriptor.appbuf.len - self->non_blocking_descriptor.index; + uint32_t num_bytes_remaining_to_copy_from_ring_buffer = num_bytes_remaining_to_copy_to_appbuf * + (I2S_RX_FRAME_SIZE_IN_BYTES / appbuf_sample_size_in_bytes); + uint32_t num_bytes_needed_from_ringbuf = MIN(SIZEOF_NON_BLOCKING_COPY_IN_BYTES, num_bytes_remaining_to_copy_from_ring_buffer); + uint8_t discard_byte; + if (ringbuf_available_data(&self->ring_buffer) >= num_bytes_needed_from_ringbuf) { + while (num_bytes_needed_from_ringbuf) { + + uint8_t f_index = get_frame_mapping_index(self->bits, self->format); + + for (uint8_t i = 0; i < I2S_RX_FRAME_SIZE_IN_BYTES; i++) { + int8_t r_to_a_mapping = i2s_frame_map[f_index][i]; + if (r_to_a_mapping != -1) { + ringbuf_pop(&self->ring_buffer, app_p + r_to_a_mapping); + num_bytes_copied_to_appbuf++; + } else { // r_a_mapping == -1 + // discard unused byte from ring buffer + ringbuf_pop(&self->ring_buffer, &discard_byte); + } + num_bytes_needed_from_ringbuf--; + } + app_p += appbuf_sample_size_in_bytes; + } + self->non_blocking_descriptor.index += num_bytes_copied_to_appbuf; + + if (self->non_blocking_descriptor.index >= self->non_blocking_descriptor.appbuf.len) { + self->non_blocking_descriptor.copy_in_progress = false; + mp_sched_schedule(self->callback_for_non_blocking, MP_OBJ_FROM_PTR(self)); + } + } +} + +STATIC uint32_t copy_appbuf_to_ringbuf(machine_i2s_obj_t *self, mp_buffer_info_t *appbuf) { + + // copy audio samples from the app buffer to the ring buffer + // loop, reading samples until the app buffer is emptied + // for uasyncio mode, the loop will make an early exit if the ring buffer becomes full + + uint32_t a_index = 0; + + while (a_index < appbuf->len) { + if (self->io_mode == BLOCKING) { + // copy a byte to the ringbuf when space becomes available + while (ringbuf_push(&self->ring_buffer, ((uint8_t *)appbuf->buf)[a_index]) == false) { + ; + } + a_index++; + } else if (self->io_mode == UASYNCIO) { + if (ringbuf_push(&self->ring_buffer, ((uint8_t *)appbuf->buf)[a_index]) == false) { + // ring buffer is full, exit + break; + } else { + a_index++; + } + } else { + return 0; // should never get here (non-blocking mode does not use this function) + } + } + + return a_index; +} + +// function is used in IRQ context +STATIC void copy_appbuf_to_ringbuf_non_blocking(machine_i2s_obj_t *self) { + + // copy audio samples from app buffer into ring buffer + uint32_t num_bytes_remaining_to_copy = self->non_blocking_descriptor.appbuf.len - self->non_blocking_descriptor.index; + uint32_t num_bytes_to_copy = MIN(SIZEOF_NON_BLOCKING_COPY_IN_BYTES, num_bytes_remaining_to_copy); + + if (ringbuf_available_space(&self->ring_buffer) >= num_bytes_to_copy) { + for (uint32_t i = 0; i < num_bytes_to_copy; i++) { + ringbuf_push(&self->ring_buffer, + ((uint8_t *)self->non_blocking_descriptor.appbuf.buf)[self->non_blocking_descriptor.index + i]); + } + + self->non_blocking_descriptor.index += num_bytes_to_copy; + if (self->non_blocking_descriptor.index >= self->non_blocking_descriptor.appbuf.len) { + self->non_blocking_descriptor.copy_in_progress = false; + mp_sched_schedule(self->callback_for_non_blocking, MP_OBJ_FROM_PTR(self)); + } + } +} + +// function is used in IRQ context +STATIC void empty_dma(machine_i2s_obj_t *self, uint8_t *dma_buffer_p) { + // when space exists, copy samples into ring buffer + if (ringbuf_available_space(&self->ring_buffer) >= SIZEOF_HALF_DMA_BUFFER_IN_BYTES) { + for (uint32_t i = 0; i < SIZEOF_HALF_DMA_BUFFER_IN_BYTES; i++) { + ringbuf_push(&self->ring_buffer, dma_buffer_p[i]); + } + } +} + +// function is used in IRQ context +STATIC void feed_dma(machine_i2s_obj_t *self, uint8_t *dma_buffer_p) { + // when data exists, copy samples from ring buffer + if (ringbuf_available_data(&self->ring_buffer) >= SIZEOF_HALF_DMA_BUFFER_IN_BYTES) { + + // copy a block of samples from the ring buffer to the dma buffer. + // STM32 HAL API has a stereo I2S implementation, but not mono + // mono format is implemented by duplicating each sample into both L and R channels. + if ((self->format == MONO) && (self->bits == 16)) { + for (uint32_t i = 0; i < SIZEOF_HALF_DMA_BUFFER_IN_BYTES / 4; i++) { + for (uint8_t b = 0; b < sizeof(uint16_t); b++) { + ringbuf_pop(&self->ring_buffer, &dma_buffer_p[i * 4 + b]); + dma_buffer_p[i * 4 + b + 2] = dma_buffer_p[i * 4 + b]; // duplicated mono sample + } + } + } else if ((self->format == MONO) && (self->bits == 32)) { + for (uint32_t i = 0; i < SIZEOF_HALF_DMA_BUFFER_IN_BYTES / 8; i++) { + for (uint8_t b = 0; b < sizeof(uint32_t); b++) { + ringbuf_pop(&self->ring_buffer, &dma_buffer_p[i * 8 + b]); + dma_buffer_p[i * 8 + b + 4] = dma_buffer_p[i * 8 + b]; // duplicated mono sample + } + } + } else { // STEREO, both 16-bit and 32-bit + for (uint32_t i = 0; i < SIZEOF_HALF_DMA_BUFFER_IN_BYTES; i++) { + ringbuf_pop(&self->ring_buffer, &dma_buffer_p[i]); + } + } + } else { + // underflow. clear buffer to transmit "silence" on the I2S bus + memset(dma_buffer_p, 0, SIZEOF_HALF_DMA_BUFFER_IN_BYTES); + } +} + +STATIC void irq_configure(machine_i2s_obj_t *self) { + if (self->i2s_id == 0) { + irq_set_exclusive_handler(DMA_IRQ_0, dma_irq0_handler); + irq_set_enabled(DMA_IRQ_0, true); + } else { + irq_set_exclusive_handler(DMA_IRQ_1, dma_irq1_handler); + irq_set_enabled(DMA_IRQ_1, true); + } +} + +STATIC void irq_deinit(machine_i2s_obj_t *self) { + if (self->i2s_id == 0) { + irq_set_enabled(DMA_IRQ_0, false); + irq_remove_handler(DMA_IRQ_0, dma_irq0_handler); + } else { + irq_set_enabled(DMA_IRQ_1, false); + irq_remove_handler(DMA_IRQ_1, dma_irq1_handler); + } +} + +STATIC void pio_configure(machine_i2s_obj_t *self) { + if (self->mode == TX) { + if (self->bits == 16) { + self->pio_program = &pio_write_16; + } else { + self->pio_program = &pio_write_32; + } + } else { // RX + self->pio_program = &pio_read_32; + } + + // find a PIO with a free state machine and adequate program space + PIO candidate_pio; + bool is_free_sm; + bool can_add_program; + for (uint8_t p = 0; p < NUM_PIOS; p++) { + candidate_pio = pio_instances[p]; + is_free_sm = false; + can_add_program = false; + + for (uint8_t sm = 0; sm < NUM_PIO_STATE_MACHINES; sm++) { + if (!pio_sm_is_claimed(candidate_pio, sm)) { + is_free_sm = true; + break; + } + } + + if (pio_can_add_program(candidate_pio, self->pio_program)) { + can_add_program = true; + } + + if (is_free_sm && can_add_program) { + break; + } + } + + if (!is_free_sm) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("no free state machines")); + } + + if (!can_add_program) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("not enough PIO program space")); + } + + self->pio = candidate_pio; + self->sm = pio_claim_unused_sm(self->pio, false); + self->prog_offset = pio_add_program(self->pio, self->pio_program); + pio_sm_init(self->pio, self->sm, self->prog_offset, NULL); + + pio_sm_config config = pio_get_default_sm_config(); + + float pio_freq = self->rate * + SAMPLES_PER_FRAME * + dma_get_bits(self->mode, self->bits) * + PIO_INSTRUCTIONS_PER_BIT; + float clkdiv = clock_get_hz(clk_sys) / pio_freq; + sm_config_set_clkdiv(&config, clkdiv); + + if (self->mode == TX) { + sm_config_set_out_pins(&config, self->sd, 1); + sm_config_set_out_shift(&config, false, true, dma_get_bits(self->mode, self->bits)); + sm_config_set_fifo_join(&config, PIO_FIFO_JOIN_TX); // double TX FIFO size + } else { // RX + sm_config_set_in_pins(&config, self->sd); + sm_config_set_in_shift(&config, false, true, dma_get_bits(self->mode, self->bits)); + sm_config_set_fifo_join(&config, PIO_FIFO_JOIN_RX); // double RX FIFO size + } + + sm_config_set_sideset(&config, 2, false, false); + sm_config_set_sideset_pins(&config, self->sck); + sm_config_set_wrap(&config, self->prog_offset, self->prog_offset + self->pio_program->length - 1); + pio_sm_set_config(self->pio, self->sm, &config); +} + +STATIC void pio_deinit(machine_i2s_obj_t *self) { + if (self->pio) { + pio_sm_set_enabled(self->pio, self->sm, false); + pio_sm_unclaim(self->pio, self->sm); + pio_remove_program(self->pio, self->pio_program, self->prog_offset); + } +} + +STATIC void gpio_init_i2s(PIO pio, uint8_t sm, mp_hal_pin_obj_t pin_num, uint8_t pin_val, gpio_dir_t pin_dir) { + uint32_t pinmask = 1 << pin_num; + pio_sm_set_pins_with_mask(pio, sm, pin_val << pin_num, pinmask); + pio_sm_set_pindirs_with_mask(pio, sm, pin_dir << pin_num, pinmask); + pio_gpio_init(pio, pin_num); +} + +STATIC void gpio_configure(machine_i2s_obj_t *self) { + gpio_init_i2s(self->pio, self->sm, self->sck, 0, GP_OUTPUT); + gpio_init_i2s(self->pio, self->sm, self->ws, 0, GP_OUTPUT); + if (self->mode == TX) { + gpio_init_i2s(self->pio, self->sm, self->sd, 0, GP_OUTPUT); + } else { // RX + gpio_init_i2s(self->pio, self->sm, self->sd, 0, GP_INPUT); + } +} + +STATIC uint8_t dma_get_bits(i2s_mode_t mode, int8_t bits) { + if (mode == TX) { + return bits; + } else { // RX + // always read 32 bit words for I2S e.g. I2S MEMS microphones + return 32; + } +} + +// determine which DMA channel is associated to this IRQ +STATIC uint dma_map_irq_to_channel(uint irq_index) { + for (uint ch = 0; ch < NUM_DMA_CHANNELS; ch++) { + if ((dma_irqn_get_channel_status(irq_index, ch))) { + return ch; + } + } + // This should never happen + return -1; +} + +// note: first DMA channel is mapped to the top half of buffer, second is mapped to the bottom half +STATIC uint8_t *dma_get_buffer(machine_i2s_obj_t *i2s_obj, uint channel) { + for (uint8_t ch = 0; ch < I2S_NUM_DMA_CHANNELS; ch++) { + if (i2s_obj->dma_channel[ch] == channel) { + return i2s_obj->dma_buffer + (SIZEOF_HALF_DMA_BUFFER_IN_BYTES * ch); + } + } + // This should never happen + return NULL; +} + +STATIC void dma_configure(machine_i2s_obj_t *self) { + uint8_t num_free_dma_channels = 0; + for (uint8_t ch = 0; ch < NUM_DMA_CHANNELS; ch++) { + if (!dma_channel_is_claimed(ch)) { + num_free_dma_channels++; + } + } + if (num_free_dma_channels < I2S_NUM_DMA_CHANNELS) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("cannot claim 2 DMA channels")); + } + + for (uint8_t ch = 0; ch < I2S_NUM_DMA_CHANNELS; ch++) { + self->dma_channel[ch] = dma_claim_unused_channel(false); + } + + // The DMA channels are chained together. The first DMA channel is used to access + // the top half of the DMA buffer. The second DMA channel accesses the bottom half of the DMA buffer. + // With chaining, when one DMA channel has completed a data transfer, the other + // DMA channel automatically starts a new data transfer. + enum dma_channel_transfer_size dma_size = (dma_get_bits(self->mode, self->bits) == 16) ? DMA_SIZE_16 : DMA_SIZE_32; + for (uint8_t ch = 0; ch < I2S_NUM_DMA_CHANNELS; ch++) { + dma_channel_config dma_config = dma_channel_get_default_config(self->dma_channel[ch]); + channel_config_set_transfer_data_size(&dma_config, dma_size); + channel_config_set_chain_to(&dma_config, self->dma_channel[(ch + 1) % I2S_NUM_DMA_CHANNELS]); + + uint8_t *dma_buffer = self->dma_buffer + (SIZEOF_HALF_DMA_BUFFER_IN_BYTES * ch); + if (self->mode == TX) { + channel_config_set_dreq(&dma_config, pio_get_dreq(self->pio, self->sm, true)); + channel_config_set_read_increment(&dma_config, true); + channel_config_set_write_increment(&dma_config, false); + dma_channel_configure(self->dma_channel[ch], + &dma_config, + (void *)&self->pio->txf[self->sm], // dest = PIO TX FIFO + dma_buffer, // src = DMA buffer + SIZEOF_HALF_DMA_BUFFER_IN_BYTES / (dma_get_bits(self->mode, self->bits) / 8), + false); + } else { // RX + channel_config_set_dreq(&dma_config, pio_get_dreq(self->pio, self->sm, false)); + channel_config_set_read_increment(&dma_config, false); + channel_config_set_write_increment(&dma_config, true); + dma_channel_configure(self->dma_channel[ch], + &dma_config, + dma_buffer, // dest = DMA buffer + (void *)&self->pio->rxf[self->sm], // src = PIO RX FIFO + SIZEOF_HALF_DMA_BUFFER_IN_BYTES / (dma_get_bits(self->mode, self->bits) / 8), + false); + } + } + + for (uint8_t ch = 0; ch < I2S_NUM_DMA_CHANNELS; ch++) { + dma_irqn_acknowledge_channel(self->i2s_id, self->dma_channel[ch]); // clear pending. e.g. from SPI + dma_irqn_set_channel_enabled(self->i2s_id, self->dma_channel[ch], true); + } +} + +STATIC void dma_deinit(machine_i2s_obj_t *self) { + for (uint8_t ch = 0; ch < I2S_NUM_DMA_CHANNELS; ch++) { + int channel = self->dma_channel[ch]; + + // unchain the channel to prevent triggering a transfer in the chained-to channel + dma_channel_config dma_config = dma_get_channel_config(channel); + channel_config_set_chain_to(&dma_config, channel); + dma_channel_set_config(channel, &dma_config, false); + + dma_irqn_set_channel_enabled(self->i2s_id, channel, false); + dma_channel_abort(channel); // in case a transfer is in flight + dma_channel_unclaim(channel); + } +} + +STATIC void dma_irq_handler(uint8_t irq_index) { + int dma_channel = dma_map_irq_to_channel(irq_index); + if (dma_channel == -1) { + // This should never happen + return; + } + + machine_i2s_obj_t *self = MP_STATE_PORT(machine_i2s_obj[irq_index]); + if (self == NULL) { + // This should never happen + return; + } + + uint8_t *dma_buffer = dma_get_buffer(self, dma_channel); + if (dma_buffer == NULL) { + // This should never happen + return; + } + + if (self->mode == TX) { + // for non-blocking operation handle the write() method requests. + if ((self->io_mode == NON_BLOCKING) && (self->non_blocking_descriptor.copy_in_progress)) { + copy_appbuf_to_ringbuf_non_blocking(self); + } + + feed_dma(self, dma_buffer); + dma_irqn_acknowledge_channel(irq_index, dma_channel); + dma_channel_set_read_addr(dma_channel, dma_buffer, false); + } else { // RX + empty_dma(self, dma_buffer); + dma_irqn_acknowledge_channel(irq_index, dma_channel); + dma_channel_set_write_addr(dma_channel, dma_buffer, false); + + // for non-blocking operation handle the readinto() method requests. + if ((self->io_mode == NON_BLOCKING) && (self->non_blocking_descriptor.copy_in_progress)) { + fill_appbuf_from_ringbuf_non_blocking(self); + } + } +} + +STATIC void dma_irq0_handler(void) { + dma_irq_handler(0); +} + +STATIC void dma_irq1_handler(void) { + dma_irq_handler(1); +} + +STATIC void machine_i2s_init_helper(machine_i2s_obj_t *self, size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + + enum { + ARG_sck, + ARG_ws, + ARG_sd, + ARG_mode, + ARG_bits, + ARG_format, + ARG_rate, + ARG_ibuf, + }; + + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_ws, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_sd, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_format, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_rate, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_ibuf, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = -1} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_pos_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // + // ---- Check validity of arguments ---- + // + + // are Pins valid? + mp_hal_pin_obj_t sck = args[ARG_sck].u_obj == MP_OBJ_NULL ? -1 : mp_hal_get_pin_obj(args[ARG_sck].u_obj); + mp_hal_pin_obj_t ws = args[ARG_ws].u_obj == MP_OBJ_NULL ? -1 : mp_hal_get_pin_obj(args[ARG_ws].u_obj); + mp_hal_pin_obj_t sd = args[ARG_sd].u_obj == MP_OBJ_NULL ? -1 : mp_hal_get_pin_obj(args[ARG_sd].u_obj); + + // does WS pin follow SCK pin? + // note: SCK and WS are implemented as PIO sideset pins. Sideset pins must be sequential. + if (ws != (sck + 1)) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid ws (must be sck+1)")); + } + + // is Mode valid? + i2s_mode_t i2s_mode = args[ARG_mode].u_int; + if ((i2s_mode != RX) && + (i2s_mode != TX)) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid mode")); + } + + // is Bits valid? + int8_t i2s_bits = args[ARG_bits].u_int; + if ((i2s_bits != 16) && + (i2s_bits != 32)) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid bits")); + } + + // is Format valid? + format_t i2s_format = args[ARG_format].u_int; + if ((i2s_format != MONO) && + (i2s_format != STEREO)) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid format")); + } + + // is Rate valid? + // Not checked + + // is Ibuf valid? + int32_t ring_buffer_len = args[ARG_ibuf].u_int; + if (ring_buffer_len > 0) { + self->ring_buffer_storage = m_new(uint8_t, ring_buffer_len); + ; + ringbuf_init(&self->ring_buffer, self->ring_buffer_storage, ring_buffer_len); + } else { + mp_raise_ValueError(MP_ERROR_TEXT("invalid ibuf")); + } + + self->sck = sck; + self->ws = ws; + self->sd = sd; + self->mode = i2s_mode; + self->bits = i2s_bits; + self->format = i2s_format; + self->rate = args[ARG_rate].u_int; + self->ibuf = ring_buffer_len; + self->callback_for_non_blocking = MP_OBJ_NULL; + self->non_blocking_descriptor.copy_in_progress = false; + self->io_mode = BLOCKING; + + irq_configure(self); + pio_configure(self); + gpio_configure(self); + dma_configure(self); + + pio_sm_set_enabled(self->pio, self->sm, true); + dma_channel_start(self->dma_channel[0]); +} + +STATIC void machine_i2s_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "I2S(id=%u,\n" + "sck="MP_HAL_PIN_FMT ",\n" + "ws="MP_HAL_PIN_FMT ",\n" + "sd="MP_HAL_PIN_FMT ",\n" + "mode=%u,\n" + "bits=%u, format=%u,\n" + "rate=%d, ibuf=%d)", + self->i2s_id, + mp_hal_pin_name(self->sck), + mp_hal_pin_name(self->ws), + mp_hal_pin_name(self->sd), + self->mode, + self->bits, self->format, + self->rate, self->ibuf + ); +} + +STATIC mp_obj_t machine_i2s_make_new(const mp_obj_type_t *type, size_t n_pos_args, size_t n_kw_args, const mp_obj_t *args) { + mp_arg_check_num(n_pos_args, n_kw_args, 1, MP_OBJ_FUN_ARGS_MAX, true); + uint8_t i2s_id = mp_obj_get_int(args[0]); + + if (i2s_id >= MAX_I2S_RP2) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid id")); + } + + machine_i2s_obj_t *self; + if (MP_STATE_PORT(machine_i2s_obj[i2s_id]) == NULL) { + self = m_new_obj(machine_i2s_obj_t); + MP_STATE_PORT(machine_i2s_obj[i2s_id]) = self; + self->base.type = &machine_i2s_type; + self->i2s_id = i2s_id; + } else { + self = MP_STATE_PORT(machine_i2s_obj[i2s_id]); + machine_i2s_deinit(MP_OBJ_FROM_PTR(self)); + } + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw_args, args + n_pos_args); + machine_i2s_init_helper(self, n_pos_args - 1, args + 1, &kw_args); + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t machine_i2s_init(size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + machine_i2s_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + machine_i2s_deinit(MP_OBJ_FROM_PTR(self)); + machine_i2s_init_helper(self, n_pos_args - 1, pos_args + 1, kw_args); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2s_init_obj, 1, machine_i2s_init); + +STATIC mp_obj_t machine_i2s_deinit(mp_obj_t self_in) { + machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // use self->pio as in indication that I2S object has already been de-initialized + if (self->pio != NULL) { + pio_deinit(self); + dma_deinit(self); + irq_deinit(self); + m_free(self->ring_buffer_storage); + self->pio = NULL; // flag object as de-initialized + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_i2s_deinit_obj, machine_i2s_deinit); + +STATIC mp_obj_t machine_i2s_irq(mp_obj_t self_in, mp_obj_t handler) { + machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (handler != mp_const_none && !mp_obj_is_callable(handler)) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid callback")); + } + + if (handler != mp_const_none) { + self->io_mode = NON_BLOCKING; + } else { + self->io_mode = BLOCKING; + } + + self->callback_for_non_blocking = handler; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_irq_obj, machine_i2s_irq); + +// Shift() is typically used as a volume control. +// shift=1 increases volume by 6dB, shift=-1 decreases volume by 6dB +STATIC mp_obj_t machine_i2s_shift(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_buf, ARG_bits, ARG_shift}; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_bits, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_shift, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + }; + + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buf].u_obj, &bufinfo, MP_BUFFER_RW); + + int16_t *buf_16 = bufinfo.buf; + int32_t *buf_32 = bufinfo.buf; + + uint8_t bits = args[ARG_bits].u_int; + int8_t shift = args[ARG_shift].u_int; + + uint32_t num_audio_samples; + switch (bits) { + case 16: + num_audio_samples = bufinfo.len / sizeof(uint16_t); + break; + + case 32: + num_audio_samples = bufinfo.len / sizeof(uint32_t); + break; + + default: + mp_raise_ValueError(MP_ERROR_TEXT("invalid bits")); + break; + } + + for (uint32_t i = 0; i < num_audio_samples; i++) { + switch (bits) { + case 16: + if (shift >= 0) { + buf_16[i] = buf_16[i] << shift; + } else { + buf_16[i] = buf_16[i] >> abs(shift); + } + break; + case 32: + if (shift >= 0) { + buf_32[i] = buf_32[i] << shift; + } else { + buf_32[i] = buf_32[i] >> abs(shift); + } + break; + } + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2s_shift_fun_obj, 0, machine_i2s_shift); +STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(machine_i2s_shift_obj, MP_ROM_PTR(&machine_i2s_shift_fun_obj)); + +STATIC const mp_rom_map_elem_t machine_i2s_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_i2s_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_i2s_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_i2s_irq_obj) }, + + // Static method + { MP_ROM_QSTR(MP_QSTR_shift), MP_ROM_PTR(&machine_i2s_shift_obj) }, + + // Constants + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_INT(RX) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_INT(TX) }, + { MP_ROM_QSTR(MP_QSTR_STEREO), MP_ROM_INT(STEREO) }, + { MP_ROM_QSTR(MP_QSTR_MONO), MP_ROM_INT(MONO) }, +}; +MP_DEFINE_CONST_DICT(machine_i2s_locals_dict, machine_i2s_locals_dict_table); + +STATIC mp_uint_t machine_i2s_stream_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { + machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (self->mode != RX) { + *errcode = MP_EPERM; + return MP_STREAM_ERROR; + } + + uint8_t appbuf_sample_size_in_bytes = (self->bits / 8) * (self->format == STEREO ? 2: 1); + if (size % appbuf_sample_size_in_bytes != 0) { + *errcode = MP_EINVAL; + return MP_STREAM_ERROR; + } + + if (size == 0) { + return 0; + } + + if (self->io_mode == NON_BLOCKING) { + self->non_blocking_descriptor.appbuf.buf = (void *)buf_in; + self->non_blocking_descriptor.appbuf.len = size; + self->non_blocking_descriptor.index = 0; + self->non_blocking_descriptor.copy_in_progress = true; + return size; + } else { // blocking or uasyncio mode + mp_buffer_info_t appbuf; + appbuf.buf = (void *)buf_in; + appbuf.len = size; + uint32_t num_bytes_read = fill_appbuf_from_ringbuf(self, &appbuf); + return num_bytes_read; + } +} + +STATIC mp_uint_t machine_i2s_stream_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (self->mode != TX) { + *errcode = MP_EPERM; + return MP_STREAM_ERROR; + } + + if (size == 0) { + return 0; + } + + if (self->io_mode == NON_BLOCKING) { + self->non_blocking_descriptor.appbuf.buf = (void *)buf_in; + self->non_blocking_descriptor.appbuf.len = size; + self->non_blocking_descriptor.index = 0; + self->non_blocking_descriptor.copy_in_progress = true; + return size; + } else { // blocking or uasyncio mode + mp_buffer_info_t appbuf; + appbuf.buf = (void *)buf_in; + appbuf.len = size; + uint32_t num_bytes_written = copy_appbuf_to_ringbuf(self, &appbuf); + return num_bytes_written; + } +} + +STATIC mp_uint_t machine_i2s_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { + machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t ret; + uintptr_t flags = arg; + self->io_mode = UASYNCIO; // a call to ioctl() is an indication that uasyncio is being used + + if (request == MP_STREAM_POLL) { + ret = 0; + + if (flags & MP_STREAM_POLL_RD) { + if (self->mode != RX) { + *errcode = MP_EPERM; + return MP_STREAM_ERROR; + } + + if (!ringbuf_is_empty(&self->ring_buffer)) { + ret |= MP_STREAM_POLL_RD; + } + } + + if (flags & MP_STREAM_POLL_WR) { + if (self->mode != TX) { + *errcode = MP_EPERM; + return MP_STREAM_ERROR; + } + + if (!ringbuf_is_full(&self->ring_buffer)) { + ret |= MP_STREAM_POLL_WR; + } + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + + return ret; +} + +STATIC const mp_stream_p_t i2s_stream_p = { + .read = machine_i2s_stream_read, + .write = machine_i2s_stream_write, + .ioctl = machine_i2s_ioctl, + .is_text = false, +}; + +const mp_obj_type_t machine_i2s_type = { + { &mp_type_type }, + .name = MP_QSTR_I2S, + .print = machine_i2s_print, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &i2s_stream_p, + .make_new = machine_i2s_make_new, + .locals_dict = (mp_obj_dict_t *)&machine_i2s_locals_dict, +}; diff --git a/ports/rp2/main.c b/ports/rp2/main.c index 0dac85c49d..793444c9a9 100644 --- a/ports/rp2/main.c +++ b/ports/rp2/main.c @@ -109,6 +109,7 @@ int main(int argc, char **argv) { readline_init0(); machine_pin_init(); rp2_pio_init(); + machine_i2s_init0(); #if MICROPY_PY_BLUETOOTH mp_bluetooth_hci_init(); diff --git a/ports/rp2/modmachine.c b/ports/rp2/modmachine.c index 32dc3d22cc..88e4bec2e8 100644 --- a/ports/rp2/modmachine.c +++ b/ports/rp2/modmachine.c @@ -163,6 +163,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_hw_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, + { MP_ROM_QSTR(MP_QSTR_I2S), MP_ROM_PTR(&machine_i2s_type) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) }, diff --git a/ports/rp2/modmachine.h b/ports/rp2/modmachine.h index 0c48565299..af02cd193d 100644 --- a/ports/rp2/modmachine.h +++ b/ports/rp2/modmachine.h @@ -5,6 +5,7 @@ extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_hw_i2c_type; +extern const mp_obj_type_t machine_i2s_type; extern const mp_obj_type_t machine_pin_type; extern const mp_obj_type_t machine_rtc_type; extern const mp_obj_type_t machine_spi_type; @@ -14,5 +15,6 @@ extern const mp_obj_type_t machine_wdt_type; void machine_pin_init(void); void machine_pin_deinit(void); +void machine_i2s_init0(void); #endif // MICROPY_INCLUDED_RP2_MODMACHINE_H diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index 2794fda2e1..b40e18d2f8 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -176,6 +176,7 @@ struct _mp_bluetooth_nimble_malloc_t; void *rp2_state_machine_irq_obj[8]; \ void *rp2_uart_rx_buffer[2]; \ void *rp2_uart_tx_buffer[2]; \ + void *machine_i2s_obj[2]; \ NETWORK_ROOT_POINTERS \ MICROPY_BOARD_ROOT_POINTERS \ MICROPY_PORT_ROOT_POINTER_BLUETOOTH \ From 43079aaf860cbc19d54cec1eca9d5897297b22ac Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 15 Aug 2021 18:51:15 +0200 Subject: [PATCH 143/335] drivers/ninaw10: Add ublox Nina-W10 WiFi/BT module driver. - Add WiFi/BT drivers for ublox Nina-W10 (esp32 based) module. - Add ublox Nina-W10 Python module in extmod. --- drivers/ninaw10/nina_bsp.h | 39 ++ drivers/ninaw10/nina_bt_hci.c | 150 ++++++ drivers/ninaw10/nina_wifi_bsp.c | 139 +++++ drivers/ninaw10/nina_wifi_drv.c | 913 ++++++++++++++++++++++++++++++++ drivers/ninaw10/nina_wifi_drv.h | 120 +++++ extmod/network_ninaw10.c | 588 ++++++++++++++++++++ tools/codeformat.py | 1 + 7 files changed, 1950 insertions(+) create mode 100644 drivers/ninaw10/nina_bsp.h create mode 100644 drivers/ninaw10/nina_bt_hci.c create mode 100644 drivers/ninaw10/nina_wifi_bsp.c create mode 100644 drivers/ninaw10/nina_wifi_drv.c create mode 100644 drivers/ninaw10/nina_wifi_drv.h create mode 100644 extmod/network_ninaw10.c diff --git a/drivers/ninaw10/nina_bsp.h b/drivers/ninaw10/nina_bsp.h new file mode 100644 index 0000000000..362583843f --- /dev/null +++ b/drivers/ninaw10/nina_bsp.h @@ -0,0 +1,39 @@ +/* + * This file is part of the OpenMV project, https://openmv.io. + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2021 Ibrahim Abdelkader + * Copyright (c) 2013-2021 Kwabena W. Agyeman + * + * 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. + * + * NINA-W10 driver BSP. + */ +#ifndef MICROPY_INCLUDED_DRIVERS_NINAW10_NINA_BSP_H +#define MICROPY_INCLUDED_DRIVERS_NINAW10_NINA_BSP_H + +int nina_bsp_init(void); +int nina_bsp_deinit(void); +int nina_bsp_read_irq(void); +int nina_bsp_spi_slave_select(uint32_t timeout); +int nina_bsp_spi_slave_deselect(void); +int nina_bsp_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, uint32_t size); + +#endif // MICROPY_INCLUDED_DRIVERS_NINAW10_NINA_BSP_H diff --git a/drivers/ninaw10/nina_bt_hci.c b/drivers/ninaw10/nina_bt_hci.c new file mode 100644 index 0000000000..6dc3204471 --- /dev/null +++ b/drivers/ninaw10/nina_bt_hci.c @@ -0,0 +1,150 @@ +/* + * This file is part of the OpenMV project, https://openmv.io. + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2021 Ibrahim Abdelkader + * Copyright (c) 2013-2021 Kwabena W. Agyeman + * + * 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. + * + * NINA-W10 Bluetooth HCI driver. + */ + +#include "py/mphal.h" + +#if MICROPY_PY_BLUETOOTH && MICROPY_PY_NETWORK_NINAW10 + +#include +#include + +#include "py/runtime.h" +#include "extmod/mpbthci.h" + +#define HCI_COMMAND_PACKET (0x01) +#define HCI_ACLDATA_PACKET (0x02) +#define HCI_EVENT_PACKET (0x04) + +#define HCI_COMMAND_COMPLETE (0x0e) +#define HCI_COMMAND_TIMEOUT (3000) + +#define OGF_LINK_CTL (0x01) +#define OGF_HOST_CTL (0x03) + +#define OCF_SET_EVENT_MASK (0x0001) +#define OCF_RESET (0x0003) + +#define error_printf(...) mp_printf(&mp_plat_print, "nina_bt_hci.c: " __VA_ARGS__) +#define debug_printf(...) // mp_printf(&mp_plat_print, "nina_bt_hci.c: " __VA_ARGS__) + +// Provided by the port, and also possibly shared with the stack. +extern uint8_t mp_bluetooth_hci_cmd_buf[4 + 256]; + +static int nina_hci_cmd(int ogf, int ocf, size_t param_len, const uint8_t *param_buf) { + uint8_t *buf = mp_bluetooth_hci_cmd_buf; + + buf[0] = HCI_COMMAND_PACKET; + buf[1] = ocf; + buf[2] = ogf << 2 | ocf >> 8; + buf[3] = param_len; + + if (param_len) { + memcpy(buf + 4, param_buf, param_len); + } + + debug_printf("HCI Command: %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]); + + mp_bluetooth_hci_uart_write(buf, 4 + param_len); + + // Receive HCI event packet, initially reading 3 bytes (HCI Event, Event code, Plen). + for (mp_uint_t start = mp_hal_ticks_ms(), size = 3, i = 0; i < size;) { + while (!mp_bluetooth_hci_uart_any()) { + MICROPY_EVENT_POLL_HOOK + // Timeout. + if ((mp_hal_ticks_ms() - start) > HCI_COMMAND_TIMEOUT) { + error_printf("timeout waiting for HCI packet\n"); + return -1; + } + } + + buf[i] = mp_bluetooth_hci_uart_readchar(); + + // There seems to be a sync issue with this fw/module. + if (i == 0 && buf[0] == 0xFF) { + continue; + } + + // Check for packet type. + if (i == 0 && buf[0] != HCI_EVENT_PACKET) { + error_printf("unexpected HCI packet: %02x\n", buf[0]); + return -1; + } + + // Sanity check the packet parameters length. + if (i == 2 && ((size += buf[2]) > sizeof(mp_bluetooth_hci_cmd_buf))) { + error_printf("unexpected event packet length: %d\n", size); + return -1; + } + + i++; + } + + // We're only looking for command complete events. + if (buf[1] != HCI_COMMAND_COMPLETE || buf[4] != ocf || buf[5] != (ogf << 2 | ocf >> 8)) { + error_printf("response mismatch: %02x %02x\n", buf[4], buf[5]); + return -1; + } + + // Log event. + debug_printf("HCI Event packet: %02x %02x %02x %02x %02x %02x %02x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); + + // Status code. + return buf[6]; +} + +int mp_bluetooth_hci_controller_init(void) { + // This is called immediately after the UART is initialised during stack initialisation. + mp_hal_pin_output(MICROPY_HW_NINA_GPIO1); + mp_hal_pin_output(MICROPY_HW_NINA_RESET); + + mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 0); + mp_hal_pin_write(MICROPY_HW_NINA_RESET, 0); + mp_hal_delay_ms(100); + + mp_hal_pin_write(MICROPY_HW_NINA_RESET, 1); + mp_hal_delay_ms(750); + + // The UART must be re-initialize here because the GPIO1/RX pin is used initially + // to reset the module in Bluetooth mode. This will change back the pin to UART RX. + mp_bluetooth_hci_uart_init(0, 0); + + // Send reset command + return nina_hci_cmd(OGF_HOST_CTL, OCF_RESET, 0, NULL); + // It seems that nothing else is needed for now. +} + +int mp_bluetooth_hci_controller_deinit(void) { + // Reset module + mp_hal_pin_output(MICROPY_HW_NINA_RESET); + mp_hal_pin_write(MICROPY_HW_NINA_RESET, 0); + return 0; +} + +#endif diff --git a/drivers/ninaw10/nina_wifi_bsp.c b/drivers/ninaw10/nina_wifi_bsp.c new file mode 100644 index 0000000000..c5a9b9b10a --- /dev/null +++ b/drivers/ninaw10/nina_wifi_bsp.c @@ -0,0 +1,139 @@ +/* + * This file is part of the OpenMV project, https://openmv.io. + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2021 Ibrahim Abdelkader + * Copyright (c) 2013-2021 Kwabena W. Agyeman + * + * 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. + * + * NINA-W10 driver BSP implementation. + */ + +#include "py/mphal.h" + +#if MICROPY_PY_NETWORK_NINAW10 + +#include +#include + +#include "py/runtime.h" +#include "modmachine.h" +#include "extmod/machine_spi.h" +#include "mpconfigboard.h" + +#include "nina_bsp.h" +#include "nina_wifi_drv.h" + +#if NINA_DEBUG +#define debug_printf(...) mp_printf(&mp_plat_print, __VA_ARGS__) +#else +#define debug_printf(...) +#endif + +int nina_bsp_init(void) { + mp_hal_pin_output(MICROPY_HW_NINA_GPIO1); + mp_hal_pin_input(MICROPY_HW_NINA_ACK); + mp_hal_pin_output(MICROPY_HW_NINA_RESET); + mp_hal_pin_output(MICROPY_HW_NINA_GPIO0); + + // Reset module in WiFi mode + mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 1); + mp_hal_pin_write(MICROPY_HW_NINA_GPIO0, 1); + + mp_hal_pin_write(MICROPY_HW_NINA_RESET, 0); + mp_hal_delay_ms(100); + + mp_hal_pin_write(MICROPY_HW_NINA_RESET, 1); + mp_hal_delay_ms(750); + + mp_hal_pin_write(MICROPY_HW_NINA_GPIO0, 0); + mp_hal_pin_input(MICROPY_HW_NINA_GPIO0); + + // Initialize SPI. + mp_obj_t args[] = { + MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIFI_SPI_ID), + MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIFI_SPI_BAUDRATE), + }; + + MP_STATE_PORT(mp_wifi_spi) = machine_spi_type.make_new((mp_obj_t)&machine_spi_type, 2, 0, args); + return 0; +} + +int nina_bsp_deinit(void) { + mp_hal_pin_output(MICROPY_HW_NINA_GPIO1); + mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 1); + + mp_hal_pin_output(MICROPY_HW_NINA_RESET); + mp_hal_pin_write(MICROPY_HW_NINA_RESET, 0); + mp_hal_delay_ms(100); + + mp_hal_pin_output(MICROPY_HW_NINA_GPIO0); + mp_hal_pin_write(MICROPY_HW_NINA_GPIO0, 1); + return 0; +} + +int nina_bsp_read_irq(void) { + return mp_hal_pin_read(MICROPY_HW_NINA_GPIO0); +} + +int nina_bsp_spi_slave_select(uint32_t timeout) { + // Wait for ACK to go low. + for (mp_uint_t start = mp_hal_ticks_ms(); mp_hal_pin_read(MICROPY_HW_NINA_ACK) == 1; mp_hal_delay_ms(1)) { + if ((mp_hal_ticks_ms() - start) >= timeout) { + return -1; + } + } + + // Chip select. + mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 0); + + // Wait for ACK to go high. + for (mp_uint_t start = mp_hal_ticks_ms(); mp_hal_pin_read(MICROPY_HW_NINA_ACK) == 0; mp_hal_delay_ms(1)) { + if ((mp_hal_ticks_ms() - start) >= 100) { + mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 1); + return -1; + } + } + + return 0; +} + +int nina_bsp_spi_slave_deselect(void) { + mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 1); + return 0; +} + +int nina_bsp_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, uint32_t size) { + mp_obj_t mp_wifi_spi = MP_STATE_PORT(mp_wifi_spi); + ((mp_machine_spi_p_t *)machine_spi_type.protocol)->transfer(mp_wifi_spi, size, tx_buf, rx_buf); + #if NINA_DEBUG + for (int i = 0; i < size; i++) { + if (tx_buf) { + debug_printf("0x%x ", tx_buf[i]); + } else { + debug_printf("0x%x ", rx_buf[i]); + } + } + #endif + return 0; +} + +#endif // MICROPY_PY_NETWORK_NINAW10 diff --git a/drivers/ninaw10/nina_wifi_drv.c b/drivers/ninaw10/nina_wifi_drv.c new file mode 100644 index 0000000000..70f1a4264c --- /dev/null +++ b/drivers/ninaw10/nina_wifi_drv.c @@ -0,0 +1,913 @@ +/* + * This file is part of the OpenMV project, https://openmv.io. + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2021 Ibrahim Abdelkader + * Copyright (c) 2013-2021 Kwabena W. Agyeman + * + * 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. + * + * NINA-W10 WiFi driver. + */ + +#include "py/mphal.h" + +#if MICROPY_PY_NETWORK_NINAW10 + +#include +#include +#include + +#include "nina_bsp.h" +#include "nina_wifi_drv.h" + +#define SPI_ACK (1) +#define SPI_ERR (0xFF) + +#define NO_SOCKET_AVAIL (255) + +#define CMD_START (0xE0) +#define CMD_END (0xEE) +#define CMD_ERROR (0xEF) +#define CMD_REPLY (1 << 7) + +#define ARG_8BITS (1) +#define ARG_16BITS (2) + +#define ARG_STR(x) {strlen(x), (const void *)x} +#define ARG_BYTE(x) {1, (uint8_t [1]) {x}} +#define ARG_SHORT(x) {2, (uint16_t [1]) {x}} +#define ARG_WORD(x) {4, (uint32_t [1]) {x}} + +#define NINA_ARGS(...) (nina_args_t []) {__VA_ARGS__} +#define NINA_VALS(...) (nina_vals_t []) {__VA_ARGS__} + +#define NINA_SSELECT_TIMEOUT (10000) +#define NINA_RESPONSE_TIMEOUT (1000) +#define NINA_CONNECT_TIMEOUT (10000) + +#if NINA_DEBUG +#define debug_printf(...) mp_printf(&mp_plat_print, __VA_ARGS__) +#else +#define debug_printf(...) +#endif + +#ifndef __REVSH +#define __REVSH(x) ((((uint16_t)x) << 8) | (((uint16_t)x) >> 8)) +#endif + +typedef struct { + uint16_t size; + const void *data; +} nina_args_t; + +typedef struct { + uint16_t *size; + void *data; +} nina_vals_t; + +typedef enum { + // STA mode commands. + NINA_CMD_CONNECT_OPEN = 0x10, + NINA_CMD_CONNECT_WEP = 0x11, + NINA_CMD_CONNECT_WPA = 0x12, + NINA_CMD_GET_SSID = 0x23, + NINA_CMD_GET_BSSID = 0x24, + NINA_CMD_GET_RSSI = 0x25, + NINA_CMD_GET_ENCRYPT = 0x26, + + // AP mode commands. + NINA_CMD_START_AP_OPEN = 0x18, + NINA_CMD_START_AP_WEP = 0x19, + + // AP mode scan commands. + NINA_CMD_AP_START_SCAN = 0x36, + NINA_CMD_AP_SCAN_RESULT = 0x27, + NINA_CMD_AP_GET_RSSI = 0x32, + NINA_CMD_AP_GET_ENCRYPT = 0x33, + NINA_CMD_AP_GET_BSSID = 0x3C, + NINA_CMD_AP_GET_CHANNEL = 0x3D, + + // Disonnect/status commands. + NINA_CMD_DISCONNECT = 0x30, + NINA_CMD_CONN_STATUS = 0x20, + + // Interface config commands. + NINA_CMD_SET_IF_CONFIG = 0x14, + NINA_CMD_GET_IF_CONFIG = 0x21, + NINA_CMD_SET_DNS_CONFIG = 0x15, + + // Hostname/Resolv commands. + NINA_CMD_SET_HOSTNAME = 0x16, + NINA_CMD_HOST_BY_NAME = 0x34, + NINA_CMD_GET_HOST_BY_NAME = 0x35, + + // Misc commands. + NINA_CMD_SET_POWER = 0x17, + NINA_CMD_PING = 0x3E, + NINA_CMD_GET_TIME = 0x3B, + NINA_CMD_GET_FW_VERSION = 0x37, + NINA_CMD_DEBUG_MODE = 0x1A, + NINA_CMD_TEMP_SENSOR = 0x1B, + NINA_CMD_GET_MAC_ADDR = 0x22, + + // Sockets commands. + NINA_CMD_SOCKET_OPEN = 0x3F, + NINA_CMD_SOCKET_CLOSE = 0x2E, + NINA_CMD_SOCKET_CONNECT = 0x2D, + NINA_CMD_SOCKET_ACCEPT = 0x2B, + NINA_CMD_SOCKET_BIND = 0x28, + NINA_CMD_SOCKET_STATE = 0x2F, + NINA_CMD_SOCKET_REMOTE_ADDR = 0x3A, + + // TCP commands + NINA_CMD_TCP_SEND = 0x44, + NINA_CMD_TCP_RECV = 0x45, + NINA_CMD_TCP_ACK = 0x2A, + + // UDP commands. + NINA_CMD_UDP_SEND = 0x46, + NINA_CMD_UDP_RECV = 0x45, + NINA_CMD_UDP_ACK = 0x39, + + // Pin control commands. + NINA_CMD_SET_PIN_MODE = 0x50, + NINA_CMD_SET_DIGITAL_WRITE = 0x51, + NINA_CMD_GET_DIGITAL_READ = 0x53, + NINA_CMD_SET_ANALOG_WRITE = 0x52, + NINA_CMD_GET_ANALOG_READ = 0x54, + + // File send/recv commands. + NINA_CMD_CMD_WRITE_FILE = 0x60, + NINA_CMD_CMD_READ_FILE = 0x61, + NINA_CMD_CMD_DELETE_FILE = 0x62, + NINA_CMD_CMD_EXISTS_FILE = 0x63, + NINA_CMD_CMD_DOWNLOAD_FILE = 0x64, + + // OTA upgrade commands. + NINA_CMD_CMD_APPLY_OTA = 0x65, + NINA_CMD_CMD_RENAME_FILE = 0x66, + NINA_CMD_CMD_DOWNLOAD_OTA = 0x67, +} nina_cmd_t; + +typedef enum { + NINA_STATUS_IDLE = 0, + NINA_STATUS_NO_SSID_AVAIL, + NINA_STATUS_SCAN_COMPLETED, + NINA_STATUS_CONNECTED, + NINA_STATUS_CONNECT_FAILED, + NINA_STATUS_CONNECTION_LOST, + NINA_STATUS_DISCONNECTED, + NINA_STATUS_AP_LISTENING, + NINA_STATUS_AP_CONNECTED, + NINA_STATUS_AP_FAILED +} nina_status_t; + +typedef enum { + SOCKET_STATE_CLOSED = 0, + SOCKET_STATE_LISTEN, + SOCKET_STATE_SYN_SENT, + SOCKET_STATE_SYN_RCVD, + SOCKET_STATE_ESTABLISHED, + SOCKET_STATE_FIN_WAIT_1, + SOCKET_STATE_FIN_WAIT_2, + SOCKET_STATE_CLOSE_WAIT, + SOCKET_STATE_CLOSING, + SOCKET_STATE_LAST_ACK, + SOCKET_STATE_TIME_WAIT +} nina_sock_state_t; + +static uint8_t nina_bsp_spi_read_byte(void) { + uint8_t byte = 0; + nina_bsp_spi_transfer(NULL, &byte, 1); + return byte; +} + +static int nina_wait_for_cmd(uint8_t cmd, uint32_t timeout) { + uint8_t buf = 0; + for (mp_uint_t start = mp_hal_ticks_ms(); ;) { + buf = nina_bsp_spi_read_byte(); + if (buf == CMD_ERROR || buf == cmd + || ((mp_hal_ticks_ms() - start) >= timeout)) { + break; + } + mp_hal_delay_ms(1); + } + + return (buf == cmd) ? 0 : -1; +} + +static int nina_send_command(uint32_t cmd, uint32_t nargs, uint32_t width, nina_args_t *args) { + int ret = -1; + uint32_t length = 4; // 3 bytes header + 1 end byte + + debug_printf("nina_send_command (cmd 0x%x nargs %d width %d): ", cmd, nargs, width); + + if (nina_bsp_spi_slave_select(NINA_SSELECT_TIMEOUT) != 0) { + return -1; + } + + // Send command header. + uint8_t cmdbuf_hdr[3] = {CMD_START, cmd, nargs}; + if (nina_bsp_spi_transfer(cmdbuf_hdr, NULL, sizeof(cmdbuf_hdr)) != 0) { + goto error_out; + } + + // Send command arg(s). + for (uint32_t i = 0; i < nargs; i++) { + // Send size MSB first if 2 bytes. + uint16_t size = (width == ARG_8BITS) ? args[i].size : __REVSH(args[i].size); + + // Send arg length. + if (nina_bsp_spi_transfer((uint8_t *)&size, NULL, width) != 0) { + goto error_out; + } + + // Send arg value. + if (nina_bsp_spi_transfer(args[i].data, NULL, args[i].size) != 0) { + goto error_out; + } + length += args[i].size + width; + } + + // Send END byte + padding to multiple of 4. + uint8_t cmdbuf_end[4] = {CMD_END, 0xFF, 0xFF, 0xFF}; + if (nina_bsp_spi_transfer(cmdbuf_end, NULL, 1 + (length % 4)) != 0) { + goto error_out; + } + + // All good + ret = 0; + +error_out: + debug_printf("\n"); + nina_bsp_spi_slave_deselect(); + return ret; +} + +static int nina_read_response(uint32_t cmd, uint32_t nvals, uint32_t width, nina_vals_t *vals) { + int ret = -1; + + debug_printf("nina_read_response(cmd 0x%x nvals %d width %d): ", cmd, nvals, width); + + // Read reply + if (nina_bsp_spi_slave_select(NINA_SSELECT_TIMEOUT) != 0) { + return -1; + } + + // Wait for CMD_START + if (nina_wait_for_cmd(CMD_START, NINA_RESPONSE_TIMEOUT) != 0) { + goto error_out; + } + + // Should return CMD + REPLY flag. + if (nina_bsp_spi_read_byte() != (cmd | CMD_REPLY)) { + goto error_out; + } + + // Sanity check the number of returned values. + // NOTE: This is to handle the special case for the scan command. + uint32_t rvals = nina_bsp_spi_read_byte(); + if (nvals > rvals) { + nvals = rvals; + } + + // Read return value(s). + for (uint32_t i = 0; i < nvals; i++) { + // Read return value size. + uint16_t bytes = nina_bsp_spi_read_byte(); + if (width == ARG_16BITS) { + bytes = (bytes << 8) | nina_bsp_spi_read_byte(); + } + + // Check the val fits the buffer. + if (*(vals[i].size) < bytes) { + goto error_out; + } + + // Read the returned value. + if (nina_bsp_spi_transfer(NULL, vals[i].data, bytes) != 0) { + goto error_out; + } + + // Set the size. + *(vals[i].size) = bytes; + } + + if (nina_bsp_spi_read_byte() != CMD_END) { + goto error_out; + } + + // All good + ret = 0; + +error_out: + debug_printf("\n"); + nina_bsp_spi_slave_deselect(); + return ret; +} + +static int nina_send_command_read_ack(uint32_t cmd, uint32_t nargs, uint32_t width, nina_args_t *args) { + uint16_t size = 1; + uint8_t rval = SPI_ERR; + if (nina_send_command(cmd, nargs, width, args) != 0 || + nina_read_response(cmd, 1, ARG_8BITS, NINA_VALS({&size, &rval})) != 0) { + return -1; + } + return rval; +} + +static int nina_send_command_read_vals(uint32_t cmd, uint32_t nargs, + uint32_t argsw, nina_args_t *args, uint32_t nvals, uint32_t valsw, nina_vals_t *vals) { + + if (nina_send_command(cmd, nargs, argsw, args) != 0 || + nina_read_response(cmd, nvals, valsw, vals) != 0) { + return -1; + } + return 0; +} + +int nina_init(void) { + // Initialize the BSP. + nina_bsp_init(); + return 0; +} + +int nina_deinit(void) { + return nina_bsp_deinit(); +} + +static int nina_connection_status() { + return nina_send_command_read_ack(NINA_CMD_CONN_STATUS, 0, ARG_8BITS, NULL); +} + +static int nina_socket_status(uint8_t fd) { + return nina_send_command_read_ack(NINA_CMD_SOCKET_STATE, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd))); +} + +static int nina_server_socket_status(uint8_t fd) { + return nina_send_command_read_ack(NINA_CMD_SOCKET_STATE & 0xF9, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd))); +} + +int nina_connect(const char *ssid, uint8_t security, const char *key, uint16_t channel) { + uint8_t status = NINA_STATUS_CONNECT_FAILED; + + if (key == NULL && security != NINA_SEC_OPEN) { + return -1; + } + + switch (security) { + case NINA_SEC_OPEN: + if (nina_send_command_read_ack(NINA_CMD_CONNECT_OPEN, + 1, ARG_8BITS, NINA_ARGS(ARG_STR(ssid))) != SPI_ACK) { + return -1; + } + break; + case NINA_SEC_WEP: + if (nina_send_command_read_ack(NINA_CMD_CONNECT_WEP, + 2, ARG_8BITS, NINA_ARGS(ARG_STR(ssid), ARG_STR(key))) != SPI_ACK) { + return -1; + } + break; + case NINA_SEC_WPA_PSK: + if (nina_send_command_read_ack(NINA_CMD_CONNECT_WPA, + 3, ARG_8BITS, NINA_ARGS(ARG_STR(ssid), ARG_BYTE(0), ARG_STR(key))) != SPI_ACK) { + return -1; + } + break; + default: + return -1; + } + + for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(10)) { + status = nina_connection_status(); + if ((status != NINA_STATUS_IDLE) && (status != NINA_STATUS_NO_SSID_AVAIL) && (status != NINA_STATUS_SCAN_COMPLETED)) { + break; + } + + if ((mp_hal_ticks_ms() - start) >= NINA_CONNECT_TIMEOUT) { + break; + } + } + + return (status == NINA_STATUS_CONNECTED) ? 0 : -1; +} + +int nina_start_ap(const char *ssid, uint8_t security, const char *key, uint16_t channel) { + uint8_t status = NINA_STATUS_AP_FAILED; + + if ((key == NULL && security != NINA_SEC_OPEN) || + (security != NINA_SEC_OPEN && security != NINA_SEC_WEP)) { + return -1; + } + + switch (security) { + case NINA_SEC_OPEN: + if (nina_send_command_read_ack(NINA_CMD_START_AP_OPEN, + 2, ARG_8BITS, NINA_ARGS(ARG_STR(ssid), ARG_BYTE(channel))) != SPI_ACK) { + return -1; + } + break; + case NINA_SEC_WEP: + if (nina_send_command_read_ack(NINA_CMD_START_AP_WEP, + 3, ARG_8BITS, NINA_ARGS(ARG_STR(ssid), ARG_STR(key), ARG_BYTE(channel))) != SPI_ACK) { + return -1; + } + break; + default: + return -1; + } + + for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(10)) { + status = nina_connection_status(); + if ((status != NINA_STATUS_IDLE) && (status != NINA_STATUS_NO_SSID_AVAIL) && (status != NINA_STATUS_SCAN_COMPLETED)) { + break; + } + + if ((mp_hal_ticks_ms() - start) >= NINA_CONNECT_TIMEOUT) { + break; + } + } + + return (status == NINA_STATUS_AP_LISTENING) ? 0 : -1; +} + +int nina_disconnect(void) { + if (nina_send_command_read_ack(NINA_CMD_DISCONNECT, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF))) != SPI_ACK) { + return -1; + } + return 0; +} + +int nina_isconnected(void) { + int status = nina_connection_status(); + if (status == -1) { + return -1; + } + return status == NINA_STATUS_CONNECTED; +} + +int nina_connected_sta(uint32_t *sta_ip) { + return -1; +} + +int nina_wait_for_sta(uint32_t *sta_ip, uint32_t timeout) { + return NINA_ERROR_TIMEOUT; +} + +int nina_ifconfig(nina_ifconfig_t *ifconfig, bool set) { + uint16_t ip_len = NINA_IPV4_ADDR_LEN; + uint16_t sub_len = NINA_IPV4_ADDR_LEN; + uint16_t gw_len = NINA_IPV4_ADDR_LEN; + uint16_t dns_len = NINA_IPV4_ADDR_LEN; + + if (set) { + if (nina_send_command_read_ack(NINA_CMD_SET_IF_CONFIG, + 4, ARG_8BITS, + NINA_ARGS( + ARG_BYTE(3), // Valid number of args. + {ip_len, ifconfig->ip_addr}, + {gw_len, ifconfig->gateway_addr}, + {sub_len, ifconfig->subnet_addr})) != SPI_ACK) { + return -1; + } + + if (nina_send_command_read_ack(NINA_CMD_SET_DNS_CONFIG, + 3, ARG_8BITS, + NINA_ARGS( + ARG_BYTE(1), // Valid number of args. + {dns_len, ifconfig->dns_addr}, + {dns_len, ifconfig->dns_addr})) != SPI_ACK) { + return -1; + } + + } else { + if (nina_send_command_read_vals(NINA_CMD_GET_IF_CONFIG, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF)), + 3, ARG_8BITS, + NINA_VALS( + {&ip_len, ifconfig->ip_addr}, + {&sub_len, ifconfig->subnet_addr}, + {&gw_len, ifconfig->gateway_addr})) != 0) { + return -1; + } + // No command to get DNS ? + memcpy(ifconfig->dns_addr, ifconfig->gateway_addr, NINA_IPV4_ADDR_LEN); + } + return 0; +} + +int nina_netinfo(nina_netinfo_t *netinfo) { + uint16_t rssi_len = 4; + uint16_t sec_len = 1; + uint16_t ssid_len = NINA_MAX_SSID_LEN; + uint16_t bssid_len = NINA_MAC_ADDR_LEN; + + if (nina_send_command_read_vals(NINA_CMD_GET_RSSI, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF)), + 1, ARG_8BITS, NINA_VALS({&rssi_len, &netinfo->rssi})) != 0) { + return -1; + } + + if (nina_send_command_read_vals(NINA_CMD_GET_ENCRYPT, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF)), + 1, ARG_8BITS, NINA_VALS({&sec_len, &netinfo->security})) != 0) { + return -1; + } + + if (nina_send_command_read_vals(NINA_CMD_GET_SSID, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF)), + 1, ARG_8BITS, NINA_VALS({&ssid_len, &netinfo->ssid})) != 0) { + return -1; + } + + if (nina_send_command_read_vals(NINA_CMD_GET_BSSID, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF)), + 1, ARG_8BITS, NINA_VALS({&bssid_len, &netinfo->bssid})) != 0) { + return -1; + } + + return 0; +} + +int nina_scan(nina_scan_callback_t scan_callback, void *arg, uint32_t timeout) { + uint16_t sizes[NINA_MAX_NETWORK_LIST]; + char ssids[NINA_MAX_NETWORK_LIST][NINA_MAX_SSID_LEN]; + nina_vals_t vals[NINA_MAX_NETWORK_LIST]; + + // Initialize the values list. + for (int i = 0; i < NINA_MAX_NETWORK_LIST; i++) { + sizes[i] = NINA_MAX_SSID_LEN - 1; + memset(ssids[i], 0, NINA_MAX_SSID_LEN); + vals[i].size = &sizes[i]; + vals[i].data = ssids[i]; + } + + if (nina_send_command_read_ack(NINA_CMD_AP_START_SCAN, + 0, ARG_8BITS, NULL) != SPI_ACK) { + return -1; + } + + for (mp_uint_t start = mp_hal_ticks_ms(); ;) { + if (nina_send_command_read_vals(NINA_CMD_AP_SCAN_RESULT, + 0, ARG_8BITS, NULL, + NINA_MAX_NETWORK_LIST, ARG_8BITS, vals) != 0) { + return -1; + } + + if (ssids[0][0] != 0) { + // Found at least 1 network. + break; + } + + if (timeout && (mp_hal_ticks_ms() - start) >= timeout) { + // Timeout, no networks. + return NINA_ERROR_TIMEOUT; + } + + mp_hal_delay_ms(100); + } + + for (int i = 0; i < NINA_MAX_NETWORK_LIST; i++) { + uint16_t rssi_len = 4; + uint16_t sec_len = 1; + uint16_t chan_len = 1; + uint16_t bssid_len = NINA_MAC_ADDR_LEN; + nina_scan_result_t scan_result; + + if (ssids[i][0] == 0) { + break; + } + + // Set AP SSID + strncpy(scan_result.ssid, ssids[i], NINA_MAX_SSID_LEN); + + // Read AP RSSI + if (nina_send_command_read_vals(NINA_CMD_AP_GET_RSSI, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(i)), + 1, ARG_8BITS, NINA_VALS({&rssi_len, &scan_result.rssi})) != 0) { + return -1; + } + + // Read AP encryption type + if (nina_send_command_read_vals(NINA_CMD_AP_GET_ENCRYPT, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(i)), + 1, ARG_8BITS, NINA_VALS({&sec_len, &scan_result.security})) != 0) { + return -1; + } + + // Read AP channel + if (nina_send_command_read_vals(NINA_CMD_AP_GET_CHANNEL, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(i)), + 1, ARG_8BITS, NINA_VALS({&chan_len, &scan_result.channel})) != 0) { + return -1; + } + + // Read AP bssid + if (nina_send_command_read_vals(NINA_CMD_AP_GET_BSSID, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(i)), + 1, ARG_8BITS, NINA_VALS({&bssid_len, scan_result.bssid})) != 0) { + return -1; + } + + scan_callback(&scan_result, arg); + } + + return 0; +} + +int nina_get_rssi(void) { + uint16_t size = 4; + int32_t rssi = 0; + if (nina_send_command_read_vals(NINA_CMD_GET_RSSI, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF)), + 1, ARG_8BITS, NINA_VALS({&size, &rssi})) != 0) { + return -1; + } + + return rssi; +} + +int nina_fw_version(uint8_t *fw_ver) { + uint16_t size = NINA_FW_VER_LEN; + if (nina_send_command_read_vals(NINA_CMD_GET_FW_VERSION, + 0, ARG_8BITS, NULL, + 1, ARG_8BITS, NINA_VALS({&size, fw_ver})) != 0) { + return -1; + } + return 0; +} + +int nina_set_hostname(const char *hostname) { + if (nina_send_command_read_ack(NINA_CMD_SET_HOSTNAME, + 1, ARG_8BITS, NINA_ARGS(ARG_STR(hostname))) != SPI_ACK) { + return -1; + } + return 0; +} + +int nina_gethostbyname(const char *name, uint8_t *out_ip) { + uint16_t size = 4; + + if (nina_send_command_read_ack(NINA_CMD_HOST_BY_NAME, + 1, ARG_8BITS, NINA_ARGS(ARG_STR(name))) != SPI_ACK) { + return -1; + } + + if (nina_send_command_read_vals(NINA_CMD_GET_HOST_BY_NAME, + 0, ARG_8BITS, NULL, + 1, ARG_8BITS, NINA_VALS({&size, out_ip})) != 0) { + return -1; + } + return 0; +} + +int nina_socket_socket(uint8_t type) { + uint16_t size = 1; + uint8_t sock = 0; + + if (nina_send_command_read_vals(NINA_CMD_SOCKET_OPEN, + 0, ARG_8BITS, NULL, + 1, ARG_8BITS, NINA_VALS({&size, &sock})) != 0) { + return -1; + } + return sock; +} + +int nina_socket_close(int fd) { + if (fd > 0 && fd < 255) { + if (nina_send_command_read_ack(NINA_CMD_SOCKET_CLOSE, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd))) != SPI_ACK) { + return -1; + } + for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(10)) { + if (nina_socket_status(fd) == SOCKET_STATE_CLOSED) { + break; + } + if ((mp_hal_ticks_ms() - start) >= 5000) { + return NINA_ERROR_TIMEOUT; + } + } + } + return 0; +} + +int nina_socket_bind(int fd, uint8_t *ip, uint16_t port, int type) { + if (nina_send_command_read_ack(NINA_CMD_SOCKET_BIND, + 3, ARG_8BITS, + NINA_ARGS( + ARG_SHORT(__REVSH(port)), + ARG_BYTE(fd), + ARG_BYTE(type))) != SPI_ACK) { + return -1; + } + + // Only TCP sockets' states should be checked. + if (type == NINA_SOCKET_TYPE_TCP && + nina_server_socket_status(fd) != SOCKET_STATE_LISTEN) { + return -1; + } + return 0; +} + +int nina_socket_listen(int fd, uint32_t backlog) { + return 0; // No listen ? +} + +int nina_socket_accept(int fd, uint8_t *ip, uint16_t *port, int *fd_out, uint32_t timeout) { + uint16_t size = 2; + uint16_t sock = NO_SOCKET_AVAIL; + + if (nina_server_socket_status(fd) != SOCKET_STATE_LISTEN) { + return -1; + } + + for (mp_uint_t start = mp_hal_ticks_ms(); sock == 0 || sock == NO_SOCKET_AVAIL; mp_hal_delay_ms(10)) { + if (nina_send_command_read_vals(NINA_CMD_SOCKET_ACCEPT, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd)), + 1, ARG_8BITS, NINA_VALS({&size, &sock})) != 0) { + return -1; + } + + if (timeout && (mp_hal_ticks_ms() - start) >= timeout) { + return NINA_ERROR_TIMEOUT; + } + } + + uint16_t port_len = 2; + uint16_t ip_len = NINA_IPV4_ADDR_LEN; + if (nina_send_command_read_vals(NINA_CMD_SOCKET_REMOTE_ADDR, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(sock)), + 2, ARG_8BITS, NINA_VALS({&ip_len, ip}, {&port_len, port})) != 0) { + return -1; + } + *fd_out = sock; + *port = __REVSH(*port); + return 0; +} + +int nina_socket_connect(int fd, uint8_t *ip, uint16_t port, uint32_t timeout) { + if (nina_send_command_read_ack(NINA_CMD_SOCKET_CONNECT, + 4, ARG_8BITS, + NINA_ARGS( + ARG_WORD((*(uint32_t *)ip)), + ARG_SHORT(__REVSH(port)), + ARG_BYTE(fd), + ARG_BYTE(NINA_SOCKET_TYPE_TCP))) != SPI_ACK) { + return -1; + } + + for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(10)) { + int state = nina_socket_status(fd); + if (state == -1) { + return -1; + } + + if (state == SOCKET_STATE_ESTABLISHED) { + break; + } + + if (timeout && (mp_hal_ticks_ms() - start) >= timeout) { + return NINA_ERROR_TIMEOUT; + } + } + + return 0; +} + +int nina_socket_send(int fd, const uint8_t *buf, uint32_t len, uint32_t timeout) { + uint16_t size = 2; + uint16_t bytes = 0; + + if (nina_socket_status(fd) != SOCKET_STATE_ESTABLISHED) { + return -1; + } + + if (nina_send_command_read_vals(NINA_CMD_TCP_SEND, + 2, ARG_16BITS, NINA_ARGS(ARG_BYTE(fd), {len, buf}), + 1, ARG_8BITS, NINA_VALS({&size, &bytes})) != 0 || bytes <= 0) { + return -1; + } + + for (mp_uint_t start = mp_hal_ticks_ms(); ;) { + int resp = nina_send_command_read_ack(NINA_CMD_TCP_ACK, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd))); + + if (resp == -1) { + return -1; + } + + if (resp == SPI_ACK) { + break; + } + + if (timeout && (mp_hal_ticks_ms() - start) >= timeout) { + return NINA_ERROR_TIMEOUT; + } + mp_hal_delay_ms(1); + } + + return bytes; +} + +int nina_socket_recv(int fd, uint8_t *buf, uint32_t len, uint32_t timeout) { + uint16_t bytes = 0; + + if (nina_socket_status(fd) != SOCKET_STATE_ESTABLISHED) { + return -1; + } + + for (mp_uint_t start = mp_hal_ticks_ms(); bytes == 0; mp_hal_delay_ms(1)) { + bytes = len; + if (nina_send_command_read_vals(NINA_CMD_TCP_RECV, + 2, ARG_16BITS, NINA_ARGS(ARG_BYTE(fd), ARG_SHORT(bytes)), + 1, ARG_16BITS, NINA_VALS({&bytes, buf})) != 0) { + return -1; + } + + if (timeout && (mp_hal_ticks_ms() - start) >= timeout) { + return NINA_ERROR_TIMEOUT; + } + } + return bytes; +} + +// Check from the upper layer if the socket is bound, if not then auto-bind it first. +int nina_socket_sendto(int fd, const uint8_t *buf, uint32_t len, uint8_t *ip, uint16_t port, uint32_t timeout) { + // TODO do we need to split the packet somewhere? + if (nina_send_command_read_ack(NINA_CMD_SOCKET_CONNECT, + 4, ARG_8BITS, + NINA_ARGS( + ARG_WORD((*(uint32_t *)ip)), + ARG_SHORT(__REVSH(port)), + ARG_BYTE(fd), + ARG_BYTE(NINA_SOCKET_TYPE_UDP))) != SPI_ACK) { + return -1; + } + + // Buffer length and socket number are passed as 16bits. + if (nina_send_command_read_ack(NINA_CMD_UDP_SEND, + 2, ARG_16BITS, NINA_ARGS(ARG_BYTE(fd), {len, buf})) != SPI_ACK) { + return -1; + } + + if (nina_send_command_read_ack(NINA_CMD_UDP_ACK, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd))) != SPI_ACK) { + return -1; + } + + return 0; +} + +// Check from the upper layer if the socket is bound, if not then auto-bind it first. +int nina_socket_recvfrom(int fd, uint8_t *buf, uint32_t len, uint8_t *ip, uint16_t *port, uint32_t timeout) { + uint16_t bytes = 0; + uint16_t port_len = 2; + uint16_t ip_len = NINA_IPV4_ADDR_LEN; + + for (mp_uint_t start = mp_hal_ticks_ms(); bytes == 0; mp_hal_delay_ms(1)) { + bytes = len; + if (nina_send_command_read_vals(NINA_CMD_UDP_RECV, + 2, ARG_16BITS, NINA_ARGS(ARG_BYTE(fd), ARG_SHORT(bytes)), + 1, ARG_16BITS, NINA_VALS({&bytes, buf})) != 0) { + return -1; + } + + if (timeout && (mp_hal_ticks_ms() - start) >= timeout) { + return NINA_ERROR_TIMEOUT; + } + } + if (nina_send_command_read_vals(NINA_CMD_SOCKET_REMOTE_ADDR, + 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd)), + 2, ARG_8BITS, NINA_VALS({&ip_len, ip}, {&port_len, port})) != 0) { + return -1; + } + + return bytes; +} + +int nina_socket_setsockopt(int fd, uint32_t level, uint32_t opt, const void *optval, uint32_t optlen) { + return -1; +} + +#endif // MICROPY_PY_NINAW10 diff --git a/drivers/ninaw10/nina_wifi_drv.h b/drivers/ninaw10/nina_wifi_drv.h new file mode 100644 index 0000000000..d8c55f5e67 --- /dev/null +++ b/drivers/ninaw10/nina_wifi_drv.h @@ -0,0 +1,120 @@ +/* + * This file is part of the OpenMV project, https://openmv.io. + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2021 Ibrahim Abdelkader + * Copyright (c) 2013-2021 Kwabena W. Agyeman + * + * 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. + * + * NINA-W10 WiFi driver. + */ +#ifndef MICROPY_INCLUDED_DRIVERS_NINAW10_NINA_WIFI_DRV_H +#define MICROPY_INCLUDED_DRIVERS_NINAW10_NINA_WIFI_DRV_H + +#define NINA_FW_VER_LEN (6) +#define NINA_IPV4_ADDR_LEN (4) +#define NINA_MAC_ADDR_LEN (6) +#define NINA_MAX_SSID_LEN (32) +#define NINA_MAX_WEP_LEN (13) +#define NINA_MAX_WPA_LEN (63) +#define NINA_MAX_NETWORK_LIST (10) +#define NINA_MAX_SOCKET (10) + +#define NINA_FW_VER_MAJOR (1) +#define NINA_FW_VER_MINOR (4) +#define NINA_FW_VER_PATCH (8) + +#define NINA_FW_VER_MAJOR_OFFS (0) +#define NINA_FW_VER_MINOR_OFFS (2) +#define NINA_FW_VER_PATCH_OFFS (4) + +typedef enum { + NINA_SEC_INVALID = 0, + NINA_SEC_OPEN, + NINA_SEC_WPA_PSK, + NINA_SEC_WEP +} nina_security_t; + +typedef enum { + NINA_SOCKET_TYPE_TCP = 0, + NINA_SOCKET_TYPE_UDP, + NINA_SOCKET_TYPE_TLS, + NINA_SOCKET_TYPE_UDP_MULTICAST, + NINA_SOCKET_TYPE_TLS_BEARSSL +} nina_socket_type_t; + +typedef enum { + NINA_ERROR_IO = -1, + NINA_ERROR_TIMEOUT = -2, +} nina_error_t; + +typedef struct { + uint8_t ip_addr[NINA_IPV4_ADDR_LEN]; + uint8_t subnet_addr[NINA_IPV4_ADDR_LEN]; + uint8_t gateway_addr[NINA_IPV4_ADDR_LEN]; + uint8_t dns_addr[NINA_IPV4_ADDR_LEN]; +} nina_ifconfig_t; + +typedef struct { + int32_t rssi; + uint8_t security; + uint8_t channel; + uint8_t bssid[NINA_MAC_ADDR_LEN]; + char ssid[NINA_MAX_SSID_LEN]; +} nina_scan_result_t; + +typedef struct { + int32_t rssi; + uint8_t security; + char ssid[NINA_MAX_SSID_LEN]; + uint8_t bssid[NINA_MAC_ADDR_LEN]; +} nina_netinfo_t; + +typedef int (*nina_scan_callback_t)(nina_scan_result_t *, void *); + +int nina_init(void); +int nina_deinit(void); +int nina_connect(const char *ssid, uint8_t security, const char *key, uint16_t channel); +int nina_start_ap(const char *ssid, uint8_t security, const char *key, uint16_t channel); +int nina_disconnect(void); +int nina_isconnected(void); +int nina_connected_sta(uint32_t *sta_ip); +int nina_wait_for_sta(uint32_t *sta_ip, uint32_t timeout); +int nina_ifconfig(nina_ifconfig_t *ifconfig, bool set); +int nina_netinfo(nina_netinfo_t *netinfo); +int nina_scan(nina_scan_callback_t scan_callback, void *arg, uint32_t timeout); +int nina_get_rssi(void); +int nina_fw_version(uint8_t *fw_ver); +int nina_set_hostname(const char *name); +int nina_gethostbyname(const char *name, uint8_t *out_ip); +int nina_socket_socket(uint8_t type); +int nina_socket_close(int fd); +int nina_socket_bind(int fd, uint8_t *ip, uint16_t port, int type); +int nina_socket_listen(int fd, uint32_t backlog); +int nina_socket_accept(int fd, uint8_t *ip, uint16_t *port, int *fd_out, uint32_t timeout); +int nina_socket_connect(int fd, uint8_t *ip, uint16_t port, uint32_t timeout); +int nina_socket_send(int fd, const uint8_t *buf, uint32_t len, uint32_t timeout); +int nina_socket_recv(int fd, uint8_t *buf, uint32_t len, uint32_t timeout); +int nina_socket_sendto(int fd, const uint8_t *buf, uint32_t len, uint8_t *ip, uint16_t port, uint32_t timeout); +int nina_socket_recvfrom(int fd, uint8_t *buf, uint32_t len, uint8_t *ip, uint16_t *port, uint32_t timeout); +int nina_socket_setsockopt(int fd, uint32_t level, uint32_t opt, const void *optval, uint32_t optlen); + +#endif // MICROPY_INCLUDED_DRIVERS_NINAW10_NINA_WIFI_DRV_H diff --git a/extmod/network_ninaw10.c b/extmod/network_ninaw10.c new file mode 100644 index 0000000000..aa4b8dd0c0 --- /dev/null +++ b/extmod/network_ninaw10.c @@ -0,0 +1,588 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2021 Ibrahim Abdelkader + * + * 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. + * + * NINA-W10 Python module. + */ + +#include "py/mphal.h" + +#if MICROPY_PY_NETWORK && MICROPY_PY_NETWORK_NINAW10 + +#include +#include +#include +#include + +#include "py/objtuple.h" +#include "py/objlist.h" +#include "py/stream.h" +#include "py/runtime.h" +#include "py/misc.h" +#include "py/mperrno.h" +#include "shared/netutils/netutils.h" +#include "extmod/modnetwork.h" + +#include "nina_wifi_drv.h" + +typedef struct _nina_obj_t { + mp_obj_base_t base; + bool active; + uint32_t itf; +} nina_obj_t; + +// For auto-binding UDP sockets +#define BIND_PORT_RANGE_MIN (65000) +#define BIND_PORT_RANGE_MAX (65535) + +static uint16_t bind_port = BIND_PORT_RANGE_MIN; +const mod_network_nic_type_t mod_network_nic_type_nina; +static nina_obj_t nina_obj = {{(mp_obj_type_t *)&mod_network_nic_type_nina}, false, MOD_NETWORK_STA_IF}; + +STATIC mp_obj_t network_ninaw10_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 0, 1, false); + + nina_obj.active = false; + if (n_args == 0) { + nina_obj.itf = MOD_NETWORK_STA_IF; + } else { + nina_obj.itf = mp_obj_get_int(args[0]); + } + + // Reset autobind port. + bind_port = BIND_PORT_RANGE_MIN; + + // Register with network module + mod_network_register_nic(MP_OBJ_FROM_PTR(&nina_obj)); + + return MP_OBJ_FROM_PTR(&nina_obj); +} + +STATIC mp_obj_t network_ninaw10_active(size_t n_args, const mp_obj_t *args) { + nina_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (n_args == 2) { + bool active = mp_obj_is_true(args[1]); + if (active) { + int error = 0; + if ((error = nina_init()) != 0) { + mp_raise_msg_varg(&mp_type_OSError, + MP_ERROR_TEXT("Failed to initialize Nina-W10 module, error: %d\n"), error); + } + // check firmware version + uint8_t fw_ver[NINA_FW_VER_LEN]; + if (nina_fw_version(fw_ver) != 0) { + nina_deinit(); + mp_raise_msg_varg(&mp_type_OSError, + MP_ERROR_TEXT("Failed to read firmware version, error: %d\n"), error); + } + // Check fw version matches the driver. + if ((fw_ver[NINA_FW_VER_MAJOR_OFFS] - 48) != NINA_FW_VER_MAJOR || + (fw_ver[NINA_FW_VER_MINOR_OFFS] - 48) != NINA_FW_VER_MINOR || + (fw_ver[NINA_FW_VER_PATCH_OFFS] - 48) != NINA_FW_VER_PATCH) { + mp_printf(&mp_plat_print, + "Warning: firmware version mismatch, expected %d.%d.%d found: %d.%d.%d\n", + NINA_FW_VER_MAJOR, NINA_FW_VER_MINOR, NINA_FW_VER_PATCH, + fw_ver[NINA_FW_VER_MAJOR_OFFS] - 48, + fw_ver[NINA_FW_VER_MINOR_OFFS] - 48, + fw_ver[NINA_FW_VER_PATCH_OFFS] - 48); + } + } else { + nina_deinit(); + } + self->active = active; + return mp_const_none; + } + return mp_obj_new_bool(self->active); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ninaw10_active_obj, 1, 2, network_ninaw10_active); + +STATIC int nina_scan_callback(nina_scan_result_t *scan_result, void *arg) { + mp_obj_t scan_list = (mp_obj_t)arg; + + // Format MAC address + VSTR_FIXED(bssid_vstr, 18); + vstr_printf(&bssid_vstr, "%02X:%02X:%02X:%02X:%02X:%02X", + scan_result->bssid[0], scan_result->bssid[1], scan_result->bssid[2], + scan_result->bssid[3], scan_result->bssid[4], scan_result->bssid[5]); + + mp_obj_t ap[5] = { + mp_obj_new_int(scan_result->channel), + mp_obj_new_int(scan_result->rssi), + mp_obj_new_int(scan_result->security), + mp_obj_new_str(bssid_vstr.buf, bssid_vstr.len), + mp_obj_new_str(scan_result->ssid, strlen(scan_result->ssid)), + }; + + mp_obj_list_append(scan_list, mp_obj_new_tuple(MP_ARRAY_SIZE(ap), ap)); + + return 0; +} + +STATIC mp_obj_t network_ninaw10_scan(mp_obj_t self_in) { + mp_obj_t scan_list; + scan_list = mp_obj_new_list(0, NULL); + nina_scan(nina_scan_callback, scan_list, 10000); + return scan_list; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_ninaw10_scan_obj, network_ninaw10_scan); + +STATIC mp_obj_t network_ninaw10_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + static const mp_arg_t allowed_args[] = { + { MP_QSTR_essid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_key, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NINA_SEC_WPA_PSK} }, + { MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + }; + + // parse args + nina_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // get ssid + const char *ssid = mp_obj_str_get_str(args[0].u_obj); + + if (strlen(ssid) == 0) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("SSID can't be empty!")); + } + + // get key and sec + const char *key = NULL; + mp_uint_t security = NINA_SEC_OPEN; + + if (args[1].u_obj != mp_const_none) { + key = mp_obj_str_get_str(args[1].u_obj); + security = args[2].u_int; + } + + if (security != NINA_SEC_OPEN && strlen(key) == 0) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Key can't be empty!")); + } + + if (self->itf == MOD_NETWORK_STA_IF) { + // Initialize WiFi in Station mode. + if (nina_connect(ssid, security, key, 0) != 0) { + mp_raise_msg_varg(&mp_type_OSError, + MP_ERROR_TEXT("could not connect to ssid=%s, sec=%d, key=%s\n"), ssid, security, key); + } + } else { + mp_uint_t channel = args[3].u_int; + + if (security != NINA_SEC_OPEN && security != NINA_SEC_WEP) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("AP mode supports WEP security only.")); + } + + // Initialize WiFi in AP mode. + if (nina_start_ap(ssid, security, key, channel) != 0) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("failed to start in AP mode")); + } + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(network_ninaw10_connect_obj, 1, network_ninaw10_connect); + +STATIC mp_obj_t network_ninaw10_disconnect(mp_obj_t self_in) { + nina_disconnect(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_ninaw10_disconnect_obj, network_ninaw10_disconnect); + +STATIC mp_obj_t network_ninaw10_isconnected(mp_obj_t self_in) { + return mp_obj_new_bool(nina_isconnected()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_ninaw10_isconnected_obj, network_ninaw10_isconnected); + +STATIC mp_obj_t network_ninaw10_ifconfig(size_t n_args, const mp_obj_t *args) { + nina_ifconfig_t ifconfig; + if (n_args == 1) { + // get ifconfig info + nina_ifconfig(&ifconfig, false); + mp_obj_t tuple[4] = { + netutils_format_ipv4_addr(ifconfig.ip_addr, NETUTILS_BIG), + netutils_format_ipv4_addr(ifconfig.subnet_addr, NETUTILS_BIG), + netutils_format_ipv4_addr(ifconfig.gateway_addr, NETUTILS_BIG), + netutils_format_ipv4_addr(ifconfig.dns_addr, NETUTILS_BIG), + }; + return mp_obj_new_tuple(4, tuple); + } else { + // set ifconfig info + mp_obj_t *items; + mp_obj_get_array_fixed_n(args[1], 4, &items); + netutils_parse_ipv4_addr(items[0], ifconfig.ip_addr, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[1], ifconfig.subnet_addr, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[2], ifconfig.gateway_addr, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[3], ifconfig.dns_addr, NETUTILS_BIG); + nina_ifconfig(&ifconfig, true); + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ninaw10_ifconfig_obj, 1, 2, network_ninaw10_ifconfig); + +STATIC mp_obj_t network_ninaw10_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + nina_obj_t *self = MP_OBJ_TO_PTR(args[0]); + (void)self; + + if (kwargs->used == 0) { + // Get config value + if (n_args != 2) { + mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); + } + + switch (mp_obj_str_get_qstr(args[1])) { + case MP_QSTR_essid: { + nina_netinfo_t netinfo; + nina_netinfo(&netinfo); + return mp_obj_new_str(netinfo.ssid, strlen(netinfo.ssid)); + } + case MP_QSTR_security: { + nina_netinfo_t netinfo; + nina_netinfo(&netinfo); + return mp_obj_new_int(netinfo.security); + } + case MP_QSTR_mac: + case MP_QSTR_bssid: { + nina_netinfo_t netinfo; + nina_netinfo(&netinfo); + return mp_obj_new_bytes(netinfo.bssid, 6); + } + case MP_QSTR_fw_version: { + uint8_t fwver[NINA_FW_VER_LEN]; + nina_fw_version(fwver); + return mp_obj_new_tuple(3, (mp_obj_t []) { + mp_obj_new_int(fwver[NINA_FW_VER_MAJOR_OFFS] - 48), + mp_obj_new_int(fwver[NINA_FW_VER_MINOR_OFFS] - 48), + mp_obj_new_int(fwver[NINA_FW_VER_PATCH_OFFS] - 48) + }); + } + default: + mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); + } + } else { + // Set config value(s) + // Not supported. + mp_raise_ValueError(MP_ERROR_TEXT("setting config values is not supported")); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(network_ninaw10_config_obj, 1, network_ninaw10_config); + +STATIC mp_obj_t network_ninaw10_status(size_t n_args, const mp_obj_t *args) { + nina_obj_t *self = MP_OBJ_TO_PTR(args[0]); + (void)self; + + if (n_args == 1) { + // no arguments: return link status + return mp_obj_new_bool(nina_isconnected()); + } + + // Query parameter. + switch (mp_obj_str_get_qstr(args[1])) { + case MP_QSTR_rssi: { + nina_netinfo_t netinfo; + nina_netinfo(&netinfo); + return mp_obj_new_int(netinfo.rssi); + } + case MP_QSTR_stations: { + if (self->itf != MOD_NETWORK_AP_IF) { + mp_raise_ValueError(MP_ERROR_TEXT("AP required")); + } + uint32_t sta_ip = 0; + mp_obj_t sta_list = mp_obj_new_list(0, NULL); + if (nina_connected_sta(&sta_ip) == 0) { + mp_obj_list_append(sta_list, + netutils_format_inet_addr((uint8_t *)&sta_ip, 0, NETUTILS_BIG)); + } + return sta_list; + } + } + + mp_raise_ValueError(MP_ERROR_TEXT("unknown status param")); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ninaw10_status_obj, 1, 2, network_ninaw10_status); + +STATIC int network_ninaw10_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { + return nina_gethostbyname(name, out_ip); +} + +STATIC int network_ninaw10_socket_socket(mod_network_socket_obj_t *socket, int *_errno) { + uint8_t type; + + if (socket->domain != MOD_NETWORK_AF_INET) { + *_errno = MP_EAFNOSUPPORT; + return -1; + } + + switch (socket->type) { + case MOD_NETWORK_SOCK_STREAM: + type = NINA_SOCKET_TYPE_TCP; + break; + + case MOD_NETWORK_SOCK_DGRAM: + type = NINA_SOCKET_TYPE_UDP; + break; + + default: + *_errno = MP_EINVAL; + return -1; + } + + // open socket + int fd = nina_socket_socket(type); + if (fd < 0) { + *_errno = fd; + return -1; + } + + // store state of this socket + socket->fileno = fd; + socket->timeout = 0; // blocking + socket->bound = false; + return 0; +} + +STATIC void network_ninaw10_socket_close(mod_network_socket_obj_t *socket) { + if (socket->fileno >= 0) { + nina_socket_close(socket->fileno); + socket->fileno = -1; // Mark socket FD as invalid + } +} + +STATIC int network_ninaw10_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { + uint8_t type; + switch (socket->type) { + case MOD_NETWORK_SOCK_STREAM: + type = NINA_SOCKET_TYPE_TCP; + break; + + case MOD_NETWORK_SOCK_DGRAM: + type = NINA_SOCKET_TYPE_UDP; + break; + + default: + *_errno = MP_EINVAL; + return -1; + } + + int ret = nina_socket_bind(socket->fileno, ip, port, type); + if (ret < 0) { + *_errno = ret; + network_ninaw10_socket_close(socket); + return -1; + } + + // Mark socket as bound to avoid auto-binding. + socket->bound = true; + return 0; +} + +STATIC int network_ninaw10_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) { + int ret = nina_socket_listen(socket->fileno, backlog); + if (ret < 0) { + *_errno = ret; + network_ninaw10_socket_close(socket); + return -1; + } + return 0; +} + +STATIC int network_ninaw10_socket_accept(mod_network_socket_obj_t *socket, + mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno) { + int fd = 0; + // Call accept. + int ret = nina_socket_accept(socket->fileno, ip, (uint16_t *)port, &fd, socket->timeout); + if (ret < 0) { + *_errno = ret; + network_ninaw10_socket_close(socket); + return -1; + } + + // Set default socket timeout. + socket2->fileno = fd; + socket2->timeout = 0; + socket2->bound = false; + return 0; +} + +STATIC int network_ninaw10_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { + int ret = nina_socket_connect(socket->fileno, ip, port, socket->timeout); + if (ret < 0) { + *_errno = ret; + network_ninaw10_socket_close(socket); + return -1; + } + return 0; +} + +STATIC mp_uint_t network_ninaw10_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) { + int ret = nina_socket_send(socket->fileno, buf, len, socket->timeout); + if (ret == NINA_ERROR_TIMEOUT) { + // The socket is Not closed on timeout when calling functions that accept a timeout. + *_errno = MP_ETIMEDOUT; + return 0; + } else if (ret < 0) { + // Close the socket on any other errors. + *_errno = ret; + network_ninaw10_socket_close(socket); + return -1; + } + return ret; +} + +STATIC mp_uint_t network_ninaw10_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) { + int ret = nina_socket_recv(socket->fileno, buf, len, socket->timeout); + if (ret == NINA_ERROR_TIMEOUT) { + // The socket is Not closed on timeout when calling functions that accept a timeout. + *_errno = MP_ETIMEDOUT; + return 0; + } else if (ret < 0) { + // Close the socket on any other errors. + *_errno = ret; + network_ninaw10_socket_close(socket); + return -1; + } + return ret; +} + +STATIC mp_uint_t network_ninaw10_socket_auto_bind(mod_network_socket_obj_t *socket, int *_errno) { + if (socket->bound == false) { + if (network_ninaw10_socket_bind(socket, NULL, bind_port, _errno) != 0) { + return -1; + } + bind_port++; + bind_port = MIN(MAX(bind_port, BIND_PORT_RANGE_MIN), BIND_PORT_RANGE_MAX); + } + return 0; +} + +STATIC mp_uint_t network_ninaw10_socket_sendto(mod_network_socket_obj_t *socket, + const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) { + // Auto-bind the socket first if the socket is unbound. + if (network_ninaw10_socket_auto_bind(socket, _errno) != 0) { + return -1; + } + + int ret = nina_socket_sendto(socket->fileno, buf, len, ip, port, socket->timeout); + if (ret == NINA_ERROR_TIMEOUT) { + // The socket is Not closed on timeout when calling functions that accept a timeout. + *_errno = MP_ETIMEDOUT; + return 0; + } else if (ret < 0) { + *_errno = ret; + network_ninaw10_socket_close(socket); + return -1; + } + return ret; +} + +STATIC mp_uint_t network_ninaw10_socket_recvfrom(mod_network_socket_obj_t *socket, + byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) { + // Auto-bind the socket first if the socket is unbound. + if (network_ninaw10_socket_auto_bind(socket, _errno) != 0) { + return -1; + } + + int ret = nina_socket_recvfrom(socket->fileno, buf, len, ip, (uint16_t *)port, socket->timeout); + if (ret == NINA_ERROR_TIMEOUT) { + // The socket is Not closed on timeout when calling functions that accept a timeout. + *_errno = MP_ETIMEDOUT; + return 0; + } else if (ret < 0) { + // Close the socket on any other errors. + *_errno = ret; + network_ninaw10_socket_close(socket); + return -1; + } + return ret; +} + +STATIC int network_ninaw10_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t + level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) { + int ret = nina_socket_setsockopt(socket->fileno, level, opt, optval, optlen); + if (ret < 0) { + *_errno = ret; + network_ninaw10_socket_close(socket); + return -1; + } + return 0; +} + +STATIC int network_ninaw10_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno) { + if (timeout_ms == UINT32_MAX) { + // no timeout is given, set the socket to blocking mode. + timeout_ms = 0; + } + socket->timeout = timeout_ms; + return 0; +} + +STATIC int network_ninaw10_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) { + *_errno = MP_EIO; + return -1; +} + +static const mp_rom_map_elem_t nina_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&network_ninaw10_active_obj) }, + { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&network_ninaw10_scan_obj) }, + { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&network_ninaw10_connect_obj) }, + { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&network_ninaw10_disconnect_obj) }, + { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&network_ninaw10_isconnected_obj) }, + { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_ninaw10_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_ninaw10_config_obj) }, + { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_ninaw10_status_obj) }, + + // Network is not secured. + { MP_ROM_QSTR(MP_QSTR_OPEN), MP_ROM_INT(NINA_SEC_OPEN) }, + // Security type WEP (40 or 104). + { MP_ROM_QSTR(MP_QSTR_WEP), MP_ROM_INT(NINA_SEC_WEP) }, + // Network secured with WPA/WPA2 personal(PSK). + { MP_ROM_QSTR(MP_QSTR_WPA_PSK), MP_ROM_INT(NINA_SEC_WPA_PSK) }, +}; + +static MP_DEFINE_CONST_DICT(nina_locals_dict, nina_locals_dict_table); + +const mod_network_nic_type_t mod_network_nic_type_nina = { + .base = { + { &mp_type_type }, + .name = MP_QSTR_nina, + .make_new = network_ninaw10_make_new, + .locals_dict = (mp_obj_t)&nina_locals_dict, + }, + .gethostbyname = network_ninaw10_gethostbyname, + .socket = network_ninaw10_socket_socket, + .close = network_ninaw10_socket_close, + .bind = network_ninaw10_socket_bind, + .listen = network_ninaw10_socket_listen, + .accept = network_ninaw10_socket_accept, + .connect = network_ninaw10_socket_connect, + .send = network_ninaw10_socket_send, + .recv = network_ninaw10_socket_recv, + .sendto = network_ninaw10_socket_sendto, + .recvfrom = network_ninaw10_socket_recvfrom, + .setsockopt = network_ninaw10_socket_setsockopt, + .settimeout = network_ninaw10_socket_settimeout, + .ioctl = network_ninaw10_socket_ioctl, +}; + +#endif // #if MICROPY_PY_BLUETOOTH && MICROPY_PY_NETWORK_NINAW10 diff --git a/tools/codeformat.py b/tools/codeformat.py index ab12745fa5..04cce1d830 100755 --- a/tools/codeformat.py +++ b/tools/codeformat.py @@ -35,6 +35,7 @@ import subprocess # Relative to top-level repo dir. PATHS = [ # C + "drivers/ninaw10/*.[ch]", "extmod/*.[ch]", "extmod/btstack/*.[ch]", "extmod/nimble/*.[ch]", From 3745c393c82050a64445dbdf4c34836fa8664ce0 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 14 Sep 2021 22:22:17 +0200 Subject: [PATCH 144/335] rp2: Add support for Nina-W10 WiFi/BT module. This commit integrates the Nina-W10 driver as an optional component in the rp2 port. --- ports/rp2/CMakeLists.txt | 26 ++++++++++++++++++++++++++ ports/rp2/mpconfigport.h | 20 ++++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index e38cd8032d..0b433da53c 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -166,6 +166,7 @@ if(MICROPY_PY_BLUETOOTH) list(APPEND MICROPY_SOURCE_PORT mpbthciport.c) target_compile_definitions(${MICROPY_TARGET} PRIVATE MICROPY_PY_BLUETOOTH=1 + MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS=1 MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE=1 MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING=1 MICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS=1 @@ -188,6 +189,31 @@ if(MICROPY_BLUETOOTH_NIMBLE) list(APPEND MICROPY_INC_CORE ${NIMBLE_INCLUDE}) endif() +if (MICROPY_PY_NETWORK_NINAW10) + target_compile_definitions(${MICROPY_TARGET} PRIVATE + MICROPY_PY_NETWORK_NINAW10=1 + ) + + target_include_directories(${MICROPY_TARGET} PRIVATE + ${MICROPY_DIR}/drivers/ninaw10/ + ) + + # Enable NINA-W10 WiFi and Bluetooth drivers. + list(APPEND MICROPY_SOURCE_DRIVERS + ${MICROPY_DIR}/drivers/ninaw10/nina_bt_hci.c + ${MICROPY_DIR}/drivers/ninaw10/nina_wifi_drv.c + ${MICROPY_DIR}/drivers/ninaw10/nina_wifi_bsp.c + ) + + list(APPEND MICROPY_SOURCE_EXTMOD + ${MICROPY_DIR}/extmod/network_ninaw10.c + ) + + list(APPEND MICROPY_SOURCE_QSTR + ${MICROPY_DIR}/extmod/network_ninaw10.c + ) +endif() + # Define mpy-cross flags and frozen manifest set(MICROPY_CROSS_FLAGS -march=armv7m) if (NOT MICROPY_FROZEN_MANIFEST) diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index b40e18d2f8..2e8a33a7a7 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -154,6 +154,20 @@ struct _mp_bluetooth_nimble_malloc_t; #define MICROPY_PORT_ROOT_POINTER_BLUETOOTH_NIMBLE #endif +#if MICROPY_PY_NETWORK_NINAW10 +// This Network interface requires the extended socket state. +#ifndef MICROPY_PY_USOCKET_EXTENDED_STATE +#define MICROPY_PY_USOCKET_EXTENDED_STATE (1) +#endif +// It also requires an additional root pointer for the SPI object. +#define MICROPY_PORT_ROOT_POINTER_NINAW10 struct _machine_spi_obj_t *mp_wifi_spi; +extern const struct _mod_network_nic_type_t mod_network_nic_type_nina; +#define MICROPY_HW_NIC_NINAW10 { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mod_network_nic_type_nina) }, +#else +#define MICROPY_HW_NIC_NINAW10 +#define MICROPY_PORT_ROOT_POINTER_NINAW10 +#endif + #define MICROPY_PORT_BUILTIN_MODULES \ { MP_OBJ_NEW_QSTR(MP_QSTR_machine), (mp_obj_t)&mp_module_machine }, \ { MP_OBJ_NEW_QSTR(MP_QSTR__onewire), (mp_obj_t)&mp_module_onewire }, \ @@ -163,12 +177,13 @@ struct _mp_bluetooth_nimble_malloc_t; SOCKET_BUILTIN_MODULE \ NETWORK_BUILTIN_MODULE \ +#define MICROPY_PORT_NETWORK_INTERFACES \ + MICROPY_HW_NIC_NINAW10 \ + #ifndef MICROPY_BOARD_ROOT_POINTERS #define MICROPY_BOARD_ROOT_POINTERS #endif -#define MICROPY_PORT_NETWORK_INTERFACES \ - #define MICROPY_PORT_ROOT_POINTERS \ const char *readline_hist[8]; \ void *machine_pin_irq_obj[30]; \ @@ -179,6 +194,7 @@ struct _mp_bluetooth_nimble_malloc_t; void *machine_i2s_obj[2]; \ NETWORK_ROOT_POINTERS \ MICROPY_BOARD_ROOT_POINTERS \ + MICROPY_PORT_ROOT_POINTER_NINAW10 \ MICROPY_PORT_ROOT_POINTER_BLUETOOTH \ MICROPY_PORT_ROOT_POINTER_BLUETOOTH_NIMBLE \ From f082793ac44dac77517bab3361a80f062b500345 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Mon, 15 Nov 2021 16:16:19 +0200 Subject: [PATCH 145/335] drivers/lsm6dsox: Add LSM6DSOX driver and examples. --- drivers/lsm6dsox/lsm6dsox.py | 234 +++++++++++++++++++++++++++++ drivers/lsm6dsox/lsm6dsox_basic.py | 13 ++ drivers/lsm6dsox/lsm6dsox_mlc.py | 48 ++++++ 3 files changed, 295 insertions(+) create mode 100644 drivers/lsm6dsox/lsm6dsox.py create mode 100644 drivers/lsm6dsox/lsm6dsox_basic.py create mode 100644 drivers/lsm6dsox/lsm6dsox_mlc.py diff --git a/drivers/lsm6dsox/lsm6dsox.py b/drivers/lsm6dsox/lsm6dsox.py new file mode 100644 index 0000000000..56a3abcbe4 --- /dev/null +++ b/drivers/lsm6dsox/lsm6dsox.py @@ -0,0 +1,234 @@ +""" +LSM6DSOX STMicro driver for MicroPython based on LSM9DS1: +Source repo: https://github.com/hoihu/projects/tree/master/raspi-hat + +The MIT License (MIT) + +Copyright (c) 2021 Damien P. George +Copyright (c) 2021 Ibrahim Abdelkader + +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. + +Basic example usage: + +import time +from lsm6dsox import LSM6DSOX + +from machine import Pin, I2C +lsm = LSM6DSOX(I2C(0, scl=Pin(13), sda=Pin(12))) + +while (True): + print('Accelerometer: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}'.format(*lsm.read_accel())) + print('Gyroscope: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}'.format(*lsm.read_gyro())) + print("") + time.sleep_ms(100) +""" +import array +from micropython import const + + +class LSM6DSOX: + _CTRL3_C = const(0x12) + _CTRL1_XL = const(0x10) + _CTRL8_XL = const(0x17) + _CTRL9_XL = const(0x18) + + _CTRL2_G = const(0x11) + _CTRL7_G = const(0x16) + + _OUTX_L_G = const(0x22) + _OUTX_L_XL = const(0x28) + _MLC_STATUS = const(0x38) + + _DEFAULT_ADDR = const(0x6A) + _WHO_AM_I_REG = const(0x0F) + + _FUNC_CFG_ACCESS = const(0x01) + _FUNC_CFG_BANK_USER = const(0) + _FUNC_CFG_BANK_HUB = const(1) + _FUNC_CFG_BANK_EMBED = const(2) + + _MLC0_SRC = const(0x70) + _MLC_INT1 = const(0x0D) + _TAP_CFG0 = const(0x56) + + _EMB_FUNC_EN_A = const(0x04) + _EMB_FUNC_EN_B = const(0x05) + + def __init__( + self, + i2c, + address=_DEFAULT_ADDR, + gyro_odr=104, + accel_odr=104, + gyro_scale=2000, + accel_scale=4, + ucf=None, + ): + """Initalizes Gyro and Accelerator. + accel_odr: (0, 1.6Hz, 3.33Hz, 6.66Hz, 12.5Hz, 26Hz, 52Hz, 104Hz, 208Hz, 416Hz, 888Hz) + gyro_odr: (0, 1.6Hz, 3.33Hz, 6.66Hz, 12.5Hz, 26Hz, 52Hz, 104Hz, 208Hz, 416Hz, 888Hz) + gyro_scale: (245dps, 500dps, 1000dps, 2000dps) + accel_scale: (+/-2g, +/-4g, +/-8g, +-16g) + ucf: MLC program to load. + """ + self.i2c = i2c + self.address = address + + # check the id of the Accelerometer/Gyro + if self.__read_reg(_WHO_AM_I_REG) != 108: + raise OSError("No LSM6DS device was found at address 0x%x" % (self.address)) + + # allocate scratch buffer for efficient conversions and memread op's + self.scratch_int = array.array("h", [0, 0, 0]) + + SCALE_GYRO = {250: 0, 500: 1, 1000: 2, 2000: 3} + SCALE_ACCEL = {2: 0, 4: 2, 8: 3, 16: 1} + # XL_HM_MODE = 0 by default. G_HM_MODE = 0 by default. + ODR = { + 0: 0x00, + 1.6: 0x08, + 3.33: 0x09, + 6.66: 0x0A, + 12.5: 0x01, + 26: 0x02, + 52: 0x03, + 104: 0x04, + 208: 0x05, + 416: 0x06, + 888: 0x07, + } + + gyro_odr = round(gyro_odr, 2) + accel_odr = round(accel_odr, 2) + + # Sanity checks + if not gyro_odr in ODR: + raise ValueError("Invalid sampling rate: %d" % accel_odr) + if not gyro_scale in SCALE_GYRO: + raise ValueError("invalid gyro scaling: %d" % gyro_scale) + if not accel_odr in ODR: + raise ValueError("Invalid sampling rate: %d" % accel_odr) + if not accel_scale in SCALE_ACCEL: + raise ValueError("invalid accelerometer scaling: %d" % accel_scale) + + # Soft-reset the device. + self.reset() + + # Load and configure MLC if UCF file is provided + if ucf != None: + self.load_mlc(ucf) + + # Set Gyroscope datarate and scale. + # Note output from LPF2 second filtering stage is selected. See Figure 18. + self.__write_reg(_CTRL1_XL, (ODR[accel_odr] << 4) | (SCALE_ACCEL[accel_scale] << 2) | 2) + + # Enable LPF2 and HPF fast-settling mode, ODR/4 + self.__write_reg(_CTRL8_XL, 0x09) + + # Set Gyroscope datarate and scale. + self.__write_reg(_CTRL2_G, (ODR[gyro_odr] << 4) | (SCALE_GYRO[gyro_scale] << 2) | 0) + + self.gyro_scale = 32768 / gyro_scale + self.accel_scale = 32768 / accel_scale + + def __read_reg(self, reg, size=1): + buf = self.i2c.readfrom_mem(self.address, reg, size) + if size == 1: + return int(buf[0]) + return [int(x) for x in buf] + + def __write_reg(self, reg, val): + self.i2c.writeto_mem(self.address, reg, bytes([val])) + + def reset(self): + self.__write_reg(_CTRL3_C, self.__read_reg(_CTRL3_C) | 0x1) + for i in range(0, 10): + if (self.__read_reg(_CTRL3_C) & 0x01) == 0: + return + time.sleep_ms(10) + raise OSError("Failed to reset LSM6DS device.") + + def set_mem_bank(self, bank): + cfg = self.__read_reg(_FUNC_CFG_ACCESS) & 0x3F + self.__write_reg(_FUNC_CFG_ACCESS, cfg | (bank << 6)) + + def set_embedded_functions(self, enable, emb_ab=None): + self.set_mem_bank(_FUNC_CFG_BANK_EMBED) + if enable: + self.__write_reg(_EMB_FUNC_EN_A, emb_ab[0]) + self.__write_reg(_EMB_FUNC_EN_B, emb_ab[1]) + else: + emb_a = self.__read_reg(_EMB_FUNC_EN_A) + emb_b = self.__read_reg(_EMB_FUNC_EN_B) + self.__write_reg(_EMB_FUNC_EN_A, (emb_a & 0xC7)) + self.__write_reg(_EMB_FUNC_EN_B, (emb_b & 0xE6)) + emb_ab = (emb_a, emb_b) + + self.set_mem_bank(_FUNC_CFG_BANK_USER) + return emb_ab + + def load_mlc(self, ucf): + # Load MLC config from file + with open(ucf, "r") as ucf_file: + for l in ucf_file: + if l.startswith("Ac"): + v = [int(v, 16) for v in l.strip().split(" ")[1:3]] + self.__write_reg(v[0], v[1]) + + emb_ab = self.set_embedded_functions(False) + + # Disable I3C interface + self.__write_reg(_CTRL9_XL, self.__read_reg(_CTRL9_XL) | 0x01) + + # Enable Block Data Update + self.__write_reg(_CTRL3_C, self.__read_reg(_CTRL3_C) | 0x40) + + # Route signals on interrupt pin 1 + self.set_mem_bank(_FUNC_CFG_BANK_EMBED) + self.__write_reg(_MLC_INT1, self.__read_reg(_MLC_INT1) & 0x01) + self.set_mem_bank(_FUNC_CFG_BANK_USER) + + # Configure interrupt pin mode + self.__write_reg(_TAP_CFG0, self.__read_reg(_TAP_CFG0) | 0x41) + + self.set_embedded_functions(True, emb_ab) + + def read_mlc_output(self): + buf = None + if self.__read_reg(_MLC_STATUS) & 0x1: + self.__read_reg(0x1A, size=12) + self.set_mem_bank(_FUNC_CFG_BANK_EMBED) + buf = self.__read_reg(_MLC0_SRC, 8) + self.set_mem_bank(_FUNC_CFG_BANK_USER) + return buf + + def read_gyro(self): + """Returns gyroscope vector in degrees/sec.""" + mv = memoryview(self.scratch_int) + f = self.gyro_scale + self.i2c.readfrom_mem_into(self.address, _OUTX_L_G, mv) + return (mv[0] / f, mv[1] / f, mv[2] / f) + + def read_accel(self): + """Returns acceleration vector in gravity units (9.81m/s^2).""" + mv = memoryview(self.scratch_int) + f = self.accel_scale + self.i2c.readfrom_mem_into(self.address, _OUTX_L_XL, mv) + return (mv[0] / f, mv[1] / f, mv[2] / f) diff --git a/drivers/lsm6dsox/lsm6dsox_basic.py b/drivers/lsm6dsox/lsm6dsox_basic.py new file mode 100644 index 0000000000..6c747ae55c --- /dev/null +++ b/drivers/lsm6dsox/lsm6dsox_basic.py @@ -0,0 +1,13 @@ +# LSM6DSOX Basic Example. +import time +from lsm6dsox import LSM6DSOX + +from machine import Pin, I2C + +lsm = LSM6DSOX(I2C(0, scl=Pin(13), sda=Pin(12))) + +while True: + print("Accelerometer: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}".format(*lsm.read_accel())) + print("Gyroscope: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}".format(*lsm.read_gyro())) + print("") + time.sleep_ms(100) diff --git a/drivers/lsm6dsox/lsm6dsox_mlc.py b/drivers/lsm6dsox/lsm6dsox_mlc.py new file mode 100644 index 0000000000..866498d0ce --- /dev/null +++ b/drivers/lsm6dsox/lsm6dsox_mlc.py @@ -0,0 +1,48 @@ +# LSM6DSOX IMU MLC (Machine Learning Core) Example. +# Download the raw UCF file, copy to storage and reset. + +# NOTE: The pre-trained models (UCF files) for the examples can be found here: +# https://github.com/STMicroelectronics/STMems_Machine_Learning_Core/tree/master/application_examples/lsm6dsox + +import time +from lsm6dsox import LSM6DSOX +from machine import Pin, I2C + +INT_MODE = True # Run in interrupt mode. +INT_FLAG = False # Set True on interrupt. + + +def imu_int_handler(pin): + global INT_FLAG + INT_FLAG = True + + +if INT_MODE == True: + int_pin = Pin(24) + int_pin.irq(handler=imu_int_handler, trigger=Pin.IRQ_RISING) + +i2c = I2C(0, scl=Pin(13), sda=Pin(12)) + +# Vibration detection example +UCF_FILE = "lsm6dsox_vibration_monitoring.ucf" +UCF_LABELS = {0: "no vibration", 1: "low vibration", 2: "high vibration"} +# NOTE: Selected data rate and scale must match the MLC data rate and scale. +lsm = LSM6DSOX(i2c, gyro_odr=26, accel_odr=26, gyro_scale=2000, accel_scale=4, ucf=UCF_FILE) + +# Head gestures example +# UCF_FILE = "lsm6dsox_head_gestures.ucf" +# UCF_LABELS = {0:"Nod", 1:"Shake", 2:"Stationary", 3:"Swing", 4:"Walk"} +# NOTE: Selected data rate and scale must match the MLC data rate and scale. +# lsm = LSM6DSOX(i2c, gyro_odr=26, accel_odr=26, gyro_scale=250, accel_scale=2, ucf=UCF_FILE) + +print("MLC configured...") + +while True: + if INT_MODE: + if INT_FLAG: + INT_FLAG = False + print(UCF_LABELS[lsm.read_mlc_output()[0]]) + else: + buf = lsm.read_mlc_output() + if buf != None: + print(UCF_LABELS[buf[0]]) From c3dceb1c3223012ae29144182d14c19678005e05 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 15 Aug 2021 20:44:36 +0200 Subject: [PATCH 146/335] rp2/boards: Add support for Arduino Nano RP2040. --- .../ARDUINO_NANO_RP2040_CONNECT/board.json | 25 ++++++++++++ .../ARDUINO_NANO_RP2040_CONNECT/manifest.py | 9 +++++ .../mpconfigboard.cmake | 6 +++ .../mpconfigboard.h | 39 +++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/board.json create mode 100644 ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py create mode 100644 ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.cmake create mode 100644 ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h diff --git a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/board.json b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/board.json new file mode 100644 index 0000000000..ca7ba089b8 --- /dev/null +++ b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/board.json @@ -0,0 +1,25 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "Breadboard Friendly", + "Castellated Pads", + "WiFi Nina-W102", + "Bluetooth Nina-W102", + "IMU LSM6DSOXTR", + "Crypto IC ATECC608A-MAHDA-T", + "Microphone MP34DT05", + "SPI Flash 16MB", + "USB-MICRO" + ], + "images": [ + "ABX00052_01.iso_999x750.jpg" + ], + "mcu": "RP2040", + "product": "Arduino Nano RP2040 Connect", + "thumbnail": "", + "url": "https://store-usa.arduino.cc/products/arduino-nano-rp2040-connect", + "vendor": "Arduino" +} diff --git a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py new file mode 100644 index 0000000000..a9c81576da --- /dev/null +++ b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py @@ -0,0 +1,9 @@ +include("$(PORT_DIR)/boards/manifest.py") +freeze("$(MPY_DIR)/drivers/lsm6dsox/", "lsm6dsox.py") +include( + "$(MPY_LIB_DIR)/micropython/bluetooth/aioble/manifest.py", + client=True, + central=True, + l2cap=True, + security=True, +) diff --git a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.cmake b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.cmake new file mode 100644 index 0000000000..b31109ac53 --- /dev/null +++ b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.cmake @@ -0,0 +1,6 @@ +# cmake file for Arduino Nano RP2040 Connect. +set(MICROPY_PY_BLUETOOTH 1) +set(MICROPY_BLUETOOTH_NIMBLE 1) +set(MICROPY_PY_NETWORK_NINAW10 1) +set(MICROPY_HW_ENABLE_DOUBLE_TAP 1) +set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) diff --git a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h new file mode 100644 index 0000000000..08995212e2 --- /dev/null +++ b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h @@ -0,0 +1,39 @@ +//Board config for Arduino Nano RP2040 Connect. + +// Board and hardware specific configuration +#define MICROPY_HW_BOARD_NAME "Arduino Nano RP2040 Connect" +#define MICROPY_HW_FLASH_STORAGE_BYTES (8 * 1024 * 1024) + +// Enable networking and sockets. +#define MICROPY_PY_NETWORK (1) +#define MICROPY_PY_USOCKET (1) + +// Enable USB Mass Storage with FatFS filesystem. +#define MICROPY_HW_USB_MSC (1) +#define MICROPY_HW_USB_VID (0x2341) +#define MICROPY_HW_USB_PID (0x015e) + +// UART 1 config. +#define MICROPY_HW_UART1_TX (8) +#define MICROPY_HW_UART1_RX (9) +#define MICROPY_HW_UART1_CTS (10) +#define MICROPY_HW_UART1_RTS (11) + +// SPI 1 config. +#define MICROPY_HW_SPI1_SCK (14) +#define MICROPY_HW_SPI1_MOSI (11) +#define MICROPY_HW_SPI1_MISO (8) + +// Bluetooth config. +#define MICROPY_HW_BLE_UART_ID (1) +#define MICROPY_HW_BLE_UART_BAUDRATE (119600) + +// WiFi/NINA-W10 config. +#define MICROPY_HW_WIFI_SPI_ID (1) +#define MICROPY_HW_WIFI_SPI_BAUDRATE (8 * 1000 * 1000) + +// ublox Nina-W10 module config. +#define MICROPY_HW_NINA_RESET (3) +#define MICROPY_HW_NINA_GPIO0 (2) +#define MICROPY_HW_NINA_GPIO1 (9) +#define MICROPY_HW_NINA_ACK (10) From d72d699dad6c75966397873d108bcc2f36222144 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 6 Oct 2021 20:30:46 +0200 Subject: [PATCH 147/335] mimxrt/boards: Add the Seeed ARCH MIX board. The ARCH MIX board exposes the Ethernet Pins at it's connectors. Therefore the software is configured for using a LAN8720 PHY device. Breakout boards with the LAN8720 are easily available. --- .../SEEED_ARCH_MIX_flexspi_nor_config.h | 258 ++++++++++++++++++ ports/mimxrt/boards/SEEED_ARCH_MIX/board.json | 20 ++ .../boards/SEEED_ARCH_MIX/clock_config.h | 119 ++++++++ ports/mimxrt/boards/SEEED_ARCH_MIX/deploy.md | 6 + .../boards/SEEED_ARCH_MIX/mpconfigboard.h | 142 ++++++++++ .../boards/SEEED_ARCH_MIX/mpconfigboard.mk | 14 + ports/mimxrt/boards/SEEED_ARCH_MIX/pins.csv | 62 +++++ .../SEEED_ARCH_MIX/qspi_nor_flash_config.c | 136 +++++++++ 8 files changed, 757 insertions(+) create mode 100644 ports/mimxrt/boards/SEEED_ARCH_MIX/SEEED_ARCH_MIX_flexspi_nor_config.h create mode 100644 ports/mimxrt/boards/SEEED_ARCH_MIX/board.json create mode 100644 ports/mimxrt/boards/SEEED_ARCH_MIX/clock_config.h create mode 100644 ports/mimxrt/boards/SEEED_ARCH_MIX/deploy.md create mode 100644 ports/mimxrt/boards/SEEED_ARCH_MIX/mpconfigboard.h create mode 100644 ports/mimxrt/boards/SEEED_ARCH_MIX/mpconfigboard.mk create mode 100644 ports/mimxrt/boards/SEEED_ARCH_MIX/pins.csv create mode 100644 ports/mimxrt/boards/SEEED_ARCH_MIX/qspi_nor_flash_config.c diff --git a/ports/mimxrt/boards/SEEED_ARCH_MIX/SEEED_ARCH_MIX_flexspi_nor_config.h b/ports/mimxrt/boards/SEEED_ARCH_MIX/SEEED_ARCH_MIX_flexspi_nor_config.h new file mode 100644 index 0000000000..33698a34d2 --- /dev/null +++ b/ports/mimxrt/boards/SEEED_ARCH_MIX/SEEED_ARCH_MIX_flexspi_nor_config.h @@ -0,0 +1,258 @@ +/* + * Copyright 2019 NXP. + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1020_flexspi_nor_config.h + +#ifndef __SEEED_ARCH_MIX_FLEXSPI_NOR_CONFIG__ +#define __SEEED_ARCH_MIX_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define 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)) + +// !@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_133MHz = 7, + kFlexSpiSerialClk_166MHz = 8, + kFlexSpiSerialClk_200MHz = 9, +} flexspi_serial_clk_freq_t; + +// !@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, // !< Clock configure for SDR mode + kFlexSpiClk_DDR, // !< Clock configurat for DDR mode +}; + +// !@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +// !@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. +}; + +// !@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +// !@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +// !@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; // !< Sequence Number, valid number: 1-16 + uint8_t seqId; // !< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +// !@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, // !< Reset device command +}; + +// !@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + // ! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + // ! Generic configuration, etc. + uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + // ! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + // ! sequence number, [31:16] Reserved + uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + // ! details + uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + // ! Chapter for more details + uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + // ! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI + uint32_t pageSize; // !< Page size of Serial NOR + uint32_t sectorSize; // !< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command + uint8_t isUniformBlockSize; // !< Sector/Block size is the same + uint8_t reserved0[2]; // !< Reserved for future use + uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; // !< Block size + uint32_t reserve2[11]; // !< Reserved for future use +} flexspi_nor_config_t; + +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __SEEED_ARCH_MIX_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/SEEED_ARCH_MIX/board.json b/ports/mimxrt/boards/SEEED_ARCH_MIX/board.json new file mode 100644 index 0000000000..3142f1a814 --- /dev/null +++ b/ports/mimxrt/boards/SEEED_ARCH_MIX/board.json @@ -0,0 +1,20 @@ +{ + "deploy": [ + "deploy.md" + ], + "docs": "", + "features": [ + "MicroSD", + "MicroUSB", + "SDRAM", + "RGB LED" + ], + "images": [ + "main1.jpg" + ], + "mcu": "mimxrt", + "product": "Arch Mix", + "thumbnail": "", + "url": "https://wiki.seeedstudio.com/Arch_Mix/", + "vendor": "Seeed Technology Co.,Ltd." +} diff --git a/ports/mimxrt/boards/SEEED_ARCH_MIX/clock_config.h b/ports/mimxrt/boards/SEEED_ARCH_MIX/clock_config.h new file mode 100644 index 0000000000..f213ac7e23 --- /dev/null +++ b/ports/mimxrt/boards/SEEED_ARCH_MIX/clock_config.h @@ -0,0 +1,119 @@ +/* + * Copyright 2017-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ + +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */ + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 600000000UL +#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_CSI_CLK_ROOT 12000000UL +#define BOARD_BOOTCLOCKRUN_ENET1_TX_CLK 2400000UL +#define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 2400000UL +#define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 1200000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 160000000UL +#define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 150000000UL +#define BOARD_BOOTCLOCKRUN_LCDIF_CLK_ROOT 9642857UL +#define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL +#define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL +#define BOARD_BOOTCLOCKRUN_LVDS1_CLK 1200000000UL +#define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL +#define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 75000000UL +#define BOARD_BOOTCLOCKRUN_PLL7_MAIN_CLK 24000000UL +#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 75000000UL +#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_USBPHY2_CLK 0UL +#define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 198000000UL +#define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 198000000UL + +/*! @brief Arm PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN; +/*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; +/*! @brief Sys PLL for BOARD_BootClockRUN configuration. + */ +extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/ports/mimxrt/boards/SEEED_ARCH_MIX/deploy.md b/ports/mimxrt/boards/SEEED_ARCH_MIX/deploy.md new file mode 100644 index 0000000000..e91c48d46c --- /dev/null +++ b/ports/mimxrt/boards/SEEED_ARCH_MIX/deploy.md @@ -0,0 +1,6 @@ +Firmware upload to the Seed ARCH MIX board can be done using the J-Link interface +For that, follow the instructions given by Seed in their Wiki at +https://wiki.seeedstudio.com/Arch_Mix/#flashing-arduino-bootloader-to-arch-mix. +You will need a J-Link debug probe and software. What has been tested was the +Segger JLlink edu or Segger JLink edu mini. As matching loader tool you can use +Segger JFlashLite. The target address for loading is 0x60000000. diff --git a/ports/mimxrt/boards/SEEED_ARCH_MIX/mpconfigboard.h b/ports/mimxrt/boards/SEEED_ARCH_MIX/mpconfigboard.h new file mode 100644 index 0000000000..7c79063eef --- /dev/null +++ b/ports/mimxrt/boards/SEEED_ARCH_MIX/mpconfigboard.h @@ -0,0 +1,142 @@ +#define MICROPY_HW_BOARD_NAME "Seeed ARCH MIX" +#define MICROPY_HW_MCU_NAME "MIMXRT1052DVL5B" + +// MIMXRT1050_EVKB has 1 user LED +#define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) +#define MICROPY_HW_LED2_PIN (pin_GPIO_AD_B0_10) +#define MICROPY_HW_LED3_PIN (pin_GPIO_AD_B0_11) +#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) +#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) + +#define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) + +// Define mapping logical UART # to hardware UART # +// LPUART1 on J3_19/J3_20 -> 1 +// LPUART2 on J4_16/J4_17 -> 2 +// LPUART3 on J4_06/J4_07 -> 3 +// LPUART8 on J4_10/J4_11 -> 4 +// LPUART4 on J5_08/J5_12 -> 5 + +#define MICROPY_HW_UART_NUM (sizeof(uart_index_table) / sizeof(uart_index_table)[0]) +#define MICROPY_HW_UART_INDEX { 0, 1, 2, 3, 8, 4 } + +#define IOMUX_TABLE_UART \ + { IOMUXC_GPIO_AD_B0_12_LPUART1_TX }, { IOMUXC_GPIO_AD_B0_13_LPUART1_RX }, \ + { IOMUXC_GPIO_AD_B1_02_LPUART2_TX }, { IOMUXC_GPIO_AD_B1_03_LPUART2_RX }, \ + { IOMUXC_GPIO_AD_B1_06_LPUART3_TX }, { IOMUXC_GPIO_AD_B1_07_LPUART3_RX }, \ + { IOMUXC_GPIO_B1_00_LPUART4_TX }, { IOMUXC_GPIO_B1_01_LPUART4_RX }, \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { IOMUXC_GPIO_AD_B1_10_LPUART8_TX }, { IOMUXC_GPIO_AD_B1_11_LPUART8_RX }, + +#define MICROPY_HW_SPI_INDEX { 3, 4 } + +#define IOMUX_TABLE_SPI \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK }, { IOMUXC_GPIO_AD_B1_12_LPSPI3_PCS0 }, \ + { IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO }, { IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI }, \ + { IOMUXC_GPIO_B1_07_LPSPI4_SCK }, { IOMUXC_GPIO_B1_04_LPSPI4_PCS0 }, \ + { IOMUXC_GPIO_B1_06_LPSPI4_SDO }, { IOMUXC_GPIO_B1_05_LPSPI4_SDI }, + +#define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \ + kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } + +#define DMA_REQ_SRC_TX { 0, kDmaRequestMuxLPSPI1Tx, kDmaRequestMuxLPSPI2Tx, \ + kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } + +// Define the mapping hardware I2C # to logical I2C # +// SDA/SCL HW-I2C Logical I2C +// J3_17/J3_16 LPI2C1 -> 0 +// J4_06/J4_07 LPI2C3 -> 1 +// J5_05/J5_04 LPI2C2 -> 2 + +#define MICROPY_HW_I2C_INDEX { 1, 3, 2 } + +#define IOMUX_TABLE_I2C \ + { IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL }, { IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA }, \ + { IOMUXC_GPIO_B0_04_LPI2C2_SCL }, { IOMUXC_GPIO_B0_05_LPI2C2_SDA }, \ + { IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL }, { IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA } + +#define USDHC_DUMMY_PIN NULL, 0 + +#define MICROPY_USDHC1 \ + { \ + .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ + .clk = { GPIO_SD_B0_01_USDHC1_CLK }, \ + .cd_b = { GPIO_B1_12_USDHC1_CD_B }, \ + .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 }, \ + .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 }, \ + .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 }, \ + .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 }, \ + } + +// Network definitions +// Transceiver Phy Address & Type +#define ENET_PHY_ADDRESS (1) +#define ENET_PHY LAN8720 +#define ENET_PHY_OPS phylan8720_ops +#define ENET_TX_CLK_OUTPUT false + +// Etherner PIN definitions +// No reset and interrupt pin by intention + +#define IOMUX_TABLE_ENET \ + { IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_06_ENET_RX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_09_ENET_TX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_10_ENET_REF_CLK, 1, 0x71u }, \ + { IOMUXC_GPIO_B1_11_ENET_RX_ER, 0, 0x30E9u }, \ + { IOMUXC_GPIO_EMC_41_ENET_MDIO, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_EMC_40_ENET_MDC, 0, 0xB0E9u }, + +// --- SEMC --- // +#define MIMXRT_IOMUXC_SEMC_DATA00 IOMUXC_GPIO_EMC_00_SEMC_DATA00 +#define MIMXRT_IOMUXC_SEMC_DATA01 IOMUXC_GPIO_EMC_01_SEMC_DATA01 +#define MIMXRT_IOMUXC_SEMC_DATA02 IOMUXC_GPIO_EMC_02_SEMC_DATA02 +#define MIMXRT_IOMUXC_SEMC_DATA03 IOMUXC_GPIO_EMC_03_SEMC_DATA03 +#define MIMXRT_IOMUXC_SEMC_DATA04 IOMUXC_GPIO_EMC_04_SEMC_DATA04 +#define MIMXRT_IOMUXC_SEMC_DATA05 IOMUXC_GPIO_EMC_05_SEMC_DATA05 +#define MIMXRT_IOMUXC_SEMC_DATA06 IOMUXC_GPIO_EMC_06_SEMC_DATA06 +#define MIMXRT_IOMUXC_SEMC_DATA07 IOMUXC_GPIO_EMC_07_SEMC_DATA07 +#define MIMXRT_IOMUXC_SEMC_DATA08 IOMUXC_GPIO_EMC_30_SEMC_DATA08 +#define MIMXRT_IOMUXC_SEMC_DATA09 IOMUXC_GPIO_EMC_31_SEMC_DATA09 +#define MIMXRT_IOMUXC_SEMC_DATA10 IOMUXC_GPIO_EMC_32_SEMC_DATA10 +#define MIMXRT_IOMUXC_SEMC_DATA11 IOMUXC_GPIO_EMC_33_SEMC_DATA11 +#define MIMXRT_IOMUXC_SEMC_DATA12 IOMUXC_GPIO_EMC_34_SEMC_DATA12 +#define MIMXRT_IOMUXC_SEMC_DATA13 IOMUXC_GPIO_EMC_35_SEMC_DATA13 +#define MIMXRT_IOMUXC_SEMC_DATA14 IOMUXC_GPIO_EMC_36_SEMC_DATA14 +#define MIMXRT_IOMUXC_SEMC_DATA15 IOMUXC_GPIO_EMC_37_SEMC_DATA15 + +#define MIMXRT_IOMUXC_SEMC_ADDR00 IOMUXC_GPIO_EMC_09_SEMC_ADDR00 +#define MIMXRT_IOMUXC_SEMC_ADDR01 IOMUXC_GPIO_EMC_10_SEMC_ADDR01 +#define MIMXRT_IOMUXC_SEMC_ADDR02 IOMUXC_GPIO_EMC_11_SEMC_ADDR02 +#define MIMXRT_IOMUXC_SEMC_ADDR03 IOMUXC_GPIO_EMC_12_SEMC_ADDR03 +#define MIMXRT_IOMUXC_SEMC_ADDR04 IOMUXC_GPIO_EMC_13_SEMC_ADDR04 +#define MIMXRT_IOMUXC_SEMC_ADDR05 IOMUXC_GPIO_EMC_14_SEMC_ADDR05 +#define MIMXRT_IOMUXC_SEMC_ADDR06 IOMUXC_GPIO_EMC_15_SEMC_ADDR06 +#define MIMXRT_IOMUXC_SEMC_ADDR07 IOMUXC_GPIO_EMC_16_SEMC_ADDR07 +#define MIMXRT_IOMUXC_SEMC_ADDR08 IOMUXC_GPIO_EMC_17_SEMC_ADDR08 +#define MIMXRT_IOMUXC_SEMC_ADDR09 IOMUXC_GPIO_EMC_18_SEMC_ADDR09 +#define MIMXRT_IOMUXC_SEMC_ADDR10 IOMUXC_GPIO_EMC_23_SEMC_ADDR10 +#define MIMXRT_IOMUXC_SEMC_ADDR11 IOMUXC_GPIO_EMC_19_SEMC_ADDR11 +#define MIMXRT_IOMUXC_SEMC_ADDR12 IOMUXC_GPIO_EMC_20_SEMC_ADDR12 + +#define MIMXRT_IOMUXC_SEMC_BA0 IOMUXC_GPIO_EMC_21_SEMC_BA0 +#define MIMXRT_IOMUXC_SEMC_BA1 IOMUXC_GPIO_EMC_22_SEMC_BA1 +#define MIMXRT_IOMUXC_SEMC_CAS IOMUXC_GPIO_EMC_24_SEMC_CAS +#define MIMXRT_IOMUXC_SEMC_CKE IOMUXC_GPIO_EMC_27_SEMC_CKE +#define MIMXRT_IOMUXC_SEMC_CLK IOMUXC_GPIO_EMC_26_SEMC_CLK +#define MIMXRT_IOMUXC_SEMC_DM00 IOMUXC_GPIO_EMC_08_SEMC_DM00 +#define MIMXRT_IOMUXC_SEMC_DM01 IOMUXC_GPIO_EMC_38_SEMC_DM01 +#define MIMXRT_IOMUXC_SEMC_DQS IOMUXC_GPIO_EMC_39_SEMC_DQS +#define MIMXRT_IOMUXC_SEMC_RAS IOMUXC_GPIO_EMC_25_SEMC_RAS +#define MIMXRT_IOMUXC_SEMC_WE IOMUXC_GPIO_EMC_28_SEMC_WE + +#define MIMXRT_IOMUXC_SEMC_CS0 IOMUXC_GPIO_EMC_29_SEMC_CS0 diff --git a/ports/mimxrt/boards/SEEED_ARCH_MIX/mpconfigboard.mk b/ports/mimxrt/boards/SEEED_ARCH_MIX/mpconfigboard.mk new file mode 100644 index 0000000000..90edc5d517 --- /dev/null +++ b/ports/mimxrt/boards/SEEED_ARCH_MIX/mpconfigboard.mk @@ -0,0 +1,14 @@ +MCU_SERIES = MIMXRT1052 +MCU_VARIANT = MIMXRT1052DVL6B + +MICROPY_FLOAT_IMPL = double +MICROPY_PY_MACHINE_SDCARD = 1 +MICROPY_HW_FLASH_TYPE ?= qspi_nor +MICROPY_HW_FLASH_SIZE ?= 0x800000 # 8MB + +MICROPY_HW_SDRAM_AVAIL = 1 +MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB + +MICROPY_PY_LWIP = 1 +MICROPY_PY_USSL = 1 +MICROPY_SSL_MBEDTLS = 1 diff --git a/ports/mimxrt/boards/SEEED_ARCH_MIX/pins.csv b/ports/mimxrt/boards/SEEED_ARCH_MIX/pins.csv new file mode 100644 index 0000000000..0183795cd7 --- /dev/null +++ b/ports/mimxrt/boards/SEEED_ARCH_MIX/pins.csv @@ -0,0 +1,62 @@ +J3_04,GPIO_B1_11 +J3_05,GPIO_B1_06 +J3_06,GPIO_EMC_41 +J3_07,GPIO_EMC_40 +J3_08,GPIO_B1_05 +J3_09,GPIO_B1_04 +J3_10,GPIO_B1_08 +J3_11,GPIO_B1_07 +J3_12,GPIO_B1_09 +J3_13,GPIO_B1_10 +J3_14,GPIO_AD_B0_14 +J3_15,GPO_AD_B0_15 +J3_16,GPIO_AD_B1_00 +J3_17,GPIO_AD_B1_01 +J3_19,GPIO_AD_B0_13 +J3_20,GPIO_AD_B0_12 +J4_04,GPIO_AD_B1_04 +J4_05,GPIO_AD_B1_05 +J4_06,GPIO_AD_B1_06 +J4_07,GPIO_AD_B1_07 +J4_08,GPIO_AD_B1_08 +J4_09,GPIO_AD_B1_09 +J4_10,GPIO_AD_B1_10 +J4_11,GPIO_AD_B1_11 +J4_12,GPIO_AD_B1_12 +J4_13,GPIO_AD_B1_13 +J4_14,GPIO_AD_B1_14 +J4_15,GPIO_AD_B1_15 +J4_16,GPIO_AD_B1_02 +J4_17,GPIO_AD_B1_03 +J4_19,GPIO_AD_B0_07 +J4_20,GPIO_AD_B0_06 +J5_32,GPIO_B0_00 +J5_28,GPIO_B0_01 +J5_29,GPIO_B0_02 +J5_30,GPIO_B0_03 +J5_04,GPIO_B0_04 +J5_05,GPIO_B0_05 +J5_06,GPIO_B0_06 +J5_07,GPIO_B0_07 +J5_08,GPIO_B0_08 +J5_12,GPIO_B0_09 +J5_13,GPIO_B0_10 +J5_14,GPIO_B0_11 +J5_15,GPIO_B0_12 +J5_16,GPIO_B0_13 +J5_17,GPIO_B0_14 +J5_22,GPIO_B0_15 +J5_23,GPIO_B1_00 +J5_24,GPIO_B1_01 +J5_25,GPIO_B1_02 +J5_26,GPIO_B1_03 +J5_34,GPIO_AD_B1_15 +J5_35,GPIO_AD_B1_14 +J5_36,GPIO_AD_B1_13 +J5_37,GPIO_AD_B1_12 +J5_42,GPIO_AD_B1_00 +J5_43,GPIO_AD_B1_01 +J5_50,GPIO_AD_B0_02 +LED_RED,GPIO_AD_B0_09 +LED_GREEN,GPIO_AD_B0_10 +LED_BLUE,GPIO_AD_B0_11 diff --git a/ports/mimxrt/boards/SEEED_ARCH_MIX/qspi_nor_flash_config.c b/ports/mimxrt/boards/SEEED_ARCH_MIX/qspi_nor_flash_config.c new file mode 100644 index 0000000000..7b2584d3de --- /dev/null +++ b/ports/mimxrt/boards/SEEED_ARCH_MIX/qspi_nor_flash_config.c @@ -0,0 +1,136 @@ +/* + * Copyright 2019 NXP. + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1010_flexspi_nor_config.c + +#include BOARD_FLASH_CONFIG_HEADER_H + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .busyOffset = FLASH_BUSY_STATUS_OFFSET, // Status bit 0 indicates busy. + .busyBitPolarity = FLASH_BUSY_STATUS_POL, // Busy when the bit is 1. + .deviceModeCfgEnable = 1u, + .deviceModeType = kDeviceConfigCmdType_QuadEnable, + .deviceModeSeq = { + .seqId = 4u, + .seqNum = 1u, + }, + .deviceModeArg = 0x40, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .deviceType = kFlexSpiDeviceType_SerialNOR, + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_100MHz, + .sflashA1Size = BOARD_FLASH_SIZE, + .lookupTable = + { + // 0 Read LUTs 0 -> 0 + 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), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = false, + // .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ From 7cc9b257a9af77a9a782e055252f2c196c212d49 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 5 Nov 2021 15:59:55 +0100 Subject: [PATCH 148/335] mimxrt/boards: Update the board.json files and add deploy_xx.md files. - Add board.md files for MIMXRT1060_EVK and MIMXRT1064_EVK warning about their experimental state. - Add separate deploy_teensy.md and deploy_mimxrt.md files. --- ports/mimxrt/boards/MIMXRT1010_EVK/board.json | 11 +++++++++-- ports/mimxrt/boards/MIMXRT1020_EVK/board.json | 14 ++++++++++++-- ports/mimxrt/boards/MIMXRT1050_EVK/board.json | 15 +++++++++++++-- ports/mimxrt/boards/MIMXRT1060_EVK/board.json | 16 ++++++++++++++-- ports/mimxrt/boards/MIMXRT1060_EVK/board.md | 1 + ports/mimxrt/boards/MIMXRT1064_EVK/board.json | 16 ++++++++++++++-- ports/mimxrt/boards/MIMXRT1064_EVK/board.md | 1 + ports/mimxrt/boards/TEENSY40/board.json | 6 ++++-- ports/mimxrt/boards/TEENSY41/board.json | 8 ++++++-- ports/mimxrt/boards/deploy.md | 0 ports/mimxrt/boards/deploy_mimxrt.md | 11 +++++++++++ ports/mimxrt/boards/deploy_teensy.md | 14 ++++++++++++++ 12 files changed, 99 insertions(+), 14 deletions(-) create mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/board.md create mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/board.md delete mode 100644 ports/mimxrt/boards/deploy.md create mode 100644 ports/mimxrt/boards/deploy_mimxrt.md create mode 100644 ports/mimxrt/boards/deploy_teensy.md diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/board.json b/ports/mimxrt/boards/MIMXRT1010_EVK/board.json index 048430bead..4bf9ce0524 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/board.json +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/board.json @@ -1,9 +1,16 @@ { "deploy": [ - "../deploy.md" + "../deploy_mimxrt.md" ], "docs": "", - "features": [], + "features": [ + "MicroUSB", + "Microphone", + "AudioCodec", + "SPDIF", + "OpenSDA", + "JLink" + ], "images": [ "i.MXRT1010-TOP.jpg" ], diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/board.json b/ports/mimxrt/boards/MIMXRT1020_EVK/board.json index 4dd3fed269..cc74c25fed 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/board.json +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/board.json @@ -1,9 +1,19 @@ { "deploy": [ - "../deploy.md" + "../deploy_mimxrt.md" ], "docs": "", - "features": [], + "features": [ + "Ethernet", + "SDRAM", + "MicroSD", + "MicroUSB", + "Microphone", + "AudioCodec", + "CAN", + "OpenSDA", + "JLink" + ], "images": [ "MIMXRT-1020-EVKBD.jpg" ], diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/board.json b/ports/mimxrt/boards/MIMXRT1050_EVK/board.json index 9c0e22b373..d99ad9fcfd 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/board.json +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/board.json @@ -1,9 +1,20 @@ { "deploy": [ - "../deploy.md" + "../deploy_mimxrt.md" ], "docs": "", - "features": [], + "features": [ + "Ethernet", + "SDRAM", + "MicroSD", + "MicroUSB", + "Microphone", + "AudioCodec", + "SPDIF", + "CAN", + "OpenSDA", + "JLink" + ], "images": [ "IMX_RT1050-EVKB_TOP-LR.jpg" ], diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/board.json b/ports/mimxrt/boards/MIMXRT1060_EVK/board.json index 14e8942de2..67a3818ee2 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/board.json +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/board.json @@ -1,9 +1,21 @@ { "deploy": [ - "../deploy.md" + "../deploy_mimxrt.md" ], "docs": "", - "features": [], + "features": [ + "Ethernet", + "SDRAM", + "MicroSD", + "MicroUSB", + "Microphone", + "AudioCodec", + "SPDIF", + "CAN", + "Camera", + "OpenSDA", + "JLink" + ], "images": [ "X-MIMXRT1060-EVK-BOARD-BOTTOM.jpg" ], diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/board.md b/ports/mimxrt/boards/MIMXRT1060_EVK/board.md new file mode 100644 index 0000000000..5bca8d57f2 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/board.md @@ -0,0 +1 @@ +The port for this board is experimental. It is made based on the documentation, but was not yet tested. \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/board.json b/ports/mimxrt/boards/MIMXRT1064_EVK/board.json index ff7f3f722e..ef12336c44 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/board.json +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/board.json @@ -1,9 +1,21 @@ { "deploy": [ - "../deploy.md" + "../deploy_mimxrt.md" ], "docs": "", - "features": [], + "features": [ + "Ethernet", + "SDRAM", + "MicroSD", + "MicroUSB", + "Microphone", + "AudioAmp", + "SPDIF", + "CAN", + "Camera", + "OpenSDA", + "JLink" + ], "images": [ "MIMXRT1064EVK-TOP.jpg" ], diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/board.md b/ports/mimxrt/boards/MIMXRT1064_EVK/board.md new file mode 100644 index 0000000000..5bca8d57f2 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/board.md @@ -0,0 +1 @@ +The port for this board is experimental. It is made based on the documentation, but was not yet tested. \ No newline at end of file diff --git a/ports/mimxrt/boards/TEENSY40/board.json b/ports/mimxrt/boards/TEENSY40/board.json index dfc0ca96b3..daa6dbf99e 100644 --- a/ports/mimxrt/boards/TEENSY40/board.json +++ b/ports/mimxrt/boards/TEENSY40/board.json @@ -1,9 +1,11 @@ { "deploy": [ - "../deploy.md" + "../deploy_teensy.md" ], "docs": "", - "features": [], + "features": [ + "Breadboard Friendly" + ], "images": [ "teensy40_front.jpg" ], diff --git a/ports/mimxrt/boards/TEENSY41/board.json b/ports/mimxrt/boards/TEENSY41/board.json index cbb397c727..1f8fe37a99 100644 --- a/ports/mimxrt/boards/TEENSY41/board.json +++ b/ports/mimxrt/boards/TEENSY41/board.json @@ -1,9 +1,13 @@ { "deploy": [ - "../deploy.md" + "../deploy_teensy.md" ], "docs": "", - "features": [], + "features": [ + "MicroSD", + "Ethernet", + "Breadboard Friendly" + ], "images": [ "teensy41_4.jpg" ], diff --git a/ports/mimxrt/boards/deploy.md b/ports/mimxrt/boards/deploy.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/ports/mimxrt/boards/deploy_mimxrt.md b/ports/mimxrt/boards/deploy_mimxrt.md new file mode 100644 index 0000000000..35752a8362 --- /dev/null +++ b/ports/mimxrt/boards/deploy_mimxrt.md @@ -0,0 +1,11 @@ +Firmware can be loaded to the MIMXRT development boards in various ways. The most convenient +one is using the built-in support MCU. When a PC is connected to the debug USB port, a drive +icon will appear. Firmware can be uploaded to the board by copying it to this drive. The copy +and flashing will take a few moments. At the end of the upload, the drive icon will disappear +and reappear again. Then the reset button has to be pushed, which starts the MicroPython firmware. + +Depending on the power jumper settings, both the debug USB and OTG USB port have to be powered +during firmware upload. + +You may as well load the firmware using the JLink port or openSDA interface with the appropriate tools. +For more options, consult the user guide of the board. diff --git a/ports/mimxrt/boards/deploy_teensy.md b/ports/mimxrt/boards/deploy_teensy.md new file mode 100644 index 0000000000..f481544900 --- /dev/null +++ b/ports/mimxrt/boards/deploy_teensy.md @@ -0,0 +1,14 @@ +For deploying the firmware use the Teensy Loader tool provided by PJRC on their web site. +PJRC provides both a graphical and command line version for Windows, OS X and Linux. +With the command line version, run the command: + +```bash +teensy_loader_cli --mcu=imxrt1062 -v -w TEENSY40-.hex +``` +or for Teensy 4.1: + +```bash +teensy_loader_cli --mcu=imxrt1062 -v -w TEENSY41-.hex +``` + +When loading the firmware the PJRC boot loader will erase the content of the board file system. From 7d7d29dbe29df909616094bbf0ec047401f8ab36 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 10 Nov 2021 13:59:09 +0100 Subject: [PATCH 149/335] mimxrt: Fix mp_hal_quiet_timing_enter()/exit() so timer still runs. The initial code disabled IRQs, which caused the us-ticks timer to stop. The change here changes the priotity level, such that the timer still runs. --- ports/mimxrt/mpconfigport.h | 17 +++++++++++++++++ ports/mimxrt/mphalport.h | 4 ++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 64e991c799..361b8bd089 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -189,6 +189,23 @@ __attribute__((always_inline)) static inline uint32_t disable_irq(void) { return state; } +static inline uint32_t raise_irq_pri(uint32_t pri) { + uint32_t basepri = __get_BASEPRI(); + // If non-zero, the processor does not process any exception with a + // priority value greater than or equal to BASEPRI. + // When writing to BASEPRI_MAX the write goes to BASEPRI only if either: + // - Rn is non-zero and the current BASEPRI value is 0 + // - Rn is non-zero and less than the current BASEPRI value + pri <<= (8 - __NVIC_PRIO_BITS); + __ASM volatile ("msr basepri_max, %0" : : "r" (pri) : "memory"); + return basepri; +} + +// "basepri" should be the value returned from raise_irq_pri +static inline void restore_irq_pri(uint32_t basepri) { + __set_BASEPRI(basepri); +} + #define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq() #define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state) diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index c02f561a9d..0dc49f01a5 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -53,8 +53,8 @@ extern ringbuf_t stdin_ringbuf; #define mp_hal_pin_od_low(p) mp_hal_pin_low(p) #define mp_hal_pin_od_high(p) mp_hal_pin_high(p) -#define mp_hal_quiet_timing_enter() MICROPY_BEGIN_ATOMIC_SECTION() -#define mp_hal_quiet_timing_exit(irq_state) MICROPY_END_ATOMIC_SECTION(irq_state) +#define mp_hal_quiet_timing_enter() raise_irq_pri(1) +#define mp_hal_quiet_timing_exit(irq_state) restore_irq_pri(irq_state) void mp_hal_set_interrupt_char(int c); From b73d8b045a6cff582280092d5a4c9d930934c25a Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 15 Sep 2021 18:16:05 +0200 Subject: [PATCH 150/335] rp2/machine_bitstream: Implement the machine.bitstream driver. Timing error is ~20ns at 125MHz, and ~10ns at 250MHz. --- ports/rp2/CMakeLists.txt | 1 + ports/rp2/machine_bitstream.c | 74 +++++++++++++++++++++++++++++++++++ ports/rp2/modmachine.c | 6 ++- ports/rp2/mpconfigport.h | 1 + ports/rp2/mphalport.h | 16 ++++++++ 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 ports/rp2/machine_bitstream.c diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index 0b433da53c..c2f8088542 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -84,6 +84,7 @@ set(MICROPY_SOURCE_DRIVERS set(MICROPY_SOURCE_PORT fatfs_port.c machine_adc.c + machine_bitstream.c machine_i2c.c machine_i2s.c machine_pin.c diff --git a/ports/rp2/machine_bitstream.c b/ports/rp2/machine_bitstream.c new file mode 100644 index 0000000000..b65ec02147 --- /dev/null +++ b/ports/rp2/machine_bitstream.c @@ -0,0 +1,74 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jim Mussared + * + * 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. + */ + +// This is a translation of the cycle counter implementation in ports/stm32/machine_bitstream.c. + +#include "py/mpconfig.h" +#include "py/mphal.h" +#include "hardware/structs/systick.h" + +#if MICROPY_PY_MACHINE_BITSTREAM + +#define MP_HAL_BITSTREAM_NS_OVERHEAD (9) + +void __time_critical_func(machine_bitstream_high_low)(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const uint8_t *buf, size_t len) { + uint32_t fcpu_mhz = mp_hal_get_cpu_freq() / 1000000; + // Convert ns to clock ticks [high_time_0, period_0, high_time_1, period_1]. + for (size_t i = 0; i < 4; ++i) { + timing_ns[i] = fcpu_mhz * timing_ns[i] / 1000; + if (timing_ns[i] > (2 * MP_HAL_BITSTREAM_NS_OVERHEAD)) { + timing_ns[i] -= MP_HAL_BITSTREAM_NS_OVERHEAD; + } + if (i % 2 == 1) { + // Convert low_time to period (i.e. add high_time). + timing_ns[i] += timing_ns[i - 1] - MP_HAL_BITSTREAM_NS_OVERHEAD; + } + } + mp_hal_pin_output(pin); + // Enable the systick counter, source CPU clock. + systick_hw->csr = 5; + + uint32_t irq_state = mp_hal_quiet_timing_enter(); + + for (size_t i = 0; i < len; ++i) { + uint8_t b = buf[i]; + for (size_t j = 0; j < 8; ++j) { + uint32_t *t = &timing_ns[b >> 6 & 2]; + uint32_t start_ticks = systick_hw->cvr = SYSTICK_MAX; + mp_hal_pin_high(pin); + while ((start_ticks - systick_hw->cvr) < t[0]) { + } + b <<= 1; + mp_hal_pin_low(pin); + while ((start_ticks - systick_hw->cvr) < t[1]) { + } + } + } + + mp_hal_quiet_timing_exit(irq_state); +} + +#endif // MICROPY_PY_MACHINE_BITSTREAM diff --git a/ports/rp2/modmachine.c b/ports/rp2/modmachine.c index 88e4bec2e8..9d6178a0f2 100644 --- a/ports/rp2/modmachine.c +++ b/ports/rp2/modmachine.c @@ -27,6 +27,7 @@ #include "py/runtime.h" #include "py/mphal.h" #include "shared/runtime/pyexec.h" +#include "extmod/machine_bitstream.h" #include "extmod/machine_i2c.h" #include "extmod/machine_mem.h" #include "extmod/machine_pulse.h" @@ -86,7 +87,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(machine_bootloader_obj, machine_bootloader); STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) { if (n_args == 0) { - return MP_OBJ_NEW_SMALL_INT(clock_get_hz(clk_sys)); + return MP_OBJ_NEW_SMALL_INT(mp_hal_get_cpu_freq()); } else { mp_int_t freq = mp_obj_get_int(args[0]); if (!set_sys_clock_khz(freq / 1000, false)) { @@ -154,6 +155,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&machine_disable_irq_obj) }, { MP_ROM_QSTR(MP_QSTR_enable_irq), MP_ROM_PTR(&machine_enable_irq_obj) }, + #if MICROPY_PY_MACHINE_BITSTREAM + { MP_ROM_QSTR(MP_QSTR_bitstream), MP_ROM_PTR(&machine_bitstream_obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) }, { MP_ROM_QSTR(MP_QSTR_mem8), MP_ROM_PTR(&machine_mem8_obj) }, diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index 2e8a33a7a7..e6a85bb682 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -86,6 +86,7 @@ #define MICROPY_PY_URANDOM_SEED_INIT_FUNC (rosc_random_u32()) #define MICROPY_PY_MACHINE (1) #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new +#define MICROPY_PY_MACHINE_BITSTREAM (1) #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_PWM (1) #define MICROPY_PY_MACHINE_PWM_DUTY_U16_NS (1) diff --git a/ports/rp2/mphalport.h b/ports/rp2/mphalport.h index 40633dcf2c..458d9a9a16 100644 --- a/ports/rp2/mphalport.h +++ b/ports/rp2/mphalport.h @@ -28,6 +28,10 @@ #include "py/mpconfig.h" #include "py/ringbuf.h" #include "pico/time.h" +#include "hardware/clocks.h" +#include "hardware/structs/systick.h" + +#define SYSTICK_MAX (0xffffff) extern int mp_interrupt_char; extern ringbuf_t stdin_ringbuf; @@ -59,6 +63,10 @@ static inline mp_uint_t mp_hal_ticks_cpu(void) { return time_us_32(); } +static inline mp_uint_t mp_hal_get_cpu_freq(void) { + return clock_get_hz(clk_sys); +} + // C-level pin HAL #include "py/obj.h" @@ -110,4 +118,12 @@ static inline void mp_hal_pin_od_high(mp_hal_pin_obj_t pin) { gpio_set_dir(pin, GPIO_IN); } +static inline void mp_hal_pin_low(mp_hal_pin_obj_t pin) { + gpio_clr_mask(1 << pin); +} + +static inline void mp_hal_pin_high(mp_hal_pin_obj_t pin) { + gpio_set_mask(1 << pin); +} + #endif // MICROPY_INCLUDED_RP2_MPHALPORT_H From 5ed7a748f0f767cdec9da95c289b934adaaecf67 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 17 Sep 2021 09:18:44 +0200 Subject: [PATCH 151/335] rp2/boards: Add neopixel.py to manifest.py. Because machine.bitstream is now implemented on the rp2 port. --- ports/rp2/boards/manifest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/rp2/boards/manifest.py b/ports/rp2/boards/manifest.py index 9df589f126..a45bbe0661 100644 --- a/ports/rp2/boards/manifest.py +++ b/ports/rp2/boards/manifest.py @@ -1,3 +1,4 @@ freeze("$(PORT_DIR)/modules") freeze("$(MPY_DIR)/drivers/onewire") include("$(MPY_DIR)/extmod/uasyncio/manifest.py") +include("$(MPY_DIR)/drivers/neopixel/manifest.py") From d11ff0499fe52cfc9443aa6c0cb1620fd3dd1e70 Mon Sep 17 00:00:00 2001 From: Henk Vergonet Date: Tue, 7 Aug 2018 13:14:00 +0200 Subject: [PATCH 152/335] unix/modos: Add support for uos.urandom(n). Use getrandom function if available, otherwise read from /dev/urandom. Signed-off-by: Henk.Vergonet@gmail.com --- ports/unix/modos.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/ports/unix/modos.c b/ports/unix/modos.c index 5e719c5736..24e5c95b18 100644 --- a/ports/unix/modos.c +++ b/ports/unix/modos.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -49,6 +50,29 @@ #define USE_STATFS 1 #endif +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +#if __GLIBC_PREREQ(2, 25) +#include +#define _HAVE_GETRANDOM +#endif +#endif + +STATIC mp_obj_t mod_os_urandom(mp_obj_t num) { + mp_int_t n = mp_obj_get_int(num); + vstr_t vstr; + vstr_init_len(&vstr, n); + #ifdef _HAVE_GETRANDOM + RAISE_ERRNO(getrandom(vstr.buf, n, 0), errno); + #else + int fd = open("/dev/urandom", O_RDONLY); + RAISE_ERRNO(fd, errno); + RAISE_ERRNO(read(fd, vstr.buf, n), errno); + close(fd); + #endif + return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_urandom_obj, mod_os_urandom); + STATIC mp_obj_t mod_os_stat(mp_obj_t path_in) { struct stat sb; const char *path = mp_obj_str_get_str(path_in); @@ -309,6 +333,7 @@ STATIC const mp_rom_map_elem_t mp_module_os_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) }, { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mod_os_errno_obj) }, { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mod_os_stat_obj) }, + { MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&mod_os_urandom_obj) }, #if MICROPY_PY_OS_STATVFS { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mod_os_statvfs_obj) }, #endif From 5cf71b55960651fc506df0ac41490f12dd1d63fd Mon Sep 17 00:00:00 2001 From: Alexey 'alexxy' Shvetsov Date: Fri, 15 May 2020 23:26:08 +0300 Subject: [PATCH 153/335] shared/libc/string0: Don't include string.h, and provide __memcpy_chk. Some toolchains will have string.h defining various macros which can lead to compile errors for string function implementations. Not including string.h fixes this. An implementation of __memcpy_chk is provided for toolchains that enable _FORTIFY_SOURCE. Fixes issue #6046. Signed-off-by: Alexey 'alexxy' Shvetsov --- shared/libc/string0.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/shared/libc/string0.c b/shared/libc/string0.c index 19ad14d0f7..a3b268e441 100644 --- a/shared/libc/string0.c +++ b/shared/libc/string0.c @@ -25,7 +25,7 @@ */ #include -#include +#include #define likely(x) __builtin_expect((x), 1) @@ -64,6 +64,13 @@ void *memcpy(void *dst, const void *src, size_t n) { return dst; } +void *__memcpy_chk(void *dest, const void *src, size_t len, size_t slen) { + if (len > slen) { + return NULL; + } + return memcpy(dest, src, len); +} + void *memmove(void *dest, const void *src, size_t n) { if (src < dest && (uint8_t*)dest < (const uint8_t*)src + n) { // need to copy backwards From 43d08688c398184013bbfb0190e2529e4032e003 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 17 Nov 2021 13:45:42 +1100 Subject: [PATCH 154/335] extmod/uasyncio: Fix gather returning exceptions from a cancelled task. Fixes issue #5882. --- extmod/uasyncio/funcs.py | 2 +- tests/extmod/uasyncio_gather.py | 10 ++++++++-- tests/extmod/uasyncio_gather.py.exp | 3 +++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/extmod/uasyncio/funcs.py b/extmod/uasyncio/funcs.py index 93f4fd256c..0ce48b015c 100644 --- a/extmod/uasyncio/funcs.py +++ b/extmod/uasyncio/funcs.py @@ -66,7 +66,7 @@ async def gather(*aws, return_exceptions=False): # # cancel all waiting tasks # raise er ts[i] = await ts[i] - except Exception as er: + except (core.CancelledError, Exception) as er: if return_exceptions: ts[i] = er else: diff --git a/tests/extmod/uasyncio_gather.py b/tests/extmod/uasyncio_gather.py index 0e2948b07c..6053873dbc 100644 --- a/tests/extmod/uasyncio_gather.py +++ b/tests/extmod/uasyncio_gather.py @@ -22,8 +22,9 @@ async def factorial(name, number): async def task(id): print("start", id) - await asyncio.sleep(0.2) + await asyncio.sleep(0.02) print("end", id) + return id async def gather_task(): @@ -36,12 +37,17 @@ async def main(): # Simple gather with return values print(await asyncio.gather(factorial("A", 2), factorial("B", 3), factorial("C", 4))) + # Test return_exceptions, where one task is cancelled and the other finishes normally + tasks = [asyncio.create_task(task(1)), asyncio.create_task(task(2))] + tasks[0].cancel() + print(await asyncio.gather(*tasks, return_exceptions=True)) + # Cancel a multi gather # TODO doesn't work, Task should not forward cancellation from gather to sub-task # but rather CancelledError should cancel the gather directly, which will then cancel # all sub-tasks explicitly # t = asyncio.create_task(gather_task()) - # await asyncio.sleep(0.1) + # await asyncio.sleep(0.01) # t.cancel() # await asyncio.sleep(0.01) diff --git a/tests/extmod/uasyncio_gather.py.exp b/tests/extmod/uasyncio_gather.py.exp index a37578d7eb..95310bbe1c 100644 --- a/tests/extmod/uasyncio_gather.py.exp +++ b/tests/extmod/uasyncio_gather.py.exp @@ -8,3 +8,6 @@ Task B: factorial(3) = 6 Task C: Compute factorial(4)... Task C: factorial(4) = 24 [2, 6, 24] +start 2 +end 2 +[CancelledError(), 2] From 19f09414a624914b29188b23f9d0da7d4b04e358 Mon Sep 17 00:00:00 2001 From: "jc_.kim" Date: Mon, 13 Jul 2020 19:22:58 +0900 Subject: [PATCH 155/335] tests/micropython/const.py: Add comment about required config for test. Expected result of const.py will be matched only when MICROPY_COMP_CONST is enabled. For easy understanding, added description at the first of the test code. --- tests/micropython/const.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/micropython/const.py b/tests/micropython/const.py index 1faf22be9a..1c805a45f9 100644 --- a/tests/micropython/const.py +++ b/tests/micropython/const.py @@ -1,4 +1,5 @@ # test constant optimisation +# This test will only work when MICROPY_COMP_CONST is enabled. from micropython import const From 95ccd9a005c09c58d7a74af97e990c798cb5c4f7 Mon Sep 17 00:00:00 2001 From: Pooya Moradi Date: Fri, 4 Dec 2020 16:01:19 +0330 Subject: [PATCH 156/335] nrf/Makefile: Improve Black Magic Probe commands. Used batch mode to get rid of the confirmation prompt on flashing. Used 'compare-sections' to verify flash. Removed the unnecessary `quit` at the end. --- ports/nrf/Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index a8a5228270..423323a9c6 100644 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -430,19 +430,19 @@ else ifeq ($(FLASHER), bmp) BMP_PORT ?= /dev/ttyACM0 deploy: $(BUILD)/$(OUTPUT_FILENAME).elf - $(Q)$(GDB) \ + $(Q)$(GDB) -nx --batch \ -ex 'target extended-remote $(BMP_PORT)' \ -ex 'monitor tpwr enable' \ -ex 'monitor swdp_scan' \ -ex 'attach 1' \ -ex 'set mem inaccessible-by-default off' \ -ex 'load' \ + -ex 'compare-sections' \ -ex 'kill' \ - -ex 'quit' \ $< sd: $(BUILD)/$(OUTPUT_FILENAME).elf - $(Q)$(GDB) \ + $(Q)$(GDB) -nx --batch \ -ex 'target extended-remote $(BMP_PORT)' \ -ex 'monitor tpwr enable' \ -ex 'monitor swdp_scan' \ @@ -450,10 +450,11 @@ sd: $(BUILD)/$(OUTPUT_FILENAME).elf -ex 'set mem inaccessible-by-default off' \ -ex 'monitor erase_mass' \ -ex 'load' \ + -ex 'compare-sections' \ -ex 'file $(SOFTDEV_HEX)' \ -ex 'load' \ + -ex 'compare-sections' \ -ex 'kill' \ - -ex 'quit' \ $< else ifeq ($(FLASHER), openocd) From 8f3510799d9ad5c2c19189a7a1dd1051d0d46c30 Mon Sep 17 00:00:00 2001 From: Sebastian Wicki Date: Sat, 14 Nov 2020 20:39:26 +0100 Subject: [PATCH 157/335] docs/library/framebuf.rst: Adjust dimensions in example. This commit swaps the dimensions of the `framebuffer.FrameBuffer` in the docs example from 10x100 to 100x10 pixels to avoid clipping. This is done to better fit the subsequent example code, which writes text of size 96x8 followed by a 96x1 horizontal line. The y coordinate of the horizontal line is also adjusted such that it is drawn inside of the new canvas bounds. --- docs/library/framebuf.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/library/framebuf.rst b/docs/library/framebuf.rst index 13502cc7ae..098ada8153 100644 --- a/docs/library/framebuf.rst +++ b/docs/library/framebuf.rst @@ -19,11 +19,11 @@ For example:: import framebuf # FrameBuffer needs 2 bytes for every RGB565 pixel - fbuf = framebuf.FrameBuffer(bytearray(10 * 100 * 2), 10, 100, framebuf.RGB565) + fbuf = framebuf.FrameBuffer(bytearray(100 * 10 * 2), 100, 10, framebuf.RGB565) fbuf.fill(0) fbuf.text('MicroPython!', 0, 0, 0xffff) - fbuf.hline(0, 10, 96, 0xffff) + fbuf.hline(0, 9, 96, 0xffff) Constructors ------------ From a4c0f52714ed176587cb43f98ea7f3b2264c600e Mon Sep 17 00:00:00 2001 From: Matt van de Werken Date: Thu, 2 Jul 2020 17:36:27 +1000 Subject: [PATCH 158/335] stm32/led: Support an extra 2 LEDs in board configuration. Although the pyboard has only 4 LEDs, there are some boards that (may) have more. This commit adds 2 more LEDs to the led.c file that if defined in the board-specific config file will be compiled in. --- ports/stm32/led.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/ports/stm32/led.c b/ports/stm32/led.c index adcb240cc0..078327462a 100644 --- a/ports/stm32/led.c +++ b/ports/stm32/led.c @@ -58,6 +58,12 @@ STATIC const pyb_led_obj_t pyb_led_obj[] = { {{&pyb_led_type}, 3, MICROPY_HW_LED3}, #if defined(MICROPY_HW_LED4) {{&pyb_led_type}, 4, MICROPY_HW_LED4}, + #if defined(MICROPY_HW_LED5) + {{&pyb_led_type}, 5, MICROPY_HW_LED5}, + #if defined(MICROPY_HW_LED6) + {{&pyb_led_type}, 6, MICROPY_HW_LED6}, + #endif + #endif #endif #endif #endif @@ -77,7 +83,9 @@ void led_init(void) { #if defined(MICROPY_HW_LED1_PWM) \ || defined(MICROPY_HW_LED2_PWM) \ || defined(MICROPY_HW_LED3_PWM) \ - || defined(MICROPY_HW_LED4_PWM) + || defined(MICROPY_HW_LED4_PWM) \ + || defined(MICROPY_HW_LED5_PWM) \ + || defined(MICROPY_HW_LED6_PWM) // The following is semi-generic code to control LEDs using PWM. // It currently supports TIM1, TIM2 and TIM3, channels 1-4. @@ -98,6 +106,12 @@ void led_init(void) { #ifndef MICROPY_HW_LED4_PWM #define MICROPY_HW_LED4_PWM { NULL, 0, 0, 0 } #endif +#ifndef MICROPY_HW_LED5_PWM +#define MICROPY_HW_LED5_PWM { NULL, 0, 0, 0 } +#endif +#ifndef MICROPY_HW_LED6_PWM +#define MICROPY_HW_LED6_PWM { NULL, 0, 0, 0 } +#endif #define LED_PWM_TIM_PERIOD (10000) // TIM runs at 1MHz and fires every 10ms @@ -116,6 +130,8 @@ STATIC const led_pwm_config_t led_pwm_config[] = { MICROPY_HW_LED2_PWM, MICROPY_HW_LED3_PWM, MICROPY_HW_LED4_PWM, + MICROPY_HW_LED5_PWM, + MICROPY_HW_LED6_PWM, }; STATIC uint8_t led_pwm_state = 0; From e5f9e2febc6e5f5f0a884a8036e0afb002680bc1 Mon Sep 17 00:00:00 2001 From: retsyo Date: Fri, 19 Feb 2021 18:53:09 +0800 Subject: [PATCH 159/335] windows/mpconfigport.h: Enable help and help("modules"). Following a similar change to the unix port in 6430cd3e02d4ec4a8fc949754b434f745b1973e6 --- ports/windows/mpconfigport.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ports/windows/mpconfigport.h b/ports/windows/mpconfigport.h index 4a8a902597..8dd95e769d 100644 --- a/ports/windows/mpconfigport.h +++ b/ports/windows/mpconfigport.h @@ -76,6 +76,8 @@ #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) #define MICROPY_PY_BUILTINS_INPUT (1) #define MICROPY_PY_BUILTINS_POW3 (1) +#define MICROPY_PY_BUILTINS_HELP (1) +#define MICROPY_PY_BUILTINS_HELP_MODULES (1) #define MICROPY_PY_BUILTINS_ROUND_INT (1) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define MICROPY_PY_ALL_SPECIAL_METHODS (1) From 1e5875557a8b7deeddfb96a9f9383b0d37dabee2 Mon Sep 17 00:00:00 2001 From: stijn Date: Mon, 27 Sep 2021 11:05:07 +0200 Subject: [PATCH 160/335] extmod/uplatform: Remove unused definitions. --- extmod/moduplatform.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/extmod/moduplatform.c b/extmod/moduplatform.c index 149df7c56f..67be2265a7 100644 --- a/extmod/moduplatform.c +++ b/extmod/moduplatform.c @@ -99,14 +99,6 @@ #define PLATFORM_SYSTEM "MicroPython" #endif -#ifndef MICROPY_HW_BOARD_NAME -#define MICROPY_HW_BOARD_NAME PLATFORM_ARCH -#endif - -#ifndef MICROPY_HW_MCU_NAME -#define MICROPY_HW_MCU_NAME "" -#endif - #ifndef MICROPY_HAL_VERSION #define MICROPY_HAL_VERSION "" #endif From 5900257dd675c198f424b9078071cb21ba258a83 Mon Sep 17 00:00:00 2001 From: stijn Date: Mon, 27 Sep 2021 11:17:15 +0200 Subject: [PATCH 161/335] extmod/uplatform: Use generic custom platform string. Don't force the 'HAL' string to be part of the platform string because it doesn't have a sensible meaning for all possible platforms, and swap it with the PLATFORM_ARCH string so the strings which most platforms have come first. --- extmod/moduplatform.c | 8 ++++---- ports/stm32/mphalport.h | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/extmod/moduplatform.c b/extmod/moduplatform.c index 67be2265a7..8f678d770c 100644 --- a/extmod/moduplatform.c +++ b/extmod/moduplatform.c @@ -99,12 +99,12 @@ #define PLATFORM_SYSTEM "MicroPython" #endif -#ifndef MICROPY_HAL_VERSION -#define MICROPY_HAL_VERSION "" +#ifndef MICROPY_PLATFORM_VERSION +#define MICROPY_PLATFORM_VERSION "" #endif -STATIC const MP_DEFINE_STR_OBJ(info_platform_obj, PLATFORM_SYSTEM "-" MICROPY_VERSION_STRING "-HAL" \ - MICROPY_HAL_VERSION "-" PLATFORM_ARCH "-with-" PLATFORM_LIBC_LIB "" PLATFORM_LIBC_VER); +STATIC const MP_DEFINE_STR_OBJ(info_platform_obj, PLATFORM_SYSTEM "-" MICROPY_VERSION_STRING "-" \ + PLATFORM_ARCH "-" MICROPY_PLATFORM_VERSION "-with-" PLATFORM_LIBC_LIB "" PLATFORM_LIBC_VER); STATIC const MP_DEFINE_STR_OBJ(info_python_compiler_obj, PLATFORM_COMPILER); STATIC const MP_DEFINE_STR_OBJ(info_libc_lib_obj, PLATFORM_LIBC_LIB); STATIC const MP_DEFINE_STR_OBJ(info_libc_ver_obj, PLATFORM_LIBC_VER); diff --git a/ports/stm32/mphalport.h b/ports/stm32/mphalport.h index edb8d8f64b..450e7098a6 100644 --- a/ports/stm32/mphalport.h +++ b/ports/stm32/mphalport.h @@ -4,19 +4,19 @@ // F0-1.9.0+F4-1.16.0+F7-1.7.0+H7-1.6.0+L0-1.11.2+L4-1.8.1+WB-1.10.0 #if defined(STM32F0) -#define MICROPY_HAL_VERSION "1.9.0" +#define MICROPY_PLATFORM_VERSION "HAL1.9.0" #elif defined(STM32F4) -#define MICROPY_HAL_VERSION "1.16.0" +#define MICROPY_PLATFORM_VERSION "HAL1.16.0" #elif defined(STM32F7) -#define MICROPY_HAL_VERSION "1.7.0" +#define MICROPY_PLATFORM_VERSION "HAL1.7.0" #elif defined(STM32H7) -#define MICROPY_HAL_VERSION "1.6.0" +#define MICROPY_PLATFORM_VERSION "HAL1.6.0" #elif defined(STM32L0) -#define MICROPY_HAL_VERSION "1.11.2" +#define MICROPY_PLATFORM_VERSION "HAL1.11.2" #elif defined(STM32L4) -#define MICROPY_HAL_VERSION "1.8.1" +#define MICROPY_PLATFORM_VERSION "HAL1.8.1" #elif defined(STM32WB) -#define MICROPY_HAL_VERSION "1.10.0" +#define MICROPY_PLATFORM_VERSION "HAL1.10.0" #endif extern const unsigned char mp_hal_status_to_errno_table[4]; From f27be2d78ab389bff4331cf60d4697c23beb57f6 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 18 Nov 2021 12:43:29 +1100 Subject: [PATCH 162/335] lib/asf4: Point submodule to latest commit on circuitpython branch. --- .gitmodules | 1 + lib/asf4 | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 474ae9890b..a92757df2c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -23,6 +23,7 @@ [submodule "lib/asf4"] path = lib/asf4 url = https://github.com/adafruit/asf4 + branch = circuitpython [submodule "lib/tinyusb"] path = lib/tinyusb url = https://github.com/hathach/tinyusb diff --git a/lib/asf4 b/lib/asf4 index d270f79aa1..84f56af132 160000 --- a/lib/asf4 +++ b/lib/asf4 @@ -1 +1 @@ -Subproject commit d270f79aa16dd8fd4ae3b6c14544283dcb992e9c +Subproject commit 84f56af13292d8f32c40acbd949bde698ddd4507 From cd2223b8fe5b242304016f2e160eca59a7cb81f9 Mon Sep 17 00:00:00 2001 From: Peter van der Burg Date: Thu, 20 May 2021 18:30:08 +1000 Subject: [PATCH 163/335] samd: Integrate latest asf4, add help, more time funcs and uPy features. - Makefile: update to use new ASF4 files, support frozen manifest, and include source files in upcoming commits - boards/manifest.py: add files to freeze - boards/samd51p19a.ld: add linker script for this MCU - help.c: add custom help text - main.c: execute _boot.py, boot.py and main.py on start-up - modules/_boot.py: startup file to freeze - modutime.c: add gmtime, localtime, mktime, time functions - mpconfigport.h: enabled more features for sys and io and modules - mphalport.h: add mp_hal_pin_xxx macros - mphalport.c: add mp_hal_stdio_poll --- ports/samd/Makefile | 48 +++++++++++++++++++++++++-- ports/samd/boards/manifest.py | 1 + ports/samd/boards/samd51p19a.ld | 17 ++++++++++ ports/samd/help.c | 42 +++++++++++++++++++++++ ports/samd/main.c | 11 ++++++ ports/samd/modules/_boot.py | 17 ++++++++++ ports/samd/modutime.c | 54 ++++++++++++++++++++++++++++++ ports/samd/mpconfigport.h | 34 +++++++++++++++++++ ports/samd/mphalport.c | 9 +++++ ports/samd/mphalport.h | 59 +++++++++++++++++++++++++++++++-- 10 files changed, 287 insertions(+), 5 deletions(-) create mode 100644 ports/samd/boards/manifest.py create mode 100644 ports/samd/boards/samd51p19a.ld create mode 100644 ports/samd/help.c create mode 100644 ports/samd/modules/_boot.py diff --git a/ports/samd/Makefile b/ports/samd/Makefile index a84fc3b12d..8476eea4b8 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -16,6 +16,10 @@ include $(BOARD_DIR)/mpconfigboard.mk QSTR_DEFS = qstrdefsport.h QSTR_GLOBAL_DEPENDENCIES = $(BOARD_DIR)/mpconfigboard.h +MCU_SERIES_LOWER = $(shell echo $(MCU_SERIES) | tr '[:upper:]' '[:lower:]') + +FROZEN_MANIFEST ?= boards/manifest.py + # Include py core make definitions include $(TOP)/py/py.mk @@ -26,14 +30,25 @@ INC += -I$(TOP) INC += -I$(BUILD) INC += -I$(BOARD_DIR) INC += -I$(TOP)/lib/cmsis/inc -INC += -I$(TOP)/lib/asf4/$(shell echo $(MCU_SERIES) | tr '[:upper:]' '[:lower:]')/include +INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/hal/include +INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/hal/utils/include +INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/config +INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/hri +INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/hpl/core +INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/hpl/gclk +INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/hpl/pm +INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/hpl/port +INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/hpl/rtc +INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/hpl/tc +INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/include +INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/include/pio INC += -I$(TOP)/lib/tinyusb/src CFLAGS_MCU_SAMD21 = -mtune=cortex-m0plus -mcpu=cortex-m0plus -msoft-float CFLAGS_MCU_SAMD51 = -mtune=cortex-m4 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard CFLAGS = $(INC) -Wall -Werror -std=c99 -nostdlib -mthumb $(CFLAGS_MCU_$(MCU_SERIES)) -fsingle-precision-constant -Wdouble-promotion CFLAGS += -DMCU_$(MCU_SERIES) -D__$(CMSIS_MCU)__ -CFLAGS += $(CFLAGS_MOD) +CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA) LDFLAGS = -nostdlib $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref LDFLAGS += $(LDFLAGS_MOD) @@ -59,12 +74,22 @@ endif SRC_C = \ main.c \ + help.c \ + moduos.c \ modutime.c \ modmachine.c \ + $(BOARD_DIR)/pins.c \ + machine_pin.c \ + machine_led.c \ + modsamd.c \ + samd_flash.c \ mphalport.c \ samd_isr.c \ samd_soc.c \ tusb_port.c \ + lib/asf4/$(MCU_SERIES_LOWER)/hal/src/hal_atomic.c \ + lib/asf4/$(MCU_SERIES_LOWER)/hal/src/hal_flash.c \ + lib/asf4/$(MCU_SERIES_LOWER)/hpl/nvmctrl/hpl_nvmctrl.c \ lib/libm/ef_sqrt.c \ lib/libm/fmodf.c \ lib/libm/math.c \ @@ -81,6 +106,8 @@ SRC_C = \ shared/runtime/gchelper_native.c \ shared/runtime/pyexec.c \ shared/runtime/stdout_helpers.c \ + shared/runtime/sys_stdio_mphal.c \ + shared/timeutils/timeutils.c \ SRC_C += $(SRC_MOD) @@ -93,12 +120,27 @@ SRC_S = shared/runtime/gchelper_m3.s endif # List of sources for qstr extraction -SRC_QSTR += modutime.c modmachine.c $(SRC_MOD) $(SRC_CXX) +SRC_QSTR += moduos.c \ + modutime.c \ + modmachine.c \ + machine_pin.c \ + machine_led.c \ + modsamd.c \ + samd_flash.c \ + +SRC_QSTR += $(SRC_MOD) $(SRC_CXX) OBJ += $(PY_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) + +ifneq ($(FROZEN_MANIFEST),) +CFLAGS += -DMICROPY_MODULE_FROZEN_MPY +CFLAGS += -DMICROPY_MODULE_FROZEN_STR +CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool +endif # Workaround for bug in older gcc, warning on "static usbd_device_t _usbd_dev = { 0 };" $(BUILD)/lib/tinyusb/src/device/usbd.o: CFLAGS += -Wno-missing-braces diff --git a/ports/samd/boards/manifest.py b/ports/samd/boards/manifest.py new file mode 100644 index 0000000000..c80309cf67 --- /dev/null +++ b/ports/samd/boards/manifest.py @@ -0,0 +1 @@ +freeze("$(PORT_DIR)/modules") diff --git a/ports/samd/boards/samd51p19a.ld b/ports/samd/boards/samd51p19a.ld new file mode 100644 index 0000000000..e0baa9bba0 --- /dev/null +++ b/ports/samd/boards/samd51p19a.ld @@ -0,0 +1,17 @@ +/* + GNU linker script for SAMD51 +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00004000, LENGTH = 512K - 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K +} + +/* Top end of the stack, with room for double-tap variable */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; +_sstack = _estack - 16K; + +_sheap = _ebss; +_eheap = _sstack; diff --git a/ports/samd/help.c b/ports/samd/help.c new file mode 100644 index 0000000000..577d153b53 --- /dev/null +++ b/ports/samd/help.c @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2016 Damien P. George + * + * 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/builtin.h" + +const char samd_help_text[] = + "Welcome to MicroPython!\n" + "\n" + "For online docs please visit http://docs.micropython.org/en/latest/samd/ .\n" + "\n" + "Control commands:\n" + " CTRL-A -- on a blank line, enter raw REPL mode\n" + " CTRL-B -- on a blank line, enter normal REPL mode\n" + " CTRL-C -- interrupt a running program\n" + " CTRL-D -- on a blank line, do a soft reset of the board\n" + " CTRL-E -- on a blank line, enter paste mode\n" + "\n" + "For further help on a specific object, type help('obj')\n" +; diff --git a/ports/samd/main.c b/ports/samd/main.c index 5d84a9e882..a08e66fda0 100644 --- a/ports/samd/main.c +++ b/ports/samd/main.c @@ -45,6 +45,13 @@ void samd_main(void) { mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); + // Execute _boot.py to set up the filesystem. + pyexec_frozen_module("_boot.py"); + + // Execute user scripts. + pyexec_file_if_exists("boot.py"); + pyexec_file_if_exists("main.py"); + for (;;) { if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { if (pyexec_raw_repl() != 0) { @@ -69,10 +76,13 @@ void gc_collect(void) { gc_collect_end(); } +/* mp_lexer_t *mp_lexer_new_from_file(const char *filename) { mp_raise_OSError(MP_ENOENT); } +*/ +#if !MICROPY_VFS mp_import_stat_t mp_import_stat(const char *path) { return MP_IMPORT_STAT_NO_EXIST; } @@ -81,6 +91,7 @@ mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open); +#endif void nlr_jump_fail(void *val) { for (;;) { diff --git a/ports/samd/modules/_boot.py b/ports/samd/modules/_boot.py new file mode 100644 index 0000000000..84b02480b7 --- /dev/null +++ b/ports/samd/modules/_boot.py @@ -0,0 +1,17 @@ +import gc +import uos +import samd + +samd.Flash.flash_init() +bdev = samd.Flash() + +# Try to mount the filesystem, and format the flash if it doesn't exist. +try: + vfs = uos.VfsLfs1(bdev) +except: + uos.VfsLfs1.mkfs(bdev) + vfs = uos.VfsLfs1(bdev) +uos.mount(vfs, "/") + +gc.collect() +del uos, vfs, gc diff --git a/ports/samd/modutime.c b/ports/samd/modutime.c index 8d6a405944..2d5ed0776d 100644 --- a/ports/samd/modutime.c +++ b/ports/samd/modutime.c @@ -24,11 +24,64 @@ * THE SOFTWARE. */ +#include "py/runtime.h" #include "extmod/utime_mphal.h" +#include "shared/timeutils/timeutils.h" + +// localtime([secs]) +STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { + timeutils_struct_time_t tm; + mp_int_t seconds; + if (n_args == 0 || args[0] == mp_const_none) { + // seconds = pyb_rtc_get_us_since_epoch() / 1000 / 1000; + seconds = mp_obj_get_int(args[0]); + } else { + seconds = mp_obj_get_int(args[0]); + } + timeutils_seconds_since_epoch_to_struct_time(seconds, &tm); + mp_obj_t tuple[8] = { + tuple[0] = mp_obj_new_int(tm.tm_year), + tuple[1] = mp_obj_new_int(tm.tm_mon), + tuple[2] = mp_obj_new_int(tm.tm_mday), + tuple[3] = mp_obj_new_int(tm.tm_hour), + tuple[4] = mp_obj_new_int(tm.tm_min), + tuple[5] = mp_obj_new_int(tm.tm_sec), + tuple[6] = mp_obj_new_int(tm.tm_wday), + tuple[7] = mp_obj_new_int(tm.tm_yday), + }; + return mp_obj_new_tuple(8, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime); + +// mktime() +STATIC mp_obj_t time_mktime(mp_obj_t tuple) { + size_t len; + mp_obj_t *elem; + mp_obj_get_array(tuple, &len, &elem); + + // localtime generates a tuple of len 8. CPython uses 9, so we accept both. + if (len < 8 || len > 9) { + mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("mktime needs a tuple of length 8 or 9 (%d given)"), len); + } + + return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]), + mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]), + mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5]))); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime); + +// time() +STATIC mp_obj_t time_time(void) { + mp_raise_NotImplementedError("time"); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time); STATIC const mp_rom_map_elem_t time_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utime) }, + { MP_ROM_QSTR(MP_QSTR_gmtime), MP_ROM_PTR(&time_localtime_obj) }, + { MP_ROM_QSTR(MP_QSTR_localtime), MP_ROM_PTR(&time_localtime_obj) }, + { MP_ROM_QSTR(MP_QSTR_mktime), MP_ROM_PTR(&time_mktime_obj) }, { MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mp_utime_sleep_obj) }, { MP_ROM_QSTR(MP_QSTR_sleep_ms), MP_ROM_PTR(&mp_utime_sleep_ms_obj) }, { MP_ROM_QSTR(MP_QSTR_sleep_us), MP_ROM_PTR(&mp_utime_sleep_us_obj) }, @@ -37,6 +90,7 @@ STATIC const mp_rom_map_elem_t time_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) }, + { MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&time_time_obj) }, }; STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table); diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 852d9e9ee5..645f16b3f7 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -48,7 +48,12 @@ #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) #define MICROPY_CPYTHON_COMPAT (0) #define MICROPY_CAN_OVERRIDE_BUILTINS (1) +#define MICROPY_PY_BUILTINS_HELP (1) +#define MICROPY_PY_BUILTINS_HELP_TEXT samd_help_text +#define MICROPY_PY_BUILTINS_HELP_MODULES (1) +// fixes sys/usys import issue +#define MICROPY_MODULE_WEAK_LINKS (1) // Control over Python builtins #define MICROPY_PY_ASYNC_AWAIT (0) #define MICROPY_PY_BUILTINS_STR_COUNT (0) @@ -59,17 +64,44 @@ #define MICROPY_PY_BUILTINS_ENUMERATE (0) #define MICROPY_PY_BUILTINS_FILTER (0) #define MICROPY_PY_BUILTINS_REVERSED (0) +#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) #define MICROPY_PY_BUILTINS_MIN_MAX (0) #define MICROPY_PY___FILE__ (0) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) #define MICROPY_PY_ATTRTUPLE (0) #define MICROPY_PY_COLLECTIONS (0) +#define MICROPY_PY_SYS (1) +#define MICROPY_PY_SYS_PLATFORM "samd" +#define MICROPY_PY_SYS_EXIT (1) +#define MICROPY_PY_SYS_STDFILES (1) #define MICROPY_PY_SYS_MAXSIZE (1) +#define MICROPY_PY_IO_FILEIO (1) +#define MICROPY_PY_IO (1) +#define MICROPY_PY_IO_IOBASE (1) // Extended modules #define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_PY_MACHINE (1) +#define MICROPY_PY_UOS (1) +#define MICROPY_READER_VFS (1) +#define MICROPY_VFS (1) +#define MICROPY_PY_UJSON (1) +#define MICROPY_PY_URE (1) +#define MICROPY_PY_UBINASCII (1) +#define MICROPY_PY_UCTYPES (1) +#define MICROPY_PY_UHEAPQ (1) +#define MICROPY_PY_URANDOM (1) +#define MICROPY_PY_UZLIB (1) +#define MICROPY_PY_UASYNCIO (1) + +// Use VfsLfs's types for fileio/textio +#define mp_type_fileio mp_type_vfs_lfs1_fileio +#define mp_type_textio mp_type_vfs_lfs1_textio + +// Use VFS's functions for import stat and builtin open +#define mp_import_stat mp_vfs_import_stat +#define mp_builtin_open_obj mp_vfs_open_obj // Hooks to add builtins @@ -77,10 +109,12 @@ { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) }, extern const struct _mp_obj_module_t mp_module_machine; +extern const struct _mp_obj_module_t mp_module_samd; extern const struct _mp_obj_module_t mp_module_utime; #define MICROPY_PORT_BUILTIN_MODULES \ { MP_ROM_QSTR(MP_QSTR_machine), MP_ROM_PTR(&mp_module_machine) }, \ + { MP_ROM_QSTR(MP_QSTR_samd), MP_ROM_PTR(&mp_module_samd) }, \ { MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_utime) }, \ #define MICROPY_PORT_ROOT_POINTERS \ diff --git a/ports/samd/mphalport.c b/ports/samd/mphalport.c index a87b7d2125..c19d542a85 100644 --- a/ports/samd/mphalport.c +++ b/ports/samd/mphalport.c @@ -26,6 +26,7 @@ #include "py/runtime.h" #include "py/mphal.h" +#include "py/stream.h" #include "samd_soc.h" #include "tusb.h" @@ -60,6 +61,14 @@ void mp_hal_delay_us(mp_uint_t us) { } } +uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) { + uintptr_t ret = 0; + if (tud_cdc_connected() && tud_cdc_available()) { + ret |= MP_STREAM_POLL_RD; + } + return ret; +} + int mp_hal_stdin_rx_chr(void) { for (;;) { if (USARTx->USART.INTFLAG.bit.RXC) { diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h index fc7dbe94cb..2bbde4390e 100644 --- a/ports/samd/mphalport.h +++ b/ports/samd/mphalport.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2019 Damien P. George + * Copyright (c) 2019-2021 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,8 +26,14 @@ #ifndef MICROPY_INCLUDED_SAMD_MPHALPORT_H #define MICROPY_INCLUDED_SAMD_MPHALPORT_H -#include +#include "py/mpconfig.h" +#include "py/ringbuf.h" +// ASF4 +#include "hal_gpio.h" + +extern int mp_interrupt_char; +extern ringbuf_t stdin_ringbuf; extern volatile uint32_t systick_ms; void mp_hal_set_interrupt_char(int c); @@ -42,4 +48,53 @@ static inline mp_uint_t mp_hal_ticks_cpu(void) { return 0; } +// C-level pin HAL + +#include "py/obj.h" + +#define MP_HAL_PIN_FMT "%u" +#define mp_hal_pin_obj_t uint + +extern uint32_t machine_pin_open_drain_mask; + +mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t pin_in); + +static inline unsigned int mp_hal_pin_name(mp_hal_pin_obj_t pin) { + return pin; +} + +static inline void mp_hal_pin_input(mp_hal_pin_obj_t pin) { + gpio_set_pin_direction(pin, GPIO_DIRECTION_IN); + machine_pin_open_drain_mask &= ~(1 << pin); +} + +static inline void mp_hal_pin_output(mp_hal_pin_obj_t pin) { + gpio_set_pin_direction(pin, GPIO_DIRECTION_OUT); + machine_pin_open_drain_mask &= ~(1 << pin); +} + +static inline void mp_hal_pin_open_drain(mp_hal_pin_obj_t pin) { + gpio_set_pin_direction(pin, GPIO_DIRECTION_IN); + gpio_set_pin_level(pin, 0); + machine_pin_open_drain_mask |= 1 << pin; +} + +static inline int mp_hal_pin_read(mp_hal_pin_obj_t pin) { + return gpio_get_pin_level(pin); +} + +static inline void mp_hal_pin_write(mp_hal_pin_obj_t pin, int v) { + gpio_set_pin_level(pin, v); +} + +/* +static inline void mp_hal_pin_od_low(mp_hal_pin_obj_t pin) { + gpio_set_pin_direction(pin, GPIO_DIRECTION_OUT); +} + +static inline void mp_hal_pin_od_high(mp_hal_pin_obj_t pin) { + gpio_set_pin_direction(pin, GPIO_DIRECTION_IN); +} +*/ + #endif // MICROPY_INCLUDED_SAMD_MPHALPORT_H From 4c132614e136970cbd12d927bc6c52e2a7f0f070 Mon Sep 17 00:00:00 2001 From: Peter van der Burg Date: Fri, 21 May 2021 10:02:01 +1000 Subject: [PATCH 164/335] samd/samd_soc: Allow a board to configure the low-level MCU config. The board specific #defines will be moved to individual boards. --- ports/samd/samd_soc.c | 95 ++++++++++++++++++++++++------------------- ports/samd/samd_soc.h | 12 ------ 2 files changed, 53 insertions(+), 54 deletions(-) diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c index a08d0de269..7f4df1bb1c 100644 --- a/ports/samd/samd_soc.c +++ b/ports/samd/samd_soc.c @@ -1,6 +1,12 @@ /* * This file is part of the MicroPython project, http://micropython.org/ * + * This file initialises the USB (tinyUSB) and USART (SERCOM). Board USART settings + * are set in 'boards//mpconfigboard.h. + * + * IMPORTANT: Please refer to "I/O Multiplexing and Considerations" chapters + * in device datasheets for I/O Pin functions and assignments. + * * The MIT License (MIT) * * Copyright (c) 2019 Damien P. George @@ -24,56 +30,53 @@ * THE SOFTWARE. */ +#include "py/runtime.h" +#include "modmachine.h" #include "samd_soc.h" #include "tusb.h" -static void uart0_init(void) { +// "MP" macros defined in "boards/$(BOARD)/mpconfigboard.h" +mp_obj_t machine_uart_init(void) { + // Firstly, assign alternate function SERCOM PADs to GPIO pins. + PORT->Group[MP_PIN_GRP].PINCFG[MP_TX_PIN].bit.PMUXEN = 1; // Enable + PORT->Group[MP_PIN_GRP].PINCFG[MP_RX_PIN].bit.PMUXEN = 1; // Enable + PORT->Group[MP_PIN_GRP].PMUX[MP_PERIPHERAL_MUX].reg = MP_PORT_FUNC; // Sets PMUXE & PMUXO in 1 hit. + uint32_t rxpo = MP_RXPO_PAD; // 1=Pad1,3=Pad3 Rx data + uint32_t txpo = MP_TXPO_PAD; // 0=pad0,1=Pad2 Tx data + + // Initialise the clocks #if defined(MCU_SAMD21) - - // SERCOM0, TX=PA06=PAD2, RX=PA07=PAD3, ALT-D - PORT->Group[0].PMUX[3].reg = 0x33; - PORT->Group[0].PINCFG[6].reg = 1; - PORT->Group[0].PINCFG[7].reg = 1; - - PM->APBCMASK.bit.SERCOM0_ = 1; - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_SERCOM0_CORE; + PM->APBCMASK.bit.MP_SERCOMx = 1; // Enable synchronous clock + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | MP_SERCOM_GCLK_ID_x_CORE; // Select multiplexer generic clock source and enable. + // Wait while it updates synchronously. while (GCLK->STATUS.bit.SYNCBUSY) { } - - uint32_t rxpo = 3; - uint32_t txpo = 1; - #elif defined(MCU_SAMD51) - - // SERCOM3, TX=PA17=PAD0, RX=PA16=PAD1, ALT-D - PORT->Group[0].PMUX[8].reg = 0x33; - PORT->Group[0].PINCFG[16].reg = 1; - PORT->Group[0].PINCFG[17].reg = 1; - - // Use Generator 0 which is already enabled and switched to DFLL @ 48MHz - GCLK->PCHCTRL[SERCOM3_GCLK_ID_CORE].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK0; - MCLK->APBBMASK.bit.SERCOM3_ = 1; - - uint32_t rxpo = 1; - uint32_t txpo = 2; - + GCLK->PCHCTRL[MP_SERCOM_GCLK_ID_x_CORE].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK0; + MCLK->APBBMASK.bit.MP_SERCOMx = 1; #endif + // Setup the Peripheral. + // Reset (clear) the peripheral registers. while (USARTx->USART.SYNCBUSY.bit.SWRST) { } - USARTx->USART.CTRLA.bit.SWRST = 1; + USARTx->USART.CTRLA.bit.SWRST = 1; // Reset all Registers, disable peripheral while (USARTx->USART.SYNCBUSY.bit.SWRST) { } - USARTx->USART.CTRLA.reg = - SERCOM_USART_CTRLA_DORD - | SERCOM_USART_CTRLA_RXPO(rxpo) - | SERCOM_USART_CTRLA_TXPO(txpo) - | SERCOM_USART_CTRLA_MODE(1) + // Set the register bits as needed + // (CMODE (async),CHSIZE (8),FORM (no parity),SBMODE (1 stop) already 0). + USARTx->USART.CTRLA.reg = // USARTx = SERCOMx set in "boards/$(BOARD)/mpconfigboard.h" + SERCOM_USART_CTRLA_DORD // Data order + | SERCOM_USART_CTRLA_RXPO(rxpo) // Set Pad# + | SERCOM_USART_CTRLA_TXPO(txpo) // Set Pad# + | SERCOM_USART_CTRLA_MODE(1) // USART with internal clock ; - USARTx->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN; + USARTx->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN; // Enable Rx & Tx while (USARTx->USART.SYNCBUSY.bit.CTRLB) { } + + // Baud rate is clock dependant. #if CPU_FREQ == 8000000 uint32_t baud = 50437; // 115200 baud; 65536*(1 - 16 * 115200/8e6) #elif CPU_FREQ == 48000000 @@ -81,12 +84,26 @@ static void uart0_init(void) { #elif CPU_FREQ == 120000000 uint32_t baud = 64529; // 115200 baud; 65536*(1 - 16 * 115200/120e6) #endif - USARTx->USART.BAUD.bit.BAUD = baud; - USARTx->USART.CTRLA.bit.ENABLE = 1; + USARTx->USART.BAUD.bit.BAUD = baud; // Set Baud + USARTx->USART.CTRLA.bit.ENABLE = 1; // Enable the peripheral + // Wait for the Registers to update. while (USARTx->USART.SYNCBUSY.bit.ENABLE) { } + + return mp_const_none; } +// Disconnect SERCOM from GPIO pins. (Can't SWRST, as that will totally kill USART). +mp_obj_t machine_uart_deinit(void) { + // Reset + printf("Disabling the Alt-Funct, releasing the USART pins for GPIO... \n"); + PORT->Group[MP_PIN_GRP].PINCFG[MP_TX_PIN].bit.PMUXEN = 0; // Disable + PORT->Group[MP_PIN_GRP].PINCFG[MP_RX_PIN].bit.PMUXEN = 0; // Disable + + return mp_const_none; +} + + static void usb_init(void) { // Init USB clock #if defined(MCU_SAMD21) @@ -142,21 +159,15 @@ void samd_init(void) { while (GCLK->STATUS.bit.SYNCBUSY) { } - // Configure PA10 as output for LED - PORT->Group[0].DIRSET.reg = 1 << 10; - #elif defined(MCU_SAMD51) GCLK->GENCTRL[1].reg = 1 << GCLK_GENCTRL_DIV_Pos | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; while (GCLK->SYNCBUSY.bit.GENCTRL1) { } - // Configure PA22 as output for LED - PORT->Group[0].DIRSET.reg = 1 << 22; - #endif SysTick_Config(CPU_FREQ / 1000); - uart0_init(); + machine_uart_init(); usb_init(); } diff --git a/ports/samd/samd_soc.h b/ports/samd/samd_soc.h index 5f68610e4d..a07e68dbed 100644 --- a/ports/samd/samd_soc.h +++ b/ports/samd/samd_soc.h @@ -29,18 +29,6 @@ #include #include "sam.h" -#if defined(MCU_SAMD21) - -#define CPU_FREQ (48000000) -#define USARTx SERCOM0 - -#elif defined(MCU_SAMD51) - -#define CPU_FREQ (48000000) -#define USARTx SERCOM3 - -#endif - void samd_init(void); void samd_main(void); From 2121353602a5f8b5c8a2b8604e7de25a96d1b327 Mon Sep 17 00:00:00 2001 From: Peter van der Burg Date: Thu, 20 May 2021 18:05:04 +1000 Subject: [PATCH 165/335] samd: Add internal flash block device, filesystem and uos support. --- ports/samd/modsamd.c | 41 +++++++++ ports/samd/moduos.c | 75 ++++++++++++++++ ports/samd/samd_flash.c | 189 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 305 insertions(+) create mode 100644 ports/samd/modsamd.c create mode 100644 ports/samd/moduos.c create mode 100644 ports/samd/samd_flash.c diff --git a/ports/samd/modsamd.c b/ports/samd/modsamd.c new file mode 100644 index 0000000000..1f91498080 --- /dev/null +++ b/ports/samd/modsamd.c @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * + * 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/runtime.h" +#include "samd_soc.h" + +extern const mp_obj_type_t samd_flash_type; + +STATIC const mp_rom_map_elem_t samd_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_samd) }, + { MP_ROM_QSTR(MP_QSTR_Flash), MP_ROM_PTR(&samd_flash_type) }, +}; +STATIC MP_DEFINE_CONST_DICT(samd_module_globals, samd_module_globals_table); + +const mp_obj_module_t mp_module_samd = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&samd_module_globals, +}; diff --git a/ports/samd/moduos.c b/ports/samd/moduos.c new file mode 100644 index 0000000000..b884d5e7b5 --- /dev/null +++ b/ports/samd/moduos.c @@ -0,0 +1,75 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * 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/runtime.h" +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" +#include "extmod/vfs_lfs.h" + +STATIC const mp_rom_map_elem_t os_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) }, + + #if MICROPY_VFS + { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) }, + { MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) }, + { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mp_vfs_rename_obj) }, + { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) }, + { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) }, + #endif + + // The following are MicroPython extensions. + + #if MICROPY_PY_OS_DUPTERM + { MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mp_uos_dupterm_obj) }, + #endif + + #if MICROPY_VFS + { MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&mp_vfs_ilistdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) }, + { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) }, + #if MICROPY_VFS_FAT + { MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) }, + #endif + #if MICROPY_VFS_LFS1 + { MP_ROM_QSTR(MP_QSTR_VfsLfs1), MP_ROM_PTR(&mp_type_vfs_lfs1) }, + #endif + #if MICROPY_VFS_LFS2 + { MP_ROM_QSTR(MP_QSTR_VfsLfs2), MP_ROM_PTR(&mp_type_vfs_lfs2) }, + #endif + #endif +}; +STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table); + +const mp_obj_module_t mp_module_uos = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&os_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_uos, mp_module_uos, MICROPY_PY_UOS); diff --git a/ports/samd/samd_flash.c b/ports/samd/samd_flash.c new file mode 100644 index 0000000000..3bccf5577e --- /dev/null +++ b/ports/samd/samd_flash.c @@ -0,0 +1,189 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * + * 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 + +#include "py/runtime.h" +#include "extmod/vfs.h" +#include "samd_soc.h" +#include "hal_flash.h" + +// ASF 4 +#include "hal_flash.h" +#include "hal_init.h" +#include "hpl_gclk_base.h" + +#if defined(MCU_SAMD21) +#include "lib/asf4/samd21/hpl/pm/hpl_pm_base.h" +#elif defined(MCU_SAMD51) +#include "lib/asf4/samd51/hpl/pm/hpl_pm_base.h" +#include "lib/asf4/samd51/hri/hri_mclk_d51.h" +#endif + +static struct flash_descriptor flash_desc; +STATIC mp_int_t BLOCK_SIZE = VFS_BLOCK_SIZE_BYTES; // Board specific: mpconfigboard.h +extern const mp_obj_type_t samd_flash_type; + +typedef struct _samd_flash_obj_t { + mp_obj_base_t base; + uint32_t flash_base; + uint32_t flash_size; +} samd_flash_obj_t; + +// Build a Flash storage at top. +STATIC samd_flash_obj_t samd_flash_obj = { + .base = { &samd_flash_type }, + .flash_base = MICROPY_HW_FLASH_STORAGE_BASE, // Board specific: mpconfigboard.h + .flash_size = MICROPY_HW_FLASH_STORAGE_BYTES, // Board specific: mpconfigboard.h +}; + +// FLASH stuff +STATIC mp_obj_t samd_flash_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + // No args required. bdev=Flash(). Start Addr & Size defined in samd_flash_obj. + mp_arg_check_num(n_args, n_kw, 0,0, false); + + // Return singleton object. + return MP_OBJ_FROM_PTR(&samd_flash_obj); +} + +// Flash init (from cctpy) +// Method is needed for when MP starts up in _boot.py +STATIC mp_obj_t samd_flash_init(void) { + #ifdef SAMD51 + hri_mclk_set_AHBMASK_NVMCTRL_bit(MCLK); + #endif + #ifdef SAMD21 + _pm_enable_bus_clock(PM_BUS_APBB, NVMCTRL); + #endif + + flash_init(&flash_desc, NVMCTRL); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(samd_flash_init_obj, samd_flash_init); + +// Function for ioctl. +STATIC mp_obj_t eraseblock(uint32_t sector_in) { + // Destination address aligned with page start to be erased. + uint32_t DEST_ADDR = sector_in; // Number of pages to be erased. + mp_int_t PAGE_SIZE = flash_get_page_size(&flash_desc); // adf4 API call + + flash_erase(&flash_desc,DEST_ADDR,(BLOCK_SIZE / PAGE_SIZE)); + + return mp_const_none; +} + +STATIC mp_obj_t samd_flash_version(void) { + printf("Flash Driver Version: %lu\n", flash_get_version()); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(samd_flash_version_obj, samd_flash_version); +STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(samd_flash_version_static_obj, MP_ROM_PTR(&samd_flash_version_obj)); + +STATIC mp_obj_t samd_flash_size(void) { + // ASF4 API calls + mp_int_t PAGES = flash_get_total_pages(&flash_desc); + mp_int_t PAGE_SIZE = flash_get_page_size(&flash_desc); + printf("Flash Size: %u Bytes\n", PAGES * PAGE_SIZE); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(samd_flash_size_obj, samd_flash_size); +STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(samd_flash_size_static_obj, MP_ROM_PTR(&samd_flash_size_obj)); + +STATIC mp_obj_t samd_flash_readblocks(size_t n_args, const mp_obj_t *args) { + uint32_t offset = (mp_obj_get_int(args[1]) * BLOCK_SIZE) + samd_flash_obj.flash_base; + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_WRITE); + if (n_args == 4) { + offset += mp_obj_get_int(args[3]); + } + + // Read data to flash (adf4 API) + flash_read(&flash_desc,offset,bufinfo.buf,bufinfo.len); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(samd_flash_readblocks_obj, 3, 4, samd_flash_readblocks); + +STATIC mp_obj_t samd_flash_writeblocks(size_t n_args, const mp_obj_t *args) { + uint32_t offset = (mp_obj_get_int(args[1]) * BLOCK_SIZE) + samd_flash_obj.flash_base; + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ); + if (n_args == 3) { + eraseblock(offset); + // TODO check return value + } else { + offset += mp_obj_get_int(args[3]); + } + // Write data to flash (adf4 API) + flash_write(&flash_desc,offset, bufinfo.buf, bufinfo.len); + // TODO check return value + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(samd_flash_writeblocks_obj, 3, 4, samd_flash_writeblocks); + +STATIC mp_obj_t samd_flash_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t arg_in) { + samd_flash_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_int_t cmd = mp_obj_get_int(cmd_in); + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_INIT: + samd_flash_init(); + return MP_OBJ_NEW_SMALL_INT(0); + case MP_BLOCKDEV_IOCTL_DEINIT: + return MP_OBJ_NEW_SMALL_INT(0); + case MP_BLOCKDEV_IOCTL_SYNC: + return MP_OBJ_NEW_SMALL_INT(0); + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + return MP_OBJ_NEW_SMALL_INT(self->flash_size / BLOCK_SIZE); + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + return MP_OBJ_NEW_SMALL_INT(BLOCK_SIZE); + case MP_BLOCKDEV_IOCTL_BLOCK_ERASE: { + eraseblock(mp_obj_get_int(arg_in) * BLOCK_SIZE + samd_flash_obj.flash_base); + // TODO check return value + return MP_OBJ_NEW_SMALL_INT(0); + } + default: + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(samd_flash_ioctl_obj, samd_flash_ioctl); + +STATIC const mp_rom_map_elem_t samd_flash_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_flash_version), MP_ROM_PTR(&samd_flash_version_static_obj) }, + { MP_ROM_QSTR(MP_QSTR_flash_size), MP_ROM_PTR(&samd_flash_size_static_obj) }, + { MP_ROM_QSTR(MP_QSTR_flash_init), MP_ROM_PTR(&samd_flash_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&samd_flash_readblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&samd_flash_writeblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&samd_flash_ioctl_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(samd_flash_locals_dict, samd_flash_locals_dict_table); + +const mp_obj_type_t samd_flash_type = { + { &mp_type_type }, + .name = MP_QSTR_Flash, + .make_new = samd_flash_make_new, + .locals_dict = (mp_obj_dict_t *)&samd_flash_locals_dict, +}; From 2f65ded1a2edaff0a125f3e1a5f288baebceed64 Mon Sep 17 00:00:00 2001 From: Peter van der Burg Date: Thu, 20 May 2021 18:15:36 +1000 Subject: [PATCH 166/335] samd: Add Pin and LED classes, and machine.unique_id. --- ports/samd/machine_led.c | 172 ++++++++++++++++++++ ports/samd/machine_pin.c | 334 +++++++++++++++++++++++++++++++++++++++ ports/samd/modmachine.c | 58 +++++++ ports/samd/modmachine.h | 37 +++++ 4 files changed, 601 insertions(+) create mode 100644 ports/samd/machine_led.c create mode 100644 ports/samd/machine_pin.c create mode 100644 ports/samd/modmachine.h diff --git a/ports/samd/machine_led.c b/ports/samd/machine_led.c new file mode 100644 index 0000000000..f4dd1aeb3c --- /dev/null +++ b/ports/samd/machine_led.c @@ -0,0 +1,172 @@ +/* + * This is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016-2021 Damien P. George + * + * 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. + * + * Uses pins.h & pins.c to create board (MCU package) specific 'machine_led_obj' array. + */ + +#include "py/runtime.h" +#include "py/mphal.h" +#include "extmod/virtpin.h" +#include "modmachine.h" +#include "pins.h" // boards// + +// ASF4 (MCU package specific pin defs in 'boards') +#include "hal_gpio.h" +#include "hpl_gpio.h" +#include "hal_atomic.h" + +STATIC void machine_led_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_led_obj_t *self = self_in; + mp_printf(print, "LED(%u)", self->id); +} + +// LED.init(mode, *, value=None) +STATIC mp_obj_t machine_led_obj_init_helper(const machine_led_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_mode, ARG_value }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + }; + + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // set initial value (do this before configuring mode/pull) + if (args[ARG_value].u_obj != mp_const_none) { + gpio_set_pin_level(self->id, mp_obj_is_true(args[ARG_value].u_obj)); + } + + // configure mode + gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); + + return mp_const_none; +} + +// constructor(id, ...) +mp_obj_t mp_led_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + + // get the wanted LED object + int wanted_led = mp_obj_get_int(args[0]); + const machine_led_obj_t *self = NULL; + if (0 <= wanted_led && wanted_led < MP_ARRAY_SIZE(machine_led_obj)) { + self = (machine_led_obj_t *)&machine_led_obj[wanted_led]; + } + + // the array could be padded with 'nulls' (see other Ports). + // Will also error if the asked for LED (index) is greater than the array row size. + if (self == NULL || self->base.type == NULL) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid LED")); + } + + if (n_args > 1 || n_kw > 0) { + // mode given, so configure this GPIO + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + machine_led_obj_init_helper(self, n_args - 1, args + 1, &kw_args); + } + + return MP_OBJ_FROM_PTR(self); +} + +// fast method for getting/setting pin value +STATIC mp_obj_t machine_led_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 0, 1, false); + machine_led_obj_t *self = self_in; + if (n_args == 0) { + // get pin + return MP_OBJ_NEW_SMALL_INT(gpio_get_pin_level(self->id)); + } else { + // set pin + bool value = mp_obj_is_true(args[0]); + gpio_set_pin_level(self->id, value); + + return mp_const_none; + } +} + +// pin.init(mode) +STATIC mp_obj_t machine_led_obj_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + return machine_led_obj_init_helper(args[0], n_args - 1, args + 1, kw_args); +} +MP_DEFINE_CONST_FUN_OBJ_KW(machine_led_init_obj, 1, machine_led_obj_init); + +// pin.value([value]) +STATIC mp_obj_t machine_led_value(size_t n_args, const mp_obj_t *args) { + return machine_led_call(args[0], n_args - 1, 0, args + 1); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_led_value_obj, 1, 2, machine_led_value); + +// pin.low() +STATIC mp_obj_t machine_led_low(mp_obj_t self_in) { + machine_led_obj_t *self = MP_OBJ_TO_PTR(self_in); + gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); + gpio_set_pin_level(self->id, false); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_led_low_obj, machine_led_low); + +// pin.high() +STATIC mp_obj_t machine_led_high(mp_obj_t self_in) { + machine_led_obj_t *self = MP_OBJ_TO_PTR(self_in); + gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); + gpio_set_pin_level(self->id, true); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_led_high_obj, machine_led_high); + +// pin.toggle() +STATIC mp_obj_t machine_led_toggle(mp_obj_t self_in) { + machine_led_obj_t *self = MP_OBJ_TO_PTR(self_in); + gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); + gpio_toggle_pin_level(self->id); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_led_toggle_obj, machine_led_toggle); + +STATIC const mp_rom_map_elem_t machine_led_locals_dict_table[] = { + // instance methods + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_led_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&machine_led_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_low), MP_ROM_PTR(&machine_led_low_obj) }, + { MP_ROM_QSTR(MP_QSTR_high), MP_ROM_PTR(&machine_led_high_obj) }, + { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_led_low_obj) }, + { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&machine_led_high_obj) }, + { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&machine_led_toggle_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(machine_led_locals_dict, machine_led_locals_dict_table); + +const mp_obj_type_t machine_led_type = { + { &mp_type_type }, + .name = MP_QSTR_LED, + .print = machine_led_print, + .make_new = mp_led_make_new, + .call = machine_led_call, + .locals_dict = (mp_obj_t)&machine_led_locals_dict, +}; diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c new file mode 100644 index 0000000000..161a3ccddd --- /dev/null +++ b/ports/samd/machine_pin.c @@ -0,0 +1,334 @@ +/* + * This is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016-2021 Damien P. George + * + * 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. + * + * Uses pins.h & pins.c to create board (MCU package) specific 'machine_pin_obj' array. + */ + +#include "py/runtime.h" +#include "py/mphal.h" +#include "extmod/virtpin.h" +#include "modmachine.h" +#include "samd_soc.h" +#include "pins.h" // boards// + +// ASF4 (MCU package specific pin defs in 'boards') +#include "hal_gpio.h" +#include "hpl_gpio.h" +#include "hal_atomic.h" + +#define GPIO_MODE_IN (0) +#define GPIO_MODE_OUT (1) +// #define GPIO_MODE_ALT (3) + +#define GPIO_STRENGTH_2MA (0) +#define GPIO_STRENGTH_8MA (1) + +// asf4 hpl_gpio.h gpio_pull_mode + +/* +typedef struct _machine_pin_irq_obj_t { + mp_irq_obj_t base; + uint32_t flags; + uint32_t trigger; +} machine_pin_irq_obj_t; + +STATIC const mp_irq_methods_t machine_pin_irq_methods; +*/ + +STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_pin_obj_t *self = self_in; + mp_printf(print, "Pin(%u)", self->id); +} + +STATIC void pin_validate_drive(bool strength) { + if (strength != GPIO_STRENGTH_2MA && strength != GPIO_STRENGTH_8MA) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value")); + } +} + +// Pin.init(mode, pull=None, *, value=None, drive=0). No 'alt' yet. +STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_mode, ARG_pull, ARG_value, ARG_drive, ARG_alt }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, + { MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, + { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, + { MP_QSTR_drive, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = GPIO_STRENGTH_2MA} }, + }; + + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // set initial value (do this before configuring mode/pull) + if (args[ARG_value].u_obj != mp_const_none) { + gpio_set_pin_level(self->id, mp_obj_is_true(args[ARG_value].u_obj)); + } + + // configure mode + if (args[ARG_mode].u_obj != mp_const_none) { + mp_int_t mode = mp_obj_get_int(args[ARG_mode].u_obj); + if (mode == GPIO_MODE_IN) { + gpio_set_pin_direction(self->id, GPIO_DIRECTION_IN); + } else if (mode == GPIO_MODE_OUT) { + gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); + } else { + gpio_set_pin_direction(self->id, GPIO_DIRECTION_IN); // If no args are given, the Pin is 'input'. + } + } + // configure pull. Only to be used with IN mode. The function sets the pin to INPUT. + uint32_t pull = 0; + mp_int_t mode = mp_obj_get_int(args[ARG_mode].u_obj); + if (mode == GPIO_MODE_OUT && args[ARG_pull].u_obj != mp_const_none) { + mp_raise_ValueError(MP_ERROR_TEXT("OUT incompatible with pull")); + } else if (args[ARG_pull].u_obj != mp_const_none) { + pull = mp_obj_get_int(args[ARG_pull].u_obj); + gpio_set_pin_pull_mode(self->id, pull); // hal_gpio.h + } + + // get the strength + bool strength = args[3].u_int; + pin_validate_drive(strength); + + return mp_const_none; +} + +// constructor(id, ...) +mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + + // get the wanted pin object + int wanted_pin = mp_obj_get_int(args[0]); + + const machine_pin_obj_t *self = NULL; + if (0 <= wanted_pin && wanted_pin < MP_ARRAY_SIZE(machine_pin_obj)) { + self = (machine_pin_obj_t *)&machine_pin_obj[wanted_pin]; + } + + if (self == NULL || self->base.type == NULL) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid pin")); + } + self = (machine_pin_obj_t *)&machine_pin_obj[wanted_pin]; + + if (n_args > 1 || n_kw > 0) { + // pin mode given, so configure this GPIO + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + machine_pin_obj_init_helper(self, n_args - 1, args + 1, &kw_args); + } + + return MP_OBJ_FROM_PTR(self); +} + +// fast method for getting/setting pin value +STATIC mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 0, 1, false); + machine_pin_obj_t *self = self_in; + if (n_args == 0) { + // get pin + return MP_OBJ_NEW_SMALL_INT(gpio_get_pin_level(self->id)); + } else { + // set pin + bool value = mp_obj_is_true(args[0]); + gpio_set_pin_level(self->id, value); + + return mp_const_none; + } +} + +// Pin.init(mode, pull) +STATIC mp_obj_t machine_pin_obj_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + return machine_pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args); +} +MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_init_obj, 1, machine_pin_obj_init); + +// Pin.value([value]) +STATIC mp_obj_t machine_pin_value(size_t n_args, const mp_obj_t *args) { + return machine_pin_call(args[0], n_args - 1, 0, args + 1); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_value_obj, 1, 2, machine_pin_value); + +// Pin.disable(pin) +STATIC mp_obj_t machine_pin_disable(mp_obj_t self_in) { + machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); + gpio_set_pin_direction(self->id, GPIO_DIRECTION_OFF); // Disables the pin (low power state) + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_disable_obj, machine_pin_disable); + +// Pin.low() Totem-pole (push-pull) +STATIC mp_obj_t machine_pin_low(mp_obj_t self_in) { + machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); + gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); + gpio_set_pin_level(self->id, false); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_low_obj, machine_pin_low); + +// Pin.high() Totem-pole (push-pull) +STATIC mp_obj_t machine_pin_high(mp_obj_t self_in) { + machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); + gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); + gpio_set_pin_level(self->id, true); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_high_obj, machine_pin_high); + +// Pin.toggle(). Only TOGGLE pins set as OUTPUT. +STATIC mp_obj_t machine_pin_toggle(mp_obj_t self_in) { + machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // Determine DIRECTION of PIN. + bool pin_dir; + + pin_dir = (PORT->Group[(enum gpio_port)GPIO_PORT(self->id)].DIR.reg // Get PORT# + & (1 << GPIO_PIN(self->id))) // Isolate the Pin in question + >> GPIO_PIN(self->id); // Shift to LSB for binary result. + + if (pin_dir) { + // Pin is OUTPUT + gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); + gpio_toggle_pin_level(self->id); + } else { + mp_raise_ValueError(MP_ERROR_TEXT("Cannot TOGGLE INPUT pin!\n")); + } + return mp_const_true; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_toggle_obj, machine_pin_toggle); + +// Pin.drive(). Normal (0) is 2mA, High (1) allows 8mA. +STATIC mp_obj_t machine_pin_drive(size_t n_args, const mp_obj_t *args) { + machine_pin_obj_t *self = args[0]; // Pin + if (n_args == 1) { + return mp_const_none; + } else { + bool strength = mp_obj_get_int(args[1]); // 0 or 1 + pin_validate_drive(strength); + // Set the DRVSTR bit (ASF hri/hri_port_dxx.h + hri_port_write_PINCFG_DRVSTR_bit(PORT, + (enum gpio_port)GPIO_PORT(self->id), + GPIO_PIN(self->id), + strength); + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_drive_obj, 1, 2, machine_pin_drive); + +STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { + // instance methods + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_pin_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&machine_pin_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_low), MP_ROM_PTR(&machine_pin_low_obj) }, + { MP_ROM_QSTR(MP_QSTR_high), MP_ROM_PTR(&machine_pin_high_obj) }, + { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_low_obj) }, + { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&machine_pin_high_obj) }, + { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&machine_pin_toggle_obj) }, + { MP_ROM_QSTR(MP_QSTR_disable), MP_ROM_PTR(&machine_pin_disable_obj) }, + { MP_ROM_QSTR(MP_QSTR_drive), MP_ROM_PTR(&machine_pin_drive_obj) }, + + + // { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_pin_irq_obj) }, + + // class constants + { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(GPIO_MODE_IN) }, + { MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(GPIO_MODE_OUT) }, + // { MP_ROM_QSTR(MP_QSTR_ALT), MP_ROM_INT(GPIO_MODE_ALT) }, + { MP_ROM_QSTR(MP_QSTR_PULL_OFF), MP_ROM_INT(GPIO_PULL_OFF) }, + { MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(GPIO_PULL_UP) }, + { MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(GPIO_PULL_DOWN) }, + { MP_ROM_QSTR(MP_QSTR_LOW_POWER), MP_ROM_INT(GPIO_STRENGTH_2MA) }, + { MP_ROM_QSTR(MP_QSTR_HIGH_POWER), MP_ROM_INT(GPIO_STRENGTH_8MA) }, + // { MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(GPIO_IRQ_EDGE_RISE) }, + // { MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(GPIO_IRQ_EDGE_FALL) }, +}; +STATIC MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table); + +STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { + (void)errcode; + machine_pin_obj_t *self = self_in; + + switch (request) { + case MP_PIN_READ: { + return gpio_get_pin_level(self->id); + } + case MP_PIN_WRITE: { + gpio_set_pin_level(self->id, arg); + return 0; + } + } + return -1; +} + +STATIC const mp_pin_p_t pin_pin_p = { + .ioctl = pin_ioctl, +}; + +const mp_obj_type_t machine_pin_type = { + { &mp_type_type }, + .name = MP_QSTR_Pin, + .print = machine_pin_print, + .make_new = mp_pin_make_new, + .call = machine_pin_call, + .protocol = &pin_pin_p, + .locals_dict = (mp_obj_t)&machine_pin_locals_dict, +}; + +/* +STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { + machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); + machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_obj[self->id]); + gpio_set_irq_enabled(self->id, GPIO_IRQ_ALL, false); + irq->flags = 0; + irq->trigger = new_trigger; + gpio_set_irq_enabled(self->id, new_trigger, true); + return 0; +} + +STATIC mp_uint_t machine_pin_irq_info(mp_obj_t self_in, mp_uint_t info_type) { + machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); + machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_obj[self->id]); + if (info_type == MP_IRQ_INFO_FLAGS) { + return irq->flags; + } else if (info_type == MP_IRQ_INFO_TRIGGERS) { + return irq->trigger; + } + return 0; +} + +STATIC const mp_irq_methods_t machine_pin_irq_methods = { + .trigger = machine_pin_irq_trigger, + .info = machine_pin_irq_info, +}; +*/ + +mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t obj) { + if (!mp_obj_is_type(obj, &machine_pin_type)) { + mp_raise_ValueError(MP_ERROR_TEXT("expecting a Pin")); + } + machine_pin_obj_t *pin = MP_OBJ_TO_PTR(obj); + return pin->id; +} diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 207e4c71ca..0ebb5581cd 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -27,6 +27,13 @@ #include "py/runtime.h" #include "extmod/machine_mem.h" #include "samd_soc.h" +#include "modmachine.h" + +// ASF 4 +#include "hal_flash.h" +#include "hal_init.h" +#include "hpl_gclk_base.h" +#include "hpl_pm_base.h" #if defined(MCU_SAMD21) #define DBL_TAP_ADDR ((volatile uint32_t *)(0x20000000 + 32 * 1024 - 4)) @@ -36,6 +43,9 @@ #define DBL_TAP_MAGIC_LOADER 0xf01669ef #define DBL_TAP_MAGIC_RESET 0xf02669ef +MP_DEFINE_CONST_FUN_OBJ_0(machine_uart_init_obj, machine_uart_init); +MP_DEFINE_CONST_FUN_OBJ_0(machine_uart_deinit_obj, machine_uart_deinit); + STATIC mp_obj_t machine_reset(void) { *DBL_TAP_ADDR = DBL_TAP_MAGIC_RESET; NVIC_SystemReset(); @@ -55,6 +65,49 @@ STATIC mp_obj_t machine_freq(void) { } MP_DEFINE_CONST_FUN_OBJ_0(machine_freq_obj, machine_freq); +STATIC mp_obj_t machine_unique_id(void) { + // Each device has a unique 128-bit serial number which is a concatenation of four 32-bit + // words contained at the following addresses. The uniqueness of the serial number is + // guaranteed only when using all 128 bits. + // Atmel SAM D21E / SAM D21G / SAM D21J + // SMART ARM-Based Microcontroller + // DATASHEET + // 9.6 (SAMD51) or 9.3.3 (or 10.3.3 depending on which manual)(SAMD21) Serial Number + // + // EXAMPLE (SAMD21) + // ---------------- + // OpenOCD: + // Word0: + // > at91samd21g18.cpu mdw 0x0080A00C 1 + // 0x0080a00c: 6e27f15f + // Words 1-3: + // > at91samd21g18.cpu mdw 0x0080A040 3 + // 0x0080a040: 50534b54 332e3120 ff091645 + // + // MicroPython (this code and same order as shown in Arduino IDE) + // >>> ubinascii.hexlify(machine.unique_id()) + // b'6e27f15f50534b54332e3120ff091645' + + #if defined(MCU_SAMD21) + uint32_t *id_addresses[4] = {(uint32_t *)0x0080A00C, (uint32_t *)0x0080A040, + (uint32_t *)0x0080A044, (uint32_t *)0x0080A048}; + #elif defined(MCU_SAMD51) + uint32_t *id_addresses[4] = {(uint32_t *)0x008061FC, (uint32_t *)0x00806010, + (uint32_t *)0x00806014, (uint32_t *)0x00806018}; + #endif + uint8_t raw_id[16]; + + for (int i = 0; i < 4; i++) { + for (int k = 0; k < 4; k++) { + // 'Reverse' the read bytes into a 32 bit word (Consistent with Arduino) + raw_id[4 * i + k] = (*(id_addresses[i]) >> (24 - k * 8)) & 0xff; + } + } + + return mp_obj_new_bytes((byte *)&raw_id, sizeof(raw_id)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id); + STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) }, @@ -63,6 +116,11 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_mem8), MP_ROM_PTR(&machine_mem8_obj) }, { MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) }, { MP_ROM_QSTR(MP_QSTR_mem32), MP_ROM_PTR(&machine_mem32_obj) }, + { MP_ROM_QSTR(MP_QSTR_unique_id), MP_ROM_PTR(&machine_unique_id_obj) }, + { MP_ROM_QSTR(MP_QSTR_uart_init), MP_ROM_PTR(&machine_uart_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_uart_deinit), MP_ROM_PTR(&machine_uart_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&machine_led_type) }, }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h new file mode 100644 index 0000000000..61bd2f4d29 --- /dev/null +++ b/ports/samd/modmachine.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Damien P. George + * + * 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_SAMD_MODMACHINE_H +#define MICROPY_INCLUDED_SAMD_MODMACHINE_H + +#include "py/obj.h" + +extern const mp_obj_type_t machine_pin_type; +extern const mp_obj_type_t machine_led_type; + +mp_obj_t machine_uart_init(void); +mp_obj_t machine_uart_deinit(void); + +#endif // MICROPY_INCLUDED_SAMD_MODMACHINE_H From 72cb4ff596a2f6bda8c79aabfb2af646e70ad590 Mon Sep 17 00:00:00 2001 From: Peter van der Burg Date: Sat, 22 May 2021 16:52:36 +1000 Subject: [PATCH 167/335] samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS: Update for flash and pins. - mpconfigboard.h: flash and USART config - mpconfigboard.mk: enable LFS1 - pins.c: define pins and LEDs - pins.h: define structs and consts --- .../mpconfigboard.h | 26 +++++++++ .../mpconfigboard.mk | 4 ++ .../boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c | 58 +++++++++++++++++++ .../boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.h | 42 ++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c create mode 100644 ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.h diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h index cec9e9ccdd..ba384645db 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h @@ -1,2 +1,28 @@ #define MICROPY_HW_BOARD_NAME "Feather M0 Express" #define MICROPY_HW_MCU_NAME "SAMD21G18A" + +// MicroPython configs +// samd_flash.c flash parameters +// Build a 64k Flash storage at top. 256k-64k=196k +// 256*1024=262144 minus 64*1024=65536 = 196608 = 0x30000 +#define MICROPY_HW_FLASH_STORAGE_BASE (0x30000) +#define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) +#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; + +// ASF4 MCU package specific Pin definitions +#include "samd21g18a.h" + +// Please consult the SAM_D21 Datasheet, I/O Multiplexing and Considerations. +// On this board (see https://learn.adafruit.com/assets/40553) TX is D1 (PA10) and RX is D0 (PA11) +// USART pin assignments: Tx=PA10=SERCOM0/PAD[2], Rx=PA11==SERCOM0/PAD[3] +#define CPU_FREQ (48000000) // For selecting Baud from clock. +#define MP_PIN_GRP 0 // A=0, B=1 +#define MP_TX_PIN 10 //'n' +#define MP_RX_PIN 11 +#define MP_PERIPHERAL_MUX 5 // 'n'th group of 2 pins +#define USARTx SERCOM0 // SERCOM0: tx/rx +#define MP_PORT_FUNC 0x22 // Sets PMUXE & PMUXO to the Alternative Function.(A-H=0-7) +#define MP_RXPO_PAD 3 // RXPO- Receive Data Pinout +#define MP_TXPO_PAD 1 // TXPO- Transmit Data Pinout +#define MP_SERCOMx SERCOM0_ // APBCMASK +#define MP_SERCOM_GCLK_ID_x_CORE GCLK_CLKCTRL_ID_SERCOM0_CORE // Generic Clock Control diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.mk b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.mk index 8696c966bc..a760cf047e 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.mk +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.mk @@ -2,3 +2,7 @@ MCU_SERIES = SAMD21 CMSIS_MCU = SAMD21G18A LD_FILES = boards/samd21x18a.ld sections.ld TEXT0 = 0x2000 + +# The ?='s allow overriding in mpconfigboard.mk. +# MicroPython settings +MICROPY_VFS_LFS1 ?= 1 diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c new file mode 100644 index 0000000000..e0dd752ec9 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c @@ -0,0 +1,58 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. + */ + +#include "modmachine.h" +#include "pins.h" + +// Ensure Declaration in 'pins.h' reflects # of Pins defined here. +const machine_pin_obj_t machine_pin_obj[] = { + {{&machine_pin_type}, PIN_PA11}, // D0 + {{&machine_pin_type}, PIN_PA10}, // D1 + {{&machine_pin_type}, PIN_PA14}, // D2 + {{&machine_pin_type}, PIN_PA09}, // D3/ + {{&machine_pin_type}, PIN_PA08}, // D4/ + {{&machine_pin_type}, PIN_PA15}, // D5 + {{&machine_pin_type}, PIN_PA20}, // D6 + {{&machine_pin_type}, PIN_PA21}, // D7 + {{&machine_pin_type}, PIN_PA06}, // D8/ + {{&machine_pin_type}, PIN_PA07}, // D9/ + {{&machine_pin_type}, PIN_PA18}, // D10 + {{&machine_pin_type}, PIN_PA16}, // D11 + {{&machine_pin_type}, PIN_PA19}, // D12 + {{&machine_pin_type}, PIN_PA17}, // D13/ + {{&machine_pin_type}, PIN_PA02}, // A0 + {{&machine_pin_type}, PIN_PB08}, // A1 + {{&machine_pin_type}, PIN_PB09}, // A2 + {{&machine_pin_type}, PIN_PA04}, // A3/ + {{&machine_pin_type}, PIN_PA05}, // A4/ + {{&machine_pin_type}, PIN_PB02}, // A5 +}; + +const machine_led_obj_t machine_led_obj[] = { + {{&machine_led_type}, PIN_PA17}, // D13/ user LED +}; diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.h b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.h new file mode 100644 index 0000000000..45bee61678 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin + * allocations. + */ + +typedef struct _machine_pin_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_pin_obj_t; + +typedef struct _machine_led_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_led_obj_t; + +// MUST explicitly hold array # of rows, else machine_pin.c wont compile. +extern const machine_pin_obj_t machine_pin_obj[20]; +extern const machine_led_obj_t machine_led_obj[1]; From 199b6a8a8b46255e22b5b144fe4aab02d7ff8f03 Mon Sep 17 00:00:00 2001 From: Peter van der Burg Date: Sat, 22 May 2021 11:44:21 +1000 Subject: [PATCH 168/335] samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS: Update for flash and pins. - mpconfigboard.h: flash and USART config - mpconfigboard.mk: enable LFS1 - pins.c: define pins and LEDs - pins.h: define structs and consts --- .../mpconfigboard.h | 25 ++++++++ .../mpconfigboard.mk | 4 ++ .../ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c | 58 +++++++++++++++++++ .../ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.h | 42 ++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c create mode 100644 ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.h diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h index 490704eadb..c1c4fd8cad 100644 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h @@ -5,3 +5,28 @@ #define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_PY_MATH (0) #define MICROPY_PY_CMATH (0) + +// MicroPython configs +// samd_flash.c flash parameters +// Build a 128k Flash storage at top. 512k-128k=384k=0x60000 +// 512*1024= 0x80000 minus 128*1024= 0x20000 = 0x60000 +#define MICROPY_HW_FLASH_STORAGE_BASE (0x60000) +#define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) +#define VFS_BLOCK_SIZE_BYTES (1536) // + +// ASF4 MCU package specific Pin definitions +#include "samd51g19a.h" + +// Please consult the SAM_D51 Datasheet, I/O Multiplexing and Considerations. +// USART pin assignments: Tx=TX_D1=PA17=SERCOM3/PAD[0], Rx=RX_D0=PA16=SERCOM3/PAD[1] +#define CPU_FREQ (48000000) // For selecting Baud from clock. +#define MP_PIN_GRP 1 // A-D=0-3 +#define MP_TX_PIN 17 +#define MP_RX_PIN 16 // 'n' +#define MP_PERIPHERAL_MUX 8 // 'n'th group of 2 pins +#define USARTx SERCOM3 // +#define MP_PORT_FUNC 0x33 // Sets PMUXE & PMUXO to the Alternative Function.A-N=0-13 +#define MP_RXPO_PAD 1 // RXPO- Receive Data Pinout +#define MP_TXPO_PAD 0 // TXPO- Tranmit Data Pinout +#define MP_SERCOMx SERCOM3_ // APBCMASK +#define MP_SERCOM_GCLK_ID_x_CORE SERCOM3_GCLK_ID_CORE diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.mk b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.mk index 2e5d7e68df..6b0192c77b 100644 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.mk +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.mk @@ -2,3 +2,7 @@ MCU_SERIES = SAMD51 CMSIS_MCU = SAMD51G19A LD_FILES = boards/samd51g19a.ld sections.ld TEXT0 = 0x4000 + +# The ?='s allow overriding in mpconfigboard.mk. +# MicroPython settings +MICROPY_VFS_LFS1 ?= 1 diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c new file mode 100644 index 0000000000..82948ccbc4 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c @@ -0,0 +1,58 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. + */ + +#include "modmachine.h" +#include "pins.h" + +// Ensure Declaration in 'pins.h' reflects # of Pins defined here. +const machine_pin_obj_t machine_pin_obj[] = { + {{&machine_pin_type}, PIN_PA16}, // RX_D0 + {{&machine_pin_type}, PIN_PA17}, // TX_D1 + {{&machine_pin_type}, PIN_PA07}, // D2 + {{&machine_pin_type}, PIN_PB22}, // D3 + {{&machine_pin_type}, PIN_PA14}, // D4 + {{&machine_pin_type}, PIN_PA15}, // D5 + {{NULL}, -1}, // D6- not terminated on breakout. + {{&machine_pin_type}, PIN_PA18}, // D7 + {{NULL}, -1}, // D8- not terminated on breakout. + {{&machine_pin_type}, PIN_PA19}, // D9 + {{&machine_pin_type}, PIN_PA20}, // D10 + {{&machine_pin_type}, PIN_PA21}, // D11 + {{&machine_pin_type}, PIN_PA23}, // D12 + {{&machine_pin_type}, PIN_PA22}, // D13 + {{&machine_pin_type}, PIN_PA02}, // A0 + {{&machine_pin_type}, PIN_PA05}, // A1 + {{&machine_pin_type}, PIN_PB08}, // A2 + {{&machine_pin_type}, PIN_PB09}, // A3 + {{&machine_pin_type}, PIN_PA04}, // A4 + {{&machine_pin_type}, PIN_PA06}, // A5 +}; + +const machine_led_obj_t machine_led_obj[] = { + {{&machine_led_type}, PIN_PA22}, // D13 +}; diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.h b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.h new file mode 100644 index 0000000000..45bee61678 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin + * allocations. + */ + +typedef struct _machine_pin_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_pin_obj_t; + +typedef struct _machine_led_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_led_obj_t; + +// MUST explicitly hold array # of rows, else machine_pin.c wont compile. +extern const machine_pin_obj_t machine_pin_obj[20]; +extern const machine_led_obj_t machine_led_obj[1]; From 3d33dbedc9d9f6df19e68461dc66cdff08ed01cc Mon Sep 17 00:00:00 2001 From: Peter van der Burg Date: Sat, 22 May 2021 17:04:04 +1000 Subject: [PATCH 169/335] samd/boards/MINISAM_M4: Update for flash and pins. - mpconfigboard.h: flash and USART config - mpconfigboard.mk: enable LFS1 - pins.c: define pins and LEDs - pins.h: define structs and consts --- ports/samd/boards/MINISAM_M4/mpconfigboard.h | 25 +++++++++ ports/samd/boards/MINISAM_M4/mpconfigboard.mk | 4 ++ ports/samd/boards/MINISAM_M4/pins.c | 51 +++++++++++++++++++ ports/samd/boards/MINISAM_M4/pins.h | 42 +++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 ports/samd/boards/MINISAM_M4/pins.c create mode 100644 ports/samd/boards/MINISAM_M4/pins.h diff --git a/ports/samd/boards/MINISAM_M4/mpconfigboard.h b/ports/samd/boards/MINISAM_M4/mpconfigboard.h index 0847a45bf1..a65eb54b49 100644 --- a/ports/samd/boards/MINISAM_M4/mpconfigboard.h +++ b/ports/samd/boards/MINISAM_M4/mpconfigboard.h @@ -5,3 +5,28 @@ #define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_PY_MATH (0) #define MICROPY_PY_CMATH (0) + +// MicroPython configs +// samd_flash.c flash parameters +// Build a 128k Flash storage at top. 512k-128k=384k=0x60000 +// 512*1024= 0x80000 minus 128*1024= 0x20000 = 0x60000 +#define MICROPY_HW_FLASH_STORAGE_BASE (0x60000) +#define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) +#define VFS_BLOCK_SIZE_BYTES (1536) // + +// ASF4 MCU package specific Pin definitions +#include "samd51g19a.h" + +// Please consult the SAM_D51 Datasheet, I/O Multiplexing and Considerations. +// USART pin assignments: Tx=TX_D1=PA17=SERCOM3/PAD[0], Rx=RX_D0=PA16=SERCOM3/PAD[1] +#define CPU_FREQ (48000000) // For selecting Baud from clock. +#define MP_PIN_GRP 0 // A-D=0-3 +#define MP_TX_PIN 17 +#define MP_RX_PIN 16 // 'n' +#define MP_PERIPHERAL_MUX 8 // 'n'th group of 2 pins +#define USARTx SERCOM3 // +#define MP_PORT_FUNC 0x33 // Sets PMUXE & PMUXO to the Alternative Function.A-N=0-13 +#define MP_RXPO_PAD 1 // RXPO- Receive Data Pinout +#define MP_TXPO_PAD 0 // TXPO- Tranmit Data Pinout +#define MP_SERCOMx SERCOM3_ // APBCMASK +#define MP_SERCOM_GCLK_ID_x_CORE SERCOM3_GCLK_ID_CORE diff --git a/ports/samd/boards/MINISAM_M4/mpconfigboard.mk b/ports/samd/boards/MINISAM_M4/mpconfigboard.mk index 54ed3273d5..6ed0ff552b 100644 --- a/ports/samd/boards/MINISAM_M4/mpconfigboard.mk +++ b/ports/samd/boards/MINISAM_M4/mpconfigboard.mk @@ -3,3 +3,7 @@ MCU_SERIES = SAMD51 CMSIS_MCU = SAMD51G19A LD_FILES = boards/samd51g19a.ld sections.ld TEXT0 = 0x4000 + +# The ?='s allow overriding in mpconfigboard.mk. +# MicroPython settings +MICROPY_VFS_LFS1 ?= 1 diff --git a/ports/samd/boards/MINISAM_M4/pins.c b/ports/samd/boards/MINISAM_M4/pins.c new file mode 100644 index 0000000000..6cdd840b6b --- /dev/null +++ b/ports/samd/boards/MINISAM_M4/pins.c @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. + */ + +#include "modmachine.h" +#include "pins.h" + +// Ensure Declaration in 'pins.h' reflects # of Pins defined here. +const machine_pin_obj_t machine_pin_obj[] = { + {{&machine_pin_type}, PIN_PA02}, // A0,D9 + {{&machine_pin_type}, PIN_PB08}, // A1,D10 + {{&machine_pin_type}, PIN_PB09}, // A2,D11 + {{&machine_pin_type}, PIN_PA04}, // A3,D12 + {{&machine_pin_type}, PIN_PA05}, // A4,D13 + {{&machine_pin_type}, PIN_PA06}, // A5 + {{&machine_pin_type}, PIN_PA16}, // RX_D0 + {{&machine_pin_type}, PIN_PA17}, // TX_D1 + {{&machine_pin_type}, PIN_PA07}, // D2,A6 + {{&machine_pin_type}, PIN_PA19}, // D3 + {{&machine_pin_type}, PIN_PA20}, // D4 + {{&machine_pin_type}, PIN_PA21}, // D5 + {{&machine_pin_type}, PIN_PA00}, // BUTTON +}; + +const machine_led_obj_t machine_led_obj[] = { + {{&machine_led_type}, PIN_PA15}, // LED +}; diff --git a/ports/samd/boards/MINISAM_M4/pins.h b/ports/samd/boards/MINISAM_M4/pins.h new file mode 100644 index 0000000000..892b0e7b97 --- /dev/null +++ b/ports/samd/boards/MINISAM_M4/pins.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin + * allocations. + */ + +typedef struct _machine_pin_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_pin_obj_t; + +typedef struct _machine_led_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_led_obj_t; + +// MUST explicitly hold array # of rows, else machine_pin.c wont compile. +extern const machine_pin_obj_t machine_pin_obj[13]; +extern const machine_led_obj_t machine_led_obj[1]; From fb79e586362227d75069e92c9965921c13c9aacf Mon Sep 17 00:00:00 2001 From: Peter van der Burg Date: Sat, 22 May 2021 16:57:53 +1000 Subject: [PATCH 170/335] samd/boards/ADAFRUIT_TRINKET_M0: Update for flash and pins. - mpconfigboard.h: flash and USART config - mpconfigboard.mk: enable LFS1 - pins.c: define pins and LEDs - pins.h: define structs and consts --- .../ADAFRUIT_TRINKET_M0/mpconfigboard.h | 25 +++++++++++ .../ADAFRUIT_TRINKET_M0/mpconfigboard.mk | 4 ++ ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c | 43 +++++++++++++++++++ ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.h | 42 ++++++++++++++++++ 4 files changed, 114 insertions(+) create mode 100644 ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c create mode 100644 ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.h diff --git a/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.h index d3a6ba2d86..128689f4f7 100644 --- a/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.h @@ -1,2 +1,27 @@ #define MICROPY_HW_BOARD_NAME "Trinket M0" #define MICROPY_HW_MCU_NAME "SAMD21E18A" + +// MicroPython configs +// samd_flash.c flash parameters +// Build a 64k Flash storage at top. 256k-64k=196k +// 256*1024=262144 minus 64*1024=65536 = 196608 = 0x30000 +#define MICROPY_HW_FLASH_STORAGE_BASE (0x30000) +#define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) +#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; + +// ASF4 MCU package specific Pin definitions +#include "samd21e18a.h" + +// Please consult the SAM_D21 Datasheet, I/O Multiplexing and Considerations. +// USART pin assignments: Tx=D4=PA06=SERCOM0/PAD[2], Rx=D3=PA07=SERCOM0/PAD[3] +#define CPU_FREQ (48000000) // For selecting Baud from clock. +#define MP_PIN_GRP 1 // A=0, B=1 +#define MP_TX_PIN 6 // 'n' +#define MP_RX_PIN 7 +#define MP_PERIPHERAL_MUX 3 // 'n'th group of 2 pins +#define USARTx SERCOM0 // SERCOM0: tx/rx +#define MP_PORT_FUNC 0x33 // Sets PMUXE & PMUXO to the Alternative Function.A-H=0-7 +#define MP_RXPO_PAD 3 // RXPO- Receive Data Pinout +#define MP_TXPO_PAD 2 // TXPO- Tranmit Data Pinout +#define MP_SERCOMx SERCOM0_ // APBCMASK +#define MP_SERCOM_GCLK_ID_x_CORE GCLK_CLKCTRL_ID_SERCOM0_CORE // Generic Clock Control diff --git a/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.mk b/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.mk index 5b4d0b63e7..448da296f4 100644 --- a/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.mk +++ b/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.mk @@ -2,3 +2,7 @@ MCU_SERIES = SAMD21 CMSIS_MCU = SAMD21E18A LD_FILES = boards/samd21x18a.ld sections.ld TEXT0 = 0x2000 + +# The ?='s allow overriding in mpconfigboard.mk. +# MicroPython settings +MICROPY_VFS_LFS1 ?= 1 diff --git a/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c b/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c new file mode 100644 index 0000000000..9fecddb6cd --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. + */ + +#include "modmachine.h" +#include "pins.h" + +// Ensure Declaration in 'pins.h' reflects # of Pins defined here. +const machine_pin_obj_t machine_pin_obj[] = { + {{&machine_pin_type}, PIN_PA08}, // D0 + {{&machine_pin_type}, PIN_PA02}, // D1 + {{&machine_pin_type}, PIN_PA09}, // D2 + {{&machine_pin_type}, PIN_PA07}, // D3/ RxD + {{&machine_pin_type}, PIN_PA06}, // D4/ TxD +}; + +const machine_led_obj_t machine_led_obj[] = { + {{&machine_led_type}, PIN_PA10}, // user LED +}; diff --git a/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.h b/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.h new file mode 100644 index 0000000000..843d69addc --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin + * allocations. + */ + +typedef struct _machine_pin_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_pin_obj_t; + +typedef struct _machine_led_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_led_obj_t; + +// MUST explicitly hold array # of rows, else machine_pin.c wont compile. +extern const machine_pin_obj_t machine_pin_obj[5]; +extern const machine_led_obj_t machine_led_obj[1]; From 771d673e5cc92405e6d96d80f8367ecbf5da1505 Mon Sep 17 00:00:00 2001 From: Peter van der Burg Date: Sat, 22 May 2021 17:02:04 +1000 Subject: [PATCH 171/335] samd/boards/SAMD21_XPLAINED_PRO: Update for flash and pins. - mpconfigboard.h: flash and USART config - mpconfigboard.mk: enable LFS1 - pins.c: define pins and LEDs - pins.h: define structs and consts --- .../SAMD21_XPLAINED_PRO/mpconfigboard.h | 26 ++++++ .../SAMD21_XPLAINED_PRO/mpconfigboard.mk | 4 + ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c | 91 +++++++++++++++++++ ports/samd/boards/SAMD21_XPLAINED_PRO/pins.h | 42 +++++++++ 4 files changed, 163 insertions(+) create mode 100644 ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c create mode 100644 ports/samd/boards/SAMD21_XPLAINED_PRO/pins.h diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h b/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h index c69b5b4c14..a7dbf76144 100644 --- a/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h +++ b/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h @@ -1,2 +1,28 @@ #define MICROPY_HW_BOARD_NAME "SAMD21-XPLAINED-PRO" #define MICROPY_HW_MCU_NAME "SAMD21J18A" + +// MicroPython configs +// samd_flash.c flash parameters +// Build a 64k Flash storage at top. 256k-64k=196k +// 256*1024=262144 minus 64*1024=65536 = 196608 = 0x30000 +#define MICROPY_HW_FLASH_STORAGE_BASE (0x30000) +#define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) +#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; + +// ASF4 MCU package specific Pin definitions +#include "samd21j18a.h" + +// Please consult the SAM_D21 Datasheet, I/O Multiplexing and Considerations. +// USART pin assignments: (This board has 3 USARTS brought out to the pins. See https://docs.zephyrproject.org/1.14.1/boards/arm/atsamd21_xpro/doc/index.html#serial-port ) +// Tx=PA10=SERCOM0/PAD[2], Rx=PA11=SERCOM0/PAD[3] +#define CPU_FREQ (48000000) // For selecting Baud from clock. +#define MP_PIN_GRP 1 // A=0, B=1 +#define MP_TX_PIN 10 // 'n' +#define MP_RX_PIN 11 +#define MP_PERIPHERAL_MUX 5 // 'n'th group of 2 pins +#define USARTx SERCOM0 // SERCOM0: tx/rx +#define MP_PORT_FUNC 0x22 // Sets PMUXE & PMUXO to the Alternative Function.(A-H=0-7) +#define MP_RXPO_PAD 3 // RXPO- Receive Data Pinout +#define MP_TXPO_PAD 2 // TXPO- Tranmit Data Pinout +#define MP_SERCOMx SERCOM0_ // APBCMASK +#define MP_SERCOM_GCLK_ID_x_CORE GCLK_CLKCTRL_ID_SERCOM0_CORE // Generic Clock Control diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.mk b/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.mk index f95c654938..b298c9d7fc 100644 --- a/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.mk +++ b/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.mk @@ -2,3 +2,7 @@ MCU_SERIES = SAMD21 CMSIS_MCU = SAMD21J18A LD_FILES = boards/samd21x18a.ld sections.ld TEXT0 = 0x2000 + +# The ?='s allow overriding in mpconfigboard.mk. +# MicroPython settings +MICROPY_VFS_LFS1 ?= 1 \ No newline at end of file diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c b/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c new file mode 100644 index 0000000000..2a2d50eb48 --- /dev/null +++ b/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c @@ -0,0 +1,91 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. + */ + +#include "modmachine.h" +#include "pins.h" + +// Ensure Declaration in 'pins.h' reflects # of Pins defined here. +const machine_pin_obj_t machine_pin_obj[] = { + // EXT1 + {{&machine_pin_type}, PIN_PB00}, // PIN3_ADC(+) + {{&machine_pin_type}, PIN_PB01}, // PIN4_ADC(-) + {{&machine_pin_type}, PIN_PB06}, // PIN5_GPIO + {{&machine_pin_type}, PIN_PB07}, // PIN6_GPIO + {{&machine_pin_type}, PIN_PB02}, // PIN7_PWM(+) + {{&machine_pin_type}, PIN_PB03}, // PIN8_PWM(-) + {{&machine_pin_type}, PIN_PB04}, // PIN9_IRQ/GPIO + {{&machine_pin_type}, PIN_PB05}, // PIN10_SPI_SS_B/GPIO + {{&machine_pin_type}, PIN_PA08}, // PIN11_TWI_SDA + {{&machine_pin_type}, PIN_PA09}, // PIN12_TWI_SCL + {{&machine_pin_type}, PIN_PB09}, // PIN13_UART_RX + {{&machine_pin_type}, PIN_PB08}, // PIN14_UART_TX + {{&machine_pin_type}, PIN_PA05}, // PIN15_SPI_SS_A + {{&machine_pin_type}, PIN_PA06}, // PIN16_SPI_MOSI + {{&machine_pin_type}, PIN_PA04}, // PIN17_SPI_MISO + {{&machine_pin_type}, PIN_PA07}, // PIN18_SPI_SCK + + // EXT2 + {{&machine_pin_type}, PIN_PA10}, // PIN3_ADC(+) + {{&machine_pin_type}, PIN_PA11}, // PIN4_ADC(-) + {{&machine_pin_type}, PIN_PA20}, // PIN5_GPIO + {{&machine_pin_type}, PIN_PA21}, // PIN6_GPIO + {{&machine_pin_type}, PIN_PB12}, // PIN7_PWM(+) + {{&machine_pin_type}, PIN_PB13}, // PIN8_PWM(-) + {{&machine_pin_type}, PIN_PB14}, // PIN9_IRQ/GPIO + {{&machine_pin_type}, PIN_PB15}, // PIN10_SPI_SS_B/GPIO + {{NULL}, -1}, // PIN_PA08/ PIN11_TWI_SDA already defined + {{NULL}, -1}, // PIN_PA09/ PIN12_TWI_SCL already defined + {{&machine_pin_type}, PIN_PB11}, // PIN13_UART_RX + {{&machine_pin_type}, PIN_PB10}, // PIN14_UART_TX + {{&machine_pin_type}, PIN_PA17}, // PIN15_SPI_SS_A + {{&machine_pin_type}, PIN_PA18}, // PIN16_SPI_MOSI + {{&machine_pin_type}, PIN_PA16}, // PIN17_SPI_MISO + {{&machine_pin_type}, PIN_PA19}, // PIN18_SPI_SCK + + // EXT3 + {{&machine_pin_type}, PIN_PA02}, // PIN3_ADC(+) + {{&machine_pin_type}, PIN_PA03}, // PIN4_ADC(-) + {{NULL}, -1}, // PIN_PB30/ PIN5_GPIO already defined + {{&machine_pin_type}, PIN_PA15}, // PIN6_GPIO; USER_BUTTON + {{&machine_pin_type}, PIN_PA12}, // PIN7_PWM(+) + {{&machine_pin_type}, PIN_PA13}, // PIN8_PWM(-) + {{&machine_pin_type}, PIN_PA28}, // PIN9_IRQ/GPIO + {{&machine_pin_type}, PIN_PA27}, // PIN10_SPI_SS_B/GPIO + {{NULL}, -1}, // PIN_PA08/ PIN11_TWI_SDA already defined + {{NULL}, -1}, // PIN_PA09/ PIN12_TWI_SCL already defined + {{NULL}, -1}, // PIN_PB11/ PIN13_UART_RX already defined + {{NULL}, -1}, // PIN_PB10/ PIN14_UART_TX already defined + {{&machine_pin_type}, PIN_PB17}, // PIN15_SPI_SS_A + {{&machine_pin_type}, PIN_PB22}, // PIN16_SPI_MOSI + {{&machine_pin_type}, PIN_PB16}, // PIN17_SPI_MISO + {{&machine_pin_type}, PIN_PB23}, // PIN18_SPI_SCK +}; + +const machine_led_obj_t machine_led_obj[] = { + {{&machine_led_type}, PIN_PB30}, // USER_LED +}; diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.h b/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.h new file mode 100644 index 0000000000..0b0e878b43 --- /dev/null +++ b/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin + * allocations. + */ + +typedef struct _machine_pin_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_pin_obj_t; + +typedef struct _machine_led_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_led_obj_t; + +// MUST explicitly hold array # of rows, else machine_pin.c wont compile. +extern const machine_pin_obj_t machine_pin_obj[48]; +extern const machine_led_obj_t machine_led_obj[1]; From ef4e63aabc15498ff4e26455c43ac535e14a7f2b Mon Sep 17 00:00:00 2001 From: Peter van der Burg Date: Thu, 20 May 2021 17:50:08 +1000 Subject: [PATCH 172/335] samd/boards/SEEED_WIO_TERMINAL: Add new board definition. --- .../samd/boards/SEEED_WIO_TERMINAL/board.json | 20 +++++++ .../boards/SEEED_WIO_TERMINAL/mpconfigboard.h | 32 ++++++++++ .../SEEED_WIO_TERMINAL/mpconfigboard.mk | 8 +++ ports/samd/boards/SEEED_WIO_TERMINAL/pins.c | 60 +++++++++++++++++++ ports/samd/boards/SEEED_WIO_TERMINAL/pins.h | 42 +++++++++++++ 5 files changed, 162 insertions(+) create mode 100644 ports/samd/boards/SEEED_WIO_TERMINAL/board.json create mode 100644 ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.h create mode 100644 ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.mk create mode 100644 ports/samd/boards/SEEED_WIO_TERMINAL/pins.c create mode 100644 ports/samd/boards/SEEED_WIO_TERMINAL/pins.h diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/board.json b/ports/samd/boards/SEEED_WIO_TERMINAL/board.json new file mode 100644 index 0000000000..350ada4c4a --- /dev/null +++ b/ports/samd/boards/SEEED_WIO_TERMINAL/board.json @@ -0,0 +1,20 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "USB-C", + "Display", + "Grove", + "WiFi", + "BLE", + "SDCard" + ], + "images": ["wio-terminal.jpg"], + "mcu": "samd51", + "product": "Wio Terminal D51R", + "thumbnail": "", + "url": "https://www.seeedstudio.com/Wio-Terminal-p-4509.html", + "vendor": "Seeed Studio" +} diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.h b/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.h new file mode 100644 index 0000000000..290bd802b8 --- /dev/null +++ b/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.h @@ -0,0 +1,32 @@ +#define MICROPY_HW_BOARD_NAME "Wio Terminal D51R" +#define MICROPY_HW_MCU_NAME "SAMD51P19A" + +#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) +#define MICROPY_PY_BUILTINS_COMPLEX (0) +#define MICROPY_PY_MATH (0) +#define MICROPY_PY_CMATH (0) + +// MicroPython configs +// samd_flash.c flash parameters +// Build a 128k Flash storage at top. 512k-128k=384k=0x60000 +// 512*1024= 0x80000 minus 128*1024= 0x20000 = 0x60000 +#define MICROPY_HW_FLASH_STORAGE_BASE (0x60000) +#define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) +#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; + +// ASF4 MCU package specific Pin definitions +#include "samd51p19a.h" + +// Please consult the SAM_D51 Datasheet, I/O Multiplexing and Considerations. +// WIO_Terminal USART pin assignments: Tx=BCM14=PB27=SERCOM2/PAD[0], Rx=BCM15=PB26=SERCOM2/PAD[1] +#define CPU_FREQ (48000000) // For selecting Baud from clock. +#define MP_PIN_GRP 1 // A-D=0-3 +#define MP_TX_PIN 27 +#define MP_RX_PIN 26 // 'n' +#define MP_PERIPHERAL_MUX 13 // 'n'th group of 2 pins +#define USARTx SERCOM2 // +#define MP_PORT_FUNC 0x22 // Sets PMUXE & PMUXO to the Alternative Function.A-N=0-13 +#define MP_RXPO_PAD 1 // RXPO- Receive Data Pinout +#define MP_TXPO_PAD 0 // TXPO- Tranmit Data Pinout +#define MP_SERCOMx SERCOM2_ // APBCMASK +#define MP_SERCOM_GCLK_ID_x_CORE SERCOM2_GCLK_ID_CORE diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.mk b/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.mk new file mode 100644 index 0000000000..90fb7f2dd0 --- /dev/null +++ b/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.mk @@ -0,0 +1,8 @@ +MCU_SERIES = SAMD51 +CMSIS_MCU = SAMD51P19A +LD_FILES = boards/samd51p19a.ld sections.ld +TEXT0 = 0x4000 + +# The ?='s allow overriding in mpconfigboard.mk. +# MicroPython settings +MICROPY_VFS_LFS1 ?= 1 diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.c b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.c new file mode 100644 index 0000000000..9862552fa3 --- /dev/null +++ b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.c @@ -0,0 +1,60 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. + */ + +#include "modmachine.h" +#include "pins.h" + +// Ensure Declaration in "pins.h" reflects # of Pins defined here. +const machine_pin_obj_t machine_pin_obj[] = { + {{&machine_pin_type}, PIN_PB08}, // A0/D0 + {{&machine_pin_type}, PIN_PB09}, // A1/D1 + {{&machine_pin_type}, PIN_PA07}, // A2/D2 + {{&machine_pin_type}, PIN_PB04}, // A3/D3 + {{&machine_pin_type}, PIN_PB05}, // A4/D4 + {{&machine_pin_type}, PIN_PB06}, // A5/D5 + {{&machine_pin_type}, PIN_PA04}, // A6/D6 + {{&machine_pin_type}, PIN_PB07}, // A7/D7 + {{&machine_pin_type}, PIN_PA06}, // A8/D8 + {{&machine_pin_type}, PIN_PD08}, // SWITCH_X + {{&machine_pin_type}, PIN_PD09}, // SWITCH_Y + {{&machine_pin_type}, PIN_PD10}, // SWITCH_Z + {{&machine_pin_type}, PIN_PD12}, // SWITCH_B + {{&machine_pin_type}, PIN_PD20}, // SWITCH_U + {{&machine_pin_type}, PIN_PC26}, // BUTTON_1 + {{&machine_pin_type}, PIN_PC27}, // BUTTON_2 + {{&machine_pin_type}, PIN_PC28}, // BUTTON_3 + {{&machine_pin_type}, PIN_PD11}, // BUZZER_CTR + {{&machine_pin_type}, PIN_PC14}, // 5V_OUTPUT_CTR- enable 5V on hdr + {{&machine_pin_type}, PIN_PC15}, // 3V3_OUTPUT_CTR- enable 3V3 on hdr +}; + +// Ensure Declaration in 'pins.h' reflects # of Pins defined here. +const machine_led_obj_t machine_led_obj[] = { + {{&machine_led_type}, PIN_PA15}, // USER_LED (Blue) + {{&machine_led_type}, PIN_PC05}, // LCD_BACKLIGHT_CTR +}; diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.h b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.h new file mode 100644 index 0000000000..45ecc254f1 --- /dev/null +++ b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin + * allocations. + */ + +typedef struct _machine_pin_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_pin_obj_t; + +typedef struct _machine_led_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_led_obj_t; + +// MUST explicitly hold array # of rows, else machine_pin.c wont compile. +extern const machine_pin_obj_t machine_pin_obj[20]; +extern const machine_led_obj_t machine_led_obj[2]; From b991902983d21f733f8ff0009d75e5362fc46900 Mon Sep 17 00:00:00 2001 From: Peter van der Burg Date: Thu, 20 May 2021 17:52:53 +1000 Subject: [PATCH 173/335] samd/boards/SEEED_XIAO: Add new board definition. --- ports/samd/boards/SEEED_XIAO/board.json | 15 ++++++ ports/samd/boards/SEEED_XIAO/mpconfigboard.h | 27 ++++++++++ ports/samd/boards/SEEED_XIAO/mpconfigboard.mk | 9 ++++ ports/samd/boards/SEEED_XIAO/pins.c | 52 +++++++++++++++++++ ports/samd/boards/SEEED_XIAO/pins.h | 42 +++++++++++++++ 5 files changed, 145 insertions(+) create mode 100644 ports/samd/boards/SEEED_XIAO/board.json create mode 100644 ports/samd/boards/SEEED_XIAO/mpconfigboard.h create mode 100644 ports/samd/boards/SEEED_XIAO/mpconfigboard.mk create mode 100644 ports/samd/boards/SEEED_XIAO/pins.c create mode 100644 ports/samd/boards/SEEED_XIAO/pins.h diff --git a/ports/samd/boards/SEEED_XIAO/board.json b/ports/samd/boards/SEEED_XIAO/board.json new file mode 100644 index 0000000000..f5fe271847 --- /dev/null +++ b/ports/samd/boards/SEEED_XIAO/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "USB-C" + ], + "images": ["seeeduino-xiao.jpg"], + "mcu": "samd21", + "product": "Seeeduino XIAO", + "thumbnail": "", + "url": "https://www.seeedstudio.com/Seeeduino-XIAO-Arduino-Microcontroller-SAMD21-Cortex-M0+-p-4426.html", + "vendor": "Seeed Studio" +} diff --git a/ports/samd/boards/SEEED_XIAO/mpconfigboard.h b/ports/samd/boards/SEEED_XIAO/mpconfigboard.h new file mode 100644 index 0000000000..6422d7ea02 --- /dev/null +++ b/ports/samd/boards/SEEED_XIAO/mpconfigboard.h @@ -0,0 +1,27 @@ +#define MICROPY_HW_BOARD_NAME "Seeed Xiao" +#define MICROPY_HW_MCU_NAME "SAMD21G18A" + +// MicroPython configs +// samd_flash.c flash parameters +// Build a 64k Flash storage at top. 256k-64k=196k +// 256*1024=262144 minus 64*1024=65536 = 196608 = 0x30000 +#define MICROPY_HW_FLASH_STORAGE_BASE (0x30000) +#define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) +#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; + +// ASF4 MCU package specific Pin definitions +#include "samd21g18a.h" + +// Please consult the SAM_D21 Datasheet, I/O Multiplexing and Considerations. +// XIAO_M0 USART pin assignments: Tx=A6=PB8=SERCOM4/PAD[0], Rx=PB9=A7=SERCOM4/PAD[1] +#define CPU_FREQ (48000000) // For selecting Baud from clock. +#define MP_PIN_GRP 1 // A=0, B=1 +#define MP_TX_PIN 8 // 'n' +#define MP_RX_PIN 9 +#define MP_PERIPHERAL_MUX 4 // 'n'th group of 2 pins +#define USARTx SERCOM4 // SERCOM4:XIAO_M0 tx/rx +#define MP_PORT_FUNC 0x33 // Sets PMUXE & PMUXO to the Alternative Function.A-H=0-7 +#define MP_RXPO_PAD 1 // RXPO- Receive Data Pinout +#define MP_TXPO_PAD 0 // TXPO- Tranmit Data Pinout +#define MP_SERCOMx SERCOM4_ // APBCMASK +#define MP_SERCOM_GCLK_ID_x_CORE GCLK_CLKCTRL_ID_SERCOM4_CORE // Generic Clock Control diff --git a/ports/samd/boards/SEEED_XIAO/mpconfigboard.mk b/ports/samd/boards/SEEED_XIAO/mpconfigboard.mk new file mode 100644 index 0000000000..eb4d4d045e --- /dev/null +++ b/ports/samd/boards/SEEED_XIAO/mpconfigboard.mk @@ -0,0 +1,9 @@ +MCU_SERIES = SAMD21 +CMSIS_MCU = SAMD21G18A +LD_FILES = boards/samd21x18a.ld sections.ld +TEXT0 = 0x2000 + +# The ?='s allow overriding in mpconfigboard.mk. +# MicroPython settings +MICROPY_VFS_LFS1 ?= 1 + diff --git a/ports/samd/boards/SEEED_XIAO/pins.c b/ports/samd/boards/SEEED_XIAO/pins.c new file mode 100644 index 0000000000..6043913d2b --- /dev/null +++ b/ports/samd/boards/SEEED_XIAO/pins.c @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. + */ + +#include "modmachine.h" +#include "pins.h" + +// Ensure Declaration in 'pins.h' reflects # of Pins defined here. +const machine_pin_obj_t machine_pin_obj[] = { + {{&machine_pin_type}, PIN_PA02}, // A0/D0 + {{&machine_pin_type}, PIN_PA04}, // A1/D1 + {{&machine_pin_type}, PIN_PA10}, // A2/D2 + {{&machine_pin_type}, PIN_PA11}, // A3/D3 + {{&machine_pin_type}, PIN_PA08}, // A4/D4 + {{&machine_pin_type}, PIN_PA09}, // A5/D5 + {{&machine_pin_type}, PIN_PB08}, // A6/D6 + {{&machine_pin_type}, PIN_PB09}, // A7/D7 + {{&machine_pin_type}, PIN_PA07}, // A8/D8 + {{&machine_pin_type}, PIN_PA05}, // A9/D9 + {{&machine_pin_type}, PIN_PA06}, // A10/D10 +}; + +const machine_led_obj_t machine_led_obj[] = { +// XIAO: Just the available LED Pins: User LED (PA17), Rx & Tx. + {{&machine_led_type}, PIN_PA17}, // W13 + {{&machine_led_type}, PIN_PA18}, // RX_LED + {{&machine_led_type}, PIN_PA19}, // TX_LED +}; diff --git a/ports/samd/boards/SEEED_XIAO/pins.h b/ports/samd/boards/SEEED_XIAO/pins.h new file mode 100644 index 0000000000..226b3f1d7b --- /dev/null +++ b/ports/samd/boards/SEEED_XIAO/pins.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Peter van der Burg + * + * 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. + * + * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin + * allocations. + */ + +typedef struct _machine_pin_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_pin_obj_t; + +typedef struct _machine_led_obj_t { + mp_obj_base_t base; + uint32_t id; +} machine_led_obj_t; + +// MUST explicitly hold array # of rows, else machine_pin.c wont compile. +extern const machine_pin_obj_t machine_pin_obj[11]; +extern const machine_led_obj_t machine_led_obj[3]; From 3dc9a42bc2a048153be742f96bd3d7f0a030ea84 Mon Sep 17 00:00:00 2001 From: Peter van der Burg Date: Mon, 24 May 2021 15:55:30 +1000 Subject: [PATCH 174/335] samd/README.md: Update README to reflect new features and boards. --- ports/samd/README.md | 141 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 1 deletion(-) diff --git a/ports/samd/README.md b/ports/samd/README.md index b2ff4023ec..4b434963d9 100644 --- a/ports/samd/README.md +++ b/ports/samd/README.md @@ -3,5 +3,144 @@ Port of MicroPython to Microchip SAMD MCUs Supports SAMD21 and SAMD51. -Features: +## Features: + +### REPL + - REPL over USB VCP +- REPL over USART using board specified USART pins (initialised on startup). + - The USART Pins are board specific, defined in `boards/$(BOARD)/mpconfigboard.h`, + and set at compile time. See the table below. At this stage, the USART cannot be + moved to different pins unless `mpconfigboard.h` is edited and the port recompiled. + - Two USART functions are accessible through MicroPython: + - `uart_init()`. The 'C' function behind this function is what initialises the + USART on startup. Calling this function in MicroPython resets any other peripheral + operating on these pins and reconnects the USART SERCOM to the designated pins. + - `uart_deinit()`. This simply 'disconnects' the SERCOM from the pins. The USART + remains operating over USB VCP to maintain access to the REPL. + +### Boards + +| Board | USART | LFS1 Flash size | Tested | +| ------------------------------------------------------------ | ----------------------------------------------------------- | --------------- | ------ | +| ADAFRUIT_FEATHER_M0_EXPRESS | Tx=PA10=SERCOM0/PAD[2], Rx=PA11=SERCOM0/PAD[3] | 64k | No | +| ADAFRUIT_ITSYBITSY_M4_EXPRESS | Tx=TX_D1=PA17=SERCOM3/PAD[0], Rx=RX_D0=PA16=SERCOM3/PAD[1] | 128k | No | +| ADAFRUIT_TRINKET_M0 | Tx=D4=PA06=SERCOM0/PAD[2], Rx=D3=PA07=SERCOM0/PAD[3] | 64k | No | +| MINISAM_M4 | Tx=TX_D1=PA17=SERCOM3/PAD[0], Rx=RX_D0=PA16=SERCOM3/PAD[1] | 128k | No | +| SAMD21_XPLAINED_PRO | Tx=PA10=SERCOM0/PAD[2], Rx=PA11=SERCOM0/PAD[3] | 64k | No | +| SEEED_WIO_TERMINAL | Tx=BCM14=PB27=SERCOM2/PAD[0], Rx=BCM15=PB26=SERCOM2/PAD[1] | 128k | Yes | +| SEEED_XIAO | Tx=A6=PB8=SERCOM4/PAD[0], Rx=A7=PB9=SERCOM4/PAD[1] | 64k | Yes | + +Note: all USARTs are set to: async, 8 bit, 1 stop bit, no parity, 115200 bps. + +### Modules + +- Internal modules and functions: + +`>>>help('modules')` +`__main__ micropython uheapq ustruct` +`_boot samd uio usys` +`_uasyncio uarray ujson utime` +`builtins uasyncio uos uzlib` +`gc ubinascii urandom` +`machine uctypes ure` +`Plus any modules on the filesystem` + +#### Flash + +- Internal Flash Block Device `samd.Flash()` initialised with littlefs1 in frozen module '`_boot.py`'. + +- **No external SPI Flash driver** (ToDo). + +- Block Device size is set in `ports/samd/boards/$(BOARD)/mpconfigboard.h` : + + - SAMD21: (eg; SEEED_XIAO): 64k `0xFFFF` + + * SAMD51: (eg; M4's): 128k `0x1FFFF` + +#### Pins & LEDs + +##### `machine.Pin()` class. + +- GPIO methods & constants: + + value IN OUT PULL_DOWN + PULL_UP high init low + off on toggle + +- Each board has its own pin numbering scheme, so please see the table below (the + structure is defined in`boards/$(BOARD)/pins.c`) for pin numbers referenced + (index) by 'Pin'. Eg; `SEEED_XIAO/pins.c`: `{{&machine_pin_type}, PIN_PA02}, // A0/D0` + means MicroPython `Pin(0)` is SEEED_XIAO pin "A0/D0" on SAMD21G18A PortA, Pin2. + +- Note: on the SEEED_XIAO, if the TX & TX pins are used by the `Pin()` class, the `Pin()` + initialisation disconnects the pins from the SERCOM similar to the way + `machine.uart_deinit()` does. + +| MicroPython Pin() | SAMD51 Pin#/ ItsyBitsy_M4 | SAMD21 Pin#/ Feather_M0 | SAMD21 Pin#/ Xplained Pro | SAMD21 Pin#/ Trinket_M0 | SAMD51 Pin#/ Minisam | SAMD21 Pin#/ SEEED_XIAO | SAMD51 Pin#/ SEEED_WIO_TERMINAL | +| ----------------- | -------------------------- | ------------------------ | ----------------------------------- | ------------------------ | -------------------- | ----------------------- | ------------------------------------- | +| Pin(0) | PA16/ RX_D0 | PA11/ D0 | PB00/ PIN3_ADC(+) (ext1) | PA08/ D0 | PA02/ A0,D9 | PA02 / A0/D0 | PB08 / A0/D0 | +| Pin(1) | PA17/ TX_D1 | PA10/ D1 | PB01/ PIN4_ADC(-) (ext1) | PA02/ D1 | PB08/ A1,D10 | PA04 / A1/D1 | PB09 / A1/D1 | +| Pin(2) | PA07/ D2 | PA14/ D2 | PB06/ PIN5_GPIO (ext1) | PA09/ D2 | PB09/ A2,D11 | PA10 / A2/D2 | PA07 / A2/D2 | +| Pin(3) | PB22/ D3 | PA09/ D3/ | PB07/ PIN6_GPIO (ext1) | PA07/ D3/ RxD | PA04/ A3,D12 | PA11 / A3/D3 | PB04 / A3/D3 | +| Pin(4) | PA14/ D4 | PA08/ D4/ | PB02/ PIN7_PWM(+) (ext1) | PA06/ D4/ TxD | PA05/ A4,D13 | PA08 / A4/D4 | PB05 / A4/D4 | +| Pin(5) | PA15/ D5 | PA15/ D5 | PB03/ PIN8_PWM(-) (ext1) | | PA06/ A5 | PA09 / A5/D5 | PB06 / A5/D5 | +| Pin(6) | -1/ D6 | PA20/ D6 | PB04/ PIN9_IRQ/GPIO (ext1) | | PA16/ RX_D0 | PB08 / A6/D6/TX | PA04 / A6/D6 | +| Pin(7) | PA18/ D7 | PA21/ D7 | PB05/ PIN10_SPI_SS_B/GPIO (ext1) | | PA17/ TX_D1 | PB09 / A7/D7/RX | PB07 / A7/D7 | +| Pin(8) | -1/ D8 | PA06/ D8/ | PA08/ PIN11_TWI_SDA (ext1) | | PA07/ D2,A6 | PA07 / A8/D8 | PA06 / A8/D8 | +| Pin(9) | PA19/ D9 | PA07/ D9/ | PA09/ PIN12_TWI_SCL (ext1) | | PA19/ D3 | PA05 / A9/D9 | PD08 / SWITCH_X | +| Pin(10) | PA20/ D10 | PA18/ D10 | PB09/ PIN13_UART_RX (ext1) | | PA20/ D4 | PA06 / A10/D10 | PD09 / SWITCH_Y | +| Pin(11) | PA21/ D11 | PA16/ D11 | PB08/ PIN14_UART_TX (ext1) | | PA21/ D5 | | PD10 / SWITCH_Z | +| Pin(12) | PA23/ D12 | PA19/ D12 | PA05/ PIN15_SPI_SS_A (ext1) | | PA00/ BUTTON | | PD12 / SWITCH_B | +| Pin(13) | PA22/ D13 | PA17/ D13/ | PA06/ PIN16_SPI_MOSI (ext1) | | | | PD20 / SWITCH_U | +| Pin(14) | PA02/ A0 | PA02/ A0 | PA04/ PIN17_SPI_MISO (ext1) | | | | PC26 / BUTTON_1 | +| Pin(15) | PA05/ A1 | PB08/ A1 | PA07/ PIN18_SPI_SCK (ext1) | | | | PC27 / BUTTON_2 | +| Pin(16) | PB08/ A2 | PB09/ A2 | PA10/ PIN3_ADC(+) (ext2) | | | | PC28 / BUTTON_3 | +| Pin(17) | PB09/ A3 | PA04/ A3/ | PA11/ PIN4_ADC(-) (ext2) | | | | PD11 / BUZZER_CTR | +| Pin(18) | PA04/ A4 | PA05/ A4/ | PA20/ PIN5_GPIO (ext2) | | | | PC14/ 5V_OUTPUT_CTR- '1'= 5V on hdr | +| Pin(19) | PA06/ A5 | PB02/ A5 | PA21/ PIN6_GPIO (ext2) | | | | PC15/ 3V3_OUTPUT_CTR- '0'= 3V3 on hdr | +| Pin(20) | | | PB12/ PIN7_PWM(+) (ext2) | | | | | +| Pin(21) | | | PB13/ PIN8_PWM(-) (ext2) | | | | | +| Pin(22) | | | PB14/ PIN9_IRQ/GPIO (ext2) | | | | | +| Pin(23) | | | PB15/ PIN10_SPI_SS_B/GPIO (ext2) | | | | | +| Pin(24) | | | -1 / PIN11_TWI_SDA already defined | | | | | +| Pin(25) | | | -1 / PIN12_TWI_SCL already defined | | | | | +| Pin(26) | | | PB11/ PIN13_UART_RX (ext2) | | | | | +| Pin(27) | | | PB10/ PIN14_UART_TX (ext2) | | | | | +| Pin(28) | | | PA17/ PIN15_SPI_SS_A (ext2) | | | | | +| Pin(29) | | | PA18/ PIN16_SPI_MOSI (ext2) | | | | | +| Pin(30) | | | PA16/ PIN17_SPI_MISO (ext2) | | | | | +| Pin(31) | | | PA19/ PIN18_SPI_SCK (ext2) | | | | | +| Pin(32) | | | PA02/ PIN3_ADC(+) (ext3) | | | | | +| Pin(33) | | | PA03/ PIN4_ADC(-) (ext3) | | | | | +| Pin(34) | | | -1/ PIN5_GPIO already defined | | | | | +| Pin(35) | | | PA15/ PIN6_GPIO; USER_BUTTON (ext3) | | | | | +| Pin(36) | | | PA12/ PIN7_PWM(+) (ext3) | | | | | +| Pin(37) | | | PA13/ PIN8_PWM(-) (ext3) | | | | | +| Pin(38) | | | PA28/ PIN9_IRQ/GPIO (ext3) | | | | | +| Pin(39) | | | PA27/ PIN10_SPI_SS_B/GPIO (ext3) | | | | | +| Pin(40) | | | -1/ PIN11_TWI_SDA already defined | | | | | +| Pin(41) | | | -1/ PIN12_TWI_SCL already defined | | | | | +| Pin(42) | | | -1/ PIN13_UART_RX already defined | | | | | +| Pin(43) | | | -1/ PIN14_UART_TX already defined | | | | | +| Pin(44) | | | PA15/ PIN6_GPIO; USER_BUTTON (ext3) | | | | | +| Pin(45) | | | PB22/ PIN16_SPI_MOSI (ext3) | | | | | +| Pin(46) | | | PB16/ PIN17_SPI_MISO (ext3) | | | | | +| Pin(47) | | | PB23/ PIN18_SPI_SCK (ext3) | | | | | + +##### `machine.LED()` class. + +- GPIO methods & constants: + +`value OUT high low` +`off on toggle` + +- As above, please see `boards/$(BOARD)/pins.c` for pin numbers referenced by 'LED'. +Eg; `SEEED_XIAO/pins.c`: `{{&machine_led_type}, PIN_PA17}, // W13` means MicroPython +`LED(0)` is SEEED_XIAO LED "W13" connected to SAMD21G18A PortA, Pin17. + +| MicroPython LED() | SAMD51 Pin#/ ItsyBitsy_M4 | SAMD21 Pin#/ Feather_M0 | SAMD21 Pin#/ Xplained Pro | SAMD21 Pin#/ Trinket_M0 | SAMD51 Pin#/ Minisam | SAMD21 Pin#/ SEEED_XIAO | SAMD51 Pin#/ SEEED_WIO_TERMINAL | +| ------------------ | -------------------------- | ------------------------ | -------------------------- | ------------------------ | --------------------- | ------------------------ | -------------------------------- | +| LED(0) | PA22/ D13/ user LED | PA17/ D13/ user LED | PB30/ USER_LED | PA10/ USER_LED | PA15/ LED | PA17 / W13 | PA15 / USER_LED (Blue) | +| LED(1) | | | | | | PA18 / RX_LED | PC05 / LCD_BACKLIGHT_CTR | +| LED(2) | | | | | | PA19 / TX_LED | | From 0a9335ecaa2bda2de1af86be426c9ed6c8849f16 Mon Sep 17 00:00:00 2001 From: oli Date: Sat, 9 Oct 2021 10:20:39 +0100 Subject: [PATCH 175/335] rp2/rp2_pio: Support exec with sideset. The rp2.StateMachine.exec errors when supplying a sideset action. This commit passes the sideset_opt from the StateMachine though to the parser. It also adds some value validation to the sideset operator. Additionally, the "word" method is added to the exec to allow any other unsupported opcodes. Fixes issue #7924. --- ports/rp2/modules/rp2.py | 12 ++++++++---- ports/rp2/rp2_pio.c | 7 ++++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ports/rp2/modules/rp2.py b/ports/rp2/modules/rp2.py index c7e4d1fdd9..1e4bb26cf0 100644 --- a/ports/rp2/modules/rp2.py +++ b/ports/rp2/modules/rp2.py @@ -88,6 +88,10 @@ class PIOASMEmit: def side(self, value): self.num_sideset += 1 if self.pass_ > 0: + if self.sideset_count == 0: + raise PIOASMError("no sideset") + elif value >= (1 << self.sideset_count): + raise PIOASMError("sideset too large") set_bit = 13 - self.sideset_count self.prog[_PROG_DATA][-1] |= self.sideset_opt << 12 | value << set_bit return self @@ -269,17 +273,17 @@ def asm_pio(**kw): # sideset_count is inclusive of enable bit -def asm_pio_encode(instr, sideset_count): +def asm_pio_encode(instr, sideset_count, sideset_opt=False): emit = PIOASMEmit() - emit.delay_max = 31 emit.sideset_count = sideset_count - if emit.sideset_count: - emit.delay_max >>= emit.sideset_count + emit.sideset_opt = sideset_opt != 0 + emit.delay_max = 31 >> (emit.sideset_count + emit.sideset_opt) emit.pass_ = 1 emit.num_instr = 0 emit.num_sideset = 0 gl = _pio_funcs + gl["word"] = emit.word gl["nop"] = emit.nop # gl["jmp"] = emit.jmp currently not supported gl["wait"] = emit.wait diff --git a/ports/rp2/rp2_pio.c b/ports/rp2/rp2_pio.c index 414fa8bd70..fe09ebe249 100644 --- a/ports/rp2/rp2_pio.c +++ b/ports/rp2/rp2_pio.c @@ -613,7 +613,12 @@ STATIC mp_obj_t rp2_state_machine_exec(mp_obj_t self_in, mp_obj_t instr_in) { mp_obj_t rp2_module = mp_import_name(MP_QSTR_rp2, mp_const_none, MP_OBJ_NEW_SMALL_INT(0)); mp_obj_t asm_pio_encode = mp_load_attr(rp2_module, MP_QSTR_asm_pio_encode); uint32_t sideset_count = self->pio->sm[self->sm].pinctrl >> PIO_SM0_PINCTRL_SIDESET_COUNT_LSB; - mp_obj_t encoded_obj = mp_call_function_2(asm_pio_encode, instr_in, MP_OBJ_NEW_SMALL_INT(sideset_count)); + uint8_t sideset_opt = !!(self->pio->sm[self->sm].execctrl & (1 << PIO_SM0_EXECCTRL_SIDE_EN_LSB)); + mp_obj_t args[3]; + args[0] = instr_in; + args[1] = MP_OBJ_NEW_SMALL_INT(sideset_count); + args[2] = MP_OBJ_NEW_SMALL_INT(sideset_opt); + mp_obj_t encoded_obj = mp_call_function_n_kw(asm_pio_encode, 3, 0, args); mp_int_t encoded = mp_obj_get_int(encoded_obj); pio_sm_exec(self->pio, self->sm, encoded); return mp_const_none; From f72b49756d08d4fa8571a88663fe4c094e5ef60c Mon Sep 17 00:00:00 2001 From: oli Date: Sat, 9 Oct 2021 11:50:50 +0100 Subject: [PATCH 176/335] docs/library/rp2.rst: Update function asm_pio_encode to add sideset_opt. --- docs/library/rp2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/library/rp2.rst b/docs/library/rp2.rst index 43143fe089..05d3b80f3a 100644 --- a/docs/library/rp2.rst +++ b/docs/library/rp2.rst @@ -58,7 +58,7 @@ For running PIO programs, see :class:`rp2.StateMachine`. combined into a single 8-word FIFO for one direction only. The options are `PIO.JOIN_NONE`, `PIO.JOIN_RX` and `PIO.JOIN_TX`. -.. function:: asm_pio_encode(instr, sideset_count) +.. function:: asm_pio_encode(instr, sideset_count, sideset_opt=False) Assemble a single PIO instruction. You usually want to use `asm_pio()` instead. From 1904833e0c7c650e86d8e151ea57ea1fa2ab09bd Mon Sep 17 00:00:00 2001 From: Seon Rozenblum Date: Fri, 12 Nov 2021 11:23:49 +1100 Subject: [PATCH 177/335] esp32: Add SDCard support for S3, and a GENERIC_S3_SPIRAM board. Also add support for GPIO 47 and 48 on S3 boards. --- ports/esp32/boards/GENERIC_S3/mpconfigboard.h | 7 +++---- .../esp32/boards/GENERIC_S3_SPIRAM/board.json | 16 ++++++++++++++++ .../GENERIC_S3_SPIRAM/mpconfigboard.cmake | 12 ++++++++++++ .../boards/GENERIC_S3_SPIRAM/mpconfigboard.h | 12 ++++++++++++ .../boards/GENERIC_S3_SPIRAM/sdkconfig.board | 12 ++++++++++++ ports/esp32/boards/sdkconfig.spiram_sx | 4 ++++ ports/esp32/machine_pin.c | 15 +++++++++++++++ ports/esp32/machine_sdcard.c | 19 +++++++++++++++++++ ports/esp32/main.c | 4 ++-- ports/esp32/mpconfigport.h | 5 +++++ 10 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 ports/esp32/boards/GENERIC_S3_SPIRAM/board.json create mode 100644 ports/esp32/boards/GENERIC_S3_SPIRAM/mpconfigboard.cmake create mode 100644 ports/esp32/boards/GENERIC_S3_SPIRAM/mpconfigboard.h create mode 100644 ports/esp32/boards/GENERIC_S3_SPIRAM/sdkconfig.board diff --git a/ports/esp32/boards/GENERIC_S3/mpconfigboard.h b/ports/esp32/boards/GENERIC_S3/mpconfigboard.h index 562521c368..53caa7f91d 100644 --- a/ports/esp32/boards/GENERIC_S3/mpconfigboard.h +++ b/ports/esp32/boards/GENERIC_S3/mpconfigboard.h @@ -2,12 +2,11 @@ #define MICROPY_HW_MCU_NAME "ESP32S3" #define MICROPY_PY_BLUETOOTH (0) -#define MICROPY_HW_ENABLE_SDCARD (0) #define MICROPY_PY_MACHINE_DAC (0) #define MICROPY_HW_I2C0_SCL (9) #define MICROPY_HW_I2C0_SDA (8) -#define MICROPY_HW_SPI1_MOSI (35) // SDO -#define MICROPY_HW_SPI1_MISO (37) // SDI -#define MICROPY_HW_SPI1_SCK (36) +#define MICROPY_HW_SPI1_MOSI (35) +#define MICROPY_HW_SPI1_MISO (36) +#define MICROPY_HW_SPI1_SCK (37) diff --git a/ports/esp32/boards/GENERIC_S3_SPIRAM/board.json b/ports/esp32/boards/GENERIC_S3_SPIRAM/board.json new file mode 100644 index 0000000000..47bc34e392 --- /dev/null +++ b/ports/esp32/boards/GENERIC_S3_SPIRAM/board.json @@ -0,0 +1,16 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "BLE", + "WiFi" + ], + "images": [], + "mcu": "esp32s3", + "product": "Generic ESP32-S3 (SPIRAM)", + "thumbnail": "", + "url": "https://www.espressif.com/en/products/modules", + "vendor": "Espressif" +} diff --git a/ports/esp32/boards/GENERIC_S3_SPIRAM/mpconfigboard.cmake b/ports/esp32/boards/GENERIC_S3_SPIRAM/mpconfigboard.cmake new file mode 100644 index 0000000000..682c31456f --- /dev/null +++ b/ports/esp32/boards/GENERIC_S3_SPIRAM/mpconfigboard.cmake @@ -0,0 +1,12 @@ +set(IDF_TARGET esp32s3) + +set(SDKCONFIG_DEFAULTS + boards/sdkconfig.base + boards/sdkconfig.usb + boards/sdkconfig.spiram_sx + boards/GENERIC_S3_SPIRAM/sdkconfig.board +) + +if(NOT MICROPY_FROZEN_MANIFEST) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +endif() diff --git a/ports/esp32/boards/GENERIC_S3_SPIRAM/mpconfigboard.h b/ports/esp32/boards/GENERIC_S3_SPIRAM/mpconfigboard.h new file mode 100644 index 0000000000..10085ae789 --- /dev/null +++ b/ports/esp32/boards/GENERIC_S3_SPIRAM/mpconfigboard.h @@ -0,0 +1,12 @@ +#define MICROPY_HW_BOARD_NAME "ESP32S3 module (spiram)" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_PY_BLUETOOTH (0) +#define MICROPY_PY_MACHINE_DAC (0) + +#define MICROPY_HW_I2C0_SCL (9) +#define MICROPY_HW_I2C0_SDA (8) + +#define MICROPY_HW_SPI1_MOSI (35) +#define MICROPY_HW_SPI1_MISO (36) +#define MICROPY_HW_SPI1_SCK (37) diff --git a/ports/esp32/boards/GENERIC_S3_SPIRAM/sdkconfig.board b/ports/esp32/boards/GENERIC_S3_SPIRAM/sdkconfig.board new file mode 100644 index 0000000000..c9726d4232 --- /dev/null +++ b/ports/esp32/boards/GENERIC_S3_SPIRAM/sdkconfig.board @@ -0,0 +1,12 @@ +CONFIG_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_AFTER_NORESET=y + +CONFIG_SPIRAM_MEMTEST= + +CONFIG_ESPTOOLPY_FLASHSIZE_4MB= +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB= +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-8MiB.csv" diff --git a/ports/esp32/boards/sdkconfig.spiram_sx b/ports/esp32/boards/sdkconfig.spiram_sx index 18a0712cbf..ef24e90829 100644 --- a/ports/esp32/boards/sdkconfig.spiram_sx +++ b/ports/esp32/boards/sdkconfig.spiram_sx @@ -1,5 +1,7 @@ # MicroPython on ESP32-S2 and ESP32-PAD1_subscript_3, ESP IDF configuration with SPIRAM support CONFIG_ESP32S2_SPIRAM_SUPPORT=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_QUAD=y CONFIG_SPIRAM_TYPE_AUTO=y CONFIG_DEFAULT_PSRAM_CLK_IO=30 CONFIG_DEFAULT_PSRAM_CS_IO=26 @@ -9,3 +11,5 @@ CONFIG_SPIRAM_BOOT_INIT=y CONFIG_SPIRAM_IGNORE_NOTFOUND=y CONFIG_SPIRAM_USE_MEMMAP=y CONFIG_SPIRAM_MEMTEST=y +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 diff --git a/ports/esp32/machine_pin.c b/ports/esp32/machine_pin.c index bf61122811..42c4194269 100644 --- a/ports/esp32/machine_pin.c +++ b/ports/esp32/machine_pin.c @@ -200,6 +200,13 @@ STATIC const machine_pin_obj_t machine_pin_obj[] = { {{&machine_pin_type}, GPIO_NUM_46}, #endif + + #if CONFIG_IDF_TARGET_ESP32S3 && MICROPY_HW_ESP32S3_EXTENDED_IO + + {{&machine_pin_type}, GPIO_NUM_47}, + {{&machine_pin_type}, GPIO_NUM_48}, + + #endif }; // forward declaration @@ -631,6 +638,14 @@ STATIC const machine_pin_irq_obj_t machine_pin_irq_object[] = { {{&machine_pin_irq_type}, GPIO_NUM_43}, {{&machine_pin_irq_type}, GPIO_NUM_44}, {{&machine_pin_irq_type}, GPIO_NUM_45}, + {{&machine_pin_irq_type}, GPIO_NUM_46}, + + #endif + + #if CONFIG_IDF_TARGET_ESP32S3 && MICROPY_HW_ESP32S3_EXTENDED_IO + + {{&machine_pin_irq_type}, GPIO_NUM_47}, + {{&machine_pin_irq_type}, GPIO_NUM_48}, #endif }; diff --git a/ports/esp32/machine_sdcard.c b/ports/esp32/machine_sdcard.c index 3f70311f74..82c2e6cd4e 100644 --- a/ports/esp32/machine_sdcard.c +++ b/ports/esp32/machine_sdcard.c @@ -188,7 +188,11 @@ STATIC mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args } if (is_spi) { + #if CONFIG_IDF_TARGET_ESP32S3 + self->host.slot = slot_num ? SPI3_HOST : SPI2_HOST; + #else self->host.slot = slot_num ? HSPI_HOST : VSPI_HOST; + #endif } DEBUG_printf(" Calling host.init()"); @@ -198,6 +202,20 @@ STATIC mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args if (is_spi) { // SPI interface + #if CONFIG_IDF_TARGET_ESP32S3 + STATIC const sdspi_slot_config_t slot_defaults[2] = { + { + .gpio_miso = GPIO_NUM_36, + .gpio_mosi = GPIO_NUM_35, + .gpio_sck = GPIO_NUM_37, + .gpio_cs = GPIO_NUM_34, + .gpio_cd = SDSPI_SLOT_NO_CD, + .gpio_wp = SDSPI_SLOT_NO_WP, + .dma_channel = 2 + }, + SDSPI_SLOT_CONFIG_DEFAULT() + }; + #else STATIC const sdspi_slot_config_t slot_defaults[2] = { { .gpio_miso = GPIO_NUM_19, @@ -210,6 +228,7 @@ STATIC mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args }, SDSPI_SLOT_CONFIG_DEFAULT() }; + #endif DEBUG_printf(" Setting up SPI slot configuration"); sdspi_slot_config_t slot_config = slot_defaults[slot_num]; diff --git a/ports/esp32/main.c b/ports/esp32/main.c index ca0ab1488a..c1728e3182 100644 --- a/ports/esp32/main.c +++ b/ports/esp32/main.c @@ -101,7 +101,7 @@ void mp_task(void *pvParameter) { #if CONFIG_ESP32_SPIRAM_SUPPORT || CONFIG_SPIRAM_SUPPORT // Try to use the entire external SPIRAM directly for the heap size_t mp_task_heap_size; - void *mp_task_heap = (void *)0x3f800000; + void *mp_task_heap = (void *)SOC_EXTRAM_DATA_LOW; switch (esp_spiram_get_chip_size()) { case ESP_SPIRAM_SIZE_16MBITS: mp_task_heap_size = 2 * 1024 * 1024; @@ -120,7 +120,7 @@ void mp_task(void *pvParameter) { // Try to use the entire external SPIRAM directly for the heap size_t mp_task_heap_size; size_t esp_spiram_size = esp_spiram_get_size(); - void *mp_task_heap = (void *)0x3ff80000 - esp_spiram_size; + void *mp_task_heap = (void *)SOC_EXTRAM_DATA_HIGH - esp_spiram_size; if (esp_spiram_size > 0) { mp_task_heap_size = esp_spiram_size; } else { diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 82bef87880..52949c5348 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -315,6 +315,11 @@ typedef long mp_off_t; // board specifics #define MICROPY_PY_SYS_PLATFORM "esp32" +// ESP32-S3 extended IO for 47 & 48 +#ifndef MICROPY_HW_ESP32S3_EXTENDED_IO +#define MICROPY_HW_ESP32S3_EXTENDED_IO (1) +#endif + #ifndef MICROPY_HW_ENABLE_MDNS_QUERIES #define MICROPY_HW_ENABLE_MDNS_QUERIES (1) #endif From 01f1c3aac200fa33f981e0e53a20005e7ae3f6e8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 8 Nov 2021 12:43:18 +1100 Subject: [PATCH 178/335] docs/reference/filesystem.rst: Add detail on how to use littlefs fuse. Without the --block_count option the fuse will fail. Signed-off-by: Damien George --- docs/reference/filesystem.rst | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/docs/reference/filesystem.rst b/docs/reference/filesystem.rst index 114e597350..ca9e56344e 100644 --- a/docs/reference/filesystem.rst +++ b/docs/reference/filesystem.rst @@ -219,15 +219,6 @@ resistant to filesystem corruption. situations, for details see `littlefs issue 347`_ and `littlefs issue 295`_. -Note: It can be still be accessed over USB MSC using the `littlefs FUSE -driver`_. Note that you must use the ``-b=4096`` option to override the block -size. - -.. _littlefs FUSE driver: https://github.com/ARMmbed/littlefs-fuse/tree/master/littlefs -.. _Littlefs: https://github.com/ARMmbed/littlefs -.. _littlefs issue 295: https://github.com/ARMmbed/littlefs/issues/295 -.. _littlefs issue 347: https://github.com/ARMmbed/littlefs/issues/347 - To format the entire flash using littlefs v2:: # ESP8266 and ESP32 @@ -243,6 +234,27 @@ To format the entire flash using littlefs v2:: os.mount(pyb.Flash(start=0), '/flash') os.chdir('/flash') +A littlefs filesystem can be still be accessed on a PC over USB MSC using the +`littlefs FUSE driver`_. Note that you must specify both the ``--block_size`` +and ``--block_count`` options to override the defaults. For example (after +building the littlefs-fuse executable):: + + $ ./lfs --block_size=4096 --block_count=512 -o allow_other /dev/sdb1 mnt + +This will allow the board's littlefs filesystem to be accessed at the ``mnt`` +directory. To get the correct values of ``block_size`` and ``block_count`` use:: + + import pyb + f = pyb.Flash(start=0) + f.ioctl(1, 1) # initialise flash in littlefs raw-block mode + block_count = f.ioctl(4, 0) + block_size = f.ioctl(5, 0) + +.. _littlefs FUSE driver: https://github.com/littlefs-project/littlefs-fuse +.. _Littlefs: https://github.com/littlefs-project/littlefs +.. _littlefs issue 295: https://github.com/littlefs-project/littlefs/issues/295 +.. _littlefs issue 347: https://github.com/littlefs-project/littlefs/issues/347 + Hybrid (STM32) ~~~~~~~~~~~~~~ From e538d8a5a6d4c643b1bff41107062511b2e7f65a Mon Sep 17 00:00:00 2001 From: NitiKaur Date: Fri, 5 Nov 2021 15:46:35 +0530 Subject: [PATCH 179/335] docs/rp2/quickref.rst: Add section on PIO. --- docs/rp2/quickref.rst | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/docs/rp2/quickref.rst b/docs/rp2/quickref.rst index 63b8928280..4824f390eb 100644 --- a/docs/rp2/quickref.rst +++ b/docs/rp2/quickref.rst @@ -92,6 +92,37 @@ Use the :ref:`machine.Pin ` class:: p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation +Programmable IO (PIO) +--------------------- + +PIO is useful to build low-level IO interfaces from scratch. See the :mod:`rp2` module +for detailed explaination of the assembly instructions. + +Example using PIO to blink an LED at 1Hz:: + + from machine import Pin + import rp2 + + @rp2.asm_pio(set_init=rp2.PIO.OUT_LOW) + def blink_1hz(): + # Cycles: 1 + 7 + 32 * (30 + 1) = 1000 + set(pins, 1) + set(x, 31) [6] + label("delay_high") + nop() [29] + jmp(x_dec, "delay_high") + + # Cycles: 1 + 7 + 32 * (30 + 1) = 1000 + set(pins, 0) + set(x, 31) [6] + label("delay_low") + nop() [29] + jmp(x_dec, "delay_low") + + # Create and start a StateMachine with blink_1hz, outputting on Pin(25) + sm = rp2.StateMachine(0, blink_1hz, freq=2000, set_base=Pin(25)) + sm.active(1) + UART (serial bus) ----------------- From b851950c26e185d46c16b993d310506992fbdb89 Mon Sep 17 00:00:00 2001 From: NitiKaur Date: Fri, 12 Nov 2021 20:39:56 +0530 Subject: [PATCH 180/335] docs/library/sys.rst: Add docs for sys.settrace. --- docs/library/sys.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/library/sys.rst b/docs/library/sys.rst index 24f9e353bb..80ac1ab84c 100644 --- a/docs/library/sys.rst +++ b/docs/library/sys.rst @@ -43,6 +43,15 @@ Functions positional; further arguments are not supported. CPython-compatible ``traceback`` module can be found in `micropython-lib`. +.. function:: settrace(tracefunc) + + Enable tracing of bytecode execution. For details see the `CPython + documentaion `_. + + This function requires a custom MicroPython build as it is typically not + present in pre-built firmware (due to it affecting performance). The relevant + configuration option is *MICROPY_PY_SYS_SETTRACE*. + Constants --------- From 172a031dff5b767be0accc9ae4810c1f897d3dde Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Wed, 17 Nov 2021 16:25:51 +1100 Subject: [PATCH 181/335] rp2/boards/PIMORONI_PICOLIPO_16MB: Fix 16MB flash size. Was incorrectly added as 7MB for an 8MB SPI flash, but this board has a 16MB chip, not 8MB, so it should be 15MB leaving 1MB for MicroPython. Thanks to @robert-hh --- ports/rp2/boards/PIMORONI_PICOLIPO_16MB/mpconfigboard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/mpconfigboard.h b/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/mpconfigboard.h index 68478f7613..134c2ff784 100644 --- a/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/mpconfigboard.h +++ b/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/mpconfigboard.h @@ -1,7 +1,7 @@ // https://shop.pimoroni.com/products/pimoroni-pico-lipo?variant=39335427080275 #define MICROPY_HW_BOARD_NAME "Pimoroni Pico LiPo 16MB" -#define MICROPY_HW_FLASH_STORAGE_BYTES (7 * 1024 * 1024) +#define MICROPY_HW_FLASH_STORAGE_BYTES (15 * 1024 * 1024) #define MICROPY_HW_USB_VID (0x2E8A) #define MICROPY_HW_USB_PID (0x1003) From 841eeb158e1d43ba34e4ee629143e10a2c4505ff Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 18 Nov 2021 00:10:49 +1100 Subject: [PATCH 182/335] drivers/neopixel: Avoid heap alloc in fill(). Previously the use of `range(start,stop,step)` caused an allocation. Replace with while loop. Signed-off-by: Jim Mussared --- drivers/neopixel/neopixel.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/neopixel/neopixel.py b/drivers/neopixel/neopixel.py index 0032d36183..caa12dc845 100644 --- a/drivers/neopixel/neopixel.py +++ b/drivers/neopixel/neopixel.py @@ -36,10 +36,14 @@ class NeoPixel: def fill(self, v): b = self.buf - for i in range(self.bpp): + l = len(self.buf) + bpp = self.bpp + for i in range(bpp): c = v[i] - for j in range(self.ORDER[i], len(self.buf), self.bpp): + j = self.ORDER[i] + while j < l: b[j] = c + j += bpp def write(self): # BITSTREAM_TYPE_HIGH_LOW = 0 From b65d17fced77f9c6ca19d4b9df9de7f679de5019 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 17 Nov 2021 17:32:09 +0200 Subject: [PATCH 183/335] drivers/ninaw10: Fix BSSID byte order, and add null byte to ESSID. - Fix the BSSID byte order from scan and netinfo. - Make sure ESSID from netinfo is null terminated. --- drivers/ninaw10/nina_wifi_drv.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/ninaw10/nina_wifi_drv.c b/drivers/ninaw10/nina_wifi_drv.c index 70f1a4264c..48127c0763 100644 --- a/drivers/ninaw10/nina_wifi_drv.c +++ b/drivers/ninaw10/nina_wifi_drv.c @@ -344,6 +344,14 @@ static int nina_send_command_read_vals(uint32_t cmd, uint32_t nargs, return 0; } +static void nina_fix_mac_addr(uint8_t *mac) { + for (int i = 0; i < 3; i++) { + uint8_t b = mac[i]; + mac[i] = mac[5 - i]; + mac[5 - i] = b; + } +} + int nina_init(void) { // Initialize the BSP. nina_bsp_init(); @@ -541,12 +549,18 @@ int nina_netinfo(nina_netinfo_t *netinfo) { return -1; } + // Null terminate SSID. + netinfo->ssid[MIN((NINA_MAX_SSID_LEN - 1), ssid_len)] = 0; + if (nina_send_command_read_vals(NINA_CMD_GET_BSSID, 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF)), 1, ARG_8BITS, NINA_VALS({&bssid_len, &netinfo->bssid})) != 0) { return -1; } + // The MAC address is read in reverse from the firmware. + nina_fix_mac_addr(netinfo->bssid); + return 0; } @@ -630,6 +644,9 @@ int nina_scan(nina_scan_callback_t scan_callback, void *arg, uint32_t timeout) { return -1; } + // The MAC address is read in reverse from the firmware. + nina_fix_mac_addr(scan_result.bssid); + scan_callback(&scan_result, arg); } From f7a0c98e00c226f40748acc619a4d7d089b3e31e Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 17 Nov 2021 17:33:15 +0200 Subject: [PATCH 184/335] extmod/network_ninaw10: Fix scan list order to match other NICs. --- extmod/network_ninaw10.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/extmod/network_ninaw10.c b/extmod/network_ninaw10.c index aa4b8dd0c0..e256188eb3 100644 --- a/extmod/network_ninaw10.c +++ b/extmod/network_ninaw10.c @@ -119,23 +119,15 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ninaw10_active_obj, 1, 2, net STATIC int nina_scan_callback(nina_scan_result_t *scan_result, void *arg) { mp_obj_t scan_list = (mp_obj_t)arg; - - // Format MAC address - VSTR_FIXED(bssid_vstr, 18); - vstr_printf(&bssid_vstr, "%02X:%02X:%02X:%02X:%02X:%02X", - scan_result->bssid[0], scan_result->bssid[1], scan_result->bssid[2], - scan_result->bssid[3], scan_result->bssid[4], scan_result->bssid[5]); - - mp_obj_t ap[5] = { + mp_obj_t ap[6] = { + mp_obj_new_bytes((uint8_t *)scan_result->ssid, strlen(scan_result->ssid)), + mp_obj_new_bytes(scan_result->bssid, sizeof(scan_result->bssid)), mp_obj_new_int(scan_result->channel), mp_obj_new_int(scan_result->rssi), mp_obj_new_int(scan_result->security), - mp_obj_new_str(bssid_vstr.buf, bssid_vstr.len), - mp_obj_new_str(scan_result->ssid, strlen(scan_result->ssid)), + MP_OBJ_NEW_SMALL_INT(1), // N }; - mp_obj_list_append(scan_list, mp_obj_new_tuple(MP_ARRAY_SIZE(ap), ap)); - return 0; } From 78425208ba0883f9b7b876a3e54ea87899f2bf99 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 18 Nov 2021 20:36:04 +0200 Subject: [PATCH 185/335] nrf/main: Use VFS helper function to mount fs and chdir. --- ports/nrf/main.c | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/ports/nrf/main.c b/ports/nrf/main.c index 254d9491c0..3768b8f404 100644 --- a/ports/nrf/main.c +++ b/ports/nrf/main.c @@ -106,28 +106,6 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) { extern uint32_t _heap_start; extern uint32_t _heap_end; -#if MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE -STATIC int vfs_mount_and_chdir(mp_obj_t bdev, mp_obj_t mount_point) { - nlr_buf_t nlr; - mp_int_t ret = -MP_EIO; - if (nlr_push(&nlr) == 0) { - mp_obj_t args[] = { bdev, mount_point }; - mp_vfs_mount(2, args, (mp_map_t *)&mp_const_empty_map); - mp_vfs_chdir(mount_point); - ret = 0; // success - nlr_pop(); - } else { - mp_obj_base_t *exc = nlr.ret_val; - if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(exc->type), MP_OBJ_FROM_PTR(&mp_type_OSError))) { - mp_obj_t v = mp_obj_exception_get_value(MP_OBJ_FROM_PTR(exc)); - mp_obj_get_int_maybe(v, &ret); // get errno value - ret = -ret; - } - } - return ret; -} -#endif - int main(int argc, char **argv) { @@ -203,11 +181,11 @@ soft_reset: // Try to mount the flash on "/flash" and chdir to it for the boot-up directory. mp_obj_t mount_point = MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash); - int ret = vfs_mount_and_chdir((mp_obj_t)&nrf_flash_obj, mount_point); + int ret = mp_vfs_mount_and_chdir_protected((mp_obj_t)&nrf_flash_obj, mount_point); if ((ret == -MP_ENODEV) || (ret == -MP_EIO)) { pyexec_frozen_module("_mkfs.py"); // Frozen script for formatting flash filesystem. - ret = vfs_mount_and_chdir((mp_obj_t)&nrf_flash_obj, mount_point); + ret = mp_vfs_mount_and_chdir_protected((mp_obj_t)&nrf_flash_obj, mount_point); } if (ret != 0) { From 16c7a808742570e3c9ab1e1f8243d0a2166995a3 Mon Sep 17 00:00:00 2001 From: Lorenzo Cappelletti Date: Wed, 27 Oct 2021 22:53:58 +0200 Subject: [PATCH 186/335] stm32/boards/MIKROE_CLICKER2_STM32: Add more detail to board.json. Signed-off-by: Lorenzo Cappelletti --- ports/stm32/boards/MIKROE_CLICKER2_STM32/board.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ports/stm32/boards/MIKROE_CLICKER2_STM32/board.json b/ports/stm32/boards/MIKROE_CLICKER2_STM32/board.json index 3d7d4904fc..8ff4dda080 100644 --- a/ports/stm32/boards/MIKROE_CLICKER2_STM32/board.json +++ b/ports/stm32/boards/MIKROE_CLICKER2_STM32/board.json @@ -3,11 +3,13 @@ "../deploy.md" ], "docs": "", - "features": [], + "features": [ + "mikroBUS" + ], "images": [], "mcu": "stm32f4", - "product": "MIKROE_CLICKER2_STM32", + "product": "MikroE Clicker 2 for STM32", "thumbnail": "", - "url": "", - "vendor": "" + "url": "https://www.mikroe.com/clicker-2-stm32f4", + "vendor": "MikroElektronika" } From 8f0e304e65a83e1f52dfb29185159e8eb9f7f34d Mon Sep 17 00:00:00 2001 From: Lorenzo Cappelletti Date: Mon, 11 Oct 2021 23:55:06 +0200 Subject: [PATCH 187/335] stm32/boards: Add new board MikroElektronika Quail, and F427 support. Quail (https://www.mikroe.com/quail, PID: MIKROE-1793) is based on an STM32F427VI CPU, featuring 2048 kB of Flash memory and 192 kB of RAM. An on-board Cypress S25FL164K adds 8 MB of SPI Flash. Quail has 4 mikroBUS(TM) sockets for Mikroe click(TM) board connectivity, along with 24 screw terminals for connecting additional electronics and two USB ports (one for programming, the other for external mass storage). 4 UARTs, 2 SPIs and 1 I2C bus are available for communication. Signed-off-by: Lorenzo Cappelletti --- ports/stm32/boards/MIKROE_QUAIL/bdev.c | 28 ++++ ports/stm32/boards/MIKROE_QUAIL/board.json | 18 +++ ports/stm32/boards/MIKROE_QUAIL/deploy.md | 13 ++ .../stm32/boards/MIKROE_QUAIL/mpconfigboard.h | 109 ++++++++++++++++ .../boards/MIKROE_QUAIL/mpconfigboard.mk | 10 ++ ports/stm32/boards/MIKROE_QUAIL/pins.csv | 120 ++++++++++++++++++ .../boards/MIKROE_QUAIL/stm32f4xx_hal_conf.h | 18 +++ ports/stm32/boards/stm32f427xi.ld | 28 ++++ ports/stm32/flashbdev.c | 2 +- 9 files changed, 345 insertions(+), 1 deletion(-) create mode 100644 ports/stm32/boards/MIKROE_QUAIL/bdev.c create mode 100644 ports/stm32/boards/MIKROE_QUAIL/board.json create mode 100644 ports/stm32/boards/MIKROE_QUAIL/deploy.md create mode 100644 ports/stm32/boards/MIKROE_QUAIL/mpconfigboard.h create mode 100644 ports/stm32/boards/MIKROE_QUAIL/mpconfigboard.mk create mode 100644 ports/stm32/boards/MIKROE_QUAIL/pins.csv create mode 100644 ports/stm32/boards/MIKROE_QUAIL/stm32f4xx_hal_conf.h create mode 100644 ports/stm32/boards/stm32f427xi.ld diff --git a/ports/stm32/boards/MIKROE_QUAIL/bdev.c b/ports/stm32/boards/MIKROE_QUAIL/bdev.c new file mode 100644 index 0000000000..7095817e49 --- /dev/null +++ b/ports/stm32/boards/MIKROE_QUAIL/bdev.c @@ -0,0 +1,28 @@ +#include "py/obj.h" +#include "storage.h" +#include "spi.h" + +#if !MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE + +STATIC const spi_proto_cfg_t spi_bus = { + .spi = &spi_obj[2], // SPI3 hardware peripheral + .baudrate = 25000000, + .polarity = 0, + .phase = 0, + .bits = 8, + .firstbit = SPI_FIRSTBIT_MSB, +}; + +STATIC mp_spiflash_cache_t spi_bdev_cache; + +const mp_spiflash_config_t spiflash_config = { + .bus_kind = MP_SPIFLASH_BUS_SPI, + .bus.u_spi.cs = MICROPY_HW_SPIFLASH_CS, + .bus.u_spi.data = (void *)&spi_bus, + .bus.u_spi.proto = &spi_proto, + .cache = &spi_bdev_cache, +}; + +spi_bdev_t spi_bdev; + +#endif diff --git a/ports/stm32/boards/MIKROE_QUAIL/board.json b/ports/stm32/boards/MIKROE_QUAIL/board.json new file mode 100644 index 0000000000..ccd9b4fdc0 --- /dev/null +++ b/ports/stm32/boards/MIKROE_QUAIL/board.json @@ -0,0 +1,18 @@ +{ + "deploy": [ + "../MIKROE_QUAIL/deploy.md" + ], + "docs": "", + "features": [ + "mikroBUS" + ], + "id": "MIKROE-QUAIL", + "images": [ + "quail_top.jpg" + ], + "mcu": "stm32f4", + "product": "MikroE Quail", + "thumbnail": "", + "url": "https://www.mikroe.com/quail", + "vendor": "MikroElektronika" +} diff --git a/ports/stm32/boards/MIKROE_QUAIL/deploy.md b/ports/stm32/boards/MIKROE_QUAIL/deploy.md new file mode 100644 index 0000000000..5d6ea00a2e --- /dev/null +++ b/ports/stm32/boards/MIKROE_QUAIL/deploy.md @@ -0,0 +1,13 @@ +### Quail via DFU + +Quail can be programmed via USB with the ST DFU bootloader, using +e.g. [dfu-util](http://dfu-util.sourceforge.net/) or +[pydfu.py](https://github.com/micropython/micropython/blob/master/tools/pydfu.py). + +To enter the bootloader press and release the Reset button while holding the +Boot button. Alternatively, you can use `machine.bootloader()` from the +MicroPython REPL. + +```bash +dfu-util --alt 0 -D firmware.dfu +``` diff --git a/ports/stm32/boards/MIKROE_QUAIL/mpconfigboard.h b/ports/stm32/boards/MIKROE_QUAIL/mpconfigboard.h new file mode 100644 index 0000000000..6cb6b72600 --- /dev/null +++ b/ports/stm32/boards/MIKROE_QUAIL/mpconfigboard.h @@ -0,0 +1,109 @@ +#define MICROPY_HW_BOARD_NAME "MikroE Quail" +#define MICROPY_HW_MCU_NAME "STM32F427VI" + +// 1 = use STM32 internal flash (1 MByte) +// 0 = use onboard external SPI flash (8 MByte) +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (0) + +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_HAS_FLASH (1) + +// HSE is 12MHz +#define MICROPY_HW_CLK_PLLM (6) +#define MICROPY_HW_CLK_PLLN (336) +#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV4) +#define MICROPY_HW_CLK_PLLQ (14) +#define MICROPY_HW_CLK_LAST_FREQ (1) + +// The board has no crystal for the RTC +#define MICROPY_HW_RTC_USE_LSE (0) +#define MICROPY_HW_RTC_USE_US (0) +#define MICROPY_HW_RTC_USE_CALOUT (0) // turn on/off PC13 512Hz output + +// UART config +// mikroBUS slot 1 +#define MICROPY_HW_UART3_NAME "SLOT1" +#define MICROPY_HW_UART3_TX (pin_D8) +#define MICROPY_HW_UART3_RX (pin_D9) +// mikroBUS slot 2 +#define MICROPY_HW_UART2_NAME "SLOT2" +#define MICROPY_HW_UART2_TX (pin_D5) +#define MICROPY_HW_UART2_RX (pin_D6) +// mikroBUS slot 3 +#define MICROPY_HW_UART6_NAME "SLOT3" +#define MICROPY_HW_UART6_TX (pin_C6) +#define MICROPY_HW_UART6_RX (pin_C7) +// mikroBUS slot 4 +#define MICROPY_HW_UART1_NAME "SLOT4" +#define MICROPY_HW_UART1_TX (pin_A9) +#define MICROPY_HW_UART1_RX (pin_A10) + +// I2C buses +// mikroBUS slot 1, 2, 3, 4, and header +#define MICROPY_HW_I2C1_NAME "SLOT1234H" +#define MICROPY_HW_I2C1_SCL (pin_B6) +#define MICROPY_HW_I2C1_SDA (pin_B7) + +// SPI buses +// mikroBUS slot 1, 2, and header +#define MICROPY_HW_SPI1_NAME "SLOT12H" +#define MICROPY_HW_SPI1_SCK (pin_B3) +#define MICROPY_HW_SPI1_MISO (pin_B4) +#define MICROPY_HW_SPI1_MOSI (pin_B5) +// mikroBUS slot 3, 4, and FLASH +#define MICROPY_HW_SPI3_NAME "SLOT34F" +#define MICROPY_HW_SPI3_SCK (pin_C10) +#define MICROPY_HW_SPI3_MISO (pin_C11) +#define MICROPY_HW_SPI3_MOSI (pin_C12) + +// LEDs +#define MICROPY_HW_LED1 (pin_E15) // orange +#define MICROPY_HW_LED2 (pin_E10) // green +#define MICROPY_HW_LED3 (pin_C3) // red +#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) +#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) + +// USB config +#define MICROPY_HW_USB_FS (1) + +// External SPI Flash config (Cypress S25FL164K) +#if !MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE + +#define MICROPY_HW_SPIFLASH_SIZE_BITS (64 * 1024 * 1024) // 64 Mbit (8 MByte) + +#define MICROPY_HW_SPIFLASH_CS (pin_A13) +#define MICROPY_HW_SPIFLASH_SCK (MICROPY_HW_SPI3_SCK) +#define MICROPY_HW_SPIFLASH_MISO (MICROPY_HW_SPI3_MISO) +#define MICROPY_HW_SPIFLASH_MOSI (MICROPY_HW_SPI3_MOSI) + +extern const struct _mp_spiflash_config_t spiflash_config; +extern struct _spi_bdev_t spi_bdev; +#define MICROPY_HW_SPIFLASH_ENABLE_CACHE (1) +#define MICROPY_HW_BDEV_IOCTL(op, arg) ( \ + (op) == BDEV_IOCTL_NUM_BLOCKS ? (MICROPY_HW_SPIFLASH_SIZE_BITS / 8 / FLASH_BLOCK_SIZE) : \ + (op) == BDEV_IOCTL_INIT ? spi_bdev_ioctl(&spi_bdev, (op), (uint32_t)&spiflash_config) : \ + spi_bdev_ioctl(&spi_bdev, (op), (arg)) \ +) +#define MICROPY_HW_BDEV_READBLOCKS(dest, bl, n) spi_bdev_readblocks(&spi_bdev, (dest), (bl), (n)) +#define MICROPY_HW_BDEV_WRITEBLOCKS(src, bl, n) spi_bdev_writeblocks(&spi_bdev, (src), (bl), (n)) +#define MICROPY_HW_BDEV_SPIFLASH_EXTENDED (&spi_bdev) // for extended block protocol + +#endif // !MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE + +// Bootloader configuration (only needed if Mboot is used) +#define MBOOT_I2C_PERIPH_ID 1 +#define MBOOT_I2C_SCL (pin_B6) +#define MBOOT_I2C_SDA (pin_B7) +#define MBOOT_I2C_ALTFUNC (4) +#define MBOOT_FSLOAD (1) +#define MBOOT_VFS_FAT (1) + +#define MBOOT_SPIFLASH_ADDR (0x80000000) +#define MBOOT_SPIFLASH_BYTE_SIZE (8 * 1024 * 1024) +#define MBOOT_SPIFLASH_LAYOUT "/0x80000000/512*8Kg" +#define MBOOT_SPIFLASH_ERASE_BLOCKS_PER_PAGE \ + (8 / 4) // 8k page, 4k erase block +#define MBOOT_SPIFLASH_CONFIG (&spiflash_config) +#define MBOOT_SPIFLASH_SPIFLASH (&spi_bdev.spiflash) diff --git a/ports/stm32/boards/MIKROE_QUAIL/mpconfigboard.mk b/ports/stm32/boards/MIKROE_QUAIL/mpconfigboard.mk new file mode 100644 index 0000000000..12f4f57988 --- /dev/null +++ b/ports/stm32/boards/MIKROE_QUAIL/mpconfigboard.mk @@ -0,0 +1,10 @@ +MCU_SERIES = f4 +CMSIS_MCU = STM32F427xx +LD_FILES = boards/stm32f427xi.ld boards/common_ifs.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08020000 + +# According to the datasheet, page 75, table 12, the alternate functions +# of STM32F427xx and STM32F429xx are exactly the same. +# See https://www.st.com/resource/en/datasheet/stm32f427vi.pdf. +AF_FILE = boards/stm32f429_af.csv diff --git a/ports/stm32/boards/MIKROE_QUAIL/pins.csv b/ports/stm32/boards/MIKROE_QUAIL/pins.csv new file mode 100644 index 0000000000..41868cf722 --- /dev/null +++ b/ports/stm32/boards/MIKROE_QUAIL/pins.csv @@ -0,0 +1,120 @@ +# Pin mapping for board MikroElektronika Quail, based on CPU STM32F427VIT6 + +### mikroBUS ########################### + +# Slot 1 (SPI1, UART3, I2C1) +MB1_AN,PA6 +MB1_RST,PA2 +MB1_CS,PA3 +MB1_SCK,PB3 +MB1_MISO,PB4 +MB1_MOSI,PB5 +MB1_PWM,PE9 +MB1_INT,PA1 +MB1_RX,PD9 +MB1_TX,PD8 +MB1_SCL,PB6 +MB1_SDA,PB7 + +# Slot 2 (SPI1, UART2, I2C1) +MB2_AN,PA4 +MB2_RST,PE1 +MB2_CS,PE0 +MB2_SCK,PB3 +MB2_MISO,PB4 +MB2_MOSI,PB5 +MB2_PWM,PD15 +MB2_INT,PB9 +MB2_RX,PD6 +MB2_TX,PD5 +MB2_SCL,PB6 +MB2_SDA,PB7 + +# Slot 3 (SPI3, UART6, I2C1) +MB3_AN,PA7 +MB3_RST,PD8 +MB3_CS,PD11 +MB3_SCK,PC10 +MB3_MISO,PC11 +MB3_MOSI,PC12 +MB3_PWM,PD13 +MB3_INT,PC8 +MB3_RX,PC7 +MB3_TX,PC6 +MB3_SCL,PB6 +MB3_SDA,PB7 + +# Slot 4 (SPI3, UART1, I2C1) +MB4_AN,PA5 +MB4_RST,PD0 +MB4_CS,PD1 +MB4_SCK,PC10 +MB4_MISO,PC11 +MB4_MOSI,PC12 +MB4_PWM,PD14 +MB4_INT,PA14 +MB4_RX,PA10 +MB4_TX,PA9 +MB4_SCL,PB6 +MB4_SDA,PB7 + + +### Edge Contacts ###################### + +,PC5 +,PB0 +,PE7 +,PE8 + +,PE11 +,PC4 +,PE13 +,PE14 + +,PB10 +,PB11 +,PB12 +,PB13 + +# I2C1 +,PB6 +,PB7 + +# SPI3 +,PC10 +,PC11 +,PC12 +,PD10 + +,PA15 +,PC13 +,PE6 +,PE5 + +,PD2 +,PD3 +,PD4 +,PD7 + +,PE2 +,PE3 +,PE4 + + +### FLASH Memory ####################### + +# Spansion S25FL164K - SPI3 +FLASH_CS,PA13 + + +### LED ################################ + +LED1,PE15 +LED2,PE10 +LED3,PC3 + + +### Micro USB ########################## + +,-PA11 +,-PA12 diff --git a/ports/stm32/boards/MIKROE_QUAIL/stm32f4xx_hal_conf.h b/ports/stm32/boards/MIKROE_QUAIL/stm32f4xx_hal_conf.h new file mode 100644 index 0000000000..b8b935915f --- /dev/null +++ b/ports/stm32/boards/MIKROE_QUAIL/stm32f4xx_hal_conf.h @@ -0,0 +1,18 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2021 Lorenzo Cappelletti + */ +#ifndef MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H + +#include "boards/stm32f4xx_hal_conf_base.h" + +// Oscillator values in Hz +#define HSE_VALUE (12000000) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (100) +#define LSE_STARTUP_TIMEOUT (0) + +#endif // MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H diff --git a/ports/stm32/boards/stm32f427xi.ld b/ports/stm32/boards/stm32f427xi.ld new file mode 100644 index 0000000000..1197848af1 --- /dev/null +++ b/ports/stm32/boards/stm32f427xi.ld @@ -0,0 +1,28 @@ +/* + GNU linker script for STM32F427xI +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K /* entire flash */ + FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0, 16 KiB */ + FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 112K /* sectors 1-4: 3*16K+64K */ + FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 896K /* sectors 5-11 are 128K */ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K +} + +/* 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 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) - _estack_reserve; +_sstack = _estack - 16K; /* tunable */ + +/* RAM extents for the garbage collector */ +_ram_start = ORIGIN(RAM); +_ram_end = ORIGIN(RAM) + LENGTH(RAM); +_heap_start = _ebss; /* heap starts just after statically allocated memory */ +_heap_end = _sstack; diff --git a/ports/stm32/flashbdev.c b/ports/stm32/flashbdev.c index 6be0cfee8a..3b7609d4d2 100644 --- a/ports/stm32/flashbdev.c +++ b/ports/stm32/flashbdev.c @@ -70,7 +70,7 @@ STATIC byte flash_cache_mem[0x4000] __attribute__((aligned(4))); // 16k #define FLASH_MEM_SEG2_START_ADDR (0x08040000) // sector 6 #define FLASH_MEM_SEG2_NUM_BLOCKS (128) // sector 6: 64k(of 128k). Filesystem 176K + 64K = 240K -#elif defined(STM32F429xx) +#elif defined(STM32F427xx) || defined(STM32F429xx) #define CACHE_MEM_START_ADDR (0x10000000) // CCM data RAM, 64k #define FLASH_SECTOR_SIZE_MAX (0x10000) // 64k max, size of CCM From 78ab2eeda311241fcb692336f6f8240d2c79e878 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 19 Nov 2021 17:05:40 +1100 Subject: [PATCH 188/335] py/showbc: Print unary-op string when dumping bytecode. Signed-off-by: Damien George --- py/showbc.c | 3 ++- tests/cmdline/cmd_showbc.py.exp | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/py/showbc.c b/py/showbc.c index c321dfd755..f3bd5ea15e 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -519,7 +519,8 @@ const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip) { } else if (ip[-1] < MP_BC_STORE_FAST_MULTI + 16) { mp_printf(print, "STORE_FAST " UINT_FMT, (mp_uint_t)ip[-1] - MP_BC_STORE_FAST_MULTI); } else if (ip[-1] < MP_BC_UNARY_OP_MULTI + MP_UNARY_OP_NUM_BYTECODE) { - mp_printf(print, "UNARY_OP " UINT_FMT, (mp_uint_t)ip[-1] - MP_BC_UNARY_OP_MULTI); + mp_uint_t op = ip[-1] - MP_BC_UNARY_OP_MULTI; + mp_printf(print, "UNARY_OP " UINT_FMT " %s", op, qstr_str(mp_unary_op_method_name[op])); } else if (ip[-1] < MP_BC_BINARY_OP_MULTI + MP_BINARY_OP_NUM_BYTECODE) { mp_uint_t op = ip[-1] - MP_BC_BINARY_OP_MULTI; mp_printf(print, "BINARY_OP " UINT_FMT " %s", op, qstr_str(mp_binary_op_method_name[op])); diff --git a/tests/cmdline/cmd_showbc.py.exp b/tests/cmdline/cmd_showbc.py.exp index d93fd7b487..22712b79ee 100644 --- a/tests/cmdline/cmd_showbc.py.exp +++ b/tests/cmdline/cmd_showbc.py.exp @@ -92,10 +92,10 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): 58 BINARY_OP 27 __add__ \\d\+ STORE_FAST 8 \\d\+ LOAD_FAST 0 -\\d\+ UNARY_OP 1 +\\d\+ UNARY_OP 1 __neg__ \\d\+ STORE_FAST 9 \\d\+ LOAD_FAST 0 -\\d\+ UNARY_OP 3 +\\d\+ UNARY_OP 3 \\d\+ STORE_FAST 10 \\d\+ LOAD_FAST 0 \\d\+ LOAD_DEREF 14 @@ -116,7 +116,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): \\d\+ LOAD_DEREF 14 \\d\+ LOAD_FAST 1 \\d\+ BINARY_OP 2 __eq__ -\\d\+ UNARY_OP 3 +\\d\+ UNARY_OP 3 \\d\+ STORE_FAST 10 \\d\+ LOAD_DEREF 14 \\d\+ LOAD_ATTR c From 123dcdb8e5b2f89b7dca07dae552db98feee309b Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 19 Nov 2021 17:26:04 +1100 Subject: [PATCH 189/335] py/modsys: Replace non-ASCII quote char with ASCII char. The source code should stay 7-bit ASCII clean. Signed-off-by: Damien George --- py/modsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/modsys.c b/py/modsys.c index 64349f3c30..43666bc00e 100644 --- a/py/modsys.c +++ b/py/modsys.c @@ -175,7 +175,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_sys_atexit_obj, mp_sys_atexit); #endif #if MICROPY_PY_SYS_SETTRACE -// settrace(tracefunc): Set the system’s trace function. +// settrace(tracefunc): Set the system's trace function. STATIC mp_obj_t mp_sys_settrace(mp_obj_t obj) { return mp_prof_settrace(obj); } From e83aa252f7c58db3d1a95b399c1bcdf791dcf819 Mon Sep 17 00:00:00 2001 From: Peter Boin Date: Wed, 8 Sep 2021 15:45:03 +1000 Subject: [PATCH 190/335] stm32/main: Run optional frozen module at boot. If a board specifies a filename via MICROPY_BOARD_FROZEN_BOOT_FILE then that will be run on start up, before the usual boot.py. --- ports/stm32/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 5d1ff2dcf5..974602cb05 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -564,6 +564,11 @@ soft_reset: // reset config variables; they should be set by boot.py MP_STATE_PORT(pyb_config_main) = MP_OBJ_NULL; + // Run optional frozen boot code. + #ifdef MICROPY_BOARD_FROZEN_BOOT_FILE + pyexec_frozen_module(MICROPY_BOARD_FROZEN_BOOT_FILE); + #endif + // Run boot.py (or whatever else a board configures at this stage). if (MICROPY_BOARD_RUN_BOOT_PY(&state) == BOARDCTRL_GOTO_SOFT_RESET_EXIT) { goto soft_reset_exit; From dfa75f33a5a2cb1737e5278f198d0dac0a5867eb Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 15 Nov 2021 14:39:32 +1100 Subject: [PATCH 191/335] stm32/sdio: Don't explicitly disable DMA2 on deinit of SDIO. Because DMA2 may be in use by other peripherals, eg SPI1. On PYBD-SF6 it's possible to trigger a bug in the existing code by turning on WLAN and connecting to an AP, pinging the IP address from a PC and running the following code on the PYBD: def spi_test(s): while 1: s.write('test') s.read(4) spi_test(machine.SPI(1,100000000)) This will eventually fail with `OSError: [Errno 110] ETIMEDOUT` because DMA2 was turned off by the CYW43 driver during the SPI1 transfer. This commit fixes the bug by removing the code that explicitly disables DMA2. Instead DMA2 will be automatically disabled after an inactivity timeout, see commit a96afae90f6e5d693173382561d06e583b0b5fa5 Signed-off-by: Damien George --- ports/stm32/sdio.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/ports/stm32/sdio.c b/ports/stm32/sdio.c index 3fb84a4d81..bedafcb138 100644 --- a/ports/stm32/sdio.c +++ b/ports/stm32/sdio.c @@ -134,9 +134,6 @@ void sdio_init(uint32_t irq_pri) { void sdio_deinit(void) { SDMMC_CLK_DISABLE(); - #if defined(STM32F7) - __HAL_RCC_DMA2_CLK_DISABLE(); - #endif } void sdio_reenable(void) { From 01ceb9aca3707114dc05b7a45691074b3603a274 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 15 Nov 2021 14:39:39 +1100 Subject: [PATCH 192/335] stm32/dma: Make DMA2_Stream3 exclusive to SDIO when CYW43 enabled. This prevents SPI4/5 from being used if SDIO and CYW43 are enabled, because the DMA for the SDIO is used on an IRQ and must be exclusivly available for use by the SDIO peripheral. Signed-off-by: Damien George --- ports/stm32/dma.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c index 4b078eebb6..b376ee23b5 100644 --- a/ports/stm32/dma.c +++ b/ports/stm32/dma.c @@ -42,6 +42,10 @@ #define ENABLE_SDIO (MICROPY_HW_ENABLE_SDCARD || MICROPY_HW_ENABLE_MMCARD || MICROPY_PY_NETWORK_CYW43) +// If the CYW43 driver is enabled then SDIO DMA can happen preemptively (on an +// IRQ) and so the SDIO needs exclusive access to its DMA resource. +#define SDIO_NEEDS_EXCLUSIVE_DMA_ACCESS (MICROPY_PY_NETWORK_CYW43 && MICROPY_HW_SDIO_SDMMC == 1) + typedef enum { dma_id_not_defined=-1, dma_id_0, @@ -298,11 +302,13 @@ const dma_descr_t dma_SPI_1_RX = { DMA2_Stream2, DMA_CHANNEL_3, dma_id_10, &dma #if MICROPY_HW_ENABLE_I2S const dma_descr_t dma_I2S_1_RX = { DMA2_Stream2, DMA_CHANNEL_3, dma_id_10, &dma_init_struct_i2s }; #endif -const dma_descr_t dma_SPI_5_RX = { DMA2_Stream3, DMA_CHANNEL_2, dma_id_11, &dma_init_struct_spi_i2c }; #if ENABLE_SDIO const dma_descr_t dma_SDIO_0 = { DMA2_Stream3, DMA_CHANNEL_4, dma_id_11, &dma_init_struct_sdio }; #endif +#if !SDIO_NEEDS_EXCLUSIVE_DMA_ACCESS +const dma_descr_t dma_SPI_5_RX = { DMA2_Stream3, DMA_CHANNEL_2, dma_id_11, &dma_init_struct_spi_i2c }; const dma_descr_t dma_SPI_4_RX = { DMA2_Stream3, DMA_CHANNEL_5, dma_id_11, &dma_init_struct_spi_i2c }; +#endif const dma_descr_t dma_SPI_5_TX = { DMA2_Stream4, DMA_CHANNEL_2, dma_id_12, &dma_init_struct_spi_i2c }; const dma_descr_t dma_SPI_4_TX = { DMA2_Stream4, DMA_CHANNEL_5, dma_id_12, &dma_init_struct_spi_i2c }; const dma_descr_t dma_SPI_6_TX = { DMA2_Stream5, DMA_CHANNEL_1, dma_id_13, &dma_init_struct_spi_i2c }; From e2ca8ab8fc2f824dc7ebaa8fe65c4d2e7891080e Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Fri, 17 Jul 2020 22:31:09 +0200 Subject: [PATCH 193/335] py/runtime: Allow types to use both .attr and .locals_dict. Make it possible to proceed to a regular lookup in locals_dict if the custom type->attr fails. This allows type->attr to extend rather than completely replace the lookup in locals_dict. This is useful for custom builtin classes that have mostly regular methods but just a few special attributes/properties. This way, type->attr needs to deal with the special cases only and the default lookup will be used for generic methods. Signed-off-by: Laurens Valk --- py/obj.h | 1 + py/runtime.c | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/py/obj.h b/py/obj.h index 11918ba176..7730059e6a 100644 --- a/py/obj.h +++ b/py/obj.h @@ -551,6 +551,7 @@ struct _mp_obj_type_t { // // dest[0] = MP_OBJ_NULL means load // return: for fail, do nothing + // for fail but continue lookup in locals_dict, dest[1] = MP_OBJ_SENTINEL // for attr, dest[0] = value // for method, dest[0] = method, dest[1] = self // diff --git a/py/runtime.c b/py/runtime.c index 27e77fc290..0120b70d74 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1100,12 +1100,20 @@ void mp_load_method_maybe(mp_obj_t obj, qstr attr, mp_obj_t *dest) { if (attr == MP_QSTR___next__ && type->iternext != NULL) { dest[0] = MP_OBJ_FROM_PTR(&mp_builtin_next_obj); dest[1] = obj; - - } else if (type->attr != NULL) { + return; + } + if (type->attr != NULL) { // this type can do its own load, so call it type->attr(obj, attr, dest); - - } else if (type->locals_dict != NULL) { + // If type->attr has set dest[1] = MP_OBJ_SENTINEL, we should proceed + // with lookups below (i.e. in locals_dict). If not, return right away. + if (dest[1] != MP_OBJ_SENTINEL) { + return; + } + // Clear the fail flag set by type->attr so it's like it never ran. + dest[1] = MP_OBJ_NULL; + } + if (type->locals_dict != NULL) { // generic method lookup // this is a lookup in the object (ie not class or type) assert(type->locals_dict->base.type == &mp_type_dict); // MicroPython restriction, for now @@ -1114,6 +1122,7 @@ void mp_load_method_maybe(mp_obj_t obj, qstr attr, mp_obj_t *dest) { if (elem != NULL) { mp_convert_member_lookup(obj, type, elem->value, dest); } + return; } } From 90554d03c0228f403df3f52ae9c4114c0bdc02b1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 21 Nov 2021 14:47:40 +1100 Subject: [PATCH 194/335] stm32/boards: Build NUCLEO_WB55 and STM32F769DISC without mboot enabled. This is to make the builds for all nucleo/discovery boards uniform, so they can be treated the same by the auto build scripts. The CI script is updated to explicitly enable mboot and packing, to test these features. Signed-off-by: Damien George --- ports/stm32/boards/NUCLEO_WB55/mpconfigboard.mk | 7 ------- ports/stm32/boards/STM32F769DISC/mpconfigboard.mk | 3 --- tools/ci.sh | 8 ++++++-- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/ports/stm32/boards/NUCLEO_WB55/mpconfigboard.mk b/ports/stm32/boards/NUCLEO_WB55/mpconfigboard.mk index 4cb047c95e..dcec788ed4 100644 --- a/ports/stm32/boards/NUCLEO_WB55/mpconfigboard.mk +++ b/ports/stm32/boards/NUCLEO_WB55/mpconfigboard.mk @@ -1,7 +1,3 @@ -# By default this board is configured to use mboot with packing (signing and encryption) -# enabled. Mboot must be deployed first. -USE_MBOOT ?= 1 - MCU_SERIES = wb CMSIS_MCU = STM32WB55xx AF_FILE = boards/stm32wb55_af.csv @@ -21,6 +17,3 @@ endif MICROPY_PY_BLUETOOTH = 1 MICROPY_BLUETOOTH_NIMBLE = 1 MICROPY_VFS_LFS2 = 1 - -# Mboot settings -MBOOT_ENABLE_PACKING = 1 diff --git a/ports/stm32/boards/STM32F769DISC/mpconfigboard.mk b/ports/stm32/boards/STM32F769DISC/mpconfigboard.mk index 5d3d11a795..dfee1a7ac7 100644 --- a/ports/stm32/boards/STM32F769DISC/mpconfigboard.mk +++ b/ports/stm32/boards/STM32F769DISC/mpconfigboard.mk @@ -1,6 +1,3 @@ -# By default this board is configured to use mboot which must be deployed first -USE_MBOOT ?= 1 - # By default the filesystem is in external QSPI flash. But by setting the # following option this board puts some code into external flash set in XIP mode. # USE_MBOOT must be enabled; see f769_qspi.ld for code that goes in QSPI flash diff --git a/tools/ci.sh b/tools/ci.sh index f9b90b9687..bf5b1fd043 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -282,12 +282,16 @@ function ci_stm32_nucleo_build { make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/stm32 submodules git submodule update --init lib/mynewt-nimble + + # Test building various MCU families, some with additional options. make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_F091RC make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_H743ZI CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_L073RZ make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_L476RG DEBUG=1 - make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_WB55 - make ${MAKEOPTS} -C ports/stm32/mboot BOARD=NUCLEO_WB55 + + # Test building a board with mboot packing enabled (encryption, signing, compression). + make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_WB55 USE_MBOOT=1 MBOOT_ENABLE_PACKING=1 + make ${MAKEOPTS} -C ports/stm32/mboot BOARD=NUCLEO_WB55 USE_MBOOT=1 MBOOT_ENABLE_PACKING=1 # Test mboot_pack_dfu.py created a valid file, and that its unpack-dfu command works. BOARD_WB55=ports/stm32/boards/NUCLEO_WB55 BUILD_WB55=ports/stm32/build-NUCLEO_WB55 From bb7aae557ba639499c5bc08d4f098913a95ad027 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 21 Nov 2021 14:54:55 +1100 Subject: [PATCH 195/335] tools/autobuild: Automatically build all stm32 boards. Any board with a board.json file will be built. Additional variants for certain pyboards will also be built by the explicit build-stm32-extra.sh script. Both .dfu and .hex files will be made available. Also build boards in a sorted order, and don't stop building if a single board fails. Signed-off-by: Damien George --- tools/autobuild/autobuild.sh | 7 ++++--- tools/autobuild/build-boards.sh | 15 ++++++++++----- ...build-stm32-latest.sh => build-stm32-extra.sh} | 13 ++----------- 3 files changed, 16 insertions(+), 19 deletions(-) rename tools/autobuild/{build-stm32-latest.sh => build-stm32-extra.sh} (82%) diff --git a/tools/autobuild/autobuild.sh b/tools/autobuild/autobuild.sh index bb77b178b9..1532c9820f 100755 --- a/tools/autobuild/autobuild.sh +++ b/tools/autobuild/autobuild.sh @@ -65,9 +65,7 @@ FW_GIT="$(git describe --dirty || echo unknown)" FW_TAG="-$FW_DATE-unstable-$FW_GIT" # build new firmware -cd ports/stm32 -${AUTODIR}/build-stm32-latest.sh ${FW_TAG} ${LOCAL_FIRMWARE} -cd ../cc3200 +cd ports/cc3200 ${AUTODIR}/build-cc3200-latest.sh ${FW_TAG} ${LOCAL_FIRMWARE} cd ../esp8266 ${AUTODIR}/build-esp8266-latest.sh ${FW_TAG} ${LOCAL_FIRMWARE} @@ -81,6 +79,9 @@ cd ../rp2 build_rp2_boards ${FW_TAG} ${LOCAL_FIRMWARE} cd ../samd build_samd_boards ${FW_TAG} ${LOCAL_FIRMWARE} +cd ../stm32 +build_stm32_boards ${FW_TAG} ${LOCAL_FIRMWARE} +${AUTODIR}/build-stm32-extra.sh ${FW_TAG} ${LOCAL_FIRMWARE} popd diff --git a/tools/autobuild/build-boards.sh b/tools/autobuild/build-boards.sh index 1ae795a7a7..bb5d8d344e 100755 --- a/tools/autobuild/build-boards.sh +++ b/tools/autobuild/build-boards.sh @@ -26,16 +26,17 @@ function build_boards { return 1 fi - for board_json in $(find boards/ -name board.json); do + for board_json in $(find boards/ -name board.json | sort); do board=$(echo $board_json | awk -F '/' '{ print $2 }') descr=$(cat $board_json | python3 -c "import json,sys; print(json.load(sys.stdin).get('id', '$board'))") build_dir=/tmp/micropython-build-$board echo "building $descr $board" - $MICROPY_AUTOBUILD_MAKE BOARD=$board BUILD=$build_dir || return 1 - for ext in $@; do - mv $build_dir/firmware.$ext $dest_dir/$descr$fw_tag.$ext - done + $MICROPY_AUTOBUILD_MAKE BOARD=$board BUILD=$build_dir && ( + for ext in $@; do + mv $build_dir/firmware.$ext $dest_dir/$descr$fw_tag.$ext + done + ) rm -rf $build_dir done } @@ -51,3 +52,7 @@ function build_rp2_boards { function build_samd_boards { build_boards $1 $2 samd_soc.c uf2 } + +function build_stm32_boards { + build_boards $1 $2 modpyb.c dfu hex +} diff --git a/tools/autobuild/build-stm32-latest.sh b/tools/autobuild/build-stm32-extra.sh similarity index 82% rename from tools/autobuild/build-stm32-latest.sh rename to tools/autobuild/build-stm32-extra.sh index 283c8a45b8..43842d6c90 100755 --- a/tools/autobuild/build-stm32-latest.sh +++ b/tools/autobuild/build-stm32-extra.sh @@ -1,4 +1,5 @@ #!/bin/bash +# Build additional variants of pyboard firmware (base variants are built by build-boards.sh). # function for building firmware function do_build() { @@ -10,6 +11,7 @@ function do_build() { build_dir=/tmp/stm-build-$board $MICROPY_AUTOBUILD_MAKE $@ BOARD=$board BUILD=$build_dir || exit 1 mv $build_dir/firmware.dfu $dest_dir/$descr$fw_tag.dfu + mv $build_dir/firmware.hex $dest_dir/$descr$fw_tag.hex rm -rf $build_dir } @@ -31,26 +33,15 @@ fi # build the versions do_build pybv3 PYBV3 do_build pybv3-network PYBV3 MICROPY_PY_WIZNET5K=5200 MICROPY_PY_CC3K=1 -do_build pybv10 PYBV10 do_build pybv10-dp PYBV10 MICROPY_FLOAT_IMPL=double do_build pybv10-thread PYBV10 CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' do_build pybv10-dp-thread PYBV10 MICROPY_FLOAT_IMPL=double CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' do_build pybv10-network PYBV10 MICROPY_PY_WIZNET5K=5200 MICROPY_PY_CC3K=1 -do_build pybv11 PYBV11 do_build pybv11-dp PYBV11 MICROPY_FLOAT_IMPL=double do_build pybv11-thread PYBV11 CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' do_build pybv11-dp-thread PYBV11 MICROPY_FLOAT_IMPL=double CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' do_build pybv11-network PYBV11 MICROPY_PY_WIZNET5K=5200 MICROPY_PY_CC3K=1 -do_build pyblitev10 PYBLITEV10 do_build pyblitev10-dp PYBLITEV10 MICROPY_FLOAT_IMPL=double do_build pyblitev10-thread PYBLITEV10 CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' do_build pyblitev10-dp-thread PYBLITEV10 MICROPY_FLOAT_IMPL=double CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' do_build pyblitev10-network PYBLITEV10 MICROPY_PY_WIZNET5K=5200 MICROPY_PY_CC3K=1 -do_build PYBD-SF2 PYBD_SF2 -do_build PYBD-SF3 PYBD_SF3 -do_build PYBD-SF6 PYBD_SF6 - -for board in boards/{NUCLEO_*,STM32F*DISC,B_L*,USBDONGLE_WB55,ESPRUINO_PICO} ; do - bd=$(basename $board) - do_build $bd $bd USE_MBOOT=0 MBOOT_ENABLE_PACKING=0 -done From 81f706aee46d60aa8a91c524da839f743e4cc608 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 26 Jul 2021 12:48:25 +0200 Subject: [PATCH 196/335] mimxrt: Support PWM using the FLEXPWM and QTMR modules. Frequency range 15Hz/18Hz to > 1 MHz, with decreasing resolution of the duty cycle. The basic API is supported as documentated, except that keyword parameters are accepted for both the instatiaton and the PWM.init() call. Extensions: support PWM for channel pairs. Channel pairs are declared by supplying 2-element tuples for the pins. The two channels of a pair must be the A/B channel of a FLEXPWM module. These form than a complementary pair. Additional supported keyword arguments: - center=value Defines the center position of a pulse within the pulse cycle. The align keyword is actually shortcut for center. - sync=True|False: If set to True, the channels will be synchronized to a submodule 0 channel, which has already to be enabled. - align=PWM.MIDDLE | PMW.BEGIN | PWM.END. It defines, whether synchronized channels are Center-Aligned or Edge-aligned. The channels must be either complementary a channel pair or a group of synchronized channels. It may as well be applied to a single channel, but withiout any benefit. - invert= 0..3. Controls ouput inversion of the pins. Bit 0 controls the first pin, bit 1 the second. - deadtime=time_ns time of complementary channels for delaying the rising slope. - xor=0|1|2 xor causes the output of channel A and B to be xored. If applied to a X channel, it shows the value oif A ^ B. If applied to an A or B channel, both channel show the xored signal for xor=1. For xor=2, the xored signal is split between channels A and B. See also the Reference Manual, chapter about double pulses. The behavior of xor=2 can also be achieved using the center method for locating a pulse within a clock period. The output is enabled for board pins only. CPU pins may still be used for FLEXPWM, e.g. as sync source, but the signal will not be routed to the output. That applies only to FLEXPWM pins. The use of QTMR pins which are not board pins will be rejected. As part of this commit, the _WFE() statement is removed from ticks_delay_us64() to prevent PWM glitching during calls to sleep(). --- ports/mimxrt/Makefile | 8 + .../boards/MIMXRT1010_EVK/mpconfigboard.h | 4 +- ports/mimxrt/boards/MIMXRT1021.ld | 4 +- ports/mimxrt/boards/MIMXRT1021_af.csv | 72 +- ports/mimxrt/boards/make-pins.py | 28 +- ports/mimxrt/hal/pwm_backport.c | 180 +++++ ports/mimxrt/hal/pwm_backport.h | 51 ++ ports/mimxrt/machine_pwm.c | 618 ++++++++++++++++++ ports/mimxrt/main.c | 1 + ports/mimxrt/modmachine.c | 1 + ports/mimxrt/modmachine.h | 2 + ports/mimxrt/mpconfigport.h | 4 + ports/mimxrt/ticks.c | 4 +- 13 files changed, 922 insertions(+), 55 deletions(-) create mode 100644 ports/mimxrt/hal/pwm_backport.c create mode 100644 ports/mimxrt/hal/pwm_backport.h create mode 100644 ports/mimxrt/machine_pwm.c diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 7cda558bdc..eeab29ddc3 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -194,6 +194,7 @@ SRC_HAL_IMX_C += \ $(MCU_DIR)/drivers/fsl_lpuart.c \ $(MCU_DIR)/drivers/fsl_ocotp.c \ $(MCU_DIR)/drivers/fsl_pit.c \ + $(MCU_DIR)/drivers/fsl_pwm.c \ $(MCU_DIR)/drivers/fsl_snvs_lp.c \ $(MCU_DIR)/drivers/fsl_trng.c \ $(MCU_DIR)/drivers/fsl_wdog.c \ @@ -209,6 +210,11 @@ ifeq ($(MICROPY_PY_MACHINE_SDCARD),1) SRC_HAL_IMX_C += $(MCU_DIR)/drivers/fsl_usdhc.c endif +ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES), MIMXRT1015 MIMXRT1021 MIMXRT1052 MIMXRT1062 MIMXRT1064)) +SRC_HAL_IMX_C += \ + $(MCU_DIR)/drivers/fsl_qtmr.c +endif + SRC_C += \ board_init.c \ dma_channel.c \ @@ -220,6 +226,7 @@ SRC_C += \ extmod/modusocket.c \ extmod/uos_dupterm.c \ fatfs_port.c \ + hal/pwm_backport.c \ led.c \ machine_adc.c \ machine_bitstream.c \ @@ -384,6 +391,7 @@ SRC_QSTR += \ machine_adc.c \ machine_led.c \ machine_pin.c \ + machine_pwm.c \ machine_rtc.c \ machine_sdcard.c \ machine_spi.c \ diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h index 918513b230..7b2d2a8a63 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h @@ -14,12 +14,12 @@ // LPUART4 on D6/D7 -> 2 #define MICROPY_HW_UART_NUM (sizeof(uart_index_table) / sizeof(uart_index_table)[0]) -#define MICROPY_HW_UART_INDEX { 0, 1, 4, 3 } +#define MICROPY_HW_UART_INDEX { 0, 1, 4 } #define IOMUX_TABLE_UART \ { IOMUXC_GPIO_10_LPUART1_TXD }, { IOMUXC_GPIO_09_LPUART1_RXD }, \ { 0 }, { 0 }, \ - { IOMUXC_GPIO_08_LPUART3_TXD }, { IOMUXC_GPIO_AD_07_LPUART3_RXD }, \ + { 0 }, { 0 }, \ { IOMUXC_GPIO_AD_02_LPUART4_TXD }, { IOMUXC_GPIO_AD_01_LPUART4_RXD }, #define MICROPY_HW_SPI_INDEX { 1 } diff --git a/ports/mimxrt/boards/MIMXRT1021.ld b/ports/mimxrt/boards/MIMXRT1021.ld index 64f4e537e0..1263cd336c 100644 --- a/ports/mimxrt/boards/MIMXRT1021.ld +++ b/ports/mimxrt/boards/MIMXRT1021.ld @@ -21,11 +21,11 @@ vfs_start = flash_start + 0x00100000; text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); itcm_start = 0x00000000; -itcm_size = 0x00008000; +itcm_size = 0x00010000; dtcm_start = 0x20000000; dtcm_size = 0x00018000; ocrm_start = 0x20200000; -ocrm_size = 0x00020000; +ocrm_size = 0x00018000; #ifdef MICROPY_HW_SDRAM_AVAIL sdram_start = 0x80000000; diff --git a/ports/mimxrt/boards/MIMXRT1021_af.csv b/ports/mimxrt/boards/MIMXRT1021_af.csv index 668b415f0b..3ce38eb0b9 100644 --- a/ports/mimxrt/boards/MIMXRT1021_af.csv +++ b/ports/mimxrt/boards/MIMXRT1021_af.csv @@ -5,30 +5,30 @@ GPIO_AD_B0_02,JTAG_MOD,,,,,GPIO1_IO02,USBPHY1_TSTI_TX_LS_MODE,GPT1_CAPTURE1,,,,, GPIO_AD_B0_03,JTAG_TDI,USDHC2_CD_B,WDOG1_B,SAI1_MCLK,USDHC1_WP,GPIO1_IO03,USB_OTG1_OC,CCM_PMIC_RDY,,,,,ALT0 GPIO_AD_B0_04,JTAG_TDO,FLEXCAN1_TX,USDHC1_WP,TMR2_TIMER0,ENET_MDIO,GPIO1_IO04,USB_OTG1_PWR,EWM_OUT_B,,,,,ALT0 GPIO_AD_B0_05,JTAG_TRSTB,FLEXCAN1_RX,USDHC1_CD_B,TMR2_TIMER1,ENET_MDC,GPIO1_IO05,USB_OTG1_ID,ARM_NMI,,,,,ALT0 -GPIO_AD_B0_06,PIT_TRIGGER0,MQS_RIGHT,LPUART1_TXD,TMR2_TIMER2,FLEXPWM2_PWMA3,GPIO1_IO06,REF_32K_OUT,,,,,,ALT5 -GPIO_AD_B0_07,PIT_TRIGGER1,MQS_LEFT,LPUART1_RXD,TMR2_TIMER3,FLEXPWM2_PWMB3,GPIO1_IO07,REF_24M_OUT,,,,,,ALT5 +GPIO_AD_B0_06,PIT_TRIGGER0,MQS_RIGHT,LPUART1_TXD,TMR2_TIMER2,FLEXPWM2_PWM3_A,GPIO1_IO06,REF_32K_OUT,,,,,,ALT5 +GPIO_AD_B0_07,PIT_TRIGGER1,MQS_LEFT,LPUART1_RXD,TMR2_TIMER3,FLEXPWM2_PWM3_B,GPIO1_IO07,REF_24M_OUT,,,,,,ALT5 GPIO_AD_B0_08,ENET_TX_CLK,LPI2C3_SCL,LPUART1_CTS_B,KPP_COL0,ENET_REF_CLK,GPIO1_IO08,ARM_CM7_TXEV,,,,,ACMP1_IN4,ALT5 GPIO_AD_B0_09,ENET_RX_DATA1,LPI2C3_SDA,LPUART1_RTS_B,KPP_ROW0,,GPIO1_IO09,ARM_CM7_RXEV,,,,,ACMP2_IN4,ALT5 -GPIO_AD_B0_10,ENET_RX_DATA0,LPSPI1_SCK,LPUART5_TXD,KPP_COL1,FLEXPWM2_PWMA2,GPIO1_IO10,ARM_TRACE_CLK,,,,,ACMP3_IN4,ALT5 -GPIO_AD_B0_11,ENET_RX_EN,LPSPI1_PCS0,LPUART5_RXD,KPP_ROW1,FLEXPWM2_PWMB2,GPIO1_IO11,ARM_TRACE_SWO,,,,,ACMP4_IN4,ALT5 -GPIO_AD_B0_12,ENET_RX_ER,LPSPI1_SDO,LPUART3_CTS_B,KPP_COL2,FLEXPWM2_PWMA1,GPIO1_IO12,ARM_TRACE0,SNVS_VIO_5_CTL,,,ADC1_IN0,,ALT5 -GPIO_AD_B0_13,ENET_TX_EN,LPSPI1_SDI,LPUART3_RTS_B,KPP_ROW2,FLEXPWM2_PWMB1,GPIO1_IO13,,SNVS_VIO_5_B,,,ADC2_IN0,,ALT5 -GPIO_AD_B0_14,ENET_TX_DATA0,FLEXCAN2_TX,LPUART3_TXD,KPP_COL3,FLEXPWM2_PWMA0,GPIO1_IO14,,WDOG1_ANY,,,"ADC1_IN1,ADC2_IN1","ACMP1_IN0,ACMP2_IN0,ACMP3_IN0,ACMP4_IN0",ALT5 -GPIO_AD_B0_15,ENET_TX_DATA1,FLEXCAN2_RX,LPUART3_RXD,KPP_ROW3,FLEXPWM2_PWMB0,GPIO1_IO15,,,,,"ADC1_IN2,ADC2_IN2","ACMP1_IN1,ACMP2_IN1,ACMP3_IN1,ACMP4_IN1",ALT5 +GPIO_AD_B0_10,ENET_RX_DATA0,LPSPI1_SCK,LPUART5_TXD,KPP_COL1,FLEXPWM2_PWM2_A,GPIO1_IO10,ARM_TRACE_CLK,,,,,ACMP3_IN4,ALT5 +GPIO_AD_B0_11,ENET_RX_EN,LPSPI1_PCS0,LPUART5_RXD,KPP_ROW1,FLEXPWM2_PWM2_B,GPIO1_IO11,ARM_TRACE_SWO,,,,,ACMP4_IN4,ALT5 +GPIO_AD_B0_12,ENET_RX_ER,LPSPI1_SDO,LPUART3_CTS_B,KPP_COL2,FLEXPWM2_PWM1_A,GPIO1_IO12,ARM_TRACE0,SNVS_VIO_5_CTL,,,ADC1_IN0,,ALT5 +GPIO_AD_B0_13,ENET_TX_EN,LPSPI1_SDI,LPUART3_RTS_B,KPP_ROW2,FLEXPWM2_PWM1_B,GPIO1_IO13,,SNVS_VIO_5_B,,,ADC2_IN0,,ALT5 +GPIO_AD_B0_14,ENET_TX_DATA0,FLEXCAN2_TX,LPUART3_TXD,KPP_COL3,FLEXPWM2_PWM0_A,GPIO1_IO14,,WDOG1_ANY,,,"ADC1_IN1,ADC2_IN1","ACMP1_IN0,ACMP2_IN0,ACMP3_IN0,ACMP4_IN0",ALT5 +GPIO_AD_B0_15,ENET_TX_DATA1,FLEXCAN2_RX,LPUART3_RXD,KPP_ROW3,FLEXPWM2_PWM0_B,GPIO1_IO15,,,,,"ADC1_IN2,ADC2_IN2","ACMP1_IN1,ACMP2_IN1,ACMP3_IN1,ACMP4_IN1",ALT5 GPIO_AD_B1_00,SEMC_RDY,FLEXSPI_A_DATA3,FLEXCAN2_TX,SAI1_MCLK,FLEXIO1_D15,GPIO1_IO16,ENET_1588_EVENT2_OUT,KPP_COL4,,,,ACMP1_IN2,ALT5 GPIO_AD_B1_01,SEMC_CSX0,FLEXSPI_A_SCLK,FLEXCAN2_RX,SAI1_TX_BCLK,FLEXIO1_D14,GPIO1_IO17,ENET_1588_EVENT2_IN,KPP_ROW4,,,ADC1_IN3,ACMP2_IN2,ALT5 GPIO_AD_B1_02,SEMC_CSX1,FLEXSPI_A_DATA0,LPSPI4_SCK,SAI1_TX_SYNC,FLEXIO1_D13,GPIO1_IO18,ENET_1588_EVENT3_OUT,KPP_COL5,,,ADC2_IN3,ACMP3_IN2,ALT5 GPIO_AD_B1_03,SEMC_CSX2,FLEXSPI_A_DATA2,LPSPI4_PCS0,SAI1_TX_DATA0,FLEXIO1_D12,GPIO1_IO19,ENET_1588_EVENT3_IN,KPP_ROW5,,,ADC1_IN4,ACMP4_IN2,ALT5 GPIO_AD_B1_04,SEMC_CSX3,FLEXSPI_A_DATA1,LPSPI4_SDO,SAI1_RX_SYNC,FLEXIO1_D11,GPIO1_IO20,LPSPI1_PCS1,KPP_COL6,,,ADC2_IN4,ACMP1_IN3,ALT5 GPIO_AD_B1_05,USDHC1_WP,FLEXSPI_A_SS0_B,LPSPI4_SDI,SAI1_RX_DATA0,FLEXIO1_D10,GPIO1_IO21,LPSPI1_PCS2,KPP_ROW6,,,"ADC1_IN5,ADC2_IN5",ACMP2_IN3,ALT5 -GPIO_AD_B1_06,USDHC1_RESET_B,FLEXPWM1_PWMA0,LPUART2_CTS_B,SAI1_RX_BCLK,FLEXIO1_D09,GPIO1_IO22,LPSPI1_PCS3,KPP_COL7,,,"ADC1_IN6,ADC2_IN6",ACMP3_IN3,ALT5 -GPIO_AD_B1_07,USDHC1_VSELECT,FLEXPWM1_PWMB0,LPUART2_RTS_B,SAI1_TX_DATA1,FLEXIO1_D08,GPIO1_IO23,LPSPI3_PCS3,KPP_ROW7,,,"ADC1_IN7,ADC2_IN7",ACMP4_IN3,ALT5 -GPIO_AD_B1_08,LPI2C2_SCL,FLEXPWM1_PWMA1,LPUART2_TXD,SAI1_TX_DATA2,FLEXIO1_D07,GPIO1_IO24,LPSPI3_PCS2,XBAR_INOUT12,,,"ADC1_IN8,ADC2_IN8",ACMP1_IN5,ALT5 -GPIO_AD_B1_09,LPI2C2_SDA,FLEXPWM1_PWMB1,LPUART2_RXD,SAI1_TX_DATA3,FLEXIO1_D06,GPIO1_IO25,LPSPI3_PCS1,XBAR_INOUT13,,,"ADC1_IN9,ADC2_IN9",ACMP2_IN5,ALT5 -GPIO_AD_B1_10,USB_OTG1_PWR,FLEXPWM1_PWMA2,LPUART4_TXD,USDHC1_CD_B,FLEXIO1_D05,GPIO1_IO26,GPT2_CAPTURE1,,,,"ADC1_IN10,ADC2_IN10",ACMP3_IN5,ALT5 -GPIO_AD_B1_11,USB_OTG1_ID,FLEXPWM1_PWMB2,LPUART4_RXD,USDHC1_WP,FLEXIO1_D04,GPIO1_IO27,GPT2_COMPARE1,,,,"ADC1_IN11,ADC2_IN11",ACMP4_IN5,ALT5 -GPIO_AD_B1_12,USB_OTG1_OC,ACMP1_OUT,LPSPI3_SCK,USDHC2_CD_B,FLEXIO1_D03,GPIO1_IO28,FLEXPWM1_PWMA3,,,,"ADC1_IN12,ADC2_IN12","ACMP1_IN6,ACMP1_OUT",ALT5 -GPIO_AD_B1_13,LPI2C1_HREQ,ACMP2_OUT,LPSPI3_PCS0,USDHC2_WP,FLEXIO1_D02,GPIO1_IO29,FLEXPWM1_PWMB3,,,,"ADC1_IN13,ADC2_IN13","ACMP2_IN6,ACMP2_OUT",ALT5 +GPIO_AD_B1_06,USDHC1_RESET_B,FLEXPWM1_PWM0_A,LPUART2_CTS_B,SAI1_RX_BCLK,FLEXIO1_D09,GPIO1_IO22,LPSPI1_PCS3,KPP_COL7,,,"ADC1_IN6,ADC2_IN6",ACMP3_IN3,ALT5 +GPIO_AD_B1_07,USDHC1_VSELECT,FLEXPWM1_PWM0_B,LPUART2_RTS_B,SAI1_TX_DATA1,FLEXIO1_D08,GPIO1_IO23,LPSPI3_PCS3,KPP_ROW7,,,"ADC1_IN7,ADC2_IN7",ACMP4_IN3,ALT5 +GPIO_AD_B1_08,LPI2C2_SCL,FLEXPWM1_PWM1_A,LPUART2_TXD,SAI1_TX_DATA2,FLEXIO1_D07,GPIO1_IO24,LPSPI3_PCS2,XBAR_INOUT12,,,"ADC1_IN8,ADC2_IN8",ACMP1_IN5,ALT5 +GPIO_AD_B1_09,LPI2C2_SDA,FLEXPWM1_PWM1_B,LPUART2_RXD,SAI1_TX_DATA3,FLEXIO1_D06,GPIO1_IO25,LPSPI3_PCS1,XBAR_INOUT13,,,"ADC1_IN9,ADC2_IN9",ACMP2_IN5,ALT5 +GPIO_AD_B1_10,USB_OTG1_PWR,FLEXPWM1_PWM2_A,LPUART4_TXD,USDHC1_CD_B,FLEXIO1_D05,GPIO1_IO26,GPT2_CAPTURE1,,,,"ADC1_IN10,ADC2_IN10",ACMP3_IN5,ALT5 +GPIO_AD_B1_11,USB_OTG1_ID,FLEXPWM1_PWM2_B,LPUART4_RXD,USDHC1_WP,FLEXIO1_D04,GPIO1_IO27,GPT2_COMPARE1,,,,"ADC1_IN11,ADC2_IN11",ACMP4_IN5,ALT5 +GPIO_AD_B1_12,USB_OTG1_OC,ACMP1_OUT,LPSPI3_SCK,USDHC2_CD_B,FLEXIO1_D03,GPIO1_IO28,FLEXPWM1_PWM3_A,,,,"ADC1_IN12,ADC2_IN12","ACMP1_IN6,ACMP1_OUT",ALT5 +GPIO_AD_B1_13,LPI2C1_HREQ,ACMP2_OUT,LPSPI3_PCS0,USDHC2_WP,FLEXIO1_D02,GPIO1_IO29,FLEXPWM1_PWM3_B,,,,"ADC1_IN13,ADC2_IN13","ACMP2_IN6,ACMP2_OUT",ALT5 GPIO_AD_B1_14,LPI2C1_SCL,ACMP3_OUT,LPSPI3_SDO,ENET_1588_EVENT0_OUT,FLEXIO1_D01,GPIO1_IO30,,,,,"ADC1_IN14,ADC2_IN14","ACMP3_IN6,ACMP3_OUT",ALT5 GPIO_AD_B1_15,LPI2C1_SDA,ACMP4_OUT,LPSPI3_SDI,ENET_1588_EVENT0_IN,FLEXIO1_D00,GPIO1_IO31,,,,,"ADC1_IN15,ADC2_IN15","ACMP4_IN6,ACMP4_OUT",ALT5 GPIO_EMC_00,SEMC_DA00,TMR2_TIMER0,LPUART4_CTS_B,SPDIF_SR_CLK,LPSPI2_SCK,GPIO2_IO00,FLEXCAN1_TX,PIT_TRIGGER2,,,,,ALT5 @@ -41,36 +41,36 @@ GPIO_EMC_06,SEMC_DA06,XBAR_INOUT06,LPUART3_TXD,SAI2_TX_DATA,FLEXIO1_D18,GPIO2_IO GPIO_EMC_07,SEMC_DA07,XBAR_INOUT07,LPUART3_RXD,SAI2_RX_SYNC,FLEXIO1_D19,GPIO2_IO07,USBPHY1_TSTO_RX_SQUELCH,,,,,,ALT5 GPIO_EMC_08,SEMC_DM0,XBAR_INOUT08,FLEXCAN2_TX,SAI2_RX_DATA,FLEXIO1_D20,GPIO2_IO08,USBPHY1_TSTO_RX_DISCON_DET,,,,,,ALT5 GPIO_EMC_09,SEMC_WE,XBAR_INOUT09,FLEXCAN2_RX,SAI2_RX_BCLK,FLEXIO1_D21,GPIO2_IO09,USBPHY1_TSTO_RX_HS_RXD,,,,,,ALT5 -GPIO_EMC_10,SEMC_CAS,XBAR_INOUT10,LPI2C4_SDA,SAI1_TX_SYNC,LPSPI2_SCK,GPIO2_IO10,FLEXPWM2_PWMX0,,,,,,ALT5 -GPIO_EMC_11,SEMC_RAS,XBAR_INOUT11,LPI2C4_SCL,SAI1_TX_BCLK,LPSPI2_PCS0,GPIO2_IO11,FLEXPWM2_PWMX1,,,,,,ALT5 -GPIO_EMC_12,SEMC_CS0,XBAR_INOUT12,LPUART6_TXD,SAI1_TX_DATA0,LPSPI2_SDO,GPIO2_IO12,FLEXPWM2_PWMX2,,,,,,ALT5 -GPIO_EMC_13,SEMC_BA0,XBAR_INOUT13,LPUART6_RXD,SAI1_RX_DATA0,LPSPI2_SDI,GPIO2_IO13,FLEXPWM2_PWMX3,CCM_PMIC_RDY,,,,,ALT5 +GPIO_EMC_10,SEMC_CAS,XBAR_INOUT10,LPI2C4_SDA,SAI1_TX_SYNC,LPSPI2_SCK,GPIO2_IO10,FLEXPWM2_PWM0_X,,,,,,ALT5 +GPIO_EMC_11,SEMC_RAS,XBAR_INOUT11,LPI2C4_SCL,SAI1_TX_BCLK,LPSPI2_PCS0,GPIO2_IO11,FLEXPWM2_PWM1_X,,,,,,ALT5 +GPIO_EMC_12,SEMC_CS0,XBAR_INOUT12,LPUART6_TXD,SAI1_TX_DATA0,LPSPI2_SDO,GPIO2_IO12,FLEXPWM2_PWM2_X,,,,,,ALT5 +GPIO_EMC_13,SEMC_BA0,XBAR_INOUT13,LPUART6_RXD,SAI1_RX_DATA0,LPSPI2_SDI,GPIO2_IO13,FLEXPWM2_PWM3_X,CCM_PMIC_RDY,,,,,ALT5 GPIO_EMC_14,SEMC_BA1,XBAR_INOUT14,LPUART6_CTS_B,SAI1_RX_BCLK,LPSPI2_PCS1,GPIO2_IO14,FLEXCAN1_TX,,,,,,ALT5 GPIO_EMC_15,SEMC_ADDR10,XBAR_INOUT15,LPUART6_RTS_B,SAI1_RX_SYNC,WDOG1_B,GPIO2_IO15,FLEXCAN1_RX,,,,,,ALT5 GPIO_EMC_16,SEMC_ADDR00,,MQS_RIGHT,SAI2_MCLK,,GPIO2_IO16,SRC_BOOT_MODE0,,,,,,ALT5 GPIO_EMC_17,SEMC_ADDR01,,MQS_LEFT,SAI3_MCLK,,GPIO2_IO17,SRC_BOOT_MODE1,,,,,,ALT5 GPIO_EMC_18,SEMC_ADDR02,XBAR_INOUT16,LPI2C2_SDA,SAI1_RX_SYNC,FLEXIO1_D22,GPIO2_IO18,SRC_BT_CFG0,,,,,,ALT5 GPIO_EMC_19,SEMC_ADDR03,XBAR_INOUT17,LPI2C2_SCL,SAI1_RX_BCLK,FLEXIO1_D23,GPIO2_IO19,SRC_BT_CFG1,,,,,,ALT5 -GPIO_EMC_20,SEMC_ADDR04,FLEXPWM1_PWMA3,LPUART2_CTS_B,SAI1_MCLK,FLEXIO1_D24,GPIO2_IO20,SRC_BT_CFG2,,,,,,ALT5 -GPIO_EMC_21,SEMC_ADDR05,FLEXPWM1_PWMB3,LPUART2_RTS_B,SAI1_RX_DATA0,FLEXIO1_D25,GPIO2_IO21,SRC_BT_CFG3,,,,,,ALT5 -GPIO_EMC_22,SEMC_ADDR06,FLEXPWM1_PWMA2,LPUART2_TXD,SAI1_TX_DATA3,FLEXIO1_D26,GPIO2_IO22,SRC_BT_CFG4,,,,,,ALT5 -GPIO_EMC_23,SEMC_ADDR07,FLEXPWM1_PWMB2,LPUART2_RXD,SAI1_TX_DATA2,FLEXIO1_D27,GPIO2_IO23,SRC_BT_CFG5,,,,,,ALT5 -GPIO_EMC_24,SEMC_ADDR08,FLEXPWM1_PWMA1,LPUART8_CTS_B,SAI1_TX_DATA1,FLEXIO1_D28,GPIO2_IO24,SRC_BT_CFG6,,,,,,ALT5 -GPIO_EMC_25,SEMC_ADDR09,FLEXPWM1_PWMB1,LPUART8_RTS_B,SAI1_TX_DATA0,FLEXIO1_D29,GPIO2_IO25,SRC_BT_CFG7,,,,,,ALT5 -GPIO_EMC_26,SEMC_ADDR11,FLEXPWM1_PWMA0,LPUART8_TXD,SAI1_TX_BCLK,FLEXIO1_D30,GPIO2_IO26,SRC_BT_CFG8,,,,,,ALT5 -GPIO_EMC_27,SEMC_ADDR12,FLEXPWM1_PWMB0,LPUART8_RXD,SAI1_TX_SYNC,FLEXIO1_D31,GPIO2_IO27,SRC_BT_CFG9,,,,,,ALT5 -GPIO_EMC_28,SEMC_DQS,FLEXPWM2_PWMA3,XBAR_INOUT18,SAI3_MCLK,EWM_OUT_B,GPIO2_IO28,GPT2_CAPTURE2,FLEXPWM1_PWMX0,,,,,ALT5 -GPIO_EMC_29,SEMC_CKE,FLEXPWM2_PWMB3,XBAR_INOUT19,SAI3_RX_BCLK,WDOG2_RST_B_DEB,GPIO2_IO29,GPT2_COMPARE2,FLEXPWM1_PWMX1,,,,,ALT5 -GPIO_EMC_30,SEMC_CLK,FLEXPWM2_PWMA2,LPUART4_CTS_B,SAI3_RX_SYNC,WDOG1_RST_B_DEB,GPIO2_IO30,GPT2_COMPARE3,FLEXPWM1_PWMX2,,,,,ALT5 -GPIO_EMC_31,SEMC_DM1,FLEXPWM2_PWMB2,LPUART4_RTS_B,SAI3_RX_DATA,WDOG2_B,GPIO2_IO31,GPT2_CLK,FLEXPWM1_PWMX3,,,,,ALT5 +GPIO_EMC_20,SEMC_ADDR04,FLEXPWM1_PWM3_A,LPUART2_CTS_B,SAI1_MCLK,FLEXIO1_D24,GPIO2_IO20,SRC_BT_CFG2,,,,,,ALT5 +GPIO_EMC_21,SEMC_ADDR05,FLEXPWM1_PWM3_B,LPUART2_RTS_B,SAI1_RX_DATA0,FLEXIO1_D25,GPIO2_IO21,SRC_BT_CFG3,,,,,,ALT5 +GPIO_EMC_22,SEMC_ADDR06,FLEXPWM1_PWM2_A,LPUART2_TXD,SAI1_TX_DATA3,FLEXIO1_D26,GPIO2_IO22,SRC_BT_CFG4,,,,,,ALT5 +GPIO_EMC_23,SEMC_ADDR07,FLEXPWM1_PWM2_B,LPUART2_RXD,SAI1_TX_DATA2,FLEXIO1_D27,GPIO2_IO23,SRC_BT_CFG5,,,,,,ALT5 +GPIO_EMC_24,SEMC_ADDR08,FLEXPWM1_PWM1_A,LPUART8_CTS_B,SAI1_TX_DATA1,FLEXIO1_D28,GPIO2_IO24,SRC_BT_CFG6,,,,,,ALT5 +GPIO_EMC_25,SEMC_ADDR09,FLEXPWM1_PWM1_B,LPUART8_RTS_B,SAI1_TX_DATA0,FLEXIO1_D29,GPIO2_IO25,SRC_BT_CFG7,,,,,,ALT5 +GPIO_EMC_26,SEMC_ADDR11,FLEXPWM1_PWM0_A,LPUART8_TXD,SAI1_TX_BCLK,FLEXIO1_D30,GPIO2_IO26,SRC_BT_CFG8,,,,,,ALT5 +GPIO_EMC_27,SEMC_ADDR12,FLEXPWM1_PWM0_B,LPUART8_RXD,SAI1_TX_SYNC,FLEXIO1_D31,GPIO2_IO27,SRC_BT_CFG9,,,,,,ALT5 +GPIO_EMC_28,SEMC_DQS,FLEXPWM2_PWM3_A,XBAR_INOUT18,SAI3_MCLK,EWM_OUT_B,GPIO2_IO28,GPT2_CAPTURE2,FLEXPWM1_PWM0_X,,,,,ALT5 +GPIO_EMC_29,SEMC_CKE,FLEXPWM2_PWM3_B,XBAR_INOUT19,SAI3_RX_BCLK,WDOG2_RST_B_DEB,GPIO2_IO29,GPT2_COMPARE2,FLEXPWM1_PWM1_X,,,,,ALT5 +GPIO_EMC_30,SEMC_CLK,FLEXPWM2_PWM2_A,LPUART4_CTS_B,SAI3_RX_SYNC,WDOG1_RST_B_DEB,GPIO2_IO30,GPT2_COMPARE3,FLEXPWM1_PWM2_X,,,,,ALT5 +GPIO_EMC_31,SEMC_DM1,FLEXPWM2_PWM2_B,LPUART4_RTS_B,SAI3_RX_DATA,WDOG2_B,GPIO2_IO31,GPT2_CLK,FLEXPWM1_PWM3_X,,,,,ALT5 GPIO_EMC_32,SEMC_DA08,TMR1_TIMER0,LPUART4_TXD,SAI3_TX_DATA,LPSPI4_SCK,GPIO3_IO00,USBPHY1_TSTO_RX_FS_RXD,REF_24M_OUT,,,,,ALT5 GPIO_EMC_33,SEMC_DA09,TMR1_TIMER1,LPUART4_RXD,SAI3_TX_BCLK,LPSPI4_PCS0,GPIO3_IO01,USBPHY1_TSTI_TX_DP,SRC_TESTER_ACK,,,,,ALT5 GPIO_EMC_34,SEMC_DA10,TMR1_TIMER2,LPUART7_TXD,SAI3_TX_SYNC,LPSPI4_SDO,GPIO3_IO02,ENET_CRS,,,,,,ALT5 GPIO_EMC_35,SEMC_DA11,TMR1_TIMER3,LPUART7_RXD,USDHC2_WP,LPSPI4_SDI,GPIO3_IO03,ENET_COL,,,,,,ALT5 -GPIO_EMC_36,SEMC_DA12,FLEXPWM2_PWMA1,LPUART5_CTS_B,CCM_PMIC_RDY,LPSPI4_PCS1,GPIO3_IO04,ENET_RX_CLK,USDHC1_WP,,,,,ALT5 -GPIO_EMC_37,SEMC_DA13,FLEXPWM2_PWMB1,LPUART5_RTS_B,MQS_RIGHT,LPSPI4_PCS2,GPIO3_IO05,ENET_RX_DATA3,USDHC1_VSELECT,,,,,ALT5 -GPIO_EMC_38,SEMC_DA14,FLEXPWM2_PWMA0,LPUART5_TXD,MQS_LEFT,LPSPI4_PCS3,GPIO3_IO06,ENET_RX_DATA2,USDHC1_CD_B,,,,,ALT5 -GPIO_EMC_39,SEMC_DA15,FLEXPWM2_PWMB0,LPUART5_RXD,USB_OTG1_OC,WDOG1_B,GPIO3_IO07,ENET_TX_ER,GPT1_CLK,,,,,ALT5 +GPIO_EMC_36,SEMC_DA12,FLEXPWM2_PWM1_A,LPUART5_CTS_B,CCM_PMIC_RDY,LPSPI4_PCS1,GPIO3_IO04,ENET_RX_CLK,USDHC1_WP,,,,,ALT5 +GPIO_EMC_37,SEMC_DA13,FLEXPWM2_PWM1_B,LPUART5_RTS_B,MQS_RIGHT,LPSPI4_PCS2,GPIO3_IO05,ENET_RX_DATA3,USDHC1_VSELECT,,,,,ALT5 +GPIO_EMC_38,SEMC_DA14,FLEXPWM2_PWM0_A,LPUART5_TXD,MQS_LEFT,LPSPI4_PCS3,GPIO3_IO06,ENET_RX_DATA2,USDHC1_CD_B,,,,,ALT5 +GPIO_EMC_39,SEMC_DA15,FLEXPWM2_PWM0_B,LPUART5_RXD,USB_OTG1_OC,WDOG1_B,GPIO3_IO07,ENET_TX_ER,GPT1_CLK,,,,,ALT5 GPIO_EMC_40,SEMC_CSX0,XBAR_INOUT18,SPDIF_OUT,USB_OTG1_ID,ENET_MDIO,GPIO3_IO08,ENET_TX_DATA3,GPT1_COMPARE3,,,,,ALT5 GPIO_EMC_41,SEMC_RDY,XBAR_INOUT19,SPDIF_IN,USB_OTG1_PWR,ENET_MDC,GPIO3_IO09,ENET_TX_DATA2,GPT1_COMPARE2,,,,,ALT5 GPIO_SD_B0_00,USDHC1_DATA2,TMR1_TIMER0,SAI1_MCLK,SAI2_MCLK,LPI2C3_SCL,GPIO3_IO13,FLEXSPI_A_SS1_B,XBAR_INOUT14,,,,,ALT5 diff --git a/ports/mimxrt/boards/make-pins.py b/ports/mimxrt/boards/make-pins.py index e13b9c578f..441676adde 100644 --- a/ports/mimxrt/boards/make-pins.py +++ b/ports/mimxrt/boards/make-pins.py @@ -8,7 +8,7 @@ import sys import csv import re -SUPPORTED_AFS = {"GPIO", "USDHC", "SEMC"} +SUPPORTED_AFS = {"GPIO", "USDHC", "FLEXPWM", "TMR"} MAX_AF = 10 # AF0 .. AF9 ADC_COL = 11 @@ -282,29 +282,33 @@ class Pins(object): hdr_file.write("extern const mp_obj_dict_t machine_pin_board_pins_locals_dict;\n") hdr_file.write("\n// Defines\n") - usdhc_instance_factory(self.cpu_pins, hdr_file) + module_instance_factory(self.cpu_pins, hdr_file, "USDHC") + module_instance_factory(self.cpu_pins, hdr_file, "FLEXPWM") + module_instance_factory(self.cpu_pins, hdr_file, "TMR") -def usdhc_instance_factory(pins, output_file): - usdhc_pins = filter(lambda p: any([af for af in p.alt_fn if "USDHC" in af.af_str]), pins) +def module_instance_factory(pins, output_file, name): + module_pin = filter(lambda p: any([af for af in p.alt_fn if name in af.af_str]), pins) - usdhc_instances = dict() - for pin in usdhc_pins: + module_instances = dict() + for pin in module_pin: for idx, alt_fn in enumerate(pin.alt_fn): - if "USDHC" in alt_fn.instance: + if name in alt_fn.instance: format_string = "#define {0}_{1} &pin_{0}, {2}" - if alt_fn.instance not in usdhc_instances: - usdhc_instances[alt_fn.instance] = [ + if alt_fn.instance not in module_instances: + module_instances[alt_fn.instance] = [ format_string.format(pin.name, alt_fn.af_str, idx) ] else: - usdhc_instances[alt_fn.instance].append( + module_instances[alt_fn.instance].append( format_string.format(pin.name, alt_fn.af_str, idx) ) - for k, v in usdhc_instances.items(): + for k, v in module_instances.items(): output_file.write(f"// {k}\n") output_file.write(f"#define {k}_AVAIL (1)\n") + if name == "FLEXPWM": + output_file.write(f"#define {k} {k[-4:]}\n") for i in v: output_file.write(i + "\n") @@ -326,7 +330,7 @@ def main(): "-i", "--iomux", dest="iomux_filename", - help="Specifies the fsl_iomux.h file for the chip", + help="Specifies the fsl_iomuxc.h file for the chip", default="fsl_iomuxc.h", ) parser.add_argument( diff --git a/ports/mimxrt/hal/pwm_backport.c b/ports/mimxrt/hal/pwm_backport.c new file mode 100644 index 0000000000..cea6642120 --- /dev/null +++ b/ports/mimxrt/hal/pwm_backport.c @@ -0,0 +1,180 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * + * Copyright (c) 2021 Robert Hammelrath + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +// These are a few functions taken from the NXP-Lib +// for PWM, for +// - dealing with an u16 duty cycle setting, +// - setting the pulse center position, and +// - factoring out pure duty cycle change. + +#include "py/runtime.h" +#include "hal/pwm_backport.h" + +void PWM_UpdatePwmDutycycle_u16( + PWM_Type *base, pwm_submodule_t subModule, pwm_channels_t pwmSignal, uint16_t dutyCycle, uint16_t Center_u16) { + assert((uint16_t)pwmSignal < 2U); + uint16_t pulseCnt = 0, pwmHighPulse = 0; + uint16_t center; + + // check and confine bounds for Center_u16 + if ((Center_u16 + dutyCycle / 2) >= PWM_FULL_SCALE) { + Center_u16 = PWM_FULL_SCALE - dutyCycle / 2 - 1; + } else if (Center_u16 < (dutyCycle / 2)) { + Center_u16 = dutyCycle / 2; + } + pulseCnt = base->SM[subModule].VAL1 + 1; + // Calculate pulse width and center position + pwmHighPulse = (pulseCnt * dutyCycle) / PWM_FULL_SCALE; + center = (pulseCnt * Center_u16) / PWM_FULL_SCALE; + + // Setup the PWM dutycycle of channel A or B + if (pwmSignal == kPWM_PwmA) { + base->SM[subModule].VAL2 = center - pwmHighPulse / 2; + base->SM[subModule].VAL3 = base->SM[subModule].VAL2 + pwmHighPulse; + } else { + base->SM[subModule].VAL4 = center - pwmHighPulse / 2; + base->SM[subModule].VAL5 = base->SM[subModule].VAL4 + pwmHighPulse; + } +} + +void PWM_SetupPwm_u16(PWM_Type *base, pwm_submodule_t subModule, pwm_signal_param_u16_t *chnlParams, + uint32_t pwmFreq_Hz, uint32_t srcClock_Hz, bool output_enable) { + + uint32_t pwmClock; + uint16_t pulseCnt = 0; + uint8_t polarityShift = 0, outputEnableShift = 0; + + // Divide the clock by the prescale value + pwmClock = (srcClock_Hz / (1U << ((base->SM[subModule].CTRL & PWM_CTRL_PRSC_MASK) >> PWM_CTRL_PRSC_SHIFT))); + pulseCnt = pwmClock / pwmFreq_Hz; + base->SM[subModule].INIT = 0; + base->SM[subModule].VAL1 = pulseCnt - 1; + + // Set up the Registers VAL2..VAL5 controlling the duty cycle of channel A/B + PWM_UpdatePwmDutycycle_u16(base, subModule, chnlParams->pwmChannel, + chnlParams->dutyCycle_u16, chnlParams->Center_u16); + + // Setup register shift values based on the channel being configured. + // Also setup the deadtime value + if (chnlParams->pwmChannel == kPWM_PwmA) { + polarityShift = PWM_OCTRL_POLA_SHIFT; + outputEnableShift = PWM_OUTEN_PWMA_EN_SHIFT; + base->SM[subModule].DTCNT0 = PWM_DTCNT0_DTCNT0(chnlParams->deadtimeValue); + } else { + polarityShift = PWM_OCTRL_POLB_SHIFT; + outputEnableShift = PWM_OUTEN_PWMB_EN_SHIFT; + base->SM[subModule].DTCNT1 = PWM_DTCNT1_DTCNT1(chnlParams->deadtimeValue); + } + + // Setup signal active level + if (chnlParams->level == kPWM_HighTrue) { + base->SM[subModule].OCTRL &= ~(1U << polarityShift); + } else { + base->SM[subModule].OCTRL |= (1U << polarityShift); + } + // Enable PWM output + if (output_enable) { + base->OUTEN |= (1U << (outputEnableShift + subModule)); + } +} + +void PWM_SetupPwmx_u16(PWM_Type *base, pwm_submodule_t subModule, + uint32_t pwmFreq_Hz, uint16_t duty_cycle, uint8_t invert, uint32_t srcClock_Hz) { + + uint32_t pulseCnt; + uint32_t pwmClock; + + // Divide the clock by the prescale value + pwmClock = (srcClock_Hz / (1U << ((base->SM[subModule].CTRL & PWM_CTRL_PRSC_MASK) >> PWM_CTRL_PRSC_SHIFT))); + pulseCnt = pwmClock / pwmFreq_Hz; + base->SM[subModule].INIT = 0; + base->SM[subModule].VAL0 = ((uint32_t)duty_cycle * pulseCnt) / PWM_FULL_SCALE; + base->SM[subModule].VAL1 = pulseCnt - 1; + + base->SM[subModule].OCTRL = (base->SM[subModule].OCTRL & ~PWM_OCTRL_POLX_MASK) | PWM_OCTRL_POLX(!invert); + + base->OUTEN |= (1U << subModule); +} + +void PWM_SetupFaultDisableMap(PWM_Type *base, pwm_submodule_t subModule, + pwm_channels_t pwmChannel, pwm_fault_channels_t pwm_fault_channels, uint16_t value) { + uint16_t reg = base->SM[subModule].DISMAP[pwm_fault_channels]; + switch (pwmChannel) { + case kPWM_PwmA: + reg &= ~((uint16_t)PWM_DISMAP_DIS0A_MASK); + reg |= (((uint16_t)(value) << (uint16_t)PWM_DISMAP_DIS0A_SHIFT) & (uint16_t)PWM_DISMAP_DIS0A_MASK); + break; + case kPWM_PwmB: + reg &= ~((uint16_t)PWM_DISMAP_DIS0B_MASK); + reg |= (((uint16_t)(value) << (uint16_t)PWM_DISMAP_DIS0B_SHIFT) & (uint16_t)PWM_DISMAP_DIS0B_MASK); + break; + case kPWM_PwmX: + reg &= ~((uint16_t)PWM_DISMAP_DIS0X_MASK); + reg |= (((uint16_t)(value) << (uint16_t)PWM_DISMAP_DIS0X_SHIFT) & (uint16_t)PWM_DISMAP_DIS0X_MASK); + break; + default: + assert(false); + break; + } + base->SM[subModule].DISMAP[pwm_fault_channels] = reg; +} + +#ifdef FSL_FEATURE_SOC_TMR_COUNT +status_t QTMR_SetupPwm_u16(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t pwmFreqHz, + uint16_t dutyCycleU16, bool outputPolarity, uint32_t srcClock_Hz, bool is_init) { + uint32_t periodCount, highCount, lowCount, reg; + + if (dutyCycleU16 >= PWM_FULL_SCALE) { + // Invalid dutycycle + return kStatus_Fail; + } + + // Counter values to generate a PWM signal + periodCount = (srcClock_Hz / pwmFreqHz) - 1; + highCount = (periodCount * dutyCycleU16) / PWM_FULL_SCALE; + lowCount = periodCount - highCount; + + // Setup the compare registers for PWM output + if (is_init == false) { + base->CHANNEL[channel].COMP1 = lowCount; + base->CHANNEL[channel].COMP2 = highCount; + } + + // Setup the pre-load registers for PWM output + base->CHANNEL[channel].CMPLD1 = lowCount; + base->CHANNEL[channel].CMPLD2 = highCount; + + reg = base->CHANNEL[channel].CSCTRL; + // Setup the compare load control for COMP1 and COMP2. + // Load COMP1 when CSCTRL[TCF2] is asserted, load COMP2 when CSCTRL[TCF1] is asserted + reg &= ~(TMR_CSCTRL_CL1_MASK | TMR_CSCTRL_CL2_MASK); + reg |= (TMR_CSCTRL_CL1(kQTMR_LoadOnComp2) | TMR_CSCTRL_CL2(kQTMR_LoadOnComp1)); + base->CHANNEL[channel].CSCTRL = reg; + + // Set OFLAG pin for output mode + base->CHANNEL[channel].SCTRL |= TMR_SCTRL_OEN_MASK; + if (outputPolarity) { + // Invert the polarity + base->CHANNEL[channel].SCTRL |= TMR_SCTRL_OPS_MASK; + } else { + // True polarity, no inversion + base->CHANNEL[channel].SCTRL &= ~TMR_SCTRL_OPS_MASK; + } + + reg = base->CHANNEL[channel].CTRL; + reg &= ~(TMR_CTRL_OUTMODE_MASK); + // Count until compare value is reached and re-initialize the counter, toggle OFLAG output + // using alternating compare register + reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_ToggleOnAltCompareReg)); + base->CHANNEL[channel].CTRL = reg; + + return kStatus_Success; +} +#endif // FSL_FEATURE_SOC_TMR_COUNT diff --git a/ports/mimxrt/hal/pwm_backport.h b/ports/mimxrt/hal/pwm_backport.h new file mode 100644 index 0000000000..cd4bdb1f8e --- /dev/null +++ b/ports/mimxrt/hal/pwm_backport.h @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * + * Copyright (c) 2021 Robert Hammelrath + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef PWM_BACKPORT_H +#define PWM_BACKPORT_H +#include "fsl_pwm.h" +#ifdef FSL_FEATURE_SOC_TMR_COUNT +#include "fsl_qtmr.h" +#endif + +typedef struct _pwm_signal_param_u16 +{ + pwm_channels_t pwmChannel; // PWM channel being configured; PWM A or PWM B + uint16_t dutyCycle_u16; // PWM pulse width, value should be between 0 to 65536 + uint16_t Center_u16; // Center of the pulse, value should be between 0 to 65536 + pwm_level_select_t level; // PWM output active level select */ + uint16_t deadtimeValue; // The deadtime value; only used if channel pair is operating in complementary mode +} pwm_signal_param_u16_t; + +typedef enum _pwm_fault_channels { + kPWM_faultchannel_0 = 0U, + kPWM_faultchannel_1 +} pwm_fault_channels_t; + +#define PWM_FULL_SCALE (65536UL) + +void PWM_UpdatePwmDutycycle_u16(PWM_Type *base, pwm_submodule_t subModule, + pwm_channels_t pwmSignal, uint16_t dutyCycle, uint16_t center); + +void PWM_SetupPwm_u16(PWM_Type *base, pwm_submodule_t subModule, pwm_signal_param_u16_t *chnlParams, + uint32_t pwmFreq_Hz, uint32_t srcClock_Hz, bool output_enable); + +void PWM_SetupPwmx_u16(PWM_Type *base, pwm_submodule_t subModule, + uint32_t pwmFreq_Hz, uint16_t duty_cycle, uint8_t invert, uint32_t srcClock_Hz); + +void PWM_SetupFaultDisableMap(PWM_Type *base, pwm_submodule_t subModule, + pwm_channels_t pwmChannel, pwm_fault_channels_t pwm_fault_channels, uint16_t value); + +#ifdef FSL_FEATURE_SOC_TMR_COUNT +status_t QTMR_SetupPwm_u16(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t pwmFreqHz, + uint16_t dutyCycleU16, bool outputPolarity, uint32_t srcClock_Hz, bool is_init); +#endif // FSL_FEATURE_SOC_TMR_COUNT + +#endif // PWM_BACKPORT_H diff --git a/ports/mimxrt/machine_pwm.c b/ports/mimxrt/machine_pwm.c new file mode 100644 index 0000000000..a13af0d80f --- /dev/null +++ b/ports/mimxrt/machine_pwm.c @@ -0,0 +1,618 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020-2021 Damien P. George + * Copyright (c) 2021 Robert Hammelrath + * + * 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/runtime.h" +#include "py/mphal.h" +#include "modmachine.h" +#include "pin.h" +#include "fsl_clock.h" +#include "fsl_iomuxc.h" +#include "hal/pwm_backport.h" + +#define PWM_MIDDLE (0) +#define PWM_BEGIN (1) +#define PWM_END (2) + +#define PWM_CHANNEL1 (1) +#define PWM_CHANNEL2 (2) + +typedef struct _machine_pwm_obj_t { + mp_obj_base_t base; + PWM_Type *instance; + bool is_flexpwm; + uint8_t complementary; + uint8_t module; + uint8_t submodule; + uint8_t channel1; + uint8_t channel2; + uint8_t invert; + bool sync; + uint32_t freq; + int16_t prescale; + uint16_t duty_u16; + uint32_t duty_ns; + uint16_t center; + uint32_t deadtime; + bool output_enable_1; + bool output_enable_2; + uint8_t xor; + bool is_init; +} machine_pwm_obj_t; + +static char channel_char[] = {'B', 'A', 'X' }; +static char *ERRMSG_FREQ = "PWM frequency too low"; +static char *ERRMSG_INIT = "PWM set-up failed"; +static char *ERRMSG_VALUE = "value larger than period"; + +STATIC void machine_pwm_start(machine_pwm_obj_t *self); + +STATIC void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->is_flexpwm) { + mp_printf(print, "module, self->submodule); + if (self->complementary) { + mp_printf(print, "channel=%c/%c", channel_char[self->channel1], channel_char[self->channel2]); + } else { + mp_printf(print, "channel=%c", channel_char[self->channel1]); + } + if (self->duty_ns != 0) { + mp_printf(print, " duty_ns=%u", self->duty_ns); + } else { + mp_printf(print, " duty_u16=%u", self->duty_u16); + } + mp_printf(print, " freq=%u center=%u, deadtime=%u, sync=%u>", + self->freq, self->center, self->deadtime, self->sync); + #ifdef FSL_FEATURE_SOC_TMR_COUNT + } else { + mp_printf(print, "module, self->channel1, self->freq); + if (self->duty_ns != 0) { + mp_printf(print, "duty_ns=%u>", self->duty_ns); + } else { + mp_printf(print, "duty_u16=%u>", self->duty_u16); + } + #endif + } +} + +// Utility functions for decoding and convertings +// +STATIC uint32_t duty_ns_to_duty_u16(uint32_t freq, uint32_t duty_ns) { + uint64_t duty = (uint64_t)duty_ns * freq * PWM_FULL_SCALE / 1000000000ULL; + if (duty >= PWM_FULL_SCALE) { + mp_raise_ValueError(MP_ERROR_TEXT(ERRMSG_VALUE)); + } + return (uint32_t)duty; +} + +STATIC uint8_t module_decode(char channel) { + switch (channel) { + case '0': + return kPWM_Module_0; + case '1': + return kPWM_Module_1; + case '2': + return kPWM_Module_2; + case '3': + return kPWM_Module_3; + default: + return kPWM_Module_1; + } +} + +STATIC uint8_t channel_decode(char channel) { + switch (channel) { + case 'A': + return kPWM_PwmA; + case 'B': + return kPWM_PwmB; + case 'X': + return kPWM_PwmX; + default: + return kPWM_PwmA; + } +} + +// decode the AF objects module and Port numer. Returns NULL if it is not a FLEXPWM object +STATIC const machine_pin_af_obj_t *af_name_decode_flexpwm(const machine_pin_af_obj_t *af_obj, + uint8_t *module, uint8_t *submodule, uint8_t *channel) { + const char *str; + size_t len; + str = (char *)qstr_data(af_obj->name, &len); + // test for the name starting with FLEXPWM + if (len < 15 || strncmp(str, "FLEXPWM", 7) != 0) { + return NULL; + } + // Get module, submodule and channel from the name, e.g. FLEXPWM1_PWM0_A + *module = str[7] - '0'; + *submodule = module_decode(str[12]); + *channel = channel_decode(str[14]); + + return af_obj; +} + +#ifdef FSL_FEATURE_SOC_TMR_COUNT +STATIC uint8_t qtmr_decode(char channel) { + switch (channel) { + case '0': + return kQTMR_Channel_0; + case '1': + return kQTMR_Channel_1; + case '2': + return kQTMR_Channel_2; + case '3': + return kQTMR_Channel_3; + default: + return kPWM_Module_1; + } +} + +// decode the AF objects module and Port numer. Returns NULL if it is not a QTMR object +STATIC const machine_pin_af_obj_t *af_name_decode_qtmr(const machine_pin_af_obj_t *af_obj, uint8_t *module, uint8_t *channel) { + const char *str; + size_t len; + str = (char *)qstr_data(af_obj->name, &len); + // test for the name starting with TMR + if (len < 11 || strncmp(str, "TMR", 3) != 0) { + return NULL; + } + // Get module, submodule and channel from the name, e.g. FLEXPWM1_PWM0_A + *module = str[3] - '0'; + *channel = qtmr_decode(str[10]); + + return af_obj; +} +#endif + +STATIC bool is_board_pin(const machine_pin_obj_t *pin) { + for (int i = 0; i < num_board_pins; i++) { + if (pin == machine_pin_board_pins[i]) { + return true; + } + } + return false; +} + +// Functions for configuring the PWM Device +// +STATIC int calc_prescaler(uint32_t clock, uint32_t freq) { + float temp = (float)clock / (float)PWM_FULL_SCALE / (float)freq; + for (int prescale = 0; prescale < 8; prescale++, temp /= 2) { + if (temp <= 1) { + return prescale; + } + } + // Frequency too low, cannot scale down. + return -1; +} + +STATIC void configure_flexpwm(machine_pwm_obj_t *self) { + pwm_signal_param_u16_t pwmSignal; + + // Initialize PWM module. + uint32_t pwmSourceClockInHz = CLOCK_GetFreq(kCLOCK_IpgClk); + + int prescale = calc_prescaler(pwmSourceClockInHz, self->freq); + if (prescale < 0) { + mp_raise_ValueError(MP_ERROR_TEXT(ERRMSG_FREQ)); + } + if (self->prescale != prescale || self->is_init == false) { + pwm_config_t pwmConfig; + PWM_GetDefaultConfig(&pwmConfig); + self->prescale = prescale; + pwmConfig.prescale = prescale; + pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle; + if (self->complementary) { + pwmConfig.pairOperation = self->channel1 == kPWM_PwmA ? kPWM_ComplementaryPwmA : kPWM_ComplementaryPwmB; + } else { + pwmConfig.pairOperation = kPWM_Independent; + } + pwmConfig.clockSource = kPWM_BusClock; + pwmConfig.enableWait = false; + pwmConfig.initializationControl = self->sync ? kPWM_Initialize_MasterSync : kPWM_Initialize_LocalSync; + + if (PWM_Init(self->instance, self->submodule, &pwmConfig) == kStatus_Fail) { + mp_raise_ValueError(MP_ERROR_TEXT(ERRMSG_INIT)); + } + } + + // Disable the fault detect function to avoid using the xbara + PWM_SetupFaultDisableMap(self->instance, self->submodule, self->channel1, kPWM_faultchannel_0, 0); + PWM_SetupFaultDisableMap(self->instance, self->submodule, self->channel1, kPWM_faultchannel_1, 0); + if (self->complementary) { + PWM_SetupFaultDisableMap(self->instance, self->submodule, self->channel2, kPWM_faultchannel_0, 0); + PWM_SetupFaultDisableMap(self->instance, self->submodule, self->channel2, kPWM_faultchannel_1, 0); + } + + if (self->channel1 != kPWM_PwmX) { // Only for A/B channels + // Initialize the channel parameters + pwmSignal.pwmChannel = self->channel1; + pwmSignal.level = (self->invert & PWM_CHANNEL1) ? kPWM_LowTrue : kPWM_HighTrue; + pwmSignal.dutyCycle_u16 = self->duty_u16; + pwmSignal.Center_u16 = self->center; + pwmSignal.deadtimeValue = ((uint64_t)pwmSourceClockInHz * self->deadtime) / 1000000000ULL; + PWM_SetupPwm_u16(self->instance, self->submodule, &pwmSignal, self->freq, + pwmSourceClockInHz, self->output_enable_1); + + if (self->complementary) { + // Initialize the second channel of the pair. + pwmSignal.pwmChannel = self->channel2; + pwmSignal.level = (self->invert & PWM_CHANNEL2) ? kPWM_LowTrue : kPWM_HighTrue; + PWM_SetupPwm_u16(self->instance, self->submodule, &pwmSignal, self->freq, + pwmSourceClockInHz, self->output_enable_2); + } + if (self->xor == 1) { + // Set the DBLEN bit for A, B = A ^ B + self->instance->SM[self->submodule].CTRL &= ~PWM_CTRL_SPLIT_MASK; + self->instance->SM[self->submodule].CTRL |= PWM_CTRL_DBLEN_MASK; + } else if (self->xor == 2) { + // Set the DBLEN and SPLIT bits for A, B = A ^ B + self->instance->SM[self->submodule].CTRL |= PWM_CTRL_DBLEN_MASK | PWM_CTRL_SPLIT_MASK; + } else { + self->instance->SM[self->submodule].CTRL &= ~(PWM_CTRL_DBLEN_MASK | PWM_CTRL_SPLIT_MASK); + } + } else { + PWM_SetupPwmx_u16(self->instance, self->submodule, self->freq, self->duty_u16, + self->invert, pwmSourceClockInHz); + if (self->xor) { + // Set the DBLX bit for X = A ^ B + self->instance->SM[self->submodule].CTRL |= PWM_CTRL_DBLX_MASK; + } else { + self->instance->SM[self->submodule].CTRL &= ~PWM_CTRL_DBLX_MASK; + } + } + // Set the load okay bit for the submodules + PWM_SetPwmLdok(self->instance, 1 << self->submodule, true); + + // Start the PWM generation from the Submodules + PWM_StartTimer(self->instance, 1 << self->submodule); +} + +#ifdef FSL_FEATURE_SOC_TMR_COUNT +STATIC void configure_qtmr(machine_pwm_obj_t *self) { + qtmr_config_t qtmrConfig; + int prescale; + + TMR_Type *instance = (TMR_Type *)self->instance; + + prescale = calc_prescaler(CLOCK_GetFreq(kCLOCK_IpgClk), self->freq); + if (prescale < 0) { + mp_raise_ValueError(MP_ERROR_TEXT(ERRMSG_FREQ)); + } + if (prescale != self->prescale) { + QTMR_GetDefaultConfig(&qtmrConfig); + qtmrConfig.primarySource = prescale + kQTMR_ClockDivide_1; + QTMR_Init(instance, self->channel1, &qtmrConfig); + self->prescale = prescale; + } + // Set up the PWM channel + if (QTMR_SetupPwm_u16(instance, self->channel1, self->freq, self->duty_u16, + self->invert, CLOCK_GetFreq(kCLOCK_IpgClk) / (1 << prescale), self->is_init) == kStatus_Fail) { + mp_raise_ValueError(MP_ERROR_TEXT(ERRMSG_INIT)); + } + // Start the output + QTMR_StartTimer(instance, self->channel1, kQTMR_PriSrcRiseEdge); +} +#endif // FSL_FEATURE_SOC_TMR_COUNT + +STATIC void configure_pwm(machine_pwm_obj_t *self) { + // Set the clock frequencies + // Freq range is 15Hz to ~ 3 MHz. + static bool set_frequency = true; + // set the frequency only once + if (set_frequency) { + CLOCK_SetDiv(kCLOCK_IpgDiv, 0x3); // Set IPG PODF to 3, divide by 4 + set_frequency = false; + } + + if (self->duty_ns != 0) { + self->duty_u16 = duty_ns_to_duty_u16(self->freq, self->duty_ns); + } + if (self->is_flexpwm) { + configure_flexpwm(self); + #ifdef FSL_FEATURE_SOC_TMR_COUNT + } else { + configure_qtmr(self); + #endif + } +} + +// Micropython API functions +// +STATIC void mp_machine_pwm_init_helper(machine_pwm_obj_t *self, + size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_freq, ARG_duty_u16, ARG_duty_ns, ARG_center, ARG_align, + ARG_invert, ARG_sync, ARG_xor, ARG_deadtime }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_freq, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_duty_u16, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_duty_ns, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_center, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_align, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1}}, + { MP_QSTR_invert, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1}}, + { MP_QSTR_sync, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1}}, + { MP_QSTR_xor, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1}}, + { MP_QSTR_deadtime, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1}}, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, + MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if ((n_args + kw_args->used) > 0 || self->is_init == false) { + // Maybe change PWM timer + if (args[ARG_freq].u_int > 0) { + self->freq = args[ARG_freq].u_int; + } + + // Set duty_u16 cycle? + uint32_t duty = args[ARG_duty_u16].u_int; + if (duty != 0) { + if (duty >= PWM_FULL_SCALE) { + mp_raise_ValueError(MP_ERROR_TEXT(ERRMSG_VALUE)); + } + self->duty_u16 = duty; + self->duty_ns = 0; + } + // Set duty_ns value? + duty = args[ARG_duty_ns].u_int; + if (duty != 0) { + self->duty_ns = duty; + self->duty_u16 = duty_ns_to_duty_u16(self->freq, self->duty_ns); + } + // Set center value? + int32_t center = args[ARG_center].u_int; + if (center >= 0) { + if (center >= PWM_FULL_SCALE) { + mp_raise_ValueError(MP_ERROR_TEXT(ERRMSG_VALUE)); + } + self->center = center; + } else { // Use alignment setting shortcut + if (args[ARG_align].u_int >= 0) { + uint8_t align = args[ARG_align].u_int & 3; // limit to 0..3 + if (align == PWM_BEGIN) { + self->center = self->duty_u16 / 2; + } else if (align == PWM_END) { + self->center = PWM_FULL_SCALE - self->duty_u16 / 2; + } else { + self->center = 32768; // Default value: mid. + } + } + } + + if (args[ARG_invert].u_int >= 0) { + self->invert = args[ARG_invert].u_int & (PWM_CHANNEL1 | PWM_CHANNEL2); + } + + if (args[ARG_sync].u_int >= 0) { + self->sync = args[ARG_sync].u_int != false && self->submodule != 0; + } + + if (args[ARG_xor].u_int >= 0) { + self->xor = args[ARG_xor].u_int & 0x03; + } + + if (args[ARG_deadtime].u_int >= 0) { + self->deadtime = args[ARG_deadtime].u_int; + } + configure_pwm(self); + self->is_init = true; + } else { + machine_pwm_start(self); + } + +} + +// PWM(pin | pin-tuple, freq, [args]) +STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + // Check number of arguments + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + + mp_obj_t *pins; + const machine_pin_obj_t *pin1; + const machine_pin_obj_t *pin2; + + // Get referred Pin object(s) + if (mp_obj_is_type(args[0], &mp_type_tuple)) { + mp_obj_get_array_fixed_n(args[0], 2, &pins); + pin1 = pin_find(pins[0]); + pin2 = pin_find(pins[1]); + } else { + pin1 = pin_find(args[0]); + pin2 = NULL; + } + + // Check whether it supports PWM and decode submodule & channel + const machine_pin_af_obj_t *af_obj1 = NULL; + uint8_t submodule1; + uint8_t channel1; + const machine_pin_af_obj_t *af_obj2 = NULL; + uint8_t submodule2; + uint8_t channel2; + uint8_t module; + bool is_flexpwm = false; + + for (int i = 0; i < pin1->af_list_len; ++i) { + af_obj1 = af_name_decode_flexpwm(&(pin1->af_list[i]), &module, &submodule1, &channel1); + if (af_obj1 != NULL) { + break; + } + } + if (pin2 != NULL) { + for (int i = 0; i < pin1->af_list_len; ++i) { + af_obj2 = af_name_decode_flexpwm(&(pin2->af_list[i]), &module, &submodule2, &channel2); + if (af_obj2 != NULL) { + break; + } + } + } + if (af_obj1 == NULL) { + submodule1 = 0; + #ifdef FSL_FEATURE_SOC_TMR_COUNT + // Check for QTimer support + if (is_board_pin(pin1)) { + for (int i = 0; i < pin1->af_list_len; ++i) { + af_obj1 = af_name_decode_qtmr(&(pin1->af_list[i]), &module, &channel1); + if (af_obj1 != NULL) { + break; + } + } + } + #endif + if (af_obj1 == NULL) { + mp_raise_ValueError(MP_ERROR_TEXT("the requested Pin(s) does not support PWM")); + } + } else { + // is flexpwm, check for instance match + is_flexpwm = true; + if (pin2 != NULL && af_obj1->instance != af_obj2->instance && submodule1 != submodule2) { + mp_raise_ValueError(MP_ERROR_TEXT("the pins must be a A/B pair of a submodule")); + } + } + + // Create and populate the PWM object. + machine_pwm_obj_t *self = m_new_obj(machine_pwm_obj_t); + self->base.type = &machine_pwm_type; + self->is_flexpwm = is_flexpwm; + self->instance = af_obj1->instance; + self->module = module; + self->submodule = submodule1; + self->channel1 = channel1; + self->invert = 0; + self->freq = 1000; + self->prescale = -1; + self->duty_u16 = 32768; + self->duty_ns = 0; + self->center = 32768; + self->output_enable_1 = is_board_pin(pin1); + self->sync = false; + self->deadtime = 0; + self->xor = 0; + self->is_init = false; + + // Initialize the Pin(s). + CLOCK_EnableClock(kCLOCK_Iomuxc); // just in case it was not set yet + IOMUXC_SetPinMux(pin1->muxRegister, af_obj1->af_mode, af_obj1->input_register, af_obj1->input_daisy, + pin1->configRegister, 0U); + IOMUXC_SetPinConfig(pin1->muxRegister, af_obj1->af_mode, af_obj1->input_register, af_obj1->input_daisy, + pin1->configRegister, 0x10B0U); + + // Settings for the second pin, if given. + if (pin2 != NULL && pin2 != pin1) { + self->complementary = 1; + self->channel2 = channel2; + self->output_enable_2 = is_board_pin(pin2); + // Initialize the Pin(s) + IOMUXC_SetPinMux(pin2->muxRegister, af_obj2->af_mode, af_obj2->input_register, af_obj2->input_daisy, + pin2->configRegister, 0U); + IOMUXC_SetPinConfig(pin2->muxRegister, af_obj2->af_mode, af_obj2->input_register, af_obj2->input_daisy, + pin2->configRegister, 0x10B0U); + } else { + self->complementary = 0; + } + + // Process the remaining parameters. + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + mp_machine_pwm_init_helper(self, n_args - 1, args + 1, &kw_args); + + return MP_OBJ_FROM_PTR(self); +} + +// Disable all PWM devices. Called on soft reset +void machine_pwm_deinit_all(void) { + static PWM_Type *const pwm_bases[] = PWM_BASE_PTRS; + + for (int i = 1; i < ARRAY_SIZE(pwm_bases); i++) { + PWM_StopTimer(pwm_bases[i], 0x0f); // Stop all submodules + pwm_bases[i]->OUTEN = 0; // Disable ouput on all submodules, all channels + } + + #ifdef FSL_FEATURE_SOC_TMR_COUNT + static TMR_Type *const tmr_bases[] = TMR_BASE_PTRS; + for (int i = 1; i < ARRAY_SIZE(tmr_bases); i++) { + for (int j = 0; j < 4; j++) { + QTMR_StopTimer(tmr_bases[i], j); // Stop all timers + } + } + #endif +} + +STATIC void machine_pwm_start(machine_pwm_obj_t *self) { + if (self->is_flexpwm) { + PWM_StartTimer(self->instance, 1 << self->submodule); + #ifdef FSL_FEATURE_SOC_TMR_COUNT + } else { + QTMR_StartTimer((TMR_Type *)self->instance, self->channel1, kQTMR_PriSrcRiseEdge); + #endif + } +} + +STATIC void mp_machine_pwm_deinit(machine_pwm_obj_t *self) { + if (self->is_flexpwm) { + PWM_StopTimer(self->instance, 1 << self->submodule); + #ifdef FSL_FEATURE_SOC_TMR_COUNT + } else { + QTMR_StopTimer((TMR_Type *)self->instance, self->channel1); + #endif + } +} + +mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) { + return MP_OBJ_NEW_SMALL_INT(self->freq); +} + +void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) { + self->freq = freq; + configure_pwm(self); +} + +mp_obj_t mp_machine_pwm_duty_get_u16(machine_pwm_obj_t *self) { + return MP_OBJ_NEW_SMALL_INT(self->duty_u16); +} + +void mp_machine_pwm_duty_set_u16(machine_pwm_obj_t *self, mp_int_t duty) { + if (duty >= 0) { + if (duty >= PWM_FULL_SCALE) { + mp_raise_ValueError(MP_ERROR_TEXT(ERRMSG_VALUE)); + } + self->duty_u16 = duty; + self->duty_ns = 0; + configure_pwm(self); + } +} + +mp_obj_t mp_machine_pwm_duty_get_ns(machine_pwm_obj_t *self) { + return MP_OBJ_NEW_SMALL_INT(1000000000ULL / self->freq * self->duty_u16 / PWM_FULL_SCALE); +} + +void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty) { + if (duty >= 0) { + self->duty_ns = duty; + self->duty_u16 = duty_ns_to_duty_u16(self->freq, self->duty_ns); + configure_pwm(self); + } +} diff --git a/ports/mimxrt/main.c b/ports/mimxrt/main.c index fa6237ca07..4d603913fd 100644 --- a/ports/mimxrt/main.c +++ b/ports/mimxrt/main.c @@ -119,6 +119,7 @@ int main(void) { #if MICROPY_PY_NETWORK mod_network_deinit(); #endif + machine_pwm_deinit_all(); gc_sweep_all(); mp_deinit(); } diff --git a/ports/mimxrt/modmachine.c b/ports/mimxrt/modmachine.c index a05c81a40a..e7f0961344 100644 --- a/ports/mimxrt/modmachine.c +++ b/ports/mimxrt/modmachine.c @@ -129,6 +129,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { #if MICROPY_PY_MACHINE_SDCARD { MP_ROM_QSTR(MP_QSTR_SDCard), MP_ROM_PTR(&machine_sdcard_type) }, #endif + { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, diff --git a/ports/mimxrt/modmachine.h b/ports/mimxrt/modmachine.h index b9949ab784..d18a227624 100644 --- a/ports/mimxrt/modmachine.h +++ b/ports/mimxrt/modmachine.h @@ -31,6 +31,7 @@ extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_i2c_type; +extern const mp_obj_type_t machine_pwm_type; extern const mp_obj_type_t machine_rtc_type; extern const mp_obj_type_t machine_sdcard_type; extern const mp_obj_type_t machine_spi_type; @@ -40,6 +41,7 @@ extern const mp_obj_type_t machine_wdt_type; void machine_adc_init(void); void machine_pin_irq_deinit(void); +void machine_pwm_deinit_all(void); void machine_timer_init_PIT(void); void machine_sdcard_init0(void); void mimxrt_sdram_init(void); diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 361b8bd089..967482dc77 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -129,6 +129,10 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new #define MICROPY_PY_MACHINE_BITSTREAM (1) #define MICROPY_PY_MACHINE_PULSE (1) +#define MICROPY_PY_MACHINE_PWM (1) +#define MICROPY_PY_MACHINE_PWM_INIT (1) +#define MICROPY_PY_MACHINE_PWM_DUTY_U16_NS (1) +#define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/mimxrt/machine_pwm.c" #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) diff --git a/ports/mimxrt/ticks.c b/ports/mimxrt/ticks.c index a5ee102428..5ae6f7f13b 100644 --- a/ports/mimxrt/ticks.c +++ b/ports/mimxrt/ticks.c @@ -129,9 +129,7 @@ void ticks_delay_us64(uint64_t us) { dt = 0xffffffff; } ticks_wake_after_us32((uint32_t)dt); - if (dt < 50) { - __WFE(); - } else { + if (dt > 50) { MICROPY_EVENT_POLL_HOOK } } From c422ca3da19767f83e038f16c62c875aebaed516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Pierson?= Date: Wed, 27 Oct 2021 10:16:55 +0200 Subject: [PATCH 197/335] rp2/boards: Add PYBSTICK26 RP2040 board definition. --- .../GARATRONIC_PYBSTICK26_RP2040/board.json | 22 +++++++++++++++++++ .../mpconfigboard.cmake | 1 + .../mpconfigboard.h | 3 +++ 3 files changed, 26 insertions(+) create mode 100644 ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/board.json create mode 100644 ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/mpconfigboard.cmake create mode 100644 ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/mpconfigboard.h diff --git a/ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/board.json b/ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/board.json new file mode 100644 index 0000000000..1b9e113143 --- /dev/null +++ b/ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/board.json @@ -0,0 +1,22 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "USB Stick form factor", + "Breadboard Friendly", + "Reset/User button", + "Red/green/orange/blue leds", + "1MB SPI Flash", + "USB-A" + ], + "images": [ + "pybstick-rp2040-26-broches-micropython-c.jpg" + ], + "mcu": "rp2040", + "product": "PYBSTICK26 RP2040", + "thumbnail": "", + "url": "https://shop.mchobby.be/product.php?id_product=2331", + "vendor": "McHobby" +} diff --git a/ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/mpconfigboard.cmake b/ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/mpconfigboard.cmake new file mode 100644 index 0000000000..11fcb3d087 --- /dev/null +++ b/ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/mpconfigboard.cmake @@ -0,0 +1 @@ +# cmake file diff --git a/ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/mpconfigboard.h b/ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/mpconfigboard.h new file mode 100644 index 0000000000..4c7153569b --- /dev/null +++ b/ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/mpconfigboard.h @@ -0,0 +1,3 @@ +// Board and hardware specific configuration +#define MICROPY_HW_BOARD_NAME "GARATRONIC_PYBSTICK26_RP2040" +#define MICROPY_HW_FLASH_STORAGE_BYTES (384 * 1024) From fdb925c4c1fdb231dda579a17fcb23d921322edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Pierson?= Date: Thu, 28 Oct 2021 19:12:09 +0200 Subject: [PATCH 198/335] stm32/boards: Add PYBSTICK26 F411 board definition. --- .../GARATRONIC_PYBSTICK26_F411/board.json | 13 +++ .../GARATRONIC_PYBSTICK26_F411/manifest.py | 2 + .../mpconfigboard.h | 84 +++++++++++++++++++ .../mpconfigboard.mk | 6 ++ .../GARATRONIC_PYBSTICK26_F411/pins.csv | 55 ++++++++++++ .../stm32f4xx_hal_conf.h | 19 +++++ 6 files changed, 179 insertions(+) create mode 100644 ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/board.json create mode 100644 ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/manifest.py create mode 100644 ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/mpconfigboard.h create mode 100644 ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/mpconfigboard.mk create mode 100644 ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/pins.csv create mode 100644 ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/stm32f4xx_hal_conf.h diff --git a/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/board.json b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/board.json new file mode 100644 index 0000000000..1df9b6f658 --- /dev/null +++ b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "GARATRONIC_PYBSTICK26_F411", + "thumbnail": "", + "url": "https://shop.mchobby.be/product.php?id_product=1844", + "vendor": "McHobby" +} diff --git a/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/manifest.py b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/manifest.py new file mode 100644 index 0000000000..b09c7ab920 --- /dev/null +++ b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/manifest.py @@ -0,0 +1,2 @@ +include("$(MPY_DIR)/extmod/uasyncio/manifest.py") +freeze("$(MPY_DIR)/drivers/", ("display/ssd1306.py")) diff --git a/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/mpconfigboard.h b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/mpconfigboard.h new file mode 100644 index 0000000000..408bc28512 --- /dev/null +++ b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/mpconfigboard.h @@ -0,0 +1,84 @@ +#define MICROPY_HW_BOARD_NAME "PYBSTICK26_STD" +#define MICROPY_HW_MCU_NAME "STM32F411RE" +#define MICROPY_PY_THREAD (1) + +#define MICROPY_HW_HAS_SWITCH (1) +#define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_HAS_KXTJ3 (0) +#define MICROPY_HW_HAS_LCD (0) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SERVO (1) +#define MICROPY_HW_ENABLE_SDCARD (1) + +// HSE is 16MHz +#define MICROPY_HW_CLK_PLLM (16) +#define MICROPY_HW_CLK_PLLN (192) +#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2) +#define MICROPY_HW_CLK_PLLQ (4) +#define MICROPY_HW_CLK_LAST_FREQ (1) + +// Pybstick26 STD has an optional 32kHz crystal +#define MICROPY_HW_RTC_USE_LSE (1) +#define MICROPY_HW_RTC_USE_US (1) +#define MICROPY_HW_RTC_USE_CALOUT (0) + +// UART config +#define MICROPY_HW_UART1_NAME "XB" +#define MICROPY_HW_UART1_TX (pin_A15) +#define MICROPY_HW_UART1_RX (pin_A10) +#define MICROPY_HW_UART2_NAME "XA" +#define MICROPY_HW_UART2_TX (pin_A2) +#define MICROPY_HW_UART2_RX (pin_A3) +//#define MICROPY_HW_UART2_RTS (pin_A1) +//#define MICROPY_HW_UART2_CTS (pin_A0) +#define MICROPY_HW_UART6_NAME "YA" +#define MICROPY_HW_UART6_TX (pin_C6) +#define MICROPY_HW_UART6_RX (pin_C7) + +// I2C buses +#define MICROPY_HW_I2C1_NAME "X" +#define MICROPY_HW_I2C1_SCL (pin_B8) // S5 +#define MICROPY_HW_I2C1_SDA (pin_B9) // S3 +#define MICROPY_HW_I2C2_NAME "Y" +#define MICROPY_HW_I2C2_SCL (pin_B10) //S13 +#define MICROPY_HW_I2C2_SDA (pin_B3) // S11 + +// SPI buses +#define MICROPY_HW_SPI1_NAME "X" +#define MICROPY_HW_SPI1_NSS (pin_A4) // S26 +#define MICROPY_HW_SPI1_SCK (pin_A5) // S23 +#define MICROPY_HW_SPI1_MISO (pin_B4) // S21 +#define MICROPY_HW_SPI1_MOSI (pin_A7) // S19 +#define MICROPY_HW_SPI2_NAME "Y" +#define MICROPY_HW_SPI2_NSS (pin_B12) // S15 +#define MICROPY_HW_SPI2_SCK (pin_B13) // S16 +#define MICROPY_HW_SPI2_MISO (pin_B14) // S18 +#define MICROPY_HW_SPI2_MOSI (pin_C3) // S13 + +// USRSW has no pullup or pulldown, and pressing the switch makes the input go low +#define MICROPY_HW_USRSW_PIN (pin_C13) +#define MICROPY_HW_USRSW_PULL (GPIO_PULLUP) +#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_FALLING) +#define MICROPY_HW_USRSW_PRESSED (0) + +// The board has 4 LEDs +#define MICROPY_HW_LED1 (pin_A13) // red +#define MICROPY_HW_LED2 (pin_A14) // green +#define MICROPY_HW_LED3 (pin_B0) // yellow +#define MICROPY_HW_LED4 (pin_B1) // blue +#define MICROPY_HW_LED3_PWM { TIM3, 3, TIM_CHANNEL_3, GPIO_AF2_TIM3 } +#define MICROPY_HW_LED4_PWM { TIM3, 4, TIM_CHANNEL_4, GPIO_AF2_TIM3 } +#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) +#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) + +// SD card with custom SDIO pins +#define MICROPY_HW_SDCARD_D0 (pin_B7) +#define MICROPY_HW_SDCARD_D1 (pin_A8) +#define MICROPY_HW_SDCARD_D2 (pin_A9) +#define MICROPY_HW_SDCARD_D3 (pin_B5) +#define MICROPY_HW_SDCARD_CK (pin_B15) +#define MICROPY_HW_SDCARD_CMD (pin_A6) + +// USB config +#define MICROPY_HW_USB_FS (1) diff --git a/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/mpconfigboard.mk b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/mpconfigboard.mk new file mode 100644 index 0000000000..df95065225 --- /dev/null +++ b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/mpconfigboard.mk @@ -0,0 +1,6 @@ +MCU_SERIES = f4 +CMSIS_MCU = STM32F411xE +AF_FILE = boards/stm32f411_af.csv +LD_FILES = boards/stm32f411.ld boards/common_ifs.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08020000 diff --git a/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/pins.csv b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/pins.csv new file mode 100644 index 0000000000..c52e65cf79 --- /dev/null +++ b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/pins.csv @@ -0,0 +1,55 @@ +S1,3.3V +S2,VBUS +S3,PB9 +S4,VIN +S5,PB8 +S6,GND +S7,PB6 +S8,PA2 +S9,GND +S10,PA3 +S11,PB3 +S12,PA0 +S13,PB10 +S13A,PC3 +S14,Reset +S15,PB12 +S15A,PC5 +S16,PB13 +S16A,PC6 +S17,GND +S18,PB14 +S18A,PC7 +S19,PA7 +S20,GND +S21,PB4 +S22,PA10 +S23,PA5 +S24,PA15 +S25,GND +S26,PA4 +SW,PC13 +SW2,PB6 +LED_GREEN,PA14 +LED_YELLOW,PB0 +LED_RED,PA13 +LED_BLUE,PB1 +SD_D0,PB7 +SD_D1,PA8 +SD_D2,PA9 +SD_D3,PB5 +SD_CMD,PA6 +SD_CK,PB15 +USB_DM,PA11 +USB_DP,PA12 +OSC_IN,PH0 +OSC_OUT,PH1 +OSC32_IN,PC14 +OSC32_OUT,PC15 +QSPI_BK1_IO3,PA1 +SDIO_CMD,PA6 +SDIO_D1,PA8 +SDIO_D2,PA9 +SDIO_D3,PB5 +SDIO_D0,PB7 +SDIO_CK,PB15 diff --git a/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/stm32f4xx_hal_conf.h b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/stm32f4xx_hal_conf.h new file mode 100644 index 0000000000..7d6344f0a2 --- /dev/null +++ b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/stm32f4xx_hal_conf.h @@ -0,0 +1,19 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2019 Damien P. George + */ +#ifndef MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H + +#include "boards/stm32f4xx_hal_conf_base.h" + +// Oscillator values in Hz +#define HSE_VALUE (16000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (100) +#define LSE_STARTUP_TIMEOUT (5000) + +#endif // MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H From d49df423e09acb24a39927e485fd43cced129ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Pierson?= Date: Sat, 20 Nov 2021 19:32:19 +0100 Subject: [PATCH 199/335] stm32/boards/NADHAT_PYBF405: Rename board to GARATRONIC_NADHAT_F405. To add the manufacturer as a prefix to the board name, for consistency with other Garatronic boards. --- .../{NADHAT_PYBF405 => GARATRONIC_NADHAT_F405}/board.json | 6 +++--- .../mpconfigboard.h | 0 .../mpconfigboard.mk | 0 .../{NADHAT_PYBF405 => GARATRONIC_NADHAT_F405}/pins.csv | 0 .../stm32f4xx_hal_conf.h | 0 5 files changed, 3 insertions(+), 3 deletions(-) rename ports/stm32/boards/{NADHAT_PYBF405 => GARATRONIC_NADHAT_F405}/board.json (52%) rename ports/stm32/boards/{NADHAT_PYBF405 => GARATRONIC_NADHAT_F405}/mpconfigboard.h (100%) rename ports/stm32/boards/{NADHAT_PYBF405 => GARATRONIC_NADHAT_F405}/mpconfigboard.mk (100%) rename ports/stm32/boards/{NADHAT_PYBF405 => GARATRONIC_NADHAT_F405}/pins.csv (100%) rename ports/stm32/boards/{NADHAT_PYBF405 => GARATRONIC_NADHAT_F405}/stm32f4xx_hal_conf.h (100%) diff --git a/ports/stm32/boards/NADHAT_PYBF405/board.json b/ports/stm32/boards/GARATRONIC_NADHAT_F405/board.json similarity index 52% rename from ports/stm32/boards/NADHAT_PYBF405/board.json rename to ports/stm32/boards/GARATRONIC_NADHAT_F405/board.json index fd4e67c61a..38873e4de8 100644 --- a/ports/stm32/boards/NADHAT_PYBF405/board.json +++ b/ports/stm32/boards/GARATRONIC_NADHAT_F405/board.json @@ -6,8 +6,8 @@ "features": [], "images": [], "mcu": "stm32f4", - "product": "PYBF405", + "product": "GARATRONIC_NADHAT_F405", "thumbnail": "", - "url": "", - "vendor": "Nadhat" + "url": "https://shop.mchobby.be/product.php?id_product=1653", + "vendor": "McHobby" } diff --git a/ports/stm32/boards/NADHAT_PYBF405/mpconfigboard.h b/ports/stm32/boards/GARATRONIC_NADHAT_F405/mpconfigboard.h similarity index 100% rename from ports/stm32/boards/NADHAT_PYBF405/mpconfigboard.h rename to ports/stm32/boards/GARATRONIC_NADHAT_F405/mpconfigboard.h diff --git a/ports/stm32/boards/NADHAT_PYBF405/mpconfigboard.mk b/ports/stm32/boards/GARATRONIC_NADHAT_F405/mpconfigboard.mk similarity index 100% rename from ports/stm32/boards/NADHAT_PYBF405/mpconfigboard.mk rename to ports/stm32/boards/GARATRONIC_NADHAT_F405/mpconfigboard.mk diff --git a/ports/stm32/boards/NADHAT_PYBF405/pins.csv b/ports/stm32/boards/GARATRONIC_NADHAT_F405/pins.csv similarity index 100% rename from ports/stm32/boards/NADHAT_PYBF405/pins.csv rename to ports/stm32/boards/GARATRONIC_NADHAT_F405/pins.csv diff --git a/ports/stm32/boards/NADHAT_PYBF405/stm32f4xx_hal_conf.h b/ports/stm32/boards/GARATRONIC_NADHAT_F405/stm32f4xx_hal_conf.h similarity index 100% rename from ports/stm32/boards/NADHAT_PYBF405/stm32f4xx_hal_conf.h rename to ports/stm32/boards/GARATRONIC_NADHAT_F405/stm32f4xx_hal_conf.h From 196d26848a76043777e4e3ebb2455f26e6349dfc Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 24 Nov 2021 13:30:04 +1100 Subject: [PATCH 200/335] stm32/usb: Use a table of allowed values to simplify usb_mode get/set. This reduces code size and code duplication, and fixes `pyb.usb_mode()` so that it now returns the correct string when in multi-VCP mode (before, it would return None when in one of these modes). Signed-off-by: Damien George --- ports/stm32/qstrdefsport.h | 14 ++++- ports/stm32/usb.c | 125 ++++++++++++++----------------------- 2 files changed, 61 insertions(+), 78 deletions(-) diff --git a/ports/stm32/qstrdefsport.h b/ports/stm32/qstrdefsport.h index bc07f2752a..e7d84cbec0 100644 --- a/ports/stm32/qstrdefsport.h +++ b/ports/stm32/qstrdefsport.h @@ -38,7 +38,19 @@ Q(/) #if MICROPY_HW_ENABLE_USB // for usb modes -Q(MSC+HID) +Q(VCP) +Q(MSC) Q(VCP+MSC) Q(VCP+HID) +Q(VCP+MSC+HID) +#if MICROPY_HW_USB_CDC_NUM >= 2 +Q(2xVCP) +Q(2xVCP+MSC) +Q(2xVCP+MSC+HID) +#endif +#if MICROPY_HW_USB_CDC_NUM >= 3 +Q(3xVCP) +Q(3xVCP+MSC) +Q(3xVCP+MSC+HID) +#endif #endif diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 1ed45592e9..9a9600f89d 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -396,6 +396,35 @@ usbd_cdc_itf_t *usb_vcp_get(int idx) { pyb.usb_mode(..., port=2) # for second USB port */ +typedef struct _pyb_usb_mode_table_t { + uint8_t usbd_mode; + uint16_t qst; + const char *deprecated_str; + uint16_t default_pid; +} pyb_usb_mode_table_t; + +// These are all the modes supported by USBD_SelectMode. +// Note: there are some names (eg CDC, VCP+VCP) which are supported for backwards compatibility. +STATIC const pyb_usb_mode_table_t pyb_usb_mode_table[] = { + { USBD_MODE_CDC, MP_QSTR_VCP, "CDC", MICROPY_HW_USB_PID_CDC }, + { USBD_MODE_MSC, MP_QSTR_MSC, NULL, MICROPY_HW_USB_PID_MSC }, + { USBD_MODE_CDC_MSC, MP_QSTR_VCP_plus_MSC, "CDC+MSC", MICROPY_HW_USB_PID_CDC_MSC }, + { USBD_MODE_CDC_HID, MP_QSTR_VCP_plus_HID, "CDC+HID", MICROPY_HW_USB_PID_CDC_HID }, + { USBD_MODE_CDC_MSC_HID, MP_QSTR_VCP_plus_MSC_plus_HID, NULL, MICROPY_HW_USB_PID_CDC_MSC_HID }, + + #if MICROPY_HW_USB_CDC_NUM >= 2 + { USBD_MODE_CDC2, MP_QSTR_2xVCP, "VCP+VCP", MICROPY_HW_USB_PID_CDC2 }, + { USBD_MODE_CDC2_MSC, MP_QSTR_2xVCP_plus_MSC, "VCP+VCP+MSC", MICROPY_HW_USB_PID_CDC2_MSC }, + { USBD_MODE_CDC2_MSC_HID, MP_QSTR_2xVCP_plus_MSC_plus_HID, NULL, MICROPY_HW_USB_PID_CDC2_MSC_HID }, + #endif + + #if MICROPY_HW_USB_CDC_NUM >= 3 + { USBD_MODE_CDC3, MP_QSTR_3xVCP, NULL, MICROPY_HW_USB_PID_CDC3 }, + { USBD_MODE_CDC3_MSC, MP_QSTR_3xVCP_plus_MSC, NULL, MICROPY_HW_USB_PID_CDC3_MSC }, + { USBD_MODE_CDC3_MSC_HID, MP_QSTR_3xVCP_plus_MSC_plus_HID, NULL, MICROPY_HW_USB_PID_CDC3_MSC_HID }, + #endif +}; + STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_mode, ARG_port, ARG_vid, ARG_pid, @@ -430,23 +459,14 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t * #if defined(USE_HOST_MODE) return MP_OBJ_NEW_QSTR(MP_QSTR_host); #else - uint8_t mode = USBD_GetMode(&usb_device.usbd_cdc_msc_hid_state); - switch (mode & USBD_MODE_IFACE_MASK) { - case USBD_MODE_CDC: - return MP_OBJ_NEW_QSTR(MP_QSTR_VCP); - case USBD_MODE_MSC: - return MP_OBJ_NEW_QSTR(MP_QSTR_MSC); - case USBD_MODE_HID: - return MP_OBJ_NEW_QSTR(MP_QSTR_HID); - case USBD_MODE_CDC_MSC: - return MP_OBJ_NEW_QSTR(MP_QSTR_VCP_plus_MSC); - case USBD_MODE_CDC_HID: - return MP_OBJ_NEW_QSTR(MP_QSTR_VCP_plus_HID); - case USBD_MODE_MSC_HID: - return MP_OBJ_NEW_QSTR(MP_QSTR_MSC_plus_HID); - default: - return mp_const_none; + uint8_t mode = USBD_GetMode(&usb_device.usbd_cdc_msc_hid_state) & USBD_MODE_IFACE_MASK; + for (size_t i = 0; i < MP_ARRAY_SIZE(pyb_usb_mode_table); ++i) { + const pyb_usb_mode_table_t *m = &pyb_usb_mode_table[i]; + if (mode == m->usbd_mode) { + return MP_OBJ_NEW_QSTR(m->qst); + } } + return mp_const_none; #endif } @@ -483,70 +503,21 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t * // get the VID, PID and USB mode // note: PID=-1 means select PID based on mode - // note: we support CDC as a synonym for VCP for backward compatibility uint16_t vid = args[ARG_vid].u_int; mp_int_t pid = args[ARG_pid].u_int; - uint8_t mode; - if (strcmp(mode_str, "CDC+MSC") == 0 || strcmp(mode_str, "VCP+MSC") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC_MSC; + uint8_t mode = 0; + for (size_t i = 0; i < MP_ARRAY_SIZE(pyb_usb_mode_table); ++i) { + const pyb_usb_mode_table_t *m = &pyb_usb_mode_table[i]; + if (strcmp(mode_str, qstr_str(m->qst)) == 0 + || (m->deprecated_str != NULL && strcmp(mode_str, m->deprecated_str) == 0)) { + if (pid == -1) { + pid = m->default_pid; + } + mode = m->usbd_mode; + break; } - mode = USBD_MODE_CDC_MSC; - } else if (strcmp(mode_str, "VCP+MSC+HID") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC_MSC_HID; - } - mode = USBD_MODE_CDC_MSC_HID; - #if MICROPY_HW_USB_CDC_NUM >= 2 - } else if (strcmp(mode_str, "VCP+VCP") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC2; - } - mode = USBD_MODE_CDC2; - } else if (strcmp(mode_str, "VCP+VCP+MSC") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC2_MSC; - } - mode = USBD_MODE_CDC2_MSC; - } else if (strcmp(mode_str, "2xVCP+MSC+HID") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC2_MSC_HID; - } - mode = USBD_MODE_CDC2_MSC_HID; - #endif - #if MICROPY_HW_USB_CDC_NUM >= 3 - } else if (strcmp(mode_str, "3xVCP") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC3; - } - mode = USBD_MODE_CDC3; - } else if (strcmp(mode_str, "3xVCP+MSC") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC3_MSC; - } - mode = USBD_MODE_CDC3_MSC; - } else if (strcmp(mode_str, "3xVCP+MSC+HID") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC3_MSC_HID; - } - mode = USBD_MODE_CDC3_MSC_HID; - #endif - } else if (strcmp(mode_str, "CDC+HID") == 0 || strcmp(mode_str, "VCP+HID") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC_HID; - } - mode = USBD_MODE_CDC_HID; - } else if (strcmp(mode_str, "CDC") == 0 || strcmp(mode_str, "VCP") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC; - } - mode = USBD_MODE_CDC; - } else if (strcmp(mode_str, "MSC") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_MSC; - } - mode = USBD_MODE_MSC; - } else { + } + if (mode == 0) { goto bad_mode; } From 11ed94797d492cabdaf09396feb69a690e86f739 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 19 Nov 2021 10:36:16 +1100 Subject: [PATCH 201/335] py/lexer: Support nested [] and {} characters within f-string params. Signed-off-by: Damien George --- py/lexer.c | 11 +++++++++-- tests/basics/string_fstring.py | 7 +++++++ tests/cpydiff/core_fstring_parser.py | 8 ++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/py/lexer.c b/py/lexer.c index 69c7d14a77..ac406bd469 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -363,9 +363,16 @@ STATIC void parse_string_literal(mp_lexer_t *lex, bool is_raw, bool is_fstring) // (MicroPython limitation) note: this is completely unaware of // Python syntax and will not handle any expression containing '}' or ':'. // e.g. f'{"}"}' or f'{foo({})}'. - while (!is_end(lex) && !is_char_or(lex, ':', '}')) { + unsigned int nested_bracket_level = 0; + while (!is_end(lex) && (nested_bracket_level != 0 || !is_char_or(lex, ':', '}'))) { + unichar c = CUR_CHAR(lex); + if (c == '[' || c == '{') { + nested_bracket_level += 1; + } else if (c == ']' || c == '}') { + nested_bracket_level -= 1; + } // like the default case at the end of this function, stay 8-bit clean - vstr_add_byte(&lex->fstring_args, CUR_CHAR(lex)); + vstr_add_byte(&lex->fstring_args, c); next_char(lex); } if (lex->fstring_args.buf[lex->fstring_args.len - 1] == '=') { diff --git a/tests/basics/string_fstring.py b/tests/basics/string_fstring.py index 4f7225fcad..7e8a97fd30 100644 --- a/tests/basics/string_fstring.py +++ b/tests/basics/string_fstring.py @@ -22,6 +22,13 @@ def foo(a, b): return f'{x}{y}{a}{b}' print(foo(7, 8)) +# ':' character within {...} that should not be interpreted as format specifiers. +print(f"a{[0,1,2][0:2]}") +print(f"a{[0,15,2][0:2][-1]:04x}") + +# Nested '{' and '}' characters. +print(f"a{ {0,1,2}}") + # PEP-0498 specifies that '\\' and '#' must be disallowed explicitly, whereas # MicroPython relies on the syntax error as a result of the substitution. diff --git a/tests/cpydiff/core_fstring_parser.py b/tests/cpydiff/core_fstring_parser.py index 6917f3cfa4..22bbc5866e 100644 --- a/tests/cpydiff/core_fstring_parser.py +++ b/tests/cpydiff/core_fstring_parser.py @@ -1,9 +1,9 @@ """ categories: Core -description: f-strings cannot support expressions that require parsing to resolve nested braces +description: f-strings cannot support expressions that require parsing to resolve unbalanced nested braces and brackets cause: MicroPython is optimised for code space. -workaround: Only use simple expressions inside f-strings +workaround: Always use balanced braces and brackets in expressions inside f-strings """ -f'{"hello {} world"}' -f"{repr({})}" +print(f'{"hello { world"}') +print(f'{"hello ] world"}') From e99f7b6d25464f36accc2f04899edfa9e982bee2 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 18 Nov 2021 23:29:48 +1100 Subject: [PATCH 202/335] tests/cpydiff: Clarify f-string diffs regarding concatenation. Concatenation of any literals (including f-strings) should be avoided. Signed-off-by: Jim Mussared --- tests/cpydiff/core_fstring_concat.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/cpydiff/core_fstring_concat.py b/tests/cpydiff/core_fstring_concat.py index fd83527b5c..c2bdb4e666 100644 --- a/tests/cpydiff/core_fstring_concat.py +++ b/tests/cpydiff/core_fstring_concat.py @@ -1,12 +1,13 @@ """ categories: Core -description: f-strings don't support concatenation with adjacent literals if the adjacent literals contain braces +description: f-strings don't support concatenation with adjacent literals if the adjacent literals contain braces or are f-strings cause: MicroPython is optimised for code space. -workaround: Use the + operator between literal strings when either is an f-string +workaround: Use the + operator between literal strings when either or both are f-strings """ -x = 1 -print("aa" f"{x}") -print(f"{x}" "ab") -print("a{}a" f"{x}") -print(f"{x}" "a{}b") +x, y = 1, 2 +print("aa" f"{x}") # works +print(f"{x}" "ab") # works +print("a{}a" f"{x}") # fails +print(f"{x}" "a{}b") # fails +print(f"{x}" f"{y}") # fails From a0890983ea25c343c510d5dad509b48bc7a96cc9 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 25 Nov 2021 23:23:34 +1100 Subject: [PATCH 203/335] py/objfun.h: Remove obsolete comments about entries in extra_args. These two entries were removed in 049a7a81531a67e068d926ad50260578fb79f94c Signed-off-by: Damien George --- py/objfun.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/py/objfun.h b/py/objfun.h index 905b5dbca6..771bf31a95 100644 --- a/py/objfun.h +++ b/py/objfun.h @@ -39,8 +39,6 @@ typedef struct _mp_obj_fun_bc_t { // the following extra_args array is allocated space to take (in order): // - values of positional default args (if any) // - a single slot for default kw args dict (if it has them) - // - a single slot for var args tuple (if it takes them) - // - a single slot for kw args dict (if it takes them) mp_obj_t extra_args[]; } mp_obj_fun_bc_t; From 6259aa50ebdf148005ce237bbcc632f6f202227c Mon Sep 17 00:00:00 2001 From: David Michieli Date: Tue, 12 Oct 2021 12:07:02 +1100 Subject: [PATCH 204/335] stm32/boards/NUCLEO_WB55: Update rfcore_firmwre for new WS. Adds a fix to behavior occuring since WS 1.11 where the FUS returns misleading statuses during WS upgrade. --- ports/stm32/boards/NUCLEO_WB55/rfcore_firmware.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ports/stm32/boards/NUCLEO_WB55/rfcore_firmware.py b/ports/stm32/boards/NUCLEO_WB55/rfcore_firmware.py index b5f1d0072e..0d13d24350 100644 --- a/ports/stm32/boards/NUCLEO_WB55/rfcore_firmware.py +++ b/ports/stm32/boards/NUCLEO_WB55/rfcore_firmware.py @@ -537,9 +537,13 @@ def resume(): elif status == 0: log("WS update successful") _write_state(_STATE_WAITING_FOR_WS) - elif result == 0: - # We get a error response with no payload sometimes at the end - # of the update (this is not in AN5185). Re-try the GET_STATE. + elif result in (0, 0xFE): + # We get an error response with no payload sometimes at the end + # of the update (this is not in AN5185). Additionally during + # WS update, newer WS reports (status, result) of (255, 254) + # before eventually reporting the correct state of + # _STATE_INSTALLING_WS once again. In these cases, re-try the + # GET_STATE. # The same thing happens transitioning from WS to FUS mode. # The actual HCI response has no payload, the result=0 comes from # _parse_vendor_response above when len=7. From de8dc4bad233e81ad3de5e7d5579cfebe045c809 Mon Sep 17 00:00:00 2001 From: gibbonsc <63733738+gibbonsc@users.noreply.github.com> Date: Tue, 5 Oct 2021 17:18:56 -0600 Subject: [PATCH 205/335] docs/esp8266/tutorial: Fix comments of FrameBuffer examples. The third and fourth parameters in display.rect() and display.fill_rect() are not x,y coordinates, but are instead width,height values. Update the comment after the example to show the correct x,y coordinates of the bottom right corner of each rectangle, respectively. --- docs/esp8266/tutorial/ssd1306.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/esp8266/tutorial/ssd1306.rst b/docs/esp8266/tutorial/ssd1306.rst index 4dca82afc4..8651522e06 100644 --- a/docs/esp8266/tutorial/ssd1306.rst +++ b/docs/esp8266/tutorial/ssd1306.rst @@ -66,8 +66,8 @@ Subclassing FrameBuffer provides support for graphics primitives:: display.hline(0, 8, 4, 1) # draw horizontal line x=0, y=8, width=4, colour=1 display.vline(0, 8, 4, 1) # draw vertical line x=0, y=8, height=4, colour=1 display.line(0, 0, 127, 63, 1) # draw a line from 0,0 to 127,63 - display.rect(10, 10, 107, 43, 1) # draw a rectangle outline 10,10 to 107,43, colour=1 - display.fill_rect(10, 10, 107, 43, 1) # draw a solid rectangle 10,10 to 107,43, colour=1 + display.rect(10, 10, 107, 43, 1) # draw a rectangle outline 10,10 to 117,53, colour=1 + display.fill_rect(10, 10, 107, 43, 1) # draw a solid rectangle 10,10 to 117,53, colour=1 display.text('Hello World', 0, 0, 1) # draw some text at x=0, y=0, colour=1 display.scroll(20, 0) # scroll 20 pixels to the right From 678f4b959f97936f7bcca8d8d5ba5030bbb13bdc Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 16 Nov 2021 22:57:45 +1100 Subject: [PATCH 206/335] esp32/boards/GENERIC_S3: Enable BLE on ESP32 S3. Signed-off-by: Jim Mussared --- ports/esp32/boards/GENERIC_S3/mpconfigboard.cmake | 1 + ports/esp32/boards/GENERIC_S3/mpconfigboard.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/esp32/boards/GENERIC_S3/mpconfigboard.cmake b/ports/esp32/boards/GENERIC_S3/mpconfigboard.cmake index eae671d286..58b1b25bb5 100644 --- a/ports/esp32/boards/GENERIC_S3/mpconfigboard.cmake +++ b/ports/esp32/boards/GENERIC_S3/mpconfigboard.cmake @@ -3,6 +3,7 @@ set(IDF_TARGET esp32s3) set(SDKCONFIG_DEFAULTS boards/sdkconfig.base boards/sdkconfig.usb + boards/sdkconfig.ble boards/GENERIC_S3/sdkconfig.board ) diff --git a/ports/esp32/boards/GENERIC_S3/mpconfigboard.h b/ports/esp32/boards/GENERIC_S3/mpconfigboard.h index 53caa7f91d..f41917ff07 100644 --- a/ports/esp32/boards/GENERIC_S3/mpconfigboard.h +++ b/ports/esp32/boards/GENERIC_S3/mpconfigboard.h @@ -1,7 +1,6 @@ #define MICROPY_HW_BOARD_NAME "ESP32S3 module" #define MICROPY_HW_MCU_NAME "ESP32S3" -#define MICROPY_PY_BLUETOOTH (0) #define MICROPY_PY_MACHINE_DAC (0) #define MICROPY_HW_I2C0_SCL (9) From 97a7cc243b028833bdcb8ce0bc19b2bce7545851 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 25 Nov 2021 14:27:06 +0200 Subject: [PATCH 207/335] lib: Update pico-sdk to 1.3.0 and tinyusb to 0.12.0. Fixes #8025 --- lib/pico-sdk | 2 +- lib/tinyusb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pico-sdk b/lib/pico-sdk index bfcbefafc5..2062372d20 160000 --- a/lib/pico-sdk +++ b/lib/pico-sdk @@ -1 +1 @@ -Subproject commit bfcbefafc5d2a210551a4d9d80b4303d4ae0adf7 +Subproject commit 2062372d203b372849d573f252cf7c6dc2800c0a diff --git a/lib/tinyusb b/lib/tinyusb index d49938d0f5..4bfab30c02 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit d49938d0f5052bce70e55c652b657c0a6a7e84fe +Subproject commit 4bfab30c02279a0530e1a56f4a7c539f2d35a293 From 84969194a18ec015d2508db14be66457f123f687 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 29 Nov 2021 13:01:51 +1100 Subject: [PATCH 208/335] stm32/flashbdev: Support generic flash storage config via link symbols. A board can now define the following linker symbols to configure its flash storage layout: _micropy_hw_internal_flash_storage_start _micropy_hw_internal_flash_storage_end _micropy_hw_internal_flash_storage_ram_cache_start _micropy_hw_internal_flash_storage_ram_cache_end And optionally have a second flash segment by configuring MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE_SEGMENT2 to 1 and defining: _micropy_hw_internal_flash_storage2_start _micropy_hw_internal_flash_storage2_end Signed-off-by: Damien George --- ports/stm32/flashbdev.c | 30 ++++++++++++++++++++++++++++-- ports/stm32/mpconfigboard_common.h | 5 +++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/ports/stm32/flashbdev.c b/ports/stm32/flashbdev.c index 3b7609d4d2..ce535d0c00 100644 --- a/ports/stm32/flashbdev.c +++ b/ports/stm32/flashbdev.c @@ -133,11 +133,35 @@ extern uint8_t _ram_fs_cache_end[]; #define FLASH_MEM_SEG1_NUM_BLOCKS ((&_flash_fs_end - &_flash_fs_start) / 512) #else -#error "no internal flash storage support for this MCU" + +// Generic configuration where the linker script specifies flash storage and RAM cache locations. + +extern uint8_t _micropy_hw_internal_flash_storage_start; +extern uint8_t _micropy_hw_internal_flash_storage_end; +extern uint8_t _micropy_hw_internal_flash_storage2_start; +extern uint8_t _micropy_hw_internal_flash_storage2_end; +extern uint8_t _micropy_hw_internal_flash_storage_ram_cache_start[]; +extern uint8_t _micropy_hw_internal_flash_storage_ram_cache_end[]; + +#define CACHE_MEM_START_ADDR \ + ((uintptr_t)&_micropy_hw_internal_flash_storage_ram_cache_start[0]) +#define FLASH_SECTOR_SIZE_MAX \ + (&_micropy_hw_internal_flash_storage_ram_cache_end[0] - &_micropy_hw_internal_flash_storage_ram_cache_start[0]) +#define FLASH_MEM_SEG1_START_ADDR \ + ((long)&_micropy_hw_internal_flash_storage_start) +#define FLASH_MEM_SEG1_NUM_BLOCKS \ + ((&_micropy_hw_internal_flash_storage_end - &_micropy_hw_internal_flash_storage_start) / 512) + +#if MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE_SEGMENT2 +#define FLASH_MEM_SEG2_START_ADDR \ + ((long)&_micropy_hw_internal_flash_storage2_start) +#define FLASH_MEM_SEG2_NUM_BLOCKS \ + ((&_micropy_hw_internal_flash_storage2_end - &_micropy_hw_internal_flash_storage2_start) / 512) +#endif + #endif #if !defined(FLASH_MEM_SEG2_START_ADDR) -#define FLASH_MEM_SEG2_START_ADDR (0) // no second segment #define FLASH_MEM_SEG2_NUM_BLOCKS (0) // no second segment #endif @@ -220,9 +244,11 @@ static uint32_t convert_block_to_flash_addr(uint32_t block) { if (block < FLASH_MEM_SEG1_NUM_BLOCKS) { return FLASH_MEM_SEG1_START_ADDR + block * FLASH_BLOCK_SIZE; } + #ifdef FLASH_MEM_SEG2_START_ADDR if (block < FLASH_MEM_SEG1_NUM_BLOCKS + FLASH_MEM_SEG2_NUM_BLOCKS) { return FLASH_MEM_SEG2_START_ADDR + (block - FLASH_MEM_SEG1_NUM_BLOCKS) * FLASH_BLOCK_SIZE; } + #endif // can add more flash segments here if needed, following above pattern // bad block diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h index 6dd51e913f..f8342f51b9 100644 --- a/ports/stm32/mpconfigboard_common.h +++ b/ports/stm32/mpconfigboard_common.h @@ -57,6 +57,11 @@ #define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (1) #endif +// If internal flash storage is enabled, whether to use a second segment of flash. +#ifndef MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE_SEGMENT2 (0) +#endif + // Whether to enable the RTC, exposed as pyb.RTC #ifndef MICROPY_HW_ENABLE_RTC #define MICROPY_HW_ENABLE_RTC (0) From 35e70c1698047170f9fb8b1edc65a7f7125f267f Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 29 Nov 2021 13:10:36 +1100 Subject: [PATCH 209/335] stm32/boards: Convert F413,F439,H743,L4xx,WB55 to new flash FS config. Signed-off-by: Damien George --- .../boards/NUCLEO_F413ZH/mpconfigboard.h | 2 + .../boards/NUCLEO_F439ZI/mpconfigboard.h | 2 + .../boards/NUCLEO_WB55/rfcore_firmware.py | 3 +- ports/stm32/boards/stm32f413xg.ld | 13 +++-- ports/stm32/boards/stm32f413xh.ld | 13 +++-- ports/stm32/boards/stm32f439.ld | 12 ++++- ports/stm32/boards/stm32h743.ld | 8 ++-- ports/stm32/boards/stm32l432.ld | 10 ++-- ports/stm32/boards/stm32l452xe.ld | 10 ++-- ports/stm32/boards/stm32l476xe.ld | 10 ++-- ports/stm32/boards/stm32l476xg.ld | 10 ++-- ports/stm32/boards/stm32l496xg.ld | 10 ++-- ports/stm32/boards/stm32wb55xg.ld | 10 ++-- ports/stm32/flashbdev.c | 48 ------------------- 14 files changed, 70 insertions(+), 91 deletions(-) diff --git a/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h index 5297ceda5c..a357c99267 100644 --- a/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h @@ -3,6 +3,8 @@ #define MICROPY_HW_HAS_SWITCH (1) #define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (1) +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE_SEGMENT2 (1) #define MICROPY_HW_ENABLE_RNG (1) #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_DAC (1) diff --git a/ports/stm32/boards/NUCLEO_F439ZI/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F439ZI/mpconfigboard.h index 010e3b1f5f..7763bd73ef 100644 --- a/ports/stm32/boards/NUCLEO_F439ZI/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F439ZI/mpconfigboard.h @@ -3,6 +3,8 @@ #define MICROPY_HW_HAS_SWITCH (1) #define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (1) +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE_SEGMENT2 (1) #define MICROPY_HW_ENABLE_RNG (1) #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_USB (1) diff --git a/ports/stm32/boards/NUCLEO_WB55/rfcore_firmware.py b/ports/stm32/boards/NUCLEO_WB55/rfcore_firmware.py index 0d13d24350..4085da90fd 100644 --- a/ports/stm32/boards/NUCLEO_WB55/rfcore_firmware.py +++ b/ports/stm32/boards/NUCLEO_WB55/rfcore_firmware.py @@ -89,7 +89,8 @@ _HCI_KIND_VENDOR_RESPONSE = const(0x11) _OBFUSCATION_KEY = const(0x0573B55AA) # On boards using the internal flash filesystem, this must match the -# `_flash_fs_end` symbol defined by the linker script (boards/stm32wb55xg.ld). +# `_micropy_hw_internal_flash_storage_end` symbol defined by the linker script +# (see eg boards/stm32wb55xg.ld). # We erase everything from here until the start of the secure area (defined by # SFSA) just to ensure that no other fragments of firmware files are left # behind. On boards with external flash, this just needs to ensure that it diff --git a/ports/stm32/boards/stm32f413xg.ld b/ports/stm32/boards/stm32f413xg.ld index 96d6dc5fb0..2df46f2b59 100644 --- a/ports/stm32/boards/stm32f413xg.ld +++ b/ports/stm32/boards/stm32f413xg.ld @@ -3,15 +3,14 @@ */ /* Specify the memory areas */ -/* FLASH_FS2 is placed before FLASH_TEXT to support 1MB and 1.5MB FLASH with common code in flashbdev.c */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* entire flash */ FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */ FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 176K /* sectors 1,2,3 are 16K, 4 is 64K, 5 is 128K (64K used) for filesystem */ - FLASH_FS2 (rx) : ORIGIN = 0x08040000, LENGTH = 128K /* sector 6 is 128K (64K used) for filesystem, Total filesystem 240K */ + FLASH_FS2 (rx) : ORIGIN = 0x08040000, LENGTH = 64K /* sector 6 is 128K (64K used) for filesystem, Total filesystem 240K */ FLASH_TEXT (rx) : ORIGIN = 0x08060000, LENGTH = 640K /* sectors 7,8,9,10,11 are 128K*/ - SRAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 64K + SRAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 64K /* used for filesystem cache */ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K } @@ -29,3 +28,11 @@ _ram_start = ORIGIN(RAM); _ram_end = ORIGIN(RAM) + LENGTH(RAM); _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _sstack; + ++/* Filesystem cache in RAM, and storage in flash */ ++_micropy_hw_internal_flash_storage_ram_cache_start = ORIGIN(SRAM2); ++_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(SRAM2) + LENGTH(SRAM2); ++_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); ++_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); ++_micropy_hw_internal_flash_storage2_start = ORIGIN(FLASH_FS2); ++_micropy_hw_internal_flash_storage2_end = ORIGIN(FLASH_FS2) + LENGTH(FLASH_FS2); diff --git a/ports/stm32/boards/stm32f413xh.ld b/ports/stm32/boards/stm32f413xh.ld index 0b28730de5..0512a3f056 100644 --- a/ports/stm32/boards/stm32f413xh.ld +++ b/ports/stm32/boards/stm32f413xh.ld @@ -3,15 +3,14 @@ */ /* Specify the memory areas */ -/* FLASH_FS2 is placed before FLASH_TEXT to support 1MB and 1.5MB FLASH with common code in flashbdev.c */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1536K /* entire flash */ FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */ FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 176K /* sectors 1,2,3 are 16K, 4 is 64K, 5 is 128K (64K used) for filesystem */ - FLASH_FS2 (rx) : ORIGIN = 0x08040000, LENGTH = 128K /* sector 6 is 128K (64K used) for filesystem, Total filesystem 240K */ + FLASH_FS2 (rx) : ORIGIN = 0x08040000, LENGTH = 64K /* sector 6 is 128K (64K used) for filesystem, Total filesystem 240K */ FLASH_TEXT (rx) : ORIGIN = 0x08060000, LENGTH = 1152K /* sectors 7,8,9,10,11,12,13,14,15 are 128K*/ - SRAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 64K + SRAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 64K /* used for filesystem cache */ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K } @@ -29,3 +28,11 @@ _ram_start = ORIGIN(RAM); _ram_end = ORIGIN(RAM) + LENGTH(RAM); _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _sstack; + ++/* Filesystem cache in RAM, and storage in flash */ ++_micropy_hw_internal_flash_storage_ram_cache_start = ORIGIN(SRAM2); ++_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(SRAM2) + LENGTH(SRAM2); ++_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); ++_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); ++_micropy_hw_internal_flash_storage2_start = ORIGIN(FLASH_FS2); ++_micropy_hw_internal_flash_storage2_end = ORIGIN(FLASH_FS2) + LENGTH(FLASH_FS2); diff --git a/ports/stm32/boards/stm32f439.ld b/ports/stm32/boards/stm32f439.ld index e847646b35..64195368c1 100644 --- a/ports/stm32/boards/stm32f439.ld +++ b/ports/stm32/boards/stm32f439.ld @@ -8,8 +8,8 @@ MEMORY FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K /* entire flash */ FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */ FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 896K /* sectors 5-11 are 128K */ - FLASH_FS (rx) : ORIGIN = 0x08100000, LENGTH = 256K /* sectors 12-17 are 4*16K+64K+128K */ - FLASH_FS2 (rx) : ORIGIN = 0x08140000, LENGTH = 128K /* sector 18 */ + FLASH_FS (rx) : ORIGIN = 0x08100000, LENGTH = 192K /* sectors 12-15 are 16K, 16 is 64K, 17 is 128K (64K used) */ + FLASH_FS2 (rx) : ORIGIN = 0x08140000, LENGTH = 64K /* sector 18 is 128K (64K used) */ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K } @@ -28,3 +28,11 @@ _ram_start = ORIGIN(RAM); _ram_end = ORIGIN(RAM) + LENGTH(RAM); _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _sstack; + +/* Filesystem cache in RAM, and storage in flash */ +_micropy_hw_internal_flash_storage_ram_cache_start = ORIGIN(CCMRAM); +_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(CCMRAM) + LENGTH(CCMRAM); +_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); +_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); +_micropy_hw_internal_flash_storage2_start = ORIGIN(FLASH_FS2); +_micropy_hw_internal_flash_storage2_end = ORIGIN(FLASH_FS2) + LENGTH(FLASH_FS2); diff --git a/ports/stm32/boards/stm32h743.ld b/ports/stm32/boards/stm32h743.ld index 13fa0c52c0..ad1b1b8922 100644 --- a/ports/stm32/boards/stm32h743.ld +++ b/ports/stm32/boards/stm32h743.ld @@ -29,12 +29,12 @@ _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _sstack; /* Location of filesystem RAM cache */ -_ram_fs_cache_start = ORIGIN(DTCM); -_ram_fs_cache_end = ORIGIN(DTCM) + LENGTH(DTCM); +_micropy_hw_internal_flash_storage_ram_cache_start = ORIGIN(DTCM); +_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(DTCM) + LENGTH(DTCM); /* Location of filesystem flash storage */ -_flash_fs_start = ORIGIN(FLASH_FS); -_flash_fs_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); +_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); +_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); /* Define output sections */ SECTIONS diff --git a/ports/stm32/boards/stm32l432.ld b/ports/stm32/boards/stm32l432.ld index 469e834f91..2006471e75 100644 --- a/ports/stm32/boards/stm32l432.ld +++ b/ports/stm32/boards/stm32l432.ld @@ -21,14 +21,14 @@ _minimum_heap_size = 16K; _ram_start = ORIGIN(RAM); _ram_end = ORIGIN(RAM) + LENGTH(RAM); -_ram_fs_cache_end = _ram_end; -_ram_fs_cache_start = _ram_fs_cache_end - 2K; /* fs cache = 2K */ +_micropy_hw_internal_flash_storage_ram_cache_end = _ram_end; +_micropy_hw_internal_flash_storage_ram_cache_start = _micropy_hw_internal_flash_storage_ram_cache_end - 2K; /* fs cache = 2K */ -_estack = _ram_fs_cache_start - _estack_reserve; +_estack = _micropy_hw_internal_flash_storage_ram_cache_start - _estack_reserve; _sstack = _estack - 10K; /* stack = 10K */ _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _sstack; /* bss + heap = 52K, tunable by adjusting stack size */ -_flash_fs_start = ORIGIN(FLASH_FS); -_flash_fs_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); +_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); +_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); diff --git a/ports/stm32/boards/stm32l452xe.ld b/ports/stm32/boards/stm32l452xe.ld index 7b07ee7018..0cb753a1c6 100644 --- a/ports/stm32/boards/stm32l452xe.ld +++ b/ports/stm32/boards/stm32l452xe.ld @@ -21,14 +21,14 @@ _minimum_heap_size = 16K; _ram_start = ORIGIN(RAM); _ram_end = ORIGIN(RAM) + LENGTH(RAM); -_ram_fs_cache_end = _ram_end; -_ram_fs_cache_start = _ram_fs_cache_end - 2K; /* fs cache = 2K */ +_micropy_hw_internal_flash_storage_ram_cache_end = _ram_end; +_micropy_hw_internal_flash_storage_ram_cache_start = _micropy_hw_internal_flash_storage_ram_cache_end - 2K; /* fs cache = 2K */ -_estack = _ram_fs_cache_start - _estack_reserve; +_estack = _micropy_hw_internal_flash_storage_ram_cache_start - _estack_reserve; _sstack = _estack - 16K; /* stack = 16K */ _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _sstack; /* bss + heap = 142K, tunable by adjusting stack size */ -_flash_fs_start = ORIGIN(FLASH_FS); -_flash_fs_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); +_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); +_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); diff --git a/ports/stm32/boards/stm32l476xe.ld b/ports/stm32/boards/stm32l476xe.ld index 6eaf71545d..1c70a9cfde 100644 --- a/ports/stm32/boards/stm32l476xe.ld +++ b/ports/stm32/boards/stm32l476xe.ld @@ -22,14 +22,14 @@ _minimum_heap_size = 16K; _ram_start = ORIGIN(RAM); _ram_end = ORIGIN(RAM) + LENGTH(RAM); -_ram_fs_cache_end = ORIGIN(SRAM2) + LENGTH(SRAM2); /* fs_cache in SRAM2 */ -_ram_fs_cache_start = _ram_fs_cache_end - 2K; /* fs cache = 2K */ +_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(SRAM2) + LENGTH(SRAM2); /* fs_cache in SRAM2 */ +_micropy_hw_internal_flash_storage_ram_cache_start = _micropy_hw_internal_flash_storage_ram_cache_end - 2K; /* fs cache = 2K */ -_estack = _ram_fs_cache_start - _estack_reserve; /* stack in SRAM2 */ +_estack = _micropy_hw_internal_flash_storage_ram_cache_start - _estack_reserve; /* stack in SRAM2 */ _sstack = ORIGIN(SRAM2); /* stack = 30K */ _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _ram_end; /* bss + heap = 96K, tunable by adjusting stack size */ -_flash_fs_start = ORIGIN(FLASH_FS); -_flash_fs_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); +_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); +_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); diff --git a/ports/stm32/boards/stm32l476xg.ld b/ports/stm32/boards/stm32l476xg.ld index 09c3f29c54..0185eb1b2d 100644 --- a/ports/stm32/boards/stm32l476xg.ld +++ b/ports/stm32/boards/stm32l476xg.ld @@ -22,14 +22,14 @@ _minimum_heap_size = 16K; _ram_start = ORIGIN(RAM); _ram_end = ORIGIN(RAM) + LENGTH(RAM); -_ram_fs_cache_end = ORIGIN(SRAM2) + LENGTH(SRAM2); /* fs_cache in SRAM2 */ -_ram_fs_cache_start = _ram_fs_cache_end - 2K; /* fs cache = 2K */ +_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(SRAM2) + LENGTH(SRAM2); /* fs_cache in SRAM2 */ +_micropy_hw_internal_flash_storage_ram_cache_start = _micropy_hw_internal_flash_storage_ram_cache_end - 2K; /* fs cache = 2K */ -_estack = _ram_fs_cache_start - _estack_reserve; /* stack in SRAM2 */ +_estack = _micropy_hw_internal_flash_storage_ram_cache_start - _estack_reserve; /* stack in SRAM2 */ _sstack = ORIGIN(SRAM2); /* stack = 30K */ _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _ram_end; /* bss + heap = 96K, tunable by adjusting stack size */ -_flash_fs_start = ORIGIN(FLASH_FS); -_flash_fs_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); +_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); +_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); diff --git a/ports/stm32/boards/stm32l496xg.ld b/ports/stm32/boards/stm32l496xg.ld index 327cb5ce13..d7cb92b8dc 100644 --- a/ports/stm32/boards/stm32l496xg.ld +++ b/ports/stm32/boards/stm32l496xg.ld @@ -21,14 +21,14 @@ _minimum_heap_size = 16K; _ram_start = ORIGIN(RAM); _ram_end = ORIGIN(RAM) + LENGTH(RAM); -_ram_fs_cache_end = _ram_end; -_ram_fs_cache_start = _ram_fs_cache_end - 2K; /* fs cache = 2K */ +_micropy_hw_internal_flash_storage_ram_cache_end = _ram_end; +_micropy_hw_internal_flash_storage_ram_cache_start = _micropy_hw_internal_flash_storage_ram_cache_end - 2K; /* fs cache = 2K */ -_estack = _ram_fs_cache_start - _estack_reserve; +_estack = _micropy_hw_internal_flash_storage_ram_cache_start - _estack_reserve; _sstack = _estack - 16K; /* stack = 16K */ _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _sstack; /* bss + heap = 302K, tunable by adjusting stack size */ -_flash_fs_start = ORIGIN(FLASH_FS); -_flash_fs_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); +_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); +_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); diff --git a/ports/stm32/boards/stm32wb55xg.ld b/ports/stm32/boards/stm32wb55xg.ld index c3dc5f5197..841c32b8a0 100644 --- a/ports/stm32/boards/stm32wb55xg.ld +++ b/ports/stm32/boards/stm32wb55xg.ld @@ -21,19 +21,19 @@ _minimum_heap_size = 16K; _ram_start = ORIGIN(RAM); _ram_end = ORIGIN(RAM) + LENGTH(RAM); -_ram_fs_cache_end = ORIGIN(RAM) + LENGTH(RAM); -_ram_fs_cache_start = _ram_fs_cache_end - 4K; /* fs cache = 4K */ +_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(RAM) + LENGTH(RAM); +_micropy_hw_internal_flash_storage_ram_cache_start = _micropy_hw_internal_flash_storage_ram_cache_end - 4K; /* fs cache = 4K */ /* Define the stack. The stack is full descending so begins at the bottom of FS cache. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = _ram_fs_cache_start - _estack_reserve; +_estack = _micropy_hw_internal_flash_storage_ram_cache_start - _estack_reserve; _sstack = _estack - 16K; _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _sstack; -_flash_fs_start = ORIGIN(FLASH_FS); -_flash_fs_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); +_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); +_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); SECTIONS { diff --git a/ports/stm32/flashbdev.c b/ports/stm32/flashbdev.c index ce535d0c00..946a9d8cc2 100644 --- a/ports/stm32/flashbdev.c +++ b/ports/stm32/flashbdev.c @@ -61,15 +61,6 @@ STATIC byte flash_cache_mem[0x4000] __attribute__((aligned(4))); // 16k #define FLASH_MEM_SEG1_START_ADDR (0x08004000) // sector 1 #define FLASH_MEM_SEG1_NUM_BLOCKS (128) // sectors 1,2,3,4: 16k+16k+16k+16k(of 64k)=64k -#elif defined(STM32F413xx) - -#define CACHE_MEM_START_ADDR (0x10000000) // SRAM2 data RAM, 64k -#define FLASH_SECTOR_SIZE_MAX (0x10000) // 64k max, size of SRAM2 -#define FLASH_MEM_SEG1_START_ADDR (0x08004000) // sector 1 -#define FLASH_MEM_SEG1_NUM_BLOCKS (352) // sectors 1,2,3,4,5: 16k+16k+16k+64k+64k(of 128k)=176k -#define FLASH_MEM_SEG2_START_ADDR (0x08040000) // sector 6 -#define FLASH_MEM_SEG2_NUM_BLOCKS (128) // sector 6: 64k(of 128k). Filesystem 176K + 64K = 240K - #elif defined(STM32F427xx) || defined(STM32F429xx) #define CACHE_MEM_START_ADDR (0x10000000) // CCM data RAM, 64k @@ -77,15 +68,6 @@ STATIC byte flash_cache_mem[0x4000] __attribute__((aligned(4))); // 16k #define FLASH_MEM_SEG1_START_ADDR (0x08004000) // sector 1 #define FLASH_MEM_SEG1_NUM_BLOCKS (224) // sectors 1,2,3,4: 16k+16k+16k+64k=112k -#elif defined(STM32F439xx) - -#define CACHE_MEM_START_ADDR (0x10000000) // CCM data RAM, 64k -#define FLASH_SECTOR_SIZE_MAX (0x10000) // 64k max, size of CCM -#define FLASH_MEM_SEG1_START_ADDR (0x08100000) // sector 12 -#define FLASH_MEM_SEG1_NUM_BLOCKS (384) // sectors 12,13,14,15,16,17: 16k+16k+16k+16k+64k+64k(of 128k)=192k -#define FLASH_MEM_SEG2_START_ADDR (0x08140000) // sector 18 -#define FLASH_MEM_SEG2_NUM_BLOCKS (128) // sector 18: 64k(of 128k) - #elif defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F732xx) || defined(STM32F733xx) #define CACHE_MEM_START_ADDR (0x20000000) // DTCM data RAM, 64k @@ -102,36 +84,6 @@ STATIC byte flash_cache_mem[0x4000] __attribute__((aligned(4))); // 16k #define FLASH_MEM_SEG1_START_ADDR (0x08008000) // sector 1 #define FLASH_MEM_SEG1_NUM_BLOCKS (192) // sectors 1,2,3: 32k+32k+32=96k -#elif defined(STM32H743xx) - -// The STM32H743 flash sectors are 128K, with locations defined in the linker script -extern uint8_t _flash_fs_start; -extern uint8_t _flash_fs_end; -extern uint8_t _ram_fs_cache_start[]; -extern uint8_t _ram_fs_cache_end[]; - -#define CACHE_MEM_START_ADDR ((uintptr_t)&_ram_fs_cache_start[0]) -#define FLASH_SECTOR_SIZE_MAX (&_ram_fs_cache_end[0] - &_ram_fs_cache_start[0]) -#define FLASH_MEM_SEG1_START_ADDR ((long)&_flash_fs_start) -#define FLASH_MEM_SEG1_NUM_BLOCKS ((&_flash_fs_end - &_flash_fs_start) / 512) - -#elif defined(STM32L432xx) || \ - defined(STM32L451xx) || defined(STM32L452xx) || defined(STM32L462xx) || \ - defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L496xx) || \ - defined(STM32WB) - -// The STM32L4xx doesn't have CCRAM, so we use SRAM2 for this, although -// actual location and size is defined by the linker script. -extern uint8_t _flash_fs_start; -extern uint8_t _flash_fs_end; -extern uint8_t _ram_fs_cache_start[]; // size determined by linker file -extern uint8_t _ram_fs_cache_end[]; - -#define CACHE_MEM_START_ADDR ((uintptr_t)&_ram_fs_cache_start[0]) -#define FLASH_SECTOR_SIZE_MAX (&_ram_fs_cache_end[0] - &_ram_fs_cache_start[0]) // 2k max -#define FLASH_MEM_SEG1_START_ADDR ((long)&_flash_fs_start) -#define FLASH_MEM_SEG1_NUM_BLOCKS ((&_flash_fs_end - &_flash_fs_start) / 512) - #else // Generic configuration where the linker script specifies flash storage and RAM cache locations. From 7e61a12eb1e153bf09b93c19f491237d72de2cf6 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 29 Nov 2021 13:25:53 +1100 Subject: [PATCH 210/335] stm32: Add support for F479 MCUs. Signed-off-by: Damien George --- ports/stm32/adc.c | 3 +- ports/stm32/boards/stm32f479_af.csv | 161 ++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 ports/stm32/boards/stm32f479_af.csv diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c index ceb6584d03..3e61abce3c 100644 --- a/ports/stm32/adc.c +++ b/ports/stm32/adc.c @@ -133,7 +133,8 @@ #elif defined(STM32F411xE) || defined(STM32F412Zx) || \ defined(STM32F413xx) || defined(STM32F427xx) || \ defined(STM32F429xx) || defined(STM32F437xx) || \ - defined(STM32F439xx) || defined(STM32F446xx) + defined(STM32F439xx) || defined(STM32F446xx) || \ + defined(STM32F479xx) #define VBAT_DIV (4) #elif defined(STM32F722xx) || defined(STM32F723xx) || \ defined(STM32F732xx) || defined(STM32F733xx) || \ diff --git a/ports/stm32/boards/stm32f479_af.csv b/ports/stm32/boards/stm32f479_af.csv new file mode 100644 index 0000000000..7cbb242a52 --- /dev/null +++ b/ports/stm32/boards/stm32f479_af.csv @@ -0,0 +1,161 @@ +Port,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15, +,,SYS,TIM1/2,TIM3/4/5,TIM8/9/10/11,I2C1/2/3,SPI1/2/3/4/5/6,SPI2/3/SAI1,SPI2/3/USART1/2/3,USART6/UART4/5/7/8,CAN1/2/TIM12/13/14/QUADSPI/LCD,QUADSPI/OTG2_HS/OTG1_FS,ETH,FMC/SDIO/OTG2_FS,DCMI/DSIHOST,LCD,SYS,ADC +PortA,PA0,,TIM2_CH1/TIM2_ETR,TIM5_CH1,TIM8_ETR,,,,USART2_CTS,UART4_TX,,,ETH_MII_CRS,,,,EVENTOUT,ADC123_IN0 +PortA,PA1,,TIM2_CH2,TIM5_CH2,,,,,USART2_RTS,UART4_RX,QUADSPI_BK1_IO3,,ETH_MII_RX_CLK/ETH_RMII_REF_CLK,,,LCD_R2,EVENTOUT,ADC123_IN1 +PortA,PA2,,TIM2_CH3,TIM5_CH3,TIM9_CH1,,,,USART2_TX,,,,ETH_MDIO,,,LCD_R1,EVENTOUT,ADC123_IN2 +PortA,PA3,,TIM2_CH4,TIM5_CH4,TIM9_CH2,,,,USART2_RX,,LCD_B2,OTG_HS_ULPI_D0,ETH_MII_COL,,,LCD_B5,EVENTOUT,ADC123_IN3 +PortA,PA4,,,,,,SPI1_NSS,SPI3_NSS/I2S3_WS,USART2_CK,,,,,OTG_HS_SOF,DCMI_HSYNC,LCD_VSYNC,EVENTOUT,ADC12_IN4 +PortA,PA5,,TIM2_CH1/TIM2_ETR,,TIM8_CH1N,,SPI1_SCK,,,,,OTG_HS_ULPI_CK,,,,LCD_R4,EVENTOUT,ADC12_IN5 +PortA,PA6,,TIM1_BKIN,TIM3_CH1,TIM8_BKIN,,SPI1_MISO,,,,TIM13_CH1,,,,DCMI_PIXCLK,LCD_G2,EVENTOUT,ADC12_IN6 +PortA,PA7,,TIM1_CH1N,TIM3_CH2,TIM8_CH1N,,SPI1_MOSI,,,,TIM14_CH1,QUADSPI_CLK,ETH_MII_RX_DV/ETH_RMII_CRS_DV,FMC_SDNWE,,,EVENTOUT,ADC12_IN7 +PortA,PA8,MCO1,TIM1_CH1,,,I2C3_SCL,,,USART1_CK,,,OTG_FS_SOF,,,,LCD_R6,EVENTOUT, +PortA,PA9,,TIM1_CH2,,,I2C3_SMBA,SPI2_SCK/I2S2_CK,,USART1_TX,,,,,,DCMI_D0,,EVENTOUT, +PortA,PA10,,TIM1_CH3,,,,,,USART1_RX,,,OTG_FS_ID,,,DCMI_D1,,EVENTOUT, +PortA,PA11,,TIM1_CH4,,,,,,USART1_CTS,,CAN1_RX,OTG_FS_DM,,,,LCD_R4,EVENTOUT, +PortA,PA12,,TIM1_ETR,,,,,,USART1_RTS,,CAN1_TX,OTG_FS_DP,,,,LCD_R5,EVENTOUT, +PortA,PA13,JTMS/SWDIO,,,,,,,,,,,,,,,EVENTOUT, +PortA,PA14,JTCK/SWCLK,,,,,,,,,,,,,,,EVENTOUT, +PortA,PA15,JTDI,TIM2_CH1/TIM2_ETR,,,,SPI1_NSS,SPI3_NSS/I2S3_WS,,,,,,,,,EVENTOUT, +PortB,PB0,,TIM1_CH2N,TIM3_CH3,TIM8_CH2N,,,,,,LCD_R3,OTG_HS_ULPI_D1,ETH_MII_RXD2,,,LCD_G1,EVENTOUT,ADC12_IN8 +PortB,PB1,,TIM1_CH3N,TIM3_CH4,TIM8_CH3N,,,,,,LCD_R6,OTG_HS_ULPI_D2,ETH_MII_RXD3,,,LCD_G0,EVENTOUT,ADC12_IN9 +PortB,PB2,,,,,,,,,,,,,,,,EVENTOUT, +PortB,PB3,JTDO/TRACESWO,TIM2_CH2,,,,SPI1_SCK,SPI3_SCK/I2S3_CK,,,,,,,,,EVENTOUT, +PortB,PB4,NJTRST,,TIM3_CH1,,,SPI1_MISO,SPI3_MISO,I2S3_EXTSD,,,,,,,,EVENTOUT, +PortB,PB5,,,TIM3_CH2,,I2C1_SMBA,SPI1_MOSI,SPI3_MOSI/I2S3_SD,,,CAN2_RX,OTG_HS_ULPI_D7,ETH_PPS_OUT,FMC_SDCKE1,DCMI_D10,LCD_G7,EVENTOUT, +PortB,PB6,,,TIM4_CH1,,I2C1_SCL,,,USART1_TX,,CAN2_TX,QUADSPI_BK1_NCS,,FMC_SDNE1,DCMI_D5,,EVENTOUT, +PortB,PB7,,,TIM4_CH2,,I2C1_SDA,,,USART1_RX,,,,,FMC_NL,DCMI_VSYNC,,EVENTOUT, +PortB,PB8,,,TIM4_CH3,TIM10_CH1,I2C1_SCL,,,,,CAN1_RX,,ETH_MII_TXD3,SDIO_D4,DCMI_D6,LCD_B6,EVENTOUT, +PortB,PB9,,,TIM4_CH4,TIM11_CH1,I2C1_SDA,SPI2_NSS/I2S2_WS,,,,CAN1_TX,,,SDIO_D5,DCMI_D7,LCD_B7,EVENTOUT, +PortB,PB10,,TIM2_CH3,,,I2C2_SCL,SPI2_SCK/I2S2_CK,,USART3_TX,,QUADSPI_BK1_NCS,OTG_HS_ULPI_D3,ETH_MII_RX_ER,,,LCD_G4,EVENTOUT, +PortB,PB11,,TIM2_CH4,,,I2C2_SDA,,,USART3_RX,,,OTG_HS_ULPI_D4,ETH_MII_TX_EN/ETH_RMII_TX_EN,,DSIHOST_TE,LCD_G5,EVENTOUT, +PortB,PB12,,TIM1_BKIN,,,I2C2_SMBA,SPI2_NSS/I2S2_WS,,USART3_CK,,CAN2_RX,OTG_HS_ULPI_D5,ETH_MII_TXD0/ETH_RMII_TXD0,OTG_HS_ID,,,EVENTOUT, +PortB,PB13,,TIM1_CH1N,,,,SPI2_SCK/I2S2_CK,,USART3_CTS,,CAN2_TX,OTG_HS_ULPI_D6,ETH_MII_TXD1/ETH_RMII_TXD1,,,,EVENTOUT, +PortB,PB14,,TIM1_CH2N,,TIM8_CH2N,,SPI2_MISO,I2S2_EXTSD,USART3_RTS,,TIM12_CH1,,,OTG_HS_DM,,,EVENTOUT, +PortB,PB15,RTC_REFIN,TIM1_CH3N,,TIM8_CH3N,,SPI2_MOSI/I2S2_SD,,,,TIM12_CH2,,,OTG_HS_DP,,,EVENTOUT, +PortC,PC0,,,,,,,,,,,OTG_HS_ULPI_STP,,FMC_SDNWE,,LCD_R5,EVENTOUT,ADC123_IN10 +PortC,PC1,TRACED0,,,,,SPI2_MOSI/I2S2_SD,SAI1_SD_A,,,,,ETH_MDC,,,,EVENTOUT,ADC123_IN11 +PortC,PC2,,,,,,SPI2_MISO,I2S2_EXTSD,,,,OTG_HS_ULPI_DIR,ETH_MII_TXD2,FMC_SDNE0,,,EVENTOUT,ADC123_IN12 +PortC,PC3,,,,,,SPI2_MOSI/I2S2_SD,,,,,OTG_HS_ULPI_NXT,ETH_MII_TX_CLK,FMC_SDCKE0,,,EVENTOUT,ADC123_IN13 +PortC,PC4,,,,,,,,,,,,ETH_MII_RXD0/ETH_RMII_RXD0,FMC_SDNE0,,,EVENTOUT,ADC12_IN14 +PortC,PC5,,,,,,,,,,,,ETH_MII_RXD1/ETH_RMII_RXD1,FMC_SDCKE0,,,EVENTOUT,ADC12_IN15 +PortC,PC6,,,TIM3_CH1,TIM8_CH1,,I2S2_MCK,,,USART6_TX,,,,SDIO_D6,DCMI_D0,LCD_HSYNC,EVENTOUT, +PortC,PC7,,,TIM3_CH2,TIM8_CH2,,,I2S3_MCK,,USART6_RX,,,,SDIO_D7,DCMI_D1,LCD_G6,EVENTOUT, +PortC,PC8,TRACED1,,TIM3_CH3,TIM8_CH3,,,,,USART6_CK,,,,SDIO_D0,DCMI_D2,,EVENTOUT, +PortC,PC9,MCO2,,TIM3_CH4,TIM8_CH4,I2C3_SDA,I2S_CKIN,,,,QUADSPI_BK1_IO0,,,SDIO_D1,DCMI_D3,,EVENTOUT, +PortC,PC10,,,,,,,SPI3_SCK/I2S3_CK,USART3_TX,UART4_TX,QUADSPI_BK1_IO1,,,SDIO_D2,DCMI_D8,LCD_R2,EVENTOUT, +PortC,PC11,,,,,,I2S3_EXTSD,SPI3_MISO,USART3_RX,UART4_RX,QUADSPI_BK2_NCS,,,SDIO_D3,DCMI_D4,,EVENTOUT, +PortC,PC12,TRACED3,,,,,,SPI3_MOSI/I2S3_SD,USART3_CK,UART5_TX,,,,SDIO_CK,DCMI_D9,,EVENTOUT, +PortC,PC13,,,,,,,,,,,,,,,,EVENTOUT, +PortC,PC14,,,,,,,,,,,,,,,,EVENTOUT, +PortC,PC15,,,,,,,,,,,,,,,,EVENTOUT, +PortD,PD0,,,,,,,,,,CAN1_RX,,,FMC_D2,,,EVENTOUT, +PortD,PD1,,,,,,,,,,CAN1_TX,,,FMC_D3,,,EVENTOUT, +PortD,PD2,TRACED2,,TIM3_ETR,,,,,,UART5_RX,,,,SDIO_CMD,DCMI_D11,,EVENTOUT, +PortD,PD3,,,,,,SPI2_SCK/I2S2_CK,,USART2_CTS,,,,,FMC_CLK,DCMI_D5,LCD_G7,EVENTOUT, +PortD,PD4,,,,,,,,USART2_RTS,,,,,FMC_NOE,,,EVENTOUT, +PortD,PD5,,,,,,,,USART2_TX,,,,,FMC_NWE,,,EVENTOUT, +PortD,PD6,,,,,,SPI3_MOSI/I2S3_SD,SAI1_SD_A,USART2_RX,,,,,FMC_NWAIT,DCMI_D10,LCD_B2,EVENTOUT, +PortD,PD7,,,,,,,,USART2_CK,,,,,FMC_NE1,,,EVENTOUT, +PortD,PD8,,,,,,,,USART3_TX,,,,,FMC_D13,,,EVENTOUT, +PortD,PD9,,,,,,,,USART3_RX,,,,,FMC_D14,,,EVENTOUT, +PortD,PD10,,,,,,,,USART3_CK,,,,,FMC_D15,,LCD_B3,EVENTOUT, +PortD,PD11,,,,,,,,USART3_CTS,,QUADSPI_BK1_IO0,,,FMC_A16/FMC_CLE,,,EVENTOUT, +PortD,PD12,,,TIM4_CH1,,,,,USART3_RTS,,QUADSPI_BK1_IO1,,,FMC_A17/FMC_ALE,,,EVENTOUT, +PortD,PD13,,,TIM4_CH2,,,,,,,QUADSPI_BK1_IO3,,,FMC_A18,,,EVENTOUT, +PortD,PD14,,,TIM4_CH3,,,,,,,,,,FMC_D0,,,EVENTOUT, +PortD,PD15,,,TIM4_CH4,,,,,,,,,,FMC_D1,,,EVENTOUT, +PortE,PE0,,,TIM4_ETR,,,,,,UART8_RX,,,,FMC_NBL0,DCMI_D2,,EVENTOUT, +PortE,PE1,,,,,,,,,UART8_TX,,,,FMC_NBL1,DCMI_D3,,EVENTOUT, +PortE,PE2,TRACECLK,,,,,SPI4_SCK,SAI1_MCLK_A,,,QUADSPI_BK1_IO2,,ETH_MII_TXD3,FMC_A23,,,EVENTOUT, +PortE,PE3,TRACED0,,,,,,SAI1_SD_B,,,,,,FMC_A19,,,EVENTOUT, +PortE,PE4,TRACED1,,,,,SPI4_NSS,SAI1_FS_A,,,,,,FMC_A20,DCMI_D4,LCD_B0,EVENTOUT, +PortE,PE5,TRACED2,,,TIM9_CH1,,SPI4_MISO,SAI1_SCK_A,,,,,,FMC_A21,DCMI_D6,LCD_G0,EVENTOUT, +PortE,PE6,TRACED3,,,TIM9_CH2,,SPI4_MOSI,SAI1_SD_A,,,,,,FMC_A22,DCMI_D7,LCD_G1,EVENTOUT, +PortE,PE7,,TIM1_ETR,,,,,,,UART7_RX,,QUADSPI_BK2_IO0,,FMC_D4,,,EVENTOUT, +PortE,PE8,,TIM1_CH1N,,,,,,,UART7_TX,,QUADSPI_BK2_IO1,,FMC_D5,,,EVENTOUT, +PortE,PE9,,TIM1_CH1,,,,,,,,,QUADSPI_BK2_IO2,,FMC_D6,,,EVENTOUT, +PortE,PE10,,TIM1_CH2N,,,,,,,,,QUADSPI_BK2_IO3,,FMC_D7,,,EVENTOUT, +PortE,PE11,,TIM1_CH2,,,,SPI4_NSS,,,,,,,FMC_D8,,LCD_G3,EVENTOUT, +PortE,PE12,,TIM1_CH3N,,,,SPI4_SCK,,,,,,,FMC_D9,,LCD_B4,EVENTOUT, +PortE,PE13,,TIM1_CH3,,,,SPI4_MISO,,,,,,,FMC_D10,,LCD_DE,EVENTOUT, +PortE,PE14,,TIM1_CH4,,,,SPI4_MOSI,,,,,,,FMC_D11,,LCD_CLK,EVENTOUT, +PortE,PE15,,TIM1_BKIN,,,,,,,,,,,FMC_D12,,LCD_R7,EVENTOUT, +PortF,PF0,,,,,I2C2_SDA,,,,,,,,FMC_A0,,,EVENTOUT, +PortF,PF1,,,,,I2C2_SCL,,,,,,,,FMC_A1,,,EVENTOUT, +PortF,PF2,,,,,I2C2_SMBA,,,,,,,,FMC_A2,,,EVENTOUT, +PortF,PF3,,,,,,,,,,,,,FMC_A3,,,EVENTOUT,ADC3_IN9 +PortF,PF4,,,,,,,,,,,,,FMC_A4,,,EVENTOUT,ADC3_IN14 +PortF,PF5,,,,,,,,,,,,,FMC_A5,,,EVENTOUT,ADC3_IN15 +PortF,PF6,,,,TIM10_CH1,,SPI5_NSS,SAI1_SD_B,,UART7_RX,QUADSPI_BK1_IO3,,,,,,EVENTOUT,ADC3_IN4 +PortF,PF7,,,,TIM11_CH1,,SPI5_SCK,SAI1_MCLK_B,,UART7_TX,QUADSPI_BK1_IO2,,,,,,EVENTOUT,ADC3_IN5 +PortF,PF8,,,,,,SPI5_MISO,SAI1_SCK_B,,,TIM13_CH1,QUADSPI_BK1_IO0,,,,,EVENTOUT,ADC3_IN6 +PortF,PF9,,,,,,SPI5_MOSI,SAI1_FS_B,,,TIM14_CH1,QUADSPI_BK1_IO1,,,,,EVENTOUT,ADC3_IN7 +PortF,PF10,,,,,,,,,,QUADSPI_CLK,,,,DCMI_D11,LCD_DE,EVENTOUT,ADC3_IN8 +PortF,PF11,,,,,,SPI5_MOSI,,,,,,,FMC_SDNRAS,DCMI_D12,,EVENTOUT, +PortF,PF12,,,,,,,,,,,,,FMC_A6,,,EVENTOUT, +PortF,PF13,,,,,,,,,,,,,FMC_A7,,,EVENTOUT, +PortF,PF14,,,,,,,,,,,,,FMC_A8,,,EVENTOUT, +PortF,PF15,,,,,,,,,,,,,FMC_A9,,,EVENTOUT, +PortG,PG0,,,,,,,,,,,,,FMC_A10,,,EVENTOUT, +PortG,PG1,,,,,,,,,,,,,FMC_A11,,,EVENTOUT, +PortG,PG2,,,,,,,,,,,,,FMC_A12,,,EVENTOUT, +PortG,PG3,,,,,,,,,,,,,FMC_A13,,,EVENTOUT, +PortG,PG4,,,,,,,,,,,,,FMC_A14/FMC_BA0,,,EVENTOUT, +PortG,PG5,,,,,,,,,,,,,FMC_A15/FMC_BA1,,,EVENTOUT, +PortG,PG6,,,,,,,,,,,,,,DCMI_D12,LCD_R7,EVENTOUT, +PortG,PG7,,,,,,,SAI1_MCLK_A,,USART6_CK,,,,FMC_INT,DCMI_D13,LCD_CLK,EVENTOUT, +PortG,PG8,,,,,,SPI6_NSS,,,USART6_RTS,,,ETH_PPS_OUT,FMC_SDCLK,,LCD_G7,EVENTOUT, +PortG,PG9,,,,,,,,,USART6_RX,QUADSPI_BK2_IO2,,,FMC_NE2/FMC_NCE,DCMI_VSYNC,,EVENTOUT, +PortG,PG10,,,,,,,,,,LCD_G3,,,FMC_NE3,DCMI_D2,LCD_B2,EVENTOUT, +PortG,PG11,,,,,,,,,,,,ETH_MII_TX_EN/ETH_RMII_TX_EN,,DCMI_D3,LCD_B3,EVENTOUT, +PortG,PG12,,,,,,SPI6_MISO,,,USART6_RTS,LCD_B4,,,FMC_NE4,,LCD_B1,EVENTOUT, +PortG,PG13,TRACED0,,,,,SPI6_SCK,,,USART6_CTS,,,ETH_MII_TXD0/ETH_RMII_TXD0,FMC_A24,,LCD_R0,EVENTOUT, +PortG,PG14,TRACED1,,,,,SPI6_MOSI,,,USART6_TX,QUADSPI_BK2_IO3,,ETH_MII_TXD1/ETH_RMII_TXD1,FMC_A25,,LCD_B0,EVENTOUT, +PortG,PG15,,,,,,,,,USART6_CTS,,,,FMC_SDNCAS,DCMI_D13,,EVENTOUT, +PortH,PH0,,,,,,,,,,,,,,,,EVENTOUT, +PortH,PH1,,,,,,,,,,,,,,,,EVENTOUT, +PortH,PH2,,,,,,,,,,QUADSPI_BK2_IO0,,ETH_MII_CRS,FMC_SDCKE0,,LCD_R0,EVENTOUT, +PortH,PH3,,,,,,,,,,QUADSPI_BK2_IO1,,ETH_MII_COL,FMC_SDNE0,,LCD_R1,EVENTOUT, +PortH,PH4,,,,,I2C2_SCL,,,,,LCD_G5,OTG_HS_ULPI_NXT,,,,LCD_G4,EVENTOUT, +PortH,PH5,,,,,I2C2_SDA,SPI5_NSS,,,,,,,FMC_SDNWE,,,EVENTOUT, +PortH,PH6,,,,,I2C2_SMBA,SPI5_SCK,,,,TIM12_CH1,,ETH_MII_RXD2,FMC_SDNE1,,,EVENTOUT, +PortH,PH7,,,,,I2C3_SCL,SPI5_MISO,,,,,,ETH_MII_RXD3,FMC_SDCKE1,DCMI_D9,,EVENTOUT, +PortH,PH8,,,,,I2C3_SDA,,,,,,,,FMC_D16,DCMI_HSYNC,LCD_R2,EVENTOUT, +PortH,PH9,,,,,I2C3_SMBA,,,,,TIM12_CH2,,,FMC_D17,DCMI_D0,LCD_R3,EVENTOUT, +PortH,PH10,,,TIM5_CH1,,,,,,,,,,FMC_D18,DCMI_D1,LCD_R4,EVENTOUT, +PortH,PH11,,,TIM5_CH2,,,,,,,,,,FMC_D19,DCMI_D2,LCD_R5,EVENTOUT, +PortH,PH12,,,TIM5_CH3,,,,,,,,,,FMC_D20,DCMI_D3,LCD_R6,EVENTOUT, +PortH,PH13,,,,TIM8_CH1N,,,,,,CAN1_TX,,,FMC_D21,,LCD_G2,EVENTOUT, +PortH,PH14,,,,TIM8_CH2N,,,,,,,,,FMC_D22,DCMI_D4,LCD_G3,EVENTOUT, +PortH,PH15,,,,TIM8_CH3N,,,,,,,,,FMC_D23,DCMI_D11,LCD_G4,EVENTOUT, +PortI,PI0,,,TIM5_CH4,,,SPI2_NSS/I2S2_WS,,,,,,,FMC_D24,DCMI_D13,LCD_G5,EVENTOUT, +PortI,PI1,,,,,,SPI2_SCK/I2S2_CK,,,,,,,FMC_D25,DCMI_D8,LCD_G6,EVENTOUT, +PortI,PI2,,,,TIM8_CH4,,SPI2_MISO,I2S2_EXTSD,,,,,,FMC_D26,DCMI_D9,LCD_G7,EVENTOUT, +PortI,PI3,,,,TIM8_ETR,,SPI2_MOSI/I2S2_SD,,,,,,,FMC_D27,DCMI_D10,,EVENTOUT, +PortI,PI4,,,,TIM8_BKIN,,,,,,,,,FMC_NBL2,DCMI_D5,LCD_B4,EVENTOUT, +PortI,PI5,,,,TIM8_CH1,,,,,,,,,FMC_NBL3,DCMI_VSYNC,LCD_B5,EVENTOUT, +PortI,PI6,,,,TIM8_CH2,,,,,,,,,FMC_D28,DCMI_D6,LCD_B6,EVENTOUT, +PortI,PI7,,,,TIM8_CH3,,,,,,,,,FMC_D29,DCMI_D7,LCD_B7,EVENTOUT, +PortI,PI8,,,,,,,,,,,,,,,,EVENTOUT, +PortI,PI9,,,,,,,,,,CAN1_RX,,,FMC_D30,,LCD_VSYNC,EVENTOUT, +PortI,PI10,,,,,,,,,,,,ETH_MII_RX_ER,FMC_D31,,LCD_HSYNC,EVENTOUT, +PortI,PI11,,,,,,,,,,LCD_G6,OTG_HS_ULPI_DIR,,,,,EVENTOUT, +PortI,PI12,,,,,,,,,,,,,,,LCD_HSYNC,EVENTOUT, +PortI,PI13,,,,,,,,,,,,,,,LCD_VSYNC,EVENTOUT, +PortI,PI14,,,,,,,,,,,,,,,LCD_CLK,EVENTOUT, +PortI,PI15,,,,,,,,,,LCD_G2,,,,,LCD_R0,EVENTOUT, +PortJ,PJ0,,,,,,,,,,LCD_R7,,,,,LCD_R1,EVENTOUT, +PortJ,PJ1,,,,,,,,,,,,,,,LCD_R2,EVENTOUT, +PortJ,PJ2,,,,,,,,,,,,,,DSIHOST_TE,LCD_R3,EVENTOUT, +PortJ,PJ3,,,,,,,,,,,,,,,LCD_R4,EVENTOUT, +PortJ,PJ4,,,,,,,,,,,,,,,LCD_R5,EVENTOUT, +PortJ,PJ5,,,,,,,,,,,,,,,LCD_R6,EVENTOUT, +PortJ,PJ12,,,,,,,,,,LCD_G3,,,,,LCD_B0,EVENTOUT, +PortJ,PJ13,,,,,,,,,,LCD_G4,,,,,LCD_B1,EVENTOUT, +PortJ,PJ14,,,,,,,,,,,,,,,LCD_B2,EVENTOUT, +PortJ,PJ15,,,,,,,,,,,,,,,LCD_B3,EVENTOUT, +PortK,PK3,,,,,,,,,,,,,,,LCD_B4,EVENTOUT, +PortK,PK4,,,,,,,,,,,,,,,LCD_B5,EVENTOUT, +PortK,PK5,,,,,,,,,,,,,,,LCD_B6,EVENTOUT, +PortK,PK6,,,,,,,,,,,,,,,LCD_B7,EVENTOUT, +PortK,PK7,,,,,,,,,,,,,,,LCD_DE,EVENTOUT, From 0c9f5b388eae485625b15c8f6e15f2bed9446138 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 29 Nov 2021 13:26:14 +1100 Subject: [PATCH 211/335] stm32: Include HAL MMC code in F4 builds. So that the MMC driver can be used on F4 MCUs. Signed-off-by: Damien George --- ports/stm32/Makefile | 5 +++++ ports/stm32/boards/stm32f4xx_hal_conf_base.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 7a869d3c04..c3b281650a 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -422,6 +422,11 @@ HAL_SRC_C += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\ hal_dma_ex.c \ hal_dcmi.c \ ) +ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4)) +# HAL F4-1.16.0 has a bug with missing parentheses in HAL_MMC_Erase. +# This function is unused so let the error go by as a warning. +$(BUILD)/$(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_hal_mmc.o: CFLAGS += -Wno-error=parentheses +endif endif ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32H743xx STM32H750xx STM32H7A3xx STM32H7A3xxQ STM32H7B3xx STM32H7B3xxQ)) diff --git a/ports/stm32/boards/stm32f4xx_hal_conf_base.h b/ports/stm32/boards/stm32f4xx_hal_conf_base.h index f09990fd95..d42f3ba19f 100644 --- a/ports/stm32/boards/stm32f4xx_hal_conf_base.h +++ b/ports/stm32/boards/stm32f4xx_hal_conf_base.h @@ -42,6 +42,7 @@ #include "stm32f4xx_hal_i2c.h" #include "stm32f4xx_hal_i2s.h" #include "stm32f4xx_hal_iwdg.h" +#include "stm32f4xx_hal_mmc.h" #include "stm32f4xx_hal_pcd.h" #include "stm32f4xx_hal_pwr.h" #include "stm32f4xx_hal_rcc.h" @@ -74,6 +75,7 @@ #define HAL_I2C_MODULE_ENABLED #define HAL_I2S_MODULE_ENABLED #define HAL_IWDG_MODULE_ENABLED +#define HAL_MMC_MODULE_ENABLED #define HAL_PCD_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED From 23a150789df1029def2a26cb757e7d6703520159 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 29 Nov 2021 13:35:43 +1100 Subject: [PATCH 212/335] stm32/boards/make-pins.py: Use cpu pins to define static alt-fun macros. Instead of board pins, so that pins which have only the CPU specified in pins.csv can still be used with mp_hal_pin_config_alt_static(). Signed-off-by: Damien George --- ports/stm32/boards/make-pins.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/stm32/boards/make-pins.py b/ports/stm32/boards/make-pins.py index c7423cb966..b11f438aae 100755 --- a/ports/stm32/boards/make-pins.py +++ b/ports/stm32/boards/make-pins.py @@ -504,7 +504,7 @@ class Pins(object): with open(af_defs_filename, "wt") as af_defs_file: STATIC_AF_TOKENS = {} - for named_pin in self.board_pins: + for named_pin in self.cpu_pins: for af in named_pin.pin().alt_fn: func = "%s%d" % (af.func, af.fn_num) if af.fn_num else af.func pin_type = (af.pin_type or "NULL").split("(")[0] From d94ac4333ff87e8a1b28ae3b10b1ef0c6de9cfb0 Mon Sep 17 00:00:00 2001 From: Peter Hinch Date: Sat, 11 Apr 2020 15:52:01 +0100 Subject: [PATCH 213/335] docs/library/uasyncio.rst: Detail exception behaviour in cancel/timeout. --- docs/library/uasyncio.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/library/uasyncio.rst b/docs/library/uasyncio.rst index 11b9c6aee4..1fc8b53db0 100644 --- a/docs/library/uasyncio.rst +++ b/docs/library/uasyncio.rst @@ -68,11 +68,13 @@ Additional functions .. function:: wait_for(awaitable, timeout) Wait for the *awaitable* to complete, but cancel it if it takes longer - that *timeout* seconds. If *awaitable* is not a task then a task will be + than *timeout* seconds. If *awaitable* is not a task then a task will be created from it. If a timeout occurs, it cancels the task and raises ``asyncio.TimeoutError``: - this should be trapped by the caller. + this should be trapped by the caller. The task receives + ``asyncio.CancelledError`` which may be ignored or trapped using ``try...except`` + or ``try...finally`` to run cleanup code. Returns the return value of *awaitable*. @@ -106,8 +108,9 @@ class Task .. method:: Task.cancel() - Cancel the task by injecting a ``CancelledError`` into it. The task may - or may not ignore this exception. + Cancel the task by injecting ``asyncio.CancelledError`` into it. The task may + ignore this exception. Cleanup code may be run by trapping it, or via + ``try ... finally``. class Event ----------- From e7900351bf954f5af939981d5c6c978636073950 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 31 Aug 2020 17:12:38 +0200 Subject: [PATCH 214/335] docs/library/machine.Timer.rst: Document 'id' as positional-only arg. Signed-off-by: Michael Buesch --- docs/library/machine.Timer.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/library/machine.Timer.rst b/docs/library/machine.Timer.rst index 77a549b40b..d1709a8189 100644 --- a/docs/library/machine.Timer.rst +++ b/docs/library/machine.Timer.rst @@ -27,11 +27,12 @@ instead of this class. Constructors ------------ -.. class:: Timer(id, ...) +.. class:: Timer(id, /, ...) - Construct a new timer object of the given id. Id of -1 constructs a + Construct a new timer object of the given ``id``. ``id`` of -1 constructs a virtual timer (if supported by a board). - + ``id`` shall not be passed as a keyword argument. + See ``init`` for parameters of initialisation. Methods From 1e7c8f2b0bdc7095f28ffda7fbb3c7f23d38b397 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 31 Aug 2020 17:38:20 +0200 Subject: [PATCH 215/335] docs/library/machine.SPI.rst: Add example SPI usage. Signed-off-by: Michael Buesch --- docs/library/machine.SPI.rst | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/library/machine.SPI.rst b/docs/library/machine.SPI.rst index 46ac2ec74c..1116f0e8a3 100644 --- a/docs/library/machine.SPI.rst +++ b/docs/library/machine.SPI.rst @@ -19,6 +19,42 @@ Software SPI is implemented by bit-banging and can be used on any pin but is not as efficient. These classes have the same methods available and differ primarily in the way they are constructed. +Example usage:: + + from machine import SPI, Pin + + spi = SPI(0, baudrate=400000) # Create SPI peripheral 0 at frequency of 400kHz. + # Depending on the use case, extra parameters may be required + # to select the bus characteristics and/or pins to use. + cs = Pin(4, mode=Pin.OUT, value=1) # Create chip-select on pin 4. + + try: + cs(0) # Select peripheral. + spi.write(b"12345678") # Write 8 bytes, and don't care about received data. + finally: + cs(1) # Deselect peripheral. + + try: + cs(0) # Select peripheral. + rxdata = spi.read(8, 0x42) # Read 8 bytes while writing 0x42 for each byte. + finally: + cs(1) # Deselect peripheral. + + rxdata = bytearray(8) + try: + cs(0) # Select peripheral. + spi.readinto(rxdata, 0x42) # Read 8 bytes inplace while writing 0x42 for each byte. + finally: + cs(1) # Deselect peripheral. + + txdata = b"12345678" + rxdata = bytearray(len(txdata)) + try: + cs(0) # Select peripheral. + spi.write_readinto(txdata, rxdata) # Simultaneously write and read bytes. + finally: + cs(1) # Deselect peripheral. + Constructors ------------ From 68d1245f423bc98fb7accb86deab10acacd6a9d8 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 31 Aug 2020 17:58:51 +0200 Subject: [PATCH 216/335] docs/library/machine.Timer.rst: Document `period` and `callback` args. Signed-off-by: Michael Buesch --- docs/library/machine.Timer.rst | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/library/machine.Timer.rst b/docs/library/machine.Timer.rst index d1709a8189..424a49bcba 100644 --- a/docs/library/machine.Timer.rst +++ b/docs/library/machine.Timer.rst @@ -42,8 +42,14 @@ Methods Initialise the timer. Example:: - tim.init(period=100) # periodic with 100ms period - tim.init(mode=Timer.ONE_SHOT, period=1000) # one shot firing after 1000ms + def mycallback(t): + pass + + # periodic with 100ms period + tim.init(period=100, callback=mycallback) + + # one shot firing after 1000ms + tim.init(mode=Timer.ONE_SHOT, period=1000, callback=mycallback) Keyword arguments: @@ -54,6 +60,14 @@ Methods - ``Timer.PERIODIC`` - The timer runs periodically at the configured frequency of the channel. + - ``period`` - The timer period, in milliseconds. + + - ``callback`` - The callable to call upon expiration of the timer period. + The callback must take one argument, which is passed the Timer object. + The ``callback`` argument shall be specified. Otherwise an exception + will occurr upon timer expiration: + ``TypeError: 'NoneType' object isn't callable`` + .. method:: Timer.deinit() Deinitialises the timer. Stops the timer, and disables the timer peripheral. From de7e3cd792d1d4cf6c4b3895d431fc8bc516b51b Mon Sep 17 00:00:00 2001 From: Scott Armitage Date: Thu, 3 Sep 2020 10:49:27 -0700 Subject: [PATCH 217/335] docs/library/machine.Pin.rst: Add Pin.ANALOG mode constant. --- docs/library/machine.Pin.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/library/machine.Pin.rst b/docs/library/machine.Pin.rst index f8e9e1054d..32fa05b49c 100644 --- a/docs/library/machine.Pin.rst +++ b/docs/library/machine.Pin.rst @@ -74,6 +74,8 @@ Constructors - ``Pin.ALT_OPEN_DRAIN`` - The Same as ``Pin.ALT``, but the pin is configured as open-drain. Not all ports implement this mode. + - ``Pin.ANALOG`` - Pin is configured for analog input, see the :class:`ADC` class. + - ``pull`` specifies if the pin has a (weak) pull resistor attached, and can be one of: @@ -247,6 +249,7 @@ not all constants are available on all ports. Pin.OPEN_DRAIN Pin.ALT Pin.ALT_OPEN_DRAIN + Pin.ANALOG Selects the pin mode. From 851ecb2da178fff0b60aefdb5af502f28787a7ec Mon Sep 17 00:00:00 2001 From: Jonathan Hogg Date: Mon, 12 Jul 2021 08:46:29 +0100 Subject: [PATCH 218/335] extmod/modbluetooth: Support gap_connect(None) to cancel a connection. Allow cancellation of in-progress peripheral connections. --- docs/library/bluetooth.rst | 7 ++++++- extmod/btstack/modbluetooth_btstack.c | 5 +++++ extmod/modbluetooth.c | 9 ++++++++- extmod/modbluetooth.h | 4 ++++ extmod/nimble/modbluetooth_nimble.c | 9 +++++++++ 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/library/bluetooth.rst b/docs/library/bluetooth.rst index cfec804eaf..7663199e91 100644 --- a/docs/library/bluetooth.rst +++ b/docs/library/bluetooth.rst @@ -365,7 +365,12 @@ A central device can connect to peripherals that it has discovered using the obs See :meth:`gap_scan ` for details about address types. - On success, the ``_IRQ_PERIPHERAL_CONNECT`` event will be raised. + To cancel an outstanding connection attempt early, call + ``gap_connect(None)``. + + On success, the ``_IRQ_PERIPHERAL_CONNECT`` event will be raised. If + cancelling a connection attempt, the ``_IRQ_PERIPHERAL_DISCONNECT`` event + will be raised. The device will wait up to *scan_duration_ms* to receive an advertising payload from the device. diff --git a/extmod/btstack/modbluetooth_btstack.c b/extmod/btstack/modbluetooth_btstack.c index cd2ba83d53..e56e488b1c 100644 --- a/extmod/btstack/modbluetooth_btstack.c +++ b/extmod/btstack/modbluetooth_btstack.c @@ -1284,6 +1284,11 @@ int mp_bluetooth_gap_peripheral_connect(uint8_t addr_type, const uint8_t *addr, return btstack_error_to_errno(gap_connect(btstack_addr, addr_type)); } +int mp_bluetooth_gap_peripheral_connect_cancel(void) { + DEBUG_printf("mp_bluetooth_gap_peripheral_connect_cancel\n"); + return btstack_error_to_errno(gap_connect_cancel()); +} + #endif // MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE #if MICROPY_PY_BLUETOOTH_ENABLE_GATT_CLIENT diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index e3d64b81f1..1bf2ae6add 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -630,6 +630,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(bluetooth_ble_gatts_register_services_obj, blue #if MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE STATIC mp_obj_t bluetooth_ble_gap_connect(size_t n_args, const mp_obj_t *args) { + if (n_args == 2) { + if (args[1] == mp_const_none) { + int err = mp_bluetooth_gap_peripheral_connect_cancel(); + return bluetooth_handle_errno(err); + } + mp_raise_TypeError(MP_ERROR_TEXT("invalid addr")); + } uint8_t addr_type = mp_obj_get_int(args[1]); mp_buffer_info_t bufinfo = {0}; mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ); @@ -652,7 +659,7 @@ STATIC mp_obj_t bluetooth_ble_gap_connect(size_t n_args, const mp_obj_t *args) { int err = mp_bluetooth_gap_peripheral_connect(addr_type, bufinfo.buf, scan_duration_ms, min_conn_interval_us, max_conn_interval_us); return bluetooth_handle_errno(err); } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gap_connect_obj, 3, 6, bluetooth_ble_gap_connect); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gap_connect_obj, 2, 6, bluetooth_ble_gap_connect); STATIC mp_obj_t bluetooth_ble_gap_scan(size_t n_args, const mp_obj_t *args) { // Default is indefinite scan, with the NimBLE "background scan" interval and window. diff --git a/extmod/modbluetooth.h b/extmod/modbluetooth.h index fe41fd5143..e52232c414 100644 --- a/extmod/modbluetooth.h +++ b/extmod/modbluetooth.h @@ -374,6 +374,10 @@ int mp_bluetooth_gap_peripheral_connect(uint8_t addr_type, const uint8_t *addr, #endif #if MICROPY_PY_BLUETOOTH_ENABLE_GATT_CLIENT + +// Cancel in-progress connection to a peripheral. +int mp_bluetooth_gap_peripheral_connect_cancel(void); + // Find all primary services on the connected peripheral. int mp_bluetooth_gattc_discover_primary_services(uint16_t conn_handle, const mp_obj_bluetooth_uuid_t *uuid); diff --git a/extmod/nimble/modbluetooth_nimble.c b/extmod/nimble/modbluetooth_nimble.c index 919841c243..fce99bcdf5 100644 --- a/extmod/nimble/modbluetooth_nimble.c +++ b/extmod/nimble/modbluetooth_nimble.c @@ -1236,6 +1236,15 @@ int mp_bluetooth_gap_peripheral_connect(uint8_t addr_type, const uint8_t *addr, return ble_hs_err_to_errno(err); } +int mp_bluetooth_gap_peripheral_connect_cancel(void) { + DEBUG_printf("mp_bluetooth_gap_peripheral_connect_cancel\n"); + if (!mp_bluetooth_is_active()) { + return ERRNO_BLUETOOTH_NOT_ACTIVE; + } + int err = ble_gap_conn_cancel(); + return ble_hs_err_to_errno(err); +} + STATIC int ble_gattc_service_cb(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *service, void *arg) { DEBUG_printf("ble_gattc_service_cb: conn_handle=%d status=%d start_handle=%d\n", conn_handle, error->status, service ? service->start_handle : -1); if (!mp_bluetooth_is_active()) { From a7fa18c203a241f670f12ab507aa8b349fcd45a1 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 26 Feb 2020 15:24:09 +1100 Subject: [PATCH 219/335] py/builtinimport: Refactor module importing. Simplify and document/comment the handling of builtin import for: - already-loaded modules - built-in modules - built-in umodules (formerly weak links) - filesystem modules Retains existing functionality with smaller code size but should also facilitate potential new features (built-in packages, controlling the frozen path). Also makes the (unix-only) -m behavior a bit more obvious and configurable. Code size change with this commit: bare-arm: +0 +0.000% minimal x86: -64 -0.039% unix x64: -32 -0.006% unix nanbox: -4 -0.001% stm32: -184 -0.047% PYBV10 cc3200: -120 -0.065% esp8266: -228 -0.033% GENERIC esp32: -268 -0.018% GENERIC[incl +16(data)] nrf: -152 -0.087% pca10040 rp2: -256 -0.052% PICO samd: -80 -0.057% ADAFRUIT_ITSYBITSY_M4_EXPRESS --- ports/unix/mpconfigport.h | 1 + ports/windows/mpconfigport.h | 1 + py/builtinimport.c | 491 ++++++++++++++++++++--------------- py/mpconfig.h | 6 + py/objmodule.c | 69 +++-- py/objmodule.h | 15 +- 6 files changed, 337 insertions(+), 246 deletions(-) diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index d6ab4e5ca9..93d790ac36 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -86,6 +86,7 @@ #define MICROPY_OPT_MAP_LOOKUP_CACHE (1) #endif #define MICROPY_MODULE_WEAK_LINKS (1) +#define MICROPY_MODULE_OVERRIDE_MAIN_IMPORT (1) #define MICROPY_CAN_OVERRIDE_BUILTINS (1) #define MICROPY_VFS_POSIX_FILE (1) #define MICROPY_PY_FUNCTION_ATTRS (1) diff --git a/ports/windows/mpconfigport.h b/ports/windows/mpconfigport.h index 8dd95e769d..69193cb6af 100644 --- a/ports/windows/mpconfigport.h +++ b/ports/windows/mpconfigport.h @@ -60,6 +60,7 @@ #define MICROPY_STREAMS_POSIX_API (1) #define MICROPY_OPT_COMPUTED_GOTO (0) #define MICROPY_MODULE_WEAK_LINKS (1) +#define MICROPY_MODULE_OVERRIDE_MAIN_IMPORT (1) #define MICROPY_CAN_OVERRIDE_BUILTINS (1) #define MICROPY_VFS_POSIX_FILE (1) #define MICROPY_PY_FUNCTION_ATTRS (1) diff --git a/py/builtinimport.c b/py/builtinimport.c index 08921f873b..755ce779a7 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -5,6 +5,7 @@ * * Copyright (c) 2013-2019 Damien P. George * Copyright (c) 2014 Paul Sokolovsky + * Copyright (c) 2021 Jim Mussared * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -46,7 +47,8 @@ #if MICROPY_ENABLE_EXTERNAL_IMPORT -#define PATH_SEP_CHAR '/' +// Must be a string of one byte. +#define PATH_SEP_CHAR "/" bool mp_obj_is_package(mp_obj_t module) { mp_obj_t dest[2]; @@ -54,9 +56,11 @@ bool mp_obj_is_package(mp_obj_t module) { return dest[0] != MP_OBJ_NULL; } -// Stat either frozen or normal module by a given path -// (whatever is available, if at all). -STATIC mp_import_stat_t mp_import_stat_any(const char *path) { +// Wrapper for mp_import_stat (which is provided by the port, and typically +// uses mp_vfs_import_stat) to also search frozen modules. Given an exact +// path to a file or directory (e.g. "foo/bar", foo/bar.py" or "foo/bar.mpy"), +// will return whether the path is a file, directory, or doesn't exist. +STATIC mp_import_stat_t stat_path_or_frozen(const char *path) { #if MICROPY_MODULE_FROZEN mp_import_stat_t st = mp_frozen_stat(path); if (st != MP_IMPORT_STAT_NO_EXIST) { @@ -66,15 +70,18 @@ STATIC mp_import_stat_t mp_import_stat_any(const char *path) { return mp_import_stat(path); } +// Given a path to a .py file, try and find this path as either a .py or .mpy +// in either the filesystem or frozen modules. STATIC mp_import_stat_t stat_file_py_or_mpy(vstr_t *path) { - mp_import_stat_t stat = mp_import_stat_any(vstr_null_terminated_str(path)); + mp_import_stat_t stat = stat_path_or_frozen(vstr_null_terminated_str(path)); if (stat == MP_IMPORT_STAT_FILE) { return stat; } #if MICROPY_PERSISTENT_CODE_LOAD + // Didn't find .py -- try the .mpy instead by inserting an 'm' into the '.py'. vstr_ins_byte(path, path->len - 2, 'm'); - stat = mp_import_stat_any(vstr_null_terminated_str(path)); + stat = stat_path_or_frozen(vstr_null_terminated_str(path)); if (stat == MP_IMPORT_STAT_FILE) { return stat; } @@ -83,8 +90,10 @@ STATIC mp_import_stat_t stat_file_py_or_mpy(vstr_t *path) { return MP_IMPORT_STAT_NO_EXIST; } +// Given an import path (e.g. "foo/bar"), try and find "foo/bar" (a directory) +// or "foo/bar.(m)py" in either the filesystem or frozen modules. STATIC mp_import_stat_t stat_dir_or_file(vstr_t *path) { - mp_import_stat_t stat = mp_import_stat_any(vstr_null_terminated_str(path)); + mp_import_stat_t stat = stat_path_or_frozen(vstr_null_terminated_str(path)); DEBUG_printf("stat %s: %d\n", vstr_str(path), stat); if (stat == MP_IMPORT_STAT_DIR) { return stat; @@ -95,14 +104,16 @@ STATIC mp_import_stat_t stat_dir_or_file(vstr_t *path) { return stat_file_py_or_mpy(path); } -STATIC mp_import_stat_t find_file(const char *file_str, uint file_len, vstr_t *dest) { +// Given a top-level module, try and find it in each of the sys.path entries +// via stat_dir_or_file. +STATIC mp_import_stat_t stat_top_level_dir_or_file(qstr mod_name, vstr_t *dest) { + DEBUG_printf("stat_top_level_dir_or_file: '%s'\n", qstr_str(mod_name)); #if MICROPY_PY_SYS - // extract the list of paths size_t path_num; mp_obj_t *path_items; mp_obj_list_get(mp_sys_path, &path_num, &path_items); - if (path_num != 0) { + if (path_num > 0) { // go through each path looking for a directory or file for (size_t i = 0; i < path_num; i++) { vstr_reset(dest); @@ -110,9 +121,9 @@ STATIC mp_import_stat_t find_file(const char *file_str, uint file_len, vstr_t *d const char *p = mp_obj_str_get_data(path_items[i], &p_len); if (p_len > 0) { vstr_add_strn(dest, p, p_len); - vstr_add_char(dest, PATH_SEP_CHAR); + vstr_add_char(dest, PATH_SEP_CHAR[0]); } - vstr_add_strn(dest, file_str, file_len); + vstr_add_str(dest, qstr_str(mod_name)); mp_import_stat_t stat = stat_dir_or_file(dest); if (stat != MP_IMPORT_STAT_NO_EXIST) { return stat; @@ -124,8 +135,9 @@ STATIC mp_import_stat_t find_file(const char *file_str, uint file_len, vstr_t *d } #endif - // mp_sys_path is empty, so just use the given file name - vstr_add_strn(dest, file_str, file_len); + // mp_sys_path is empty (or not enabled), so just stat the given path + // directly. + vstr_add_str(dest, qstr_str(mod_name)); return stat_dir_or_file(dest); } @@ -189,7 +201,6 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { #if MICROPY_MODULE_FROZEN void *modref; int frozen_type = mp_find_frozen_module(file_str, file->len, &modref); - #endif // If we support frozen str modules and the compiler is enabled, and we // found the filename in the list of frozen files, then load and execute it. @@ -209,6 +220,8 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { } #endif + #endif // MICROPY_MODULE_FROZEN + // If we support loading .mpy files then check if the file extension is of // the correct format and, if so, load and execute the file. #if MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD @@ -232,15 +245,212 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { #endif } -STATIC void chop_component(const char *start, const char **end) { - const char *p = *end; - while (p > start) { +// Convert a relative (to the current module) import, going up "level" levels, +// into an absolute import. +STATIC void evaluate_relative_import(mp_int_t level, const char **module_name, size_t *module_name_len) { + // What we want to do here is to take the name of the current module, + // remove trailing components, and concatenate the passed-in + // module name. + // For example, level=3, module_name="foo.bar", __name__="a.b.c.d" --> "a.foo.bar" + // "Relative imports use a module's __name__ attribute to determine that + // module's position in the package hierarchy." + // http://legacy.python.org/dev/peps/pep-0328/#relative-imports-and-name + + mp_obj_t current_module_name_obj = mp_obj_dict_get(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(MP_QSTR___name__)); + assert(current_module_name_obj != MP_OBJ_NULL); + + #if MICROPY_MODULE_OVERRIDE_MAIN_IMPORT && MICROPY_CPYTHON_COMPAT + if (MP_OBJ_QSTR_VALUE(current_module_name_obj) == MP_QSTR___main__) { + // This is a module loaded by -m command-line switch (e.g. unix port), + // and so its __name__ has been set to "__main__". Get its real name + // that we stored during import in the __main__ attribute. + current_module_name_obj = mp_obj_dict_get(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(MP_QSTR___main__)); + } + #endif + + // If we have a __path__ in the globals dict, then we're a package. + bool is_pkg = mp_map_lookup(&mp_globals_get()->map, MP_OBJ_NEW_QSTR(MP_QSTR___path__), MP_MAP_LOOKUP); + + #if DEBUG_PRINT + DEBUG_printf("Current module/package: "); + mp_obj_print_helper(MICROPY_DEBUG_PRINTER, current_module_name_obj, PRINT_REPR); + DEBUG_printf(", is_package: %d", is_pkg); + DEBUG_printf("\n"); + #endif + + size_t current_module_name_len; + const char *current_module_name = mp_obj_str_get_data(current_module_name_obj, ¤t_module_name_len); + + const char *p = current_module_name + current_module_name_len; + if (is_pkg) { + // If we're evaluating relative to a package, then take off one fewer + // level (i.e. the relative search starts inside the package, rather + // than as a sibling of the package). + --level; + } + + // Walk back 'level' dots (or run out of path). + while (level && p > current_module_name) { if (*--p == '.') { - *end = p; - return; + --level; } } - *end = p; + + // We must have some component left over to import from. + if (p == current_module_name) { + mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("can't perform relative import")); + } + + // New length is len("."). Note: might be one byte + // more than we need if module_name is empty (for the extra . we will + // append). + uint new_module_name_len = (size_t)(p - current_module_name) + 1 + *module_name_len; + char *new_mod = mp_local_alloc(new_module_name_len); + memcpy(new_mod, current_module_name, p - current_module_name); + + // Only append "." if there was one). + if (*module_name_len != 0) { + new_mod[p - current_module_name] = '.'; + memcpy(new_mod + (p - current_module_name) + 1, *module_name, *module_name_len); + } else { + --new_module_name_len; + } + + // Copy into a QSTR. + qstr new_mod_q = qstr_from_strn(new_mod, new_module_name_len); + mp_local_free(new_mod); + + DEBUG_printf("Resolved base name for relative import: '%s'\n", qstr_str(new_mod_q)); + *module_name = qstr_str(new_mod_q); + *module_name_len = new_module_name_len; +} + +// Load a module at the specified absolute path, possibly as a submodule of the given outer module. +// full_mod_name: The full absolute path to this module (e.g. "foo.bar.baz"). +// level_mod_name: The final component of the path (e.g. "baz"). +// outer_module_obj: The parent module (we need to store this module as an +// attribute on it) (or MP_OBJ_NULL for top-level). +// path: The filesystem path where we found the parent module +// (or empty for a top level module). +// override_main: Whether to set the __name__ to "__main__" (and use __main__ +// for the actual path). +STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name, mp_obj_t outer_module_obj, vstr_t *path, bool override_main) { + mp_import_stat_t stat = MP_IMPORT_STAT_NO_EXIST; + + // Exact-match of built-in (or already-loaded) takes priority. + mp_obj_t module_obj = mp_module_get_loaded_or_builtin(full_mod_name); + + // Even if we find the module, go through the motions of searching for it + // because we may actually be in the process of importing a sub-module. + // So we need to (re-)find the correct path to be finding the sub-module + // on the next iteration of process_import_at_level. + + if (outer_module_obj == MP_OBJ_NULL) { + DEBUG_printf("Searching for top-level module\n"); + + // First module in the dotted-name; search for a directory or file + // relative to all the locations in sys.path. + stat = stat_top_level_dir_or_file(full_mod_name, path); + + // If the module "foo" doesn't exist on the filesystem, and it's not a + // builtin, try and find "ufoo" as a built-in. (This feature was + // formerly known as "weak links"). + #if MICROPY_MODULE_WEAK_LINKS + if (stat == MP_IMPORT_STAT_NO_EXIST && module_obj == MP_OBJ_NULL) { + char *umodule_buf = vstr_str(path); + umodule_buf[0] = 'u'; + strcpy(umodule_buf + 1, qstr_str(level_mod_name)); + qstr umodule_name = qstr_from_str(umodule_buf); + module_obj = mp_module_get_builtin(umodule_name); + } + #endif + } else { + DEBUG_printf("Searching for sub-module\n"); + + // Add the current part of the module name to the path. + vstr_add_char(path, PATH_SEP_CHAR[0]); + vstr_add_str(path, qstr_str(level_mod_name)); + + // Because it's not top level, we already know which path the parent was found in. + stat = stat_dir_or_file(path); + } + DEBUG_printf("Current path: %.*s\n", (int)vstr_len(path), vstr_str(path)); + + if (module_obj == MP_OBJ_NULL) { + // Not a built-in and not already-loaded. + + if (stat == MP_IMPORT_STAT_NO_EXIST) { + // And the file wasn't found -- fail. + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE + mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("module not found")); + #else + mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("no module named '%q'"), full_mod_name); + #endif + } + + // Not a built-in but found on the filesystem, try and load it. + + DEBUG_printf("Found path: %.*s\n", (int)vstr_len(path), vstr_str(path)); + + // Prepare for loading from the filesystem. Create a new shell module. + module_obj = mp_obj_new_module(full_mod_name); + + #if MICROPY_MODULE_OVERRIDE_MAIN_IMPORT + // If this module is being loaded via -m on unix, then + // override __name__ to "__main__". Do this only for *modules* + // however - packages never have their names replaced, instead + // they're -m'ed using a special __main__ submodule in them. (This all + // apparently is done to not touch the package name itself, which is + // important for future imports). + if (override_main && stat != MP_IMPORT_STAT_DIR) { + mp_obj_module_t *o = MP_OBJ_TO_PTR(module_obj); + mp_obj_dict_store(MP_OBJ_FROM_PTR(o->globals), MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR___main__)); + #if MICROPY_CPYTHON_COMPAT + // Store module as "__main__" in the dictionary of loaded modules (returned by sys.modules). + mp_obj_dict_store(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_loaded_modules_dict)), MP_OBJ_NEW_QSTR(MP_QSTR___main__), module_obj); + // Store real name in "__main__" attribute. Need this for + // resolving relative imports later. "__main__ was chosen + // semi-randonly, to reuse existing qstr's. + mp_obj_dict_store(MP_OBJ_FROM_PTR(o->globals), MP_OBJ_NEW_QSTR(MP_QSTR___main__), MP_OBJ_NEW_QSTR(full_mod_name)); + #endif + } + #endif // MICROPY_MODULE_OVERRIDE_MAIN_IMPORT + + if (stat == MP_IMPORT_STAT_DIR) { + // Directory -- execute "path/__init__.py". + DEBUG_printf("%.*s is dir\n", (int)vstr_len(path), vstr_str(path)); + // Store the __path__ attribute onto this module. + // https://docs.python.org/3/reference/import.html + // "Specifically, any module that contains a __path__ attribute is considered a package." + mp_store_attr(module_obj, MP_QSTR___path__, mp_obj_new_str(vstr_str(path), vstr_len(path))); + size_t orig_path_len = path->len; + vstr_add_str(path, PATH_SEP_CHAR "__init__.py"); + if (stat_file_py_or_mpy(path) == MP_IMPORT_STAT_FILE) { + do_load(module_obj, path); + } else { + // No-op. Nothing to load. + // mp_warning("%s is imported as namespace package", vstr_str(&path)); + } + // Remove /__init__.py suffix. + path->len = orig_path_len; + } else { // MP_IMPORT_STAT_FILE + // File -- execute "path.(m)py". + do_load(module_obj, path); + // Note: This should be the last component in the import path. If + // there are remaining components then it's an ImportError + // because the current path(the module that was just loaded) is + // not a package. This will be caught on the next iteration + // because the file will not exist. + } + } + + if (outer_module_obj != MP_OBJ_NULL) { + // If it's a sub-module (not a built-in one), then make it available on + // the parent module. + mp_store_attr(outer_module_obj, level_mod_name, module_obj); + } + + return module_obj; } mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { @@ -253,9 +463,23 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { } #endif - mp_obj_t module_name = args[0]; + // This is the import path, with any leading dots stripped. + // "import foo.bar" --> module_name="foo.bar" + // "from foo.bar import baz" --> module_name="foo.bar" + // "from . import foo" --> module_name="" + // "from ...foo.bar import baz" --> module_name="foo.bar" + mp_obj_t module_name_obj = args[0]; + + // These are the imported names. + // i.e. "from foo.bar import baz, zap" --> fromtuple=("baz", "zap",) + // Note: There's a special case on the Unix port, where this is set to mp_const_false which means that it's __main__. mp_obj_t fromtuple = mp_const_none; + + // Level is the number of leading dots in a relative import. + // i.e. "from . import foo" --> level=1 + // i.e. "from ...foo.bar import baz" --> level=3 mp_int_t level = 0; + if (n_args >= 4) { fromtuple = args[3]; if (n_args >= 5) { @@ -266,211 +490,64 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { } } - size_t mod_len; - const char *mod_str = mp_obj_str_get_data(module_name, &mod_len); + size_t module_name_len; + const char *module_name = mp_obj_str_get_data(module_name_obj, &module_name_len); if (level != 0) { - // What we want to do here is to take name of current module, - // chop trailing components, and concatenate with passed-in - // module name, thus resolving relative import name into absolute. - // This even appears to be correct per - // http://legacy.python.org/dev/peps/pep-0328/#relative-imports-and-name - // "Relative imports use a module's __name__ attribute to determine that - // module's position in the package hierarchy." - level--; - mp_obj_t this_name_q = mp_obj_dict_get(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(MP_QSTR___name__)); - assert(this_name_q != MP_OBJ_NULL); - #if MICROPY_CPYTHON_COMPAT - if (MP_OBJ_QSTR_VALUE(this_name_q) == MP_QSTR___main__) { - // This is a module run by -m command-line switch, get its real name from backup attribute - this_name_q = mp_obj_dict_get(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(MP_QSTR___main__)); - } - #endif - mp_map_t *globals_map = &mp_globals_get()->map; - mp_map_elem_t *elem = mp_map_lookup(globals_map, MP_OBJ_NEW_QSTR(MP_QSTR___path__), MP_MAP_LOOKUP); - bool is_pkg = (elem != NULL); - - #if DEBUG_PRINT - DEBUG_printf("Current module/package: "); - mp_obj_print_helper(MICROPY_DEBUG_PRINTER, this_name_q, PRINT_REPR); - DEBUG_printf(", is_package: %d", is_pkg); - DEBUG_printf("\n"); - #endif - - size_t this_name_l; - const char *this_name = mp_obj_str_get_data(this_name_q, &this_name_l); - - const char *p = this_name + this_name_l; - if (!is_pkg) { - // We have module, but relative imports are anchored at package, so - // go there. - chop_component(this_name, &p); - } - - while (level--) { - chop_component(this_name, &p); - } - - // We must have some component left over to import from - if (p == this_name) { - mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("can't perform relative import")); - } - - uint new_mod_l = (mod_len == 0 ? (size_t)(p - this_name) : (size_t)(p - this_name) + 1 + mod_len); - char *new_mod = mp_local_alloc(new_mod_l); - memcpy(new_mod, this_name, p - this_name); - if (mod_len != 0) { - new_mod[p - this_name] = '.'; - memcpy(new_mod + (p - this_name) + 1, mod_str, mod_len); - } - - qstr new_mod_q = qstr_from_strn(new_mod, new_mod_l); - mp_local_free(new_mod); - DEBUG_printf("Resolved base name for relative import: '%s'\n", qstr_str(new_mod_q)); - module_name = MP_OBJ_NEW_QSTR(new_mod_q); - mod_str = qstr_str(new_mod_q); - mod_len = new_mod_l; + // Turn "foo.bar" into ".foo.bar". + evaluate_relative_import(level, &module_name, &module_name_len); } - if (mod_len == 0) { + if (module_name_len == 0) { mp_raise_ValueError(NULL); } - // check if module already exists - qstr module_name_qstr = mp_obj_str_get_qstr(module_name); - mp_obj_t module_obj = mp_module_get(module_name_qstr); - if (module_obj != MP_OBJ_NULL) { - DEBUG_printf("Module already loaded\n"); - // If it's not a package, return module right away - char *p = strchr(mod_str, '.'); - if (p == NULL) { - return module_obj; - } - // If fromlist is not empty, return leaf module - if (fromtuple != mp_const_none) { - return module_obj; - } - // Otherwise, we need to return top-level package - qstr pkg_name = qstr_from_strn(mod_str, p - mod_str); - return mp_module_get(pkg_name); - } - DEBUG_printf("Module not yet loaded\n"); + DEBUG_printf("Starting module search for '%s'\n", module_name); - uint last = 0; VSTR_FIXED(path, MICROPY_ALLOC_PATH_MAX) - module_obj = MP_OBJ_NULL; mp_obj_t top_module_obj = MP_OBJ_NULL; mp_obj_t outer_module_obj = MP_OBJ_NULL; - uint i; - for (i = 1; i <= mod_len; i++) { - if (i == mod_len || mod_str[i] == '.') { - // create a qstr for the module name up to this depth - qstr mod_name = qstr_from_strn(mod_str, i); - DEBUG_printf("Processing module: %s\n", qstr_str(mod_name)); - DEBUG_printf("Previous path: =%.*s=\n", vstr_len(&path), vstr_str(&path)); - // find the file corresponding to the module name - mp_import_stat_t stat; - if (vstr_len(&path) == 0) { - // first module in the dotted-name; search for a directory or file - stat = find_file(mod_str, i, &path); - } else { - // latter module in the dotted-name; append to path - vstr_add_char(&path, PATH_SEP_CHAR); - vstr_add_strn(&path, mod_str + last, i - last); - stat = stat_dir_or_file(&path); - } - DEBUG_printf("Current path: %.*s\n", vstr_len(&path), vstr_str(&path)); + // Search for the end of each component. + size_t current_component_start = 0; + for (size_t i = 1; i <= module_name_len; i++) { + if (i == module_name_len || module_name[i] == '.') { + // The module name up to this depth (e.g. foo.bar.baz). + qstr full_mod_name = qstr_from_strn(module_name, i); + // The current level name (e.g. baz). + qstr level_mod_name = qstr_from_strn(module_name + current_component_start, i - current_component_start); - if (stat == MP_IMPORT_STAT_NO_EXIST) { - module_obj = MP_OBJ_NULL; - #if MICROPY_MODULE_WEAK_LINKS - // check if there is a weak link to this module - if (i == mod_len) { - module_obj = mp_module_search_umodule(mod_str); - if (module_obj != MP_OBJ_NULL) { - // found weak linked module - mp_module_call_init(mod_name, module_obj); - } - } - #endif - if (module_obj == MP_OBJ_NULL) { - // couldn't find the file, so fail - #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE - mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("module not found")); - #else - mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("no module named '%q'"), mod_name); - #endif - } - } else { - // found the file, so get the module - module_obj = mp_module_get(mod_name); - } + DEBUG_printf("Processing module: '%s' at level '%s'\n", qstr_str(full_mod_name), qstr_str(level_mod_name)); + DEBUG_printf("Previous path: =%.*s=\n", (int)vstr_len(&path), vstr_str(&path)); - if (module_obj == MP_OBJ_NULL) { - // module not already loaded, so load it! + #if MICROPY_MODULE_OVERRIDE_MAIN_IMPORT + // On unix, if this is being loaded via -m (magic mp_const_false), + // then handle that if it's the final component. + bool override_main = (i == module_name_len && fromtuple == mp_const_false); + #else + bool override_main = false; + #endif - module_obj = mp_obj_new_module(mod_name); + // Import this module. + mp_obj_t module_obj = process_import_at_level(full_mod_name, level_mod_name, outer_module_obj, &path, override_main); - // if args[3] (fromtuple) has magic value False, set up - // this module for command-line "-m" option (set module's - // name to __main__ instead of real name). Do this only - // for *modules* however - packages never have their names - // replaced, instead they're -m'ed using a special __main__ - // submodule in them. (This all apparently is done to not - // touch package name itself, which is important for future - // imports). - if (i == mod_len && fromtuple == mp_const_false && stat != MP_IMPORT_STAT_DIR) { - mp_obj_module_t *o = MP_OBJ_TO_PTR(module_obj); - mp_obj_dict_store(MP_OBJ_FROM_PTR(o->globals), MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR___main__)); - #if MICROPY_CPYTHON_COMPAT - // Store module as "__main__" in the dictionary of loaded modules (returned by sys.modules). - mp_obj_dict_store(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_loaded_modules_dict)), MP_OBJ_NEW_QSTR(MP_QSTR___main__), module_obj); - // Store real name in "__main__" attribute. Chosen semi-randonly, to reuse existing qstr's. - mp_obj_dict_store(MP_OBJ_FROM_PTR(o->globals), MP_OBJ_NEW_QSTR(MP_QSTR___main__), MP_OBJ_NEW_QSTR(mod_name)); - #endif - } - - if (stat == MP_IMPORT_STAT_DIR) { - DEBUG_printf("%.*s is dir\n", vstr_len(&path), vstr_str(&path)); - // https://docs.python.org/3/reference/import.html - // "Specifically, any module that contains a __path__ attribute is considered a package." - mp_store_attr(module_obj, MP_QSTR___path__, mp_obj_new_str(vstr_str(&path), vstr_len(&path))); - size_t orig_path_len = path.len; - vstr_add_char(&path, PATH_SEP_CHAR); - vstr_add_str(&path, "__init__.py"); - if (stat_file_py_or_mpy(&path) != MP_IMPORT_STAT_FILE) { - // mp_warning("%s is imported as namespace package", vstr_str(&path)); - } else { - do_load(module_obj, &path); - } - path.len = orig_path_len; - } else { // MP_IMPORT_STAT_FILE - do_load(module_obj, &path); - // This should be the last component in the import path. If there are - // remaining components then it's an ImportError because the current path - // (the module that was just loaded) is not a package. This will be caught - // on the next iteration because the file will not exist. - } - } - if (outer_module_obj != MP_OBJ_NULL) { - qstr s = qstr_from_strn(mod_str + last, i - last); - mp_store_attr(outer_module_obj, s, module_obj); - } + // Set this as the parent module, and remember the top-level module if it's the first. outer_module_obj = module_obj; if (top_module_obj == MP_OBJ_NULL) { top_module_obj = module_obj; } - last = i + 1; + + current_component_start = i + 1; } } - // If fromlist is not empty, return leaf module if (fromtuple != mp_const_none) { - return module_obj; + // If fromtuple is not empty, return leaf module + return outer_module_obj; + } else { + // Otherwise, we need to return top-level package + return top_module_obj; } - // Otherwise, we need to return top-level package - return top_module_obj; } #else // MICROPY_ENABLE_EXTERNAL_IMPORT @@ -483,17 +560,19 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { // Check if module already exists, and return it if it does qstr module_name_qstr = mp_obj_str_get_qstr(args[0]); - mp_obj_t module_obj = mp_module_get(module_name_qstr); + mp_obj_t module_obj = mp_module_get_loaded_or_builtin(module_name_qstr); if (module_obj != MP_OBJ_NULL) { return module_obj; } #if MICROPY_MODULE_WEAK_LINKS // Check if there is a weak link to this module - module_obj = mp_module_search_umodule(qstr_str(module_name_qstr)); + char umodule_buf[MICROPY_ALLOC_PATH_MAX]; + umodule_buf[0] = 'u'; + strcpy(umodule_buf + 1, args[0]); + qstr umodule_name_qstr = qstr_from_str(umodule_buf); + module_obj = mp_module_get_loaded_or_builtin(umodule_name_qstr); if (module_obj != MP_OBJ_NULL) { - // Found weak-linked module - mp_module_call_init(module_name_qstr, module_obj); return module_obj; } #endif diff --git a/py/mpconfig.h b/py/mpconfig.h index 06c46b8c73..308a776661 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -829,6 +829,12 @@ typedef double mp_float_t; #define MICROPY_MODULE_WEAK_LINKS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif +// Whether to enable importing foo.py with __name__ set to '__main__' +// Used by the unix port for the -m flag. +#ifndef MICROPY_MODULE_OVERRIDE_MAIN_IMPORT +#define MICROPY_MODULE_OVERRIDE_MAIN_IMPORT (0) +#endif + // Whether frozen modules are supported in the form of strings #ifndef MICROPY_MODULE_FROZEN_STR #define MICROPY_MODULE_FROZEN_STR (0) diff --git a/py/objmodule.c b/py/objmodule.c index d648f0f8ce..6b06740e4d 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -35,6 +35,10 @@ #include "genhdr/moduledefs.h" +#if MICROPY_MODULE_BUILTIN_INIT +STATIC void mp_module_call_init(mp_obj_t module_name, mp_obj_t module_obj); +#endif + STATIC void module_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_module_t *self = MP_OBJ_TO_PTR(self_in); @@ -245,47 +249,56 @@ STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = { MP_DEFINE_CONST_MAP(mp_builtin_module_map, mp_builtin_module_table); -// returns MP_OBJ_NULL if not found -mp_obj_t mp_module_get(qstr module_name) { - mp_map_t *mp_loaded_modules_map = &MP_STATE_VM(mp_loaded_modules_dict).map; - // lookup module - mp_map_elem_t *el = mp_map_lookup(mp_loaded_modules_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP); +// Tries to find a loaded module, otherwise attempts to load a builtin, otherwise MP_OBJ_NULL. +mp_obj_t mp_module_get_loaded_or_builtin(qstr module_name) { + // First try loaded modules. + mp_map_elem_t *elem = mp_map_lookup(&MP_STATE_VM(mp_loaded_modules_dict).map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP); - if (el == NULL) { - // module not found, look for builtin module names - el = mp_map_lookup((mp_map_t *)&mp_builtin_module_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP); - if (el == NULL) { + if (!elem) { + #if MICROPY_MODULE_WEAK_LINKS + return mp_module_get_builtin(module_name); + #else + // Otherwise try builtin. + elem = mp_map_lookup((mp_map_t *)&mp_builtin_module_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP); + if (!elem) { return MP_OBJ_NULL; } - mp_module_call_init(module_name, el->value); + + #if MICROPY_MODULE_BUILTIN_INIT + // If found, it's a newly loaded built-in, so init it. + mp_module_call_init(MP_OBJ_NEW_QSTR(module_name), elem->value); + #endif + #endif } - // module found, return it - return el->value; -} - -void mp_module_register(qstr qst, mp_obj_t module) { - mp_map_t *mp_loaded_modules_map = &MP_STATE_VM(mp_loaded_modules_dict).map; - mp_map_lookup(mp_loaded_modules_map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = module; + return elem->value; } #if MICROPY_MODULE_WEAK_LINKS -// Search for u"foo" in built-in modules, return MP_OBJ_NULL if not found -mp_obj_t mp_module_search_umodule(const char *module_str) { - for (size_t i = 0; i < MP_ARRAY_SIZE(mp_builtin_module_table); ++i) { - const mp_map_elem_t *entry = (const mp_map_elem_t *)&mp_builtin_module_table[i]; - const char *key = qstr_str(MP_OBJ_QSTR_VALUE(entry->key)); - if (key[0] == 'u' && strcmp(&key[1], module_str) == 0) { - return (mp_obj_t)entry->value; - } - +// Tries to find a loaded module, otherwise attempts to load a builtin, otherwise MP_OBJ_NULL. +mp_obj_t mp_module_get_builtin(qstr module_name) { + // Try builtin. + mp_map_elem_t *elem = mp_map_lookup((mp_map_t *)&mp_builtin_module_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP); + if (!elem) { + return MP_OBJ_NULL; } - return MP_OBJ_NULL; + + #if MICROPY_MODULE_BUILTIN_INIT + // If found, it's a newly loaded built-in, so init it. + mp_module_call_init(MP_OBJ_NEW_QSTR(module_name), elem->value); + #endif + + return elem->value; } #endif #if MICROPY_MODULE_BUILTIN_INIT -void mp_module_call_init(qstr module_name, mp_obj_t module_obj) { +STATIC void mp_module_register(mp_obj_t module_name, mp_obj_t module) { + mp_map_t *mp_loaded_modules_map = &MP_STATE_VM(mp_loaded_modules_dict).map; + mp_map_lookup(mp_loaded_modules_map, module_name, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = module; +} + +STATIC void mp_module_call_init(mp_obj_t module_name, mp_obj_t module_obj) { // Look for __init__ and call it if it exists mp_obj_t dest[2]; mp_load_method_maybe(module_obj, MP_QSTR___init__, dest); diff --git a/py/objmodule.h b/py/objmodule.h index fde4fff34e..8a82d13fe5 100644 --- a/py/objmodule.h +++ b/py/objmodule.h @@ -30,18 +30,9 @@ extern const mp_map_t mp_builtin_module_map; -mp_obj_t mp_module_get(qstr module_name); -void mp_module_register(qstr qstr, mp_obj_t module); - -mp_obj_t mp_module_search_umodule(const char *module_str); - -#if MICROPY_MODULE_BUILTIN_INIT -void mp_module_call_init(qstr module_name, mp_obj_t module_obj); -#else -static inline void mp_module_call_init(qstr module_name, mp_obj_t module_obj) { - (void)module_name; - (void)module_obj; -} +mp_obj_t mp_module_get_loaded_or_builtin(qstr module_name); +#if MICROPY_MODULE_WEAK_LINKS +mp_obj_t mp_module_get_builtin(qstr module_name); #endif #endif // MICROPY_INCLUDED_PY_OBJMODULE_H From b491967bbd99470632b783ee3bf91914aa692047 Mon Sep 17 00:00:00 2001 From: IhorNehrutsa Date: Fri, 15 Oct 2021 14:04:40 -0700 Subject: [PATCH 220/335] esp32/machine_pwm: Implement duty_u16() and duty_ns() PWM methods. The methods duty_u16() and duty_ns() are implemented to match the existing docs. The duty will remain the same when the frequency is changed. Standard ESP32 as well as S2, S3 and C3 are supported. Thanks to @kdschlosser for the fix for rounding in resolution calculation. Documentation is updated and examples expanded for esp32, including the quickref and tutorial. Additional notes are added to the machine.PWM docs regarding limitations of hardware PWM. --- docs/esp32/quickref.rst | 22 +- docs/esp32/tutorial/pwm.rst | 104 +++++++-- docs/library/machine.PWM.rst | 31 +++ ports/esp32/machine_pwm.c | 426 ++++++++++++++++++++++++++--------- ports/esp32/main.c | 2 + ports/esp32/modmachine.h | 2 + ports/esp32/mpconfigport.h | 1 + 7 files changed, 449 insertions(+), 139 deletions(-) diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index 7391a4aa4b..97b6fba38d 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -218,20 +218,24 @@ range from 1Hz to 40MHz but there is a tradeoff; as the base frequency *increases* the duty resolution *decreases*. See `LED Control `_ for more details. -Currently the duty cycle has to be in the range of 0-1023. -Use the ``machine.PWM`` class:: +Use the :ref:`machine.PWM ` class:: from machine import Pin, PWM - pwm0 = PWM(Pin(0)) # create PWM object from a pin - pwm0.freq() # get current frequency (default 5kHz) - pwm0.freq(1000) # set frequency - pwm0.duty() # get current duty cycle (default 512, 50%) - pwm0.duty(200) # set duty cycle - pwm0.deinit() # turn off PWM on the pin + pwm0 = PWM(Pin(0)) # create PWM object from a pin + pwm0.freq() # get current frequency (default 5kHz) + pwm0.freq(1000) # set PWM frequency from 1Hz to 40MHz + pwm0.duty() # get current duty cycle, range 0-1023 (default 512, 50%) + pwm0.duty(256) # set duty cycle from 0 to 1023 as a ratio duty/1023, (now 25%) + pwm0.duty_u16(2**16*3//4) # set duty cycle from 0 to 65535 as a ratio duty_u16/65535, (now 75%) + pwm0.duty_u16() # get current duty cycle, range 0-65535 + pwm0.duty_ns(250_000) # set pulse width in nanoseconds from 0 to 1_000_000_000/freq, (now 25%) + pwm0.duty_ns() # get current pulse width in ns + pwm0.deinit() # turn off PWM on the pin pwm2 = PWM(Pin(2), freq=20000, duty=512) # create and configure in one go + print(pwm2) # view PWM settings ESP chips have different hardware peripherals: @@ -251,6 +255,8 @@ but only 8 different PWM frequencies are available, the remaining 8 channels mus have the same frequency. On the other hand, 16 independent PWM duty cycles are possible at the same frequency. +See more examples in the :ref:`esp32_pwm` tutorial. + ADC (analog to digital conversion) ---------------------------------- diff --git a/docs/esp32/tutorial/pwm.rst b/docs/esp32/tutorial/pwm.rst index 0c1afb213b..12d10a86b9 100644 --- a/docs/esp32/tutorial/pwm.rst +++ b/docs/esp32/tutorial/pwm.rst @@ -1,4 +1,4 @@ -.. _esp32_pwm: +.. _esp32_pwm: Pulse Width Modulation ====================== @@ -11,7 +11,7 @@ compared with the length of a single period (low plus high time). Maximum duty cycle is when the pin is high all of the time, and minimum is when it is low all of the time. -More comprehensive example with all 16 PWM channels and 8 timers:: +* More comprehensive example with all 16 PWM channels and 8 timers:: from machine import Pin, PWM try: @@ -29,21 +29,87 @@ More comprehensive example with all 16 PWM channels and 8 timers:: except: pass -Output is:: + Output is:: - PWM(pin=15, freq=100, duty=64, resolution=10, mode=0, channel=0, timer=0) - PWM(pin=2, freq=100, duty=128, resolution=10, mode=0, channel=1, timer=0) - PWM(pin=4, freq=200, duty=192, resolution=10, mode=0, channel=2, timer=1) - PWM(pin=16, freq=200, duty=256, resolution=10, mode=0, channel=3, timer=1) - PWM(pin=18, freq=300, duty=320, resolution=10, mode=0, channel=4, timer=2) - PWM(pin=19, freq=300, duty=384, resolution=10, mode=0, channel=5, timer=2) - PWM(pin=22, freq=400, duty=448, resolution=10, mode=0, channel=6, timer=3) - PWM(pin=23, freq=400, duty=512, resolution=10, mode=0, channel=7, timer=3) - PWM(pin=25, freq=500, duty=576, resolution=10, mode=1, channel=0, timer=0) - PWM(pin=26, freq=500, duty=640, resolution=10, mode=1, channel=1, timer=0) - PWM(pin=27, freq=600, duty=704, resolution=10, mode=1, channel=2, timer=1) - PWM(pin=14, freq=600, duty=768, resolution=10, mode=1, channel=3, timer=1) - PWM(pin=12, freq=700, duty=832, resolution=10, mode=1, channel=4, timer=2) - PWM(pin=13, freq=700, duty=896, resolution=10, mode=1, channel=5, timer=2) - PWM(pin=32, freq=800, duty=960, resolution=10, mode=1, channel=6, timer=3) - PWM(pin=33, freq=800, duty=1023, resolution=10, mode=1, channel=7, timer=3) + PWM(Pin(15), freq=100, duty=64, resolution=10, mode=0, channel=0, timer=0) + PWM(Pin(2), freq=100, duty=128, resolution=10, mode=0, channel=1, timer=0) + PWM(Pin(4), freq=200, duty=192, resolution=10, mode=0, channel=2, timer=1) + PWM(Pin(16), freq=200, duty=256, resolution=10, mode=0, channel=3, timer=1) + PWM(Pin(18), freq=300, duty=320, resolution=10, mode=0, channel=4, timer=2) + PWM(Pin(19), freq=300, duty=384, resolution=10, mode=0, channel=5, timer=2) + PWM(Pin(22), freq=400, duty=448, resolution=10, mode=0, channel=6, timer=3) + PWM(Pin(23), freq=400, duty=512, resolution=10, mode=0, channel=7, timer=3) + PWM(Pin(25), freq=500, duty=576, resolution=10, mode=1, channel=0, timer=0) + PWM(Pin(26), freq=500, duty=640, resolution=10, mode=1, channel=1, timer=0) + PWM(Pin(27), freq=600, duty=704, resolution=10, mode=1, channel=2, timer=1) + PWM(Pin(14), freq=600, duty=768, resolution=10, mode=1, channel=3, timer=1) + PWM(Pin(12), freq=700, duty=832, resolution=10, mode=1, channel=4, timer=2) + PWM(Pin(13), freq=700, duty=896, resolution=10, mode=1, channel=5, timer=2) + PWM(Pin(32), freq=800, duty=960, resolution=10, mode=1, channel=6, timer=3) + PWM(Pin(33), freq=800, duty=1023, resolution=10, mode=1, channel=7, timer=3) + +* Example of a smooth frequency change:: + + from utime import sleep + from machine import Pin, PWM + + F_MIN = 500 + F_MAX = 1000 + + f = F_MIN + delta_f = 1 + + p = PWM(Pin(5), f) + print(p) + + while True: + p.freq(f) + + sleep(10 / F_MIN) + + f += delta_f + if f >= F_MAX or f <= F_MIN: + delta_f = -delta_f + + See PWM wave at Pin(5) with an oscilloscope. + +* Example of a smooth duty change:: + + from utime import sleep + from machine import Pin, PWM + + DUTY_MAX = 2**16 - 1 + + duty_u16 = 0 + delta_d = 16 + + p = PWM(Pin(5), 1000, duty_u16=duty_u16) + print(p) + + while True: + p.duty_u16(duty_u16) + + sleep(1 / 1000) + + duty_u16 += delta_d + if duty_u16 >= DUTY_MAX: + duty_u16 = DUTY_MAX + delta_d = -delta_d + elif duty_u16 <= 0: + duty_u16 = 0 + delta_d = -delta_d + + See PWM wave at Pin(5) with an oscilloscope. + +Note: the Pin.OUT mode does not need to be specified. The channel is initialized +to PWM mode internally once for each Pin that is passed to the PWM constructor. + +The following code is wrong:: + + pwm = PWM(Pin(5, Pin.OUT), freq=1000, duty=512) # Pin(5) in PWM mode here + pwm = PWM(Pin(5, Pin.OUT), freq=500, duty=256) # Pin(5) in OUT mode here, PWM is off + +Use this code instead:: + + pwm = PWM(Pin(5), freq=1000, duty=512) + pwm.init(freq=500, duty=256) diff --git a/docs/library/machine.PWM.rst b/docs/library/machine.PWM.rst index f2273d8b45..4c72255d81 100644 --- a/docs/library/machine.PWM.rst +++ b/docs/library/machine.PWM.rst @@ -77,3 +77,34 @@ Methods With no arguments the pulse width in nanoseconds is returned. With a single *value* argument the pulse width is set to that value. + +Limitations of PWM +------------------ + +* Not all frequencies can be generated with absolute accuracy due to + the discrete nature of the computing hardware. Typically the PWM frequency + is obtained by dividing some integer base frequency by an integer divider. + For example, if the base frequency is 80MHz and the required PWM frequency is + 300kHz the divider must be a non-integer number 80000000 / 300000 = 266.67. + After rounding the divider is set to 267 and the PWM frequency will be + 80000000 / 267 = 299625.5 Hz, not 300kHz. If the divider is set to 266 then + the PWM frequency will be 80000000 / 266 = 300751.9 Hz, but again not 300kHz. + +* The duty cycle has the same discrete nature and its absolute accuracy is not + achievable. On most hardware platforms the duty will be applied at the next + frequency period. Therefore, you should wait more than "1/frequency" before + measuring the duty. + +* The frequency and the duty cycle resolution are usually interdependent. + The higher the PWM frequency the lower the duty resolution which is available, + and vice versa. For example, a 300kHz PWM frequency can have a duty cycle + resolution of 8 bit, not 16-bit as may be expected. In this case, the lowest + 8 bits of *duty_u16* are insignificant. So:: + + pwm=PWM(Pin(13), freq=300_000, duty_u16=2**16//2) + + and:: + + pwm=PWM(Pin(13), freq=300_000, duty_u16=2**16//2 + 255) + + will generate PWM with the same 50% duty cycle. diff --git a/ports/esp32/machine_pwm.c b/ports/esp32/machine_pwm.c index 41b8dbcbfe..1cf3bc033a 100644 --- a/ports/esp32/machine_pwm.c +++ b/ports/esp32/machine_pwm.c @@ -27,6 +27,8 @@ * THE SOFTWARE. */ +#include + #include "py/runtime.h" #include "py/mphal.h" @@ -34,10 +36,11 @@ #include "esp_err.h" #define PWM_DBG(...) -// #define PWM_DBG(...) mp_printf(&mp_plat_print, __VA_ARGS__) +// #define PWM_DBG(...) mp_printf(&mp_plat_print, __VA_ARGS__); mp_printf(&mp_plat_print, "\n"); // Total number of channels #define PWM_CHANNEL_MAX (LEDC_SPEED_MODE_MAX * LEDC_CHANNEL_MAX) + typedef struct _chan_t { // Which channel has which GPIO pin assigned? // (-1 if not assigned) @@ -46,6 +49,7 @@ typedef struct _chan_t { // (-1 if not assigned) int timer_idx; } chan_t; + // List of PWM channels STATIC chan_t chans[PWM_CHANNEL_MAX]; @@ -57,6 +61,7 @@ STATIC chan_t chans[PWM_CHANNEL_MAX]; // Total number of timers #define PWM_TIMER_MAX (LEDC_SPEED_MODE_MAX * LEDC_TIMER_MAX) + // List of timer configs STATIC ledc_timer_config_t timers[PWM_TIMER_MAX]; @@ -73,6 +78,28 @@ STATIC ledc_timer_config_t timers[PWM_TIMER_MAX]; // 10-bit resolution (compatible with esp8266 PWM) #define PWRES (LEDC_TIMER_10_BIT) +// Maximum duty value on 10-bit resolution +#define MAX_DUTY_U10 ((1 << PWRES) - 1) +// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/ledc.html#supported-range-of-frequency-and-duty-resolutions +// duty() uses 10-bit resolution or less +// duty_u16() and duty_ns() use 16-bit resolution or less + +// Possible highest resolution in device +#if CONFIG_IDF_TARGET_ESP32 +#define HIGHEST_PWM_RES (LEDC_TIMER_16_BIT) // 20 bit in fact, but 16 bit is used +#else +#define HIGHEST_PWM_RES (LEDC_TIMER_14_BIT) +#endif +// Duty resolution of user interface in `duty_u16()` and `duty_u16` parameter in constructor/initializer +#define UI_RES_16_BIT (16) +// Maximum duty value on highest user interface resolution +#define UI_MAX_DUTY ((1 << UI_RES_16_BIT) - 1) +// How much to shift from the HIGHEST_PWM_RES duty resolution to the user interface duty resolution UI_RES_16_BIT +#define UI_RES_SHIFT (16 - HIGHEST_PWM_RES) // 0 for ESP32, 2 for S2, S3, C3 + +// If the PWM frequency is less than EMPIRIC_FREQ, then LEDC_REF_CLK_HZ(1 MHz) source is used, else LEDC_APB_CLK_HZ(80 MHz) source is used +#define EMPIRIC_FREQ (10) // Hz + // Config of timer upon which we run all PWM'ed GPIO pins STATIC bool pwm_inited = false; @@ -84,8 +111,17 @@ typedef struct _machine_pwm_obj_t { int mode; int channel; int timer; + int duty_x; // PWRES if duty(), HIGHEST_PWM_RES if duty_u16(), -HIGHEST_PWM_RES if duty_ns() + int duty_u10; // stored values from previous duty setters + int duty_u16; // - / - + int duty_ns; // - / - } machine_pwm_obj_t; +STATIC bool is_timer_in_use(int current_channel_idx, int timer_idx); +STATIC void set_duty_u16(machine_pwm_obj_t *self, int duty); +STATIC void set_duty_u10(machine_pwm_obj_t *self, int duty); +STATIC void set_duty_ns(machine_pwm_obj_t *self, int ns); + STATIC void pwm_init(void) { // Initial condition: no channels assigned for (int i = 0; i < PWM_CHANNEL_MAX; ++i) { @@ -96,12 +132,61 @@ STATIC void pwm_init(void) { // Prepare all timers config // Initial condition: no timers assigned for (int i = 0; i < PWM_TIMER_MAX; ++i) { - timers[i].duty_resolution = PWRES; + timers[i].duty_resolution = HIGHEST_PWM_RES; // unset timer is -1 timers[i].freq_hz = -1; timers[i].speed_mode = TIMER_IDX_TO_MODE(i); timers[i].timer_num = TIMER_IDX_TO_TIMER(i); - timers[i].clk_cfg = LEDC_AUTO_CLK; + timers[i].clk_cfg = LEDC_AUTO_CLK; // will reinstall later according to the EMPIRIC_FREQ + } +} + +// Deinit channel and timer if the timer is unused +STATIC void pwm_deinit(int channel_idx) { + // Valid channel? + if ((channel_idx >= 0) && (channel_idx < PWM_CHANNEL_MAX)) { + // Clean up timer if necessary + int timer_idx = chans[channel_idx].timer_idx; + if (timer_idx != -1) { + if (!is_timer_in_use(channel_idx, timer_idx)) { + check_esp_err(ledc_timer_rst(TIMER_IDX_TO_MODE(timer_idx), TIMER_IDX_TO_TIMER(timer_idx))); + // Flag it unused + timers[chans[channel_idx].timer_idx].freq_hz = -1; + } + } + + int pin = chans[channel_idx].pin; + if (pin != -1) { + int mode = CHANNEL_IDX_TO_MODE(channel_idx); + int channel = CHANNEL_IDX_TO_CHANNEL(channel_idx); + // Mark it unused, and tell the hardware to stop routing + check_esp_err(ledc_stop(mode, channel, 0)); + // Disable ledc signal for the pin + // gpio_matrix_out(pin, SIG_GPIO_OUT_IDX, false, false); + if (mode == LEDC_LOW_SPEED_MODE) { + gpio_matrix_out(pin, LEDC_LS_SIG_OUT0_IDX + channel, false, true); + } else { + #if LEDC_SPEED_MODE_MAX > 1 + #if CONFIG_IDF_TARGET_ESP32 + gpio_matrix_out(pin, LEDC_HS_SIG_OUT0_IDX + channel, false, true); + #else + #error Add supported CONFIG_IDF_TARGET_ESP32_xxx + #endif + #endif + } + } + chans[channel_idx].pin = -1; + chans[channel_idx].timer_idx = -1; + } +} + +// This called from Ctrl-D soft reboot +void machine_pwm_deinit_all(void) { + if (pwm_inited) { + for (int channel_idx = 0; channel_idx < PWM_CHANNEL_MAX; ++channel_idx) { + pwm_deinit(channel_idx); + } + pwm_inited = false; } } @@ -119,74 +204,169 @@ STATIC void configure_channel(machine_pwm_obj_t *self) { } } -STATIC void set_freq(int newval, ledc_timer_config_t *timer) { - // If already set, do nothing - if (newval == timer->freq_hz) { - return; - } +STATIC void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_config_t *timer) { + // Even if the timer frequency is already set, + // the set_duty_x() is required to reconfigure the channel duty anyway + if (freq != timer->freq_hz) { + PWM_DBG("set_freq(%d)", freq) - // Find the highest bit resolution for the requested frequency - if (newval <= 0) { - newval = 1; - } - unsigned int res = 0; - for (unsigned int i = LEDC_APB_CLK_HZ / newval; i > 1; i >>= 1) { - ++res; - } - if (res == 0) { - res = 1; - } else if (res > PWRES) { - // Limit resolution to PWRES to match units of our duty - res = PWRES; - } - - // Configure the new resolution and frequency - timer->duty_resolution = res; - timer->freq_hz = newval; - - // set freq - esp_err_t err = ledc_timer_config(timer); - if (err != ESP_OK) { - if (err == ESP_FAIL) { - PWM_DBG("timer timer->speed_mode %d, timer->timer_num %d, timer->clk_cfg %d, timer->freq_hz %d, timer->duty_resolution %d)", timer->speed_mode, timer->timer_num, timer->clk_cfg, timer->freq_hz, timer->duty_resolution); - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("bad frequency %d"), newval); - } else { - check_esp_err(err); + // Find the highest bit resolution for the requested frequency + unsigned int i = LEDC_APB_CLK_HZ; // 80 MHz + if (freq < EMPIRIC_FREQ) { + i = LEDC_REF_CLK_HZ; // 1 MHz } + + #if 1 + // original code + i /= freq; + #else + // See https://github.com/espressif/esp-idf/issues/7722 + unsigned int divider = i / freq; // truncated + // int divider = (i + freq / 2) / freq; // rounded + if (divider == 0) { + divider = 1; + } + float f = (float)i / divider; // actual frequency + if (f <= 1.0) { + f = 1.0; + } + i = (unsigned int)roundf((float)i / f); + #endif + + unsigned int res = 0; + for (; i > 1; i >>= 1) { + ++res; + } + if (res == 0) { + res = 1; + } else if (res > HIGHEST_PWM_RES) { + // Limit resolution to HIGHEST_PWM_RES to match units of our duty + res = HIGHEST_PWM_RES; + } + + // Configure the new resolution and frequency + timer->duty_resolution = res; + timer->freq_hz = freq; + timer->clk_cfg = LEDC_USE_APB_CLK; + if (freq < EMPIRIC_FREQ) { + timer->clk_cfg = LEDC_USE_REF_TICK; + } + + // Set frequency + esp_err_t err = ledc_timer_config(timer); + if (err != ESP_OK) { + if (err == ESP_FAIL) { + PWM_DBG(" (timer timer->speed_mode %d, timer->timer_num %d, timer->clk_cfg %d, timer->freq_hz %d, timer->duty_resolution %d) ", timer->speed_mode, timer->timer_num, timer->clk_cfg, timer->freq_hz, timer->duty_resolution); + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("unreachable frequency %d"), freq); + } else { + check_esp_err(err); + } + } + // Reset the timer if low speed + if (self->mode == LEDC_LOW_SPEED_MODE) { + check_esp_err(ledc_timer_rst(self->mode, self->timer)); + } + } + + // Save the same duty cycle when frequency or channel are changed + if (self->duty_x == HIGHEST_PWM_RES) { + set_duty_u16(self, self->duty_u16); + } else if (self->duty_x == PWRES) { + set_duty_u10(self, self->duty_u10); + } else if (self->duty_x == -HIGHEST_PWM_RES) { + set_duty_ns(self, self->duty_ns); } } -STATIC int get_duty(machine_pwm_obj_t *self) { - uint32_t duty = ledc_get_duty(self->mode, self->channel); - duty <<= PWRES - timers[TIMER_IDX(self->mode, self->timer)].duty_resolution; +// Calculate the duty parameters based on an ns value +STATIC int ns_to_duty(machine_pwm_obj_t *self, int ns) { + ledc_timer_config_t timer = timers[TIMER_IDX(self->mode, self->timer)]; + int64_t duty = ((int64_t)ns * UI_MAX_DUTY * timer.freq_hz + 500000000LL) / 1000000000LL; + if ((ns > 0) && (duty == 0)) { + duty = 1; + } else if (duty > UI_MAX_DUTY) { + duty = UI_MAX_DUTY; + } + // PWM_DBG(" ns_to_duty(UI_MAX_DUTY=%d freq_hz=%d duty=%d=%f <- ns=%d) ", UI_MAX_DUTY, timer.freq_hz, duty, (float)ns * UI_MAX_DUTY * timer.freq_hz / 1000000000.0, ns); return duty; } -STATIC void set_duty(machine_pwm_obj_t *self, int duty) { - if ((duty < 0) || (duty > (1 << PWRES) - 1)) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("duty must be between 0 and %u"), (1 << PWRES) - 1); +STATIC int duty_to_ns(machine_pwm_obj_t *self, int duty) { + ledc_timer_config_t timer = timers[TIMER_IDX(self->mode, self->timer)]; + int64_t ns = ((int64_t)duty * 1000000000LL + (int64_t)timer.freq_hz * UI_MAX_DUTY / 2) / ((int64_t)timer.freq_hz * UI_MAX_DUTY); + // PWM_DBG(" duty_to_ns(UI_MAX_DUTY=%d freq_hz=%d duty=%d -> ns=%f=%d) ", UI_MAX_DUTY, timer.freq_hz, duty, (float)duty * 1000000000.0 / ((float)timer.freq_hz * UI_MAX_DUTY), ns); + return ns; +} + +#define get_duty_raw(self) ledc_get_duty(self->mode, self->channel) + +STATIC uint32_t get_duty_u16(machine_pwm_obj_t *self) { + return ledc_get_duty(self->mode, self->channel) << (HIGHEST_PWM_RES + UI_RES_SHIFT - timers[TIMER_IDX(self->mode, self->timer)].duty_resolution); +} + +STATIC uint32_t get_duty_u10(machine_pwm_obj_t *self) { + return get_duty_u16(self) >> (HIGHEST_PWM_RES - PWRES); +} + +STATIC uint32_t get_duty_ns(machine_pwm_obj_t *self) { + return duty_to_ns(self, get_duty_u16(self)); +} + +STATIC void set_duty_u16(machine_pwm_obj_t *self, int duty) { + if ((duty < 0) || (duty > UI_MAX_DUTY)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("duty_u16 must be from 0 to %d"), UI_MAX_DUTY); + } + duty >>= HIGHEST_PWM_RES + UI_RES_SHIFT - timers[TIMER_IDX(self->mode, self->timer)].duty_resolution; + int max_duty = (1 << timers[TIMER_IDX(self->mode, self->timer)].duty_resolution) - 1; + if (duty < 0) { + duty = 0; + } else if (duty > max_duty) { + duty = max_duty; } - duty &= (1 << PWRES) - 1; - duty >>= PWRES - timers[TIMER_IDX(self->mode, self->timer)].duty_resolution; check_esp_err(ledc_set_duty(self->mode, self->channel, duty)); check_esp_err(ledc_update_duty(self->mode, self->channel)); - // check_esp_err(ledc_set_duty_and_update(self->mode, self->channel, duty, (1 << PWRES) - 1)); // thread safe function ??? + /* // Bug: Sometimes duty is not set right now. // See https://github.com/espressif/esp-idf/issues/7288 - /* - if (duty != get_duty(self)) { - PWM_DBG("\n duty_set %u %u %d %d \n", duty, get_duty(self), PWRES, timers[TIMER_IDX(self->mode, self->timer)].duty_resolution); + if (duty != get_duty_u16(self)) { + ets_delay_us(100); + if (duty != get_duty_u16(self)) { + PWM_DBG(" (set_duty_u16(%u) get_duty_u16()=%u duty_resolution=%d) ", duty, get_duty_u16(self), timers[TIMER_IDX(self->mode, self->timer)].duty_resolution); + } } */ + + self->duty_x = HIGHEST_PWM_RES; + self->duty_u16 = duty; +} + +STATIC void set_duty_u10(machine_pwm_obj_t *self, int duty) { + if ((duty < 0) || (duty > MAX_DUTY_U10)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("duty must be from 0 to %u"), MAX_DUTY_U10); + } + set_duty_u16(self, duty << (HIGHEST_PWM_RES + UI_RES_SHIFT - PWRES)); + self->duty_x = PWRES; + self->duty_u10 = duty; +} + +STATIC void set_duty_ns(machine_pwm_obj_t *self, int ns) { + if ((ns < 0) || (ns > duty_to_ns(self, UI_MAX_DUTY))) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("duty_ns must be from 0 to %d ns"), duty_to_ns(self, UI_MAX_DUTY)); + } + set_duty_u16(self, ns_to_duty(self, ns)); + self->duty_x = -HIGHEST_PWM_RES; + self->duty_ns = ns; } /******************************************************************************/ + #define SAME_FREQ_ONLY (true) #define SAME_FREQ_OR_FREE (false) #define ANY_MODE (-1) + // Return timer_idx. Use TIMER_IDX_TO_MODE(timer_idx) and TIMER_IDX_TO_TIMER(timer_idx) to get mode and timer -STATIC int find_timer(int freq, bool same_freq_only, int mode) { +STATIC int find_timer(unsigned int freq, bool same_freq_only, int mode) { int free_timer_idx_found = -1; // Find a free PWM Timer using the same freq for (int timer_idx = 0; timer_idx < PWM_TIMER_MAX; ++timer_idx) { @@ -242,22 +422,36 @@ STATIC int find_channel(int pin, int mode) { STATIC void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "PWM(pin=%u", self->pin); + mp_printf(print, "PWM(Pin(%u)", self->pin); if (self->active) { - int duty = get_duty(self); - mp_printf(print, ", freq=%u, duty=%u", ledc_get_freq(self->mode, self->timer), duty); - mp_printf(print, ", resolution=%u", timers[TIMER_IDX(self->mode, self->timer)].duty_resolution); + mp_printf(print, ", freq=%u", ledc_get_freq(self->mode, self->timer)); + + if (self->duty_x == PWRES) { + mp_printf(print, ", duty=%d", get_duty_u10(self)); + } else if (self->duty_x == -HIGHEST_PWM_RES) { + mp_printf(print, ", duty_ns=%d", get_duty_ns(self)); + } else { + mp_printf(print, ", duty_u16=%d", get_duty_u16(self)); + } + int resolution = timers[TIMER_IDX(self->mode, self->timer)].duty_resolution; + mp_printf(print, ", resolution=%d", resolution); + + mp_printf(print, ", (duty=%.2f%%, resolution=%.3f%%)", 100.0 * get_duty_raw(self) / (1 << resolution), 100.0 * 1 / (1 << resolution)); // percents + mp_printf(print, ", mode=%d, channel=%d, timer=%d", self->mode, self->channel, self->timer); } mp_printf(print, ")"); } +// This called from pwm.init() method STATIC void mp_machine_pwm_init_helper(machine_pwm_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_freq, ARG_duty }; + enum { ARG_freq, ARG_duty, ARG_duty_u16, ARG_duty_ns }; static const mp_arg_t allowed_args[] = { { MP_QSTR_freq, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_duty, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_duty, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_duty_u16, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_duty_ns, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, @@ -268,25 +462,40 @@ STATIC void mp_machine_pwm_init_helper(machine_pwm_obj_t *self, mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("out of PWM channels:%d"), PWM_CHANNEL_MAX); // in all modes } - int freq = args[ARG_freq].u_int; - if ((freq < -1) || (freq > 40000000)) { - mp_raise_ValueError(MP_ERROR_TEXT("freqency must be between 1Hz and 40MHz")); + int duty = args[ARG_duty].u_int; + int duty_u16 = args[ARG_duty_u16].u_int; + int duty_ns = args[ARG_duty_ns].u_int; + if (((duty != -1) && (duty_u16 != -1)) || ((duty != -1) && (duty_ns != -1)) || ((duty_u16 != -1) && (duty_ns != -1))) { + mp_raise_ValueError(MP_ERROR_TEXT("only one of parameters 'duty', 'duty_u16' or 'duty_ns' is allowed")); } + + int freq = args[ARG_freq].u_int; // Check if freq wasn't passed as an argument if (freq == -1) { // Check if already set, otherwise use the default freq. - // Possible case: + // It is possible in case: // pwm = PWM(pin, freq=1000, duty=256) // pwm = PWM(pin, duty=128) if (chans[channel_idx].timer_idx != -1) { freq = timers[chans[channel_idx].timer_idx].freq_hz; } - if (freq < 0) { + if (freq <= 0) { freq = PWFREQ; } } + if ((freq <= 0) || (freq > 40000000)) { + mp_raise_ValueError(MP_ERROR_TEXT("freqency must be from 1Hz to 40MHz")); + } + + int timer_idx; + int current_timer_idx = chans[channel_idx].timer_idx; + bool current_in_use = is_timer_in_use(channel_idx, current_timer_idx); + if (current_in_use) { + timer_idx = find_timer(freq, SAME_FREQ_OR_FREE, CHANNEL_IDX_TO_MODE(channel_idx)); + } else { + timer_idx = chans[channel_idx].timer_idx; + } - int timer_idx = find_timer(freq, SAME_FREQ_OR_FREE, CHANNEL_IDX_TO_MODE(channel_idx)); if (timer_idx == -1) { timer_idx = find_timer(freq, SAME_FREQ_OR_FREE, ANY_MODE); } @@ -318,23 +527,24 @@ STATIC void mp_machine_pwm_init_helper(machine_pwm_obj_t *self, self->active = true; // Set timer frequency - set_freq(freq, &timers[timer_idx]); + set_freq(self, freq, &timers[timer_idx]); // Set duty cycle? - int duty = args[ARG_duty].u_int; - if (duty != -1) { - set_duty(self, duty); - } - - // Reset the timer if low speed - if (self->mode == LEDC_LOW_SPEED_MODE) { - check_esp_err(ledc_timer_rst(self->mode, self->timer)); + if (duty_u16 != -1) { + set_duty_u16(self, duty_u16); + } else if (duty_ns != -1) { + set_duty_ns(self, duty_ns); + } else if (duty != -1) { + set_duty_u10(self, duty); + } else if (self->duty_x == 0) { + set_duty_u10(self, (1 << PWRES) / 2); // 50% } } +// This called from PWM() constructor STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + mp_arg_check_num(n_args, n_kw, 1, 2, true); gpio_num_t pin_id = machine_pin_get_id(args[0]); // create PWM object from the given pin @@ -345,6 +555,7 @@ STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, self->mode = -1; self->channel = -1; self->timer = -1; + self->duty_x = 0; // start the PWM subsystem if it's not already running if (!pwm_inited) { @@ -360,47 +571,27 @@ STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, return MP_OBJ_FROM_PTR(self); } +// This called from pwm.deinit() method STATIC void mp_machine_pwm_deinit(machine_pwm_obj_t *self) { - int chan = CHANNEL_IDX(self->mode, self->channel); - - // Valid channel? - if ((chan >= 0) && (chan < PWM_CHANNEL_MAX)) { - // Clean up timer if necessary - if (!is_timer_in_use(chan, chans[chan].timer_idx)) { - check_esp_err(ledc_timer_rst(self->mode, self->timer)); - // Flag it unused - timers[chans[chan].timer_idx].freq_hz = -1; - } - - // Mark it unused, and tell the hardware to stop routing - check_esp_err(ledc_stop(self->mode, chan, 0)); - // Disable ledc signal for the pin - // gpio_matrix_out(self->pin, SIG_GPIO_OUT_IDX, false, false); - if (self->mode == LEDC_LOW_SPEED_MODE) { - gpio_matrix_out(self->pin, LEDC_LS_SIG_OUT0_IDX + self->channel, false, true); - } else { - #if LEDC_SPEED_MODE_MAX > 1 - #if CONFIG_IDF_TARGET_ESP32 - gpio_matrix_out(self->pin, LEDC_HS_SIG_OUT0_IDX + self->channel, false, true); - #else - #error Add supported CONFIG_IDF_TARGET_ESP32_xxx - #endif - #endif - } - chans[chan].pin = -1; - chans[chan].timer_idx = -1; - self->active = false; - self->mode = -1; - self->channel = -1; - self->timer = -1; - } + int channel_idx = CHANNEL_IDX(self->mode, self->channel); + pwm_deinit(channel_idx); + self->active = false; + self->mode = -1; + self->channel = -1; + self->timer = -1; + self->duty_x = 0; } +// Set's and get's methods of PWM class + STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) { return MP_OBJ_NEW_SMALL_INT(ledc_get_freq(self->mode, self->timer)); } STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) { + if ((freq <= 0) || (freq > 40000000)) { + mp_raise_ValueError(MP_ERROR_TEXT("freqency must be from 1Hz to 40MHz")); + } if (freq == timers[TIMER_IDX(self->mode, self->timer)].freq_hz) { return; } @@ -441,19 +632,30 @@ STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) { self->mode = TIMER_IDX_TO_MODE(current_timer_idx); self->timer = TIMER_IDX_TO_TIMER(current_timer_idx); - // Set the freq - set_freq(freq, &timers[current_timer_idx]); - - // Reset the timer if low speed - if (self->mode == LEDC_LOW_SPEED_MODE) { - check_esp_err(ledc_timer_rst(self->mode, self->timer)); - } + // Set the frequency + set_freq(self, freq, &timers[current_timer_idx]); } STATIC mp_obj_t mp_machine_pwm_duty_get(machine_pwm_obj_t *self) { - return MP_OBJ_NEW_SMALL_INT(get_duty(self)); + return MP_OBJ_NEW_SMALL_INT(get_duty_u10(self)); } STATIC void mp_machine_pwm_duty_set(machine_pwm_obj_t *self, mp_int_t duty) { - set_duty(self, duty); + set_duty_u10(self, duty); +} + +STATIC mp_obj_t mp_machine_pwm_duty_get_u16(machine_pwm_obj_t *self) { + return MP_OBJ_NEW_SMALL_INT(get_duty_u16(self)); +} + +STATIC void mp_machine_pwm_duty_set_u16(machine_pwm_obj_t *self, mp_int_t duty_u16) { + set_duty_u16(self, duty_u16); +} + +STATIC mp_obj_t mp_machine_pwm_duty_get_ns(machine_pwm_obj_t *self) { + return MP_OBJ_NEW_SMALL_INT(get_duty_ns(self)); +} + +STATIC void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty_ns) { + set_duty_ns(self, duty_ns); } diff --git a/ports/esp32/main.c b/ports/esp32/main.c index c1728e3182..4920180b23 100644 --- a/ports/esp32/main.c +++ b/ports/esp32/main.c @@ -193,6 +193,8 @@ soft_reset_exit: mp_hal_stdout_tx_str("MPY: soft reboot\r\n"); // deinitialise peripherals + machine_pwm_deinit_all(); + // TODO: machine_rmt_deinit_all(); machine_pins_deinit(); machine_deinit(); usocket_events_deinit(); diff --git a/ports/esp32/modmachine.h b/ports/esp32/modmachine.h index afc2ab07f4..c773f8dbc9 100644 --- a/ports/esp32/modmachine.h +++ b/ports/esp32/modmachine.h @@ -26,6 +26,8 @@ void machine_init(void); void machine_deinit(void); void machine_pins_init(void); void machine_pins_deinit(void); +void machine_pwm_deinit_all(void); +// TODO: void machine_rmt_deinit_all(void); void machine_timer_deinit_all(void); void machine_i2s_init0(); diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 52949c5348..e49c97ab1d 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -165,6 +165,7 @@ #define MICROPY_PY_MACHINE_PWM (1) #define MICROPY_PY_MACHINE_PWM_INIT (1) #define MICROPY_PY_MACHINE_PWM_DUTY (1) +#define MICROPY_PY_MACHINE_PWM_DUTY_U16_NS (1) #define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/esp32/machine_pwm.c" #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_SOFTI2C (1) From 3770fab33449a5dadf8eb06edfae0767e75320a6 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 8 Dec 2021 16:40:08 +1100 Subject: [PATCH 221/335] all: Update Python formatting to latest Black version 21.12b0. Signed-off-by: Jim Mussared --- extmod/uasyncio/event.py | 1 - ports/stm32/make-stmconst.py | 1 - tests/extmod/utimeq1.py | 1 - tools/pydfu.py | 1 - 4 files changed, 4 deletions(-) diff --git a/extmod/uasyncio/event.py b/extmod/uasyncio/event.py index c28ad1fb31..1954c80f54 100644 --- a/extmod/uasyncio/event.py +++ b/extmod/uasyncio/event.py @@ -57,6 +57,5 @@ try: yield core._io_queue.queue_read(self) self._flag = 0 - except ImportError: pass diff --git a/ports/stm32/make-stmconst.py b/ports/stm32/make-stmconst.py index 602bdc6c19..217a801a8f 100644 --- a/ports/stm32/make-stmconst.py +++ b/ports/stm32/make-stmconst.py @@ -17,7 +17,6 @@ if platform.python_version_tuple()[0] == "2": def convert_bytes_to_str(b): return b - elif platform.python_version_tuple()[0] == "3": def convert_bytes_to_str(b): diff --git a/tests/extmod/utimeq1.py b/tests/extmod/utimeq1.py index 234d7a31dd..ddbc969afb 100644 --- a/tests/extmod/utimeq1.py +++ b/tests/extmod/utimeq1.py @@ -17,7 +17,6 @@ if DEBUG: def dprint(*v): print(*v) - else: def dprint(*v): diff --git a/tools/pydfu.py b/tools/pydfu.py index ea658d300b..f2d845a70b 100755 --- a/tools/pydfu.py +++ b/tools/pydfu.py @@ -84,7 +84,6 @@ if "length" in getargspec(usb.util.get_string).args: def get_string(dev, index): return usb.util.get_string(dev, 255, index) - else: # PyUSB 1.0.0.b2 dropped the length argument def get_string(dev, index): From 71168ec55c4059ecfe44b0be166248ce0b7935b5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 9 Dec 2021 12:38:26 +1100 Subject: [PATCH 222/335] unix/coverage: Change remaining printf to mp_printf. For consistency with all other prints in this file, so that the ordering of output is correct. Signed-off-by: Damien George --- ports/unix/coverage.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index d5b5d8dd76..6b00cdfef2 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -153,7 +153,7 @@ STATIC void pairheap_test(size_t nops, int *ops) { mp_pairheap_init_node(pairheap_lt, &node[i]); } mp_pairheap_t *heap = mp_pairheap_new(pairheap_lt); - printf("create:"); + mp_printf(&mp_plat_print, "create:"); for (size_t i = 0; i < nops; ++i) { if (ops[i] >= 0) { heap = mp_pairheap_push(pairheap_lt, heap, &node[ops[i]]); @@ -167,13 +167,13 @@ STATIC void pairheap_test(size_t nops, int *ops) { ; } } - printf("\npop all:"); + mp_printf(&mp_plat_print, "\npop all:"); while (!mp_pairheap_is_empty(pairheap_lt, heap)) { mp_printf(&mp_plat_print, " %d", mp_pairheap_peek(pairheap_lt, heap) - &node[0]); ; heap = mp_pairheap_pop(pairheap_lt, heap); } - printf("\n"); + mp_printf(&mp_plat_print, "\n"); } // function to run extra tests for things that can't be checked by scripts From efde4b2c756033715919ec80084f3399e8d16921 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 9 Dec 2021 12:52:27 +1100 Subject: [PATCH 223/335] extmod/modure: Redirect regex debug printing to mp_printf. Signed-off-by: Damien George --- extmod/modure.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/extmod/modure.c b/extmod/modure.c index 738a2b9843..36c987a80d 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -454,11 +454,16 @@ const mp_obj_module_t mp_module_ure = { // only if module is enabled by config setting. #define re1_5_fatal(x) assert(!x) + #include "lib/re1.5/compilecode.c" -#if MICROPY_PY_URE_DEBUG -#include "lib/re1.5/dumpcode.c" -#endif #include "lib/re1.5/recursiveloop.c" #include "lib/re1.5/charclass.c" +#if MICROPY_PY_URE_DEBUG +// Make sure the output print statements go to the same output as other Python output. +#define printf(...) mp_printf(&mp_plat_print, __VA_ARGS__) +#include "lib/re1.5/dumpcode.c" +#undef printf +#endif + #endif // MICROPY_PY_URE From 9ffb1ad2f83b2147cc4dc6385713aab1d4242ded Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 9 Dec 2021 12:53:09 +1100 Subject: [PATCH 224/335] unix/Makefile: Use -Og instead of -O0 for debug builds. For the coverage build this reduces the binary size to about 1/4 of its size, and seems to help gcov/lcov coverage analysis so that it doesn't miss lines. Signed-off-by: Damien George --- ports/unix/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/unix/Makefile b/ports/unix/Makefile index 60e37ade0a..f829838ab3 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -44,7 +44,7 @@ CFLAGS += $(INC) $(CWARN) -std=gnu99 -DUNIX $(CFLAGS_MOD) $(COPT) -I$(VARIANT_DI # Debugging/Optimization ifdef DEBUG -COPT ?= -O0 +COPT ?= -Og else COPT ?= -Os COPT += -DNDEBUG From 67f66795c05f729ff1ca39f1d41461807c14c824 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 5 Dec 2021 09:20:04 +1100 Subject: [PATCH 225/335] tools/mpremote: Implement seek and flush in ioctl method. Fixes issue #8058. Signed-off-by: Damien George --- tools/mpremote/mpremote/pyboardextended.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/mpremote/mpremote/pyboardextended.py b/tools/mpremote/mpremote/pyboardextended.py index ccd3098e38..70e3748ec8 100644 --- a/tools/mpremote/mpremote/pyboardextended.py +++ b/tools/mpremote/mpremote/pyboardextended.py @@ -142,7 +142,13 @@ class RemoteFile(uio.IOBase): self.close() def ioctl(self, request, arg): - if request == 4: # CLOSE + if request == 1: # FLUSH + self.flush() + elif request == 2: # SEEK + # This assumes a 32-bit bare-metal machine. + import machine + machine.mem32[arg] = self.seek(machine.mem32[arg], machine.mem32[arg + 4]) + elif request == 4: # CLOSE self.close() return 0 From 92f54fe8d9618dd5e6101ac5c5f83ffc53b1bc57 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 1 Dec 2021 19:02:22 +1100 Subject: [PATCH 226/335] stm32/boards/NUCLEO_WB55: Fix LED ordering. These were commented correctly by their colour, but in the wrong order with respect to the PCB silkscreen. Fixes issue #8054. Signed-off-by: Jim Mussared --- ports/stm32/boards/NUCLEO_WB55/mpconfigboard.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/stm32/boards/NUCLEO_WB55/mpconfigboard.h b/ports/stm32/boards/NUCLEO_WB55/mpconfigboard.h index a7473b9d6a..19b911a2ea 100644 --- a/ports/stm32/boards/NUCLEO_WB55/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_WB55/mpconfigboard.h @@ -51,9 +51,9 @@ #define MICROPY_HW_USRSW_PRESSED (0) // LEDs -#define MICROPY_HW_LED1 (pin_B1) // red +#define MICROPY_HW_LED1 (pin_B5) // blue #define MICROPY_HW_LED2 (pin_B0) // green -#define MICROPY_HW_LED3 (pin_B5) // blue +#define MICROPY_HW_LED3 (pin_B1) // red #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) From c613f5bb49bd83137c11912260c7691f4b284a90 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 9 Dec 2021 16:51:35 +1100 Subject: [PATCH 227/335] stm32/boards/LEGO_HUB_NO6: Set filesystem label as HUB_NO6. Signed-off-by: Damien George --- ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.h b/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.h index b3e061efb7..188cd67af5 100644 --- a/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.h +++ b/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.h @@ -18,6 +18,7 @@ #define MICROPY_HW_ENABLE_RNG (1) #define MICROPY_HW_ENABLE_DAC (1) #define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_FLASH_FS_LABEL "HUB_NO6" // HSE is 16MHz, CPU freq set to 100MHz, buses at maximum freq #define MICROPY_HW_CLK_PLLM (16) From 3f589e2f39aeb6734962c2eadb3da8a2ca2f65c8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 10 Dec 2021 21:26:08 +1100 Subject: [PATCH 228/335] tools/autobuild: Automatically build all esp32 boards. Any board with a board.json file will be built. ESP32-based boards will be built using the IDF at $IDF_PATH_V42, all other MCU variants (S2, S3, C3) will be built using the IDF at $IDF_PATH_V44. Signed-off-by: Damien George --- tools/autobuild/autobuild.sh | 11 ++- tools/autobuild/build-boards.sh | 96 +++++++++++++++++++++------ tools/autobuild/build-esp32-latest.sh | 54 --------------- 3 files changed, 82 insertions(+), 79 deletions(-) delete mode 100755 tools/autobuild/build-esp32-latest.sh diff --git a/tools/autobuild/autobuild.sh b/tools/autobuild/autobuild.sh index 1532c9820f..6ac97373f3 100755 --- a/tools/autobuild/autobuild.sh +++ b/tools/autobuild/autobuild.sh @@ -5,7 +5,7 @@ # Requirements: # - All toolchains must be in path (arm-none-eabi-gcc, xtensa-lx106-elf) # - IDF_PATH_V42 must be set -# - IDF_PATH_V43 must be set +# - IDF_PATH_V44 must be set # - MICROPY_AUTOBUILD_MICROPYTHON_REPO must be set to location of micropython repository # - MICROPY_AUTOBUILD_MAKE must be set to the make command to use, eg "make -j2" # @@ -18,8 +18,8 @@ if [ ! -d "$IDF_PATH_V42" ]; then exit 1 fi -if [ ! -d "$IDF_PATH_V43" ]; then - echo "must set IDF_PATH_V43" +if [ ! -d "$IDF_PATH_V44" ]; then + echo "must set IDF_PATH_V44" exit 1 fi @@ -70,9 +70,8 @@ ${AUTODIR}/build-cc3200-latest.sh ${FW_TAG} ${LOCAL_FIRMWARE} cd ../esp8266 ${AUTODIR}/build-esp8266-latest.sh ${FW_TAG} ${LOCAL_FIRMWARE} cd ../esp32 -${AUTODIR}/build-esp32-latest.sh ${IDF_PATH_V42} ${FW_TAG} ${LOCAL_FIRMWARE} -${AUTODIR}/build-esp32-latest.sh ${IDF_PATH_V43} ${FW_TAG} ${LOCAL_FIRMWARE} - +(source ${IDF_PATH_V42}/export.sh && build_esp32_boards ${FW_TAG} ${LOCAL_FIRMWARE}) +(source ${IDF_PATH_V44}/export.sh && build_esp32_boards ${FW_TAG} ${LOCAL_FIRMWARE}) cd ../mimxrt build_mimxrt_boards ${FW_TAG} ${LOCAL_FIRMWARE} cd ../rp2 diff --git a/tools/autobuild/build-boards.sh b/tools/autobuild/build-boards.sh index bb5d8d344e..4b5259b667 100755 --- a/tools/autobuild/build-boards.sh +++ b/tools/autobuild/build-boards.sh @@ -6,53 +6,111 @@ # $ source build-boards.sh # $ MICROPY_AUTOBUILD_MAKE=make build_rp2_boards -latest /tmp -function build_boards { +function build_board { # check/get parameters if [ $# -lt 4 ]; then - echo "usage: $0 " + echo "usage: $0 " return 1 fi - fw_tag=$1 - dest_dir=$2 - check_file=$3 + board_json=$1 + fw_tag=$2 + dest_dir=$3 shift shift shift + board=$(echo $board_json | awk -F '/' '{ print $2 }') + descr=$(cat $board_json | python3 -c "import json,sys; print(json.load(sys.stdin).get('id', '$board'))") + build_dir=/tmp/micropython-build-$board + + echo "building $descr $board" + $MICROPY_AUTOBUILD_MAKE BOARD=$board BUILD=$build_dir && ( + for ext in $@; do + dest=$dest_dir/$descr$fw_tag.$ext + if [ -r $build_dir/firmware.$ext ]; then + mv $build_dir/firmware.$ext $dest + else + # esp32 has micropython.elf and micropython.map + mv $build_dir/micropython.$ext $dest + fi + done + ) + rm -rf $build_dir +} + +function build_boards { + # check/get parameters + if [ $# -lt 4 ]; then + echo "usage: $0 " + return 1 + fi + + check_file=$1 + shift + # check we are in the correct directory if [ ! -r $check_file ]; then echo "must be in directory containing $check_file" return 1 fi + # build all boards that have a board.json file for board_json in $(find boards/ -name board.json | sort); do - board=$(echo $board_json | awk -F '/' '{ print $2 }') - descr=$(cat $board_json | python3 -c "import json,sys; print(json.load(sys.stdin).get('id', '$board'))") - build_dir=/tmp/micropython-build-$board + build_board $board_json $@ + done +} - echo "building $descr $board" - $MICROPY_AUTOBUILD_MAKE BOARD=$board BUILD=$build_dir && ( - for ext in $@; do - mv $build_dir/firmware.$ext $dest_dir/$descr$fw_tag.$ext - done - ) - rm -rf $build_dir +function build_esp32_boards { + # check/get parameters + if [ $# != 2 ]; then + echo "usage: $0 " + return 1 + fi + + fw_tag=$1 + dest_dir=$2 + + # check we are in the correct directory + if [ ! -r modesp32.c ]; then + echo "must be in esp32 directory" + return 1 + fi + + # build the boards, based on the IDF version + for board_json in $(find boards/ -name board.json | sort); do + mcu=$(cat $board_json | python3 -c "import json,sys; print(json.load(sys.stdin).get('mcu', 'unknown'))") + if idf.py --version | grep -q v4.2; then + if [ $mcu = esp32 ]; then + # build standard esp32-based boards with IDF v4.2 + if echo $board_json | grep -q GENERIC; then + # traditionally, GENERIC and GENERIC_SPIRAM boards used manifest_release.py + MICROPY_AUTOBUILD_MAKE="$MICROPY_AUTOBUILD_MAKE FROZEN_MANIFEST=$(pwd)/boards/manifest_release.py" build_board $board_json $fw_tag $dest_dir bin elf map + else + build_board $board_json $fw_tag $dest_dir bin elf map + fi + fi + else + if [ $mcu != esp32 ]; then + # build esp32-s2/s3/c3 based boards with IDF v4.4+ + build_board $board_json $fw_tag $dest_dir bin elf map + fi + fi done } function build_mimxrt_boards { - build_boards $1 $2 modmimxrt.c bin hex + build_boards modmimxrt.c $1 $2 bin hex } function build_rp2_boards { - build_boards $1 $2 modrp2.c uf2 + build_boards modrp2.c $1 $2 uf2 } function build_samd_boards { - build_boards $1 $2 samd_soc.c uf2 + build_boards samd_soc.c $1 $2 uf2 } function build_stm32_boards { - build_boards $1 $2 modpyb.c dfu hex + build_boards modpyb.c $1 $2 dfu hex } diff --git a/tools/autobuild/build-esp32-latest.sh b/tools/autobuild/build-esp32-latest.sh deleted file mode 100755 index e0e932e026..0000000000 --- a/tools/autobuild/build-esp32-latest.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -# -# Build esp32 port - -# for debugging -#exec &> /tmp/esp-log-$$.txt - -# function for building firmware -function do_build() { - descr=$1 - board=$2 - shift - shift - echo "building $descr $board" - build_dir=/tmp/esp32-build-$board - rm -rf $build_dir # be sure we don't have anything leftover from a previous build - make $@ BOARD=$board BUILD=$build_dir || exit 1 - mv $build_dir/firmware.bin $dest_dir/$descr$fw_tag.bin - mv $build_dir/micropython.elf $dest_dir/$descr$fw_tag.elf - mv $build_dir/micropython.map $dest_dir/$descr$fw_tag.map - rm -rf $build_dir -} - -# check/get parameters -if [ $# != 3 ]; then - echo "usage: $0 " - exit 1 -fi - -idf_path=$1 -fw_tag=$2 -dest_dir=$3 - -# check we are in the correct directory -if [ ! -r modesp32.c ]; then - echo "must be in esp32 directory" - exit 1 -fi - -source $idf_path/export.sh - -# build the boards, based on the IDF version -if idf.py --version | grep -q v4.2; then - do_build esp32 GENERIC FROZEN_MANIFEST=$(pwd)/boards/manifest_release.py - do_build esp32spiram GENERIC_SPIRAM FROZEN_MANIFEST=$(pwd)/boards/manifest_release.py - do_build tinypico UM_TINYPICO - do_build wesp32 SIL_WESP32 -else - do_build esp32c3 GENERIC_C3 - do_build esp32c3usb GENERIC_C3_USB - do_build tinys2 UM_TINYS2 - do_build featherS2 UM_FEATHERS2 - do_build featherS2neo UM_FEATHERS2NEO -fi From 10c6f03cbef1c8af687c37c7b5e04b5f1db8b6aa Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 10 Dec 2021 23:15:25 +1100 Subject: [PATCH 229/335] stm32/boards: Remove stray '+' characters at start of lines in ld files. Signed-off-by: Damien George --- ports/stm32/boards/stm32f413xg.ld | 14 +++++++------- ports/stm32/boards/stm32f413xh.ld | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/ports/stm32/boards/stm32f413xg.ld b/ports/stm32/boards/stm32f413xg.ld index 2df46f2b59..cecfcaa881 100644 --- a/ports/stm32/boards/stm32f413xg.ld +++ b/ports/stm32/boards/stm32f413xg.ld @@ -29,10 +29,10 @@ _ram_end = ORIGIN(RAM) + LENGTH(RAM); _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _sstack; -+/* Filesystem cache in RAM, and storage in flash */ -+_micropy_hw_internal_flash_storage_ram_cache_start = ORIGIN(SRAM2); -+_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(SRAM2) + LENGTH(SRAM2); -+_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); -+_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); -+_micropy_hw_internal_flash_storage2_start = ORIGIN(FLASH_FS2); -+_micropy_hw_internal_flash_storage2_end = ORIGIN(FLASH_FS2) + LENGTH(FLASH_FS2); +/* Filesystem cache in RAM, and storage in flash */ +_micropy_hw_internal_flash_storage_ram_cache_start = ORIGIN(SRAM2); +_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(SRAM2) + LENGTH(SRAM2); +_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); +_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); +_micropy_hw_internal_flash_storage2_start = ORIGIN(FLASH_FS2); +_micropy_hw_internal_flash_storage2_end = ORIGIN(FLASH_FS2) + LENGTH(FLASH_FS2); diff --git a/ports/stm32/boards/stm32f413xh.ld b/ports/stm32/boards/stm32f413xh.ld index 0512a3f056..0846b5c80f 100644 --- a/ports/stm32/boards/stm32f413xh.ld +++ b/ports/stm32/boards/stm32f413xh.ld @@ -29,10 +29,10 @@ _ram_end = ORIGIN(RAM) + LENGTH(RAM); _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _sstack; -+/* Filesystem cache in RAM, and storage in flash */ -+_micropy_hw_internal_flash_storage_ram_cache_start = ORIGIN(SRAM2); -+_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(SRAM2) + LENGTH(SRAM2); -+_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); -+_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); -+_micropy_hw_internal_flash_storage2_start = ORIGIN(FLASH_FS2); -+_micropy_hw_internal_flash_storage2_end = ORIGIN(FLASH_FS2) + LENGTH(FLASH_FS2); +/* Filesystem cache in RAM, and storage in flash */ +_micropy_hw_internal_flash_storage_ram_cache_start = ORIGIN(SRAM2); +_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(SRAM2) + LENGTH(SRAM2); +_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); +_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); +_micropy_hw_internal_flash_storage2_start = ORIGIN(FLASH_FS2); +_micropy_hw_internal_flash_storage2_end = ORIGIN(FLASH_FS2) + LENGTH(FLASH_FS2); From 5fc55999b2b454400c5efa8339239b19c802c9d2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 10 Dec 2021 23:19:00 +1100 Subject: [PATCH 230/335] stm32/boards: Remove unused MICROPY_HW_ENABLE_TIMER config. Signed-off-by: Damien George --- ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h | 1 - ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h | 1 - ports/stm32/boards/PYBD_SF2/mpconfigboard.h | 1 - ports/stm32/boards/STM32L496GDISC/mpconfigboard.h | 1 - 4 files changed, 4 deletions(-) diff --git a/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h index a0bff59961..7df86d75fd 100644 --- a/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h @@ -13,7 +13,6 @@ #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_ADC (1) #define MICROPY_HW_ENABLE_DAC (1) -#define MICROPY_HW_ENABLE_TIMER (1) #define MICROPY_HW_HAS_SWITCH (1) // For system clock, enable one source: diff --git a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h index 8b3a8f38b1..ce9de3c4dd 100644 --- a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h @@ -17,7 +17,6 @@ #define MICROPY_HW_ENABLE_ADC (1) #define MICROPY_HW_ENABLE_DAC (1) #define MICROPY_HW_ENABLE_USB (0) // requires a custom USB connector on PA11/PA12 -#define MICROPY_HW_ENABLE_TIMER (1) #define MICROPY_HW_HAS_SWITCH (0) #define MICROPY_HW_HAS_FLASH (1) diff --git a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h index 4afa037c4c..ea0abc6ea5 100644 --- a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h +++ b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h @@ -33,7 +33,6 @@ #define MICROPY_HW_HAS_FLASH (1) #define MICROPY_HW_ENABLE_RNG (1) #define MICROPY_HW_ENABLE_RTC (1) -#define MICROPY_HW_ENABLE_TIMER (1) #define MICROPY_HW_ENABLE_SERVO (1) #define MICROPY_HW_ENABLE_DAC (1) #define MICROPY_HW_ENABLE_USB (1) diff --git a/ports/stm32/boards/STM32L496GDISC/mpconfigboard.h b/ports/stm32/boards/STM32L496GDISC/mpconfigboard.h index d4d78454af..944d6ecd55 100644 --- a/ports/stm32/boards/STM32L496GDISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32L496GDISC/mpconfigboard.h @@ -4,7 +4,6 @@ #define MICROPY_HW_HAS_SWITCH (1) #define MICROPY_HW_ENABLE_RNG (1) #define MICROPY_HW_ENABLE_RTC (1) -#define MICROPY_HW_ENABLE_TIMER (1) #define MICROPY_HW_ENABLE_USB (1) // MSI is used and is 4MHz, From 0892ebe09105185a2e9bc97a7047187b4d141270 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 10 Dec 2021 23:19:20 +1100 Subject: [PATCH 231/335] stm32/boards: Enable MICROPY_HW_ENABLE_SERVO on various boards. Fixes issue #8059. Signed-off-by: Damien George --- ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h | 1 + ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h | 1 + ports/stm32/boards/NUCLEO_F412ZG/mpconfigboard.h | 1 + ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h | 1 + ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h | 1 + ports/stm32/boards/NUCLEO_F439ZI/mpconfigboard.h | 1 + ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h | 1 + ports/stm32/boards/STM32F429DISC/mpconfigboard.h | 1 + ports/stm32/boards/STM32F439/mpconfigboard.h | 1 + ports/stm32/boards/STM32F4DISC/mpconfigboard.h | 1 + ports/stm32/boards/STM32F769DISC/mpconfigboard.h | 1 + 11 files changed, 11 insertions(+) diff --git a/ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h index 6b874e298c..8dda34f4a0 100644 --- a/ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h @@ -4,6 +4,7 @@ #define MICROPY_HW_HAS_SWITCH (1) #define MICROPY_HW_HAS_FLASH (1) #define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_SERVO (1) // HSE is 8MHz, HSI is 16MHz CPU freq set to 84MHz // Default source for the clock is HSI. diff --git a/ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h index e37ce889c3..a883ffb3e7 100644 --- a/ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h @@ -4,6 +4,7 @@ #define MICROPY_HW_HAS_SWITCH (1) #define MICROPY_HW_HAS_FLASH (1) #define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_SERVO (1) // HSE is 8MHz, CPU freq set to 96MHz #define MICROPY_HW_CLK_PLLM (8) diff --git a/ports/stm32/boards/NUCLEO_F412ZG/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F412ZG/mpconfigboard.h index 2a557f1350..df661985d9 100644 --- a/ports/stm32/boards/NUCLEO_F412ZG/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F412ZG/mpconfigboard.h @@ -6,6 +6,7 @@ #define MICROPY_HW_ENABLE_RNG (1) #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SERVO (1) // HSE is 8MHz, CPU freq set to 96MHz #define MICROPY_HW_CLK_PLLM (8) diff --git a/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h index a357c99267..621132137a 100644 --- a/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h @@ -9,6 +9,7 @@ #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_DAC (1) #define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SERVO (1) // HSE is 8MHz, CPU freq set to 96MHz #define MICROPY_HW_CLK_PLLM (8) diff --git a/ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h index 86c02b5178..76f075546c 100644 --- a/ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h @@ -6,6 +6,7 @@ #define MICROPY_HW_ENABLE_RNG (1) #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SERVO (1) // HSE is 8MHz #define MICROPY_HW_CLK_PLLM (8) diff --git a/ports/stm32/boards/NUCLEO_F439ZI/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F439ZI/mpconfigboard.h index 7763bd73ef..4d5050b1bf 100644 --- a/ports/stm32/boards/NUCLEO_F439ZI/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F439ZI/mpconfigboard.h @@ -8,6 +8,7 @@ #define MICROPY_HW_ENABLE_RNG (1) #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SERVO (1) // HSE is 8MHz from ST-LINK, in bypass mode, run SYSCLK at 168MHz #define MICROPY_HW_CLK_USE_BYPASS (1) diff --git a/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h index 681231578e..88bfd39b41 100644 --- a/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h @@ -5,6 +5,7 @@ #define MICROPY_HW_HAS_FLASH (1) #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_SERVO (1) // HSE is 8MHz, CPU freq set to 168MHz. Using PLLQ for USB this gives a nice // 48 MHz clock for USB. To goto 180 MHz, I think that USB would need to be diff --git a/ports/stm32/boards/STM32F429DISC/mpconfigboard.h b/ports/stm32/boards/STM32F429DISC/mpconfigboard.h index cfd9ef9d08..bae6ae2552 100644 --- a/ports/stm32/boards/STM32F429DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F429DISC/mpconfigboard.h @@ -6,6 +6,7 @@ #define MICROPY_HW_ENABLE_RNG (1) #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SERVO (1) // HSE is 8MHz #define MICROPY_HW_CLK_PLLM (8) diff --git a/ports/stm32/boards/STM32F439/mpconfigboard.h b/ports/stm32/boards/STM32F439/mpconfigboard.h index 702ef265bb..917ea89481 100644 --- a/ports/stm32/boards/STM32F439/mpconfigboard.h +++ b/ports/stm32/boards/STM32F439/mpconfigboard.h @@ -6,6 +6,7 @@ #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_DAC (1) #define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SERVO (1) #define MICROPY_HW_ENABLE_SDCARD (1) // works with no SD card too // SD card detect switch diff --git a/ports/stm32/boards/STM32F4DISC/mpconfigboard.h b/ports/stm32/boards/STM32F4DISC/mpconfigboard.h index 3b291ad762..d4ecde17d8 100644 --- a/ports/stm32/boards/STM32F4DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F4DISC/mpconfigboard.h @@ -7,6 +7,7 @@ #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_DAC (1) #define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SERVO (1) // HSE is 8MHz #define MICROPY_HW_CLK_PLLM (8) diff --git a/ports/stm32/boards/STM32F769DISC/mpconfigboard.h b/ports/stm32/boards/STM32F769DISC/mpconfigboard.h index 981f17848f..8728d1b37e 100644 --- a/ports/stm32/boards/STM32F769DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F769DISC/mpconfigboard.h @@ -10,6 +10,7 @@ #define MICROPY_HW_ENABLE_RNG (1) #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SERVO (1) #define MICROPY_HW_ENABLE_SDCARD (1) #define MICROPY_BOARD_EARLY_INIT board_early_init From a0f5b3148a5c276aa1abf7b77b0964eec80cda16 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 14 Dec 2021 00:25:58 +1100 Subject: [PATCH 232/335] lib/stm32lib: Update library for L4 v1.17.0, new G4, WL, and MMC fixes. Changes in this new library version are: - Update L4 HAL to v1.17.0. - Add G4 HAL at v1.3.0. - Add WL HAL at v1.1.0. - Fix F4 UART and DMA data loss with RX hardware flow control. - Optimise USB to pass config struct by reference. - Fix bug in F4 MMC HAL_MMC_Erase function. - Fix bug setting MMC relative address in F4 and F7 HAL. Signed-off-by: Damien George --- lib/stm32lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stm32lib b/lib/stm32lib index 302c52794d..1eebcda2c9 160000 --- a/lib/stm32lib +++ b/lib/stm32lib @@ -1 +1 @@ -Subproject commit 302c52794d2f579903f4e49cbad1f5d3a7f401ad +Subproject commit 1eebcda2c95d7593c68e1c81f042d23485baab26 From 88ac5a3116d97f4b18f10b9a5855f008cffff6db Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 14 Dec 2021 00:00:35 +1100 Subject: [PATCH 233/335] stm32: Update L4 code to build with latest stm32lib and L4 HAL 1.17.0. Signed-off-by: Damien George --- ports/stm32/Makefile | 7 ++++++- ports/stm32/adc.h | 4 +++- ports/stm32/boards/stm32l4xx_hal_conf_base.h | 9 ++++++--- ports/stm32/machine_adc.c | 4 +++- ports/stm32/mphalport.h | 8 ++++++-- ports/stm32/stm32_it.c | 4 +++- 6 files changed, 27 insertions(+), 9 deletions(-) diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index c3b281650a..c5f159102e 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -432,8 +432,13 @@ endif ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32H743xx STM32H750xx STM32H7A3xx STM32H7A3xxQ STM32H7B3xx STM32H7B3xxQ)) HAL_SRC_C += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_, hal_fdcan.c) else -ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 f4 f7 h7 l4)) +ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 f4 f7 h7)) HAL_SRC_C += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_, hal_can.c) +else +ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),l4)) +HAL_SRC_C += $(addprefix $(HAL_DIR)/Src/Legacy/stm32$(MCU_SERIES)xx_, hal_can.c) +$(BUILD)/$(HAL_DIR)/Src/Legacy/stm32$(MCU_SERIES)xx_hal_can.o: CFLAGS += -Wno-error=cpp +endif endif endif diff --git a/ports/stm32/adc.h b/ports/stm32/adc.h index 5821eb9d67..9101b9db83 100644 --- a/ports/stm32/adc.h +++ b/ports/stm32/adc.h @@ -44,7 +44,7 @@ static inline void adc_deselect_vbat(ADC_TypeDef *adc, uint32_t channel) { #if defined(STM32F0) || defined(STM32WB) adc_common = ADC1_COMMON; - #elif defined(STM32F4) || defined(STM32L4) + #elif defined(STM32F4) adc_common = ADC_COMMON_REGISTER(0); #elif defined(STM32F7) adc_common = ADC123_COMMON; @@ -52,6 +52,8 @@ static inline void adc_deselect_vbat(ADC_TypeDef *adc, uint32_t channel) { adc_common = ADC12_COMMON; #elif defined(STM32H7) adc_common = adc == ADC3 ? ADC3_COMMON : ADC12_COMMON; + #elif defined(STM32L4) + adc_common = __LL_ADC_COMMON_INSTANCE(0); #endif adc_common->CCR &= ~LL_ADC_PATH_INTERNAL_VBAT; diff --git a/ports/stm32/boards/stm32l4xx_hal_conf_base.h b/ports/stm32/boards/stm32l4xx_hal_conf_base.h index 4f3a78d509..ce35dee28c 100644 --- a/ports/stm32/boards/stm32l4xx_hal_conf_base.h +++ b/ports/stm32/boards/stm32l4xx_hal_conf_base.h @@ -26,10 +26,13 @@ #ifndef MICROPY_INCLUDED_STM32L4XX_HAL_CONF_BASE_H #define MICROPY_INCLUDED_STM32L4XX_HAL_CONF_BASE_H +// Needs to be defined before ll_usb.h is included +#define HAL_PCD_MODULE_ENABLED + // Include various HAL modules for convenience #include "stm32l4xx_hal_dma.h" #include "stm32l4xx_hal_adc.h" -#include "stm32l4xx_hal_can.h" +#include "Legacy/stm32l4xx_hal_can_legacy.h" #include "stm32l4xx_hal_cortex.h" #include "stm32l4xx_hal_crc.h" #include "stm32l4xx_hal_dac.h" @@ -54,11 +57,12 @@ #include "stm32l4xx_ll_lpuart.h" #include "stm32l4xx_ll_rtc.h" #include "stm32l4xx_ll_usart.h" +#include "stm32l4xx_ll_usb.h" // Enable various HAL modules #define HAL_MODULE_ENABLED #define HAL_ADC_MODULE_ENABLED -#define HAL_CAN_MODULE_ENABLED +#define HAL_CAN_LEGACY_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED #define HAL_CRC_MODULE_ENABLED #define HAL_DAC_MODULE_ENABLED @@ -70,7 +74,6 @@ #define HAL_HCD_MODULE_ENABLED #define HAL_I2C_MODULE_ENABLED #define HAL_IWDG_MODULE_ENABLED -#define HAL_PCD_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED #define HAL_RTC_MODULE_ENABLED diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c index a114a9ad1a..8480bff53e 100644 --- a/ports/stm32/machine_adc.c +++ b/ports/stm32/machine_adc.c @@ -34,10 +34,12 @@ #define ADC_V2 (0) #endif -#if defined(STM32F4) || defined(STM32L4) +#if defined(STM32F4) #define ADCx_COMMON ADC_COMMON_REGISTER(0) #elif defined(STM32F7) #define ADCx_COMMON ADC123_COMMON +#elif defined(STM32L4) +#define ADCx_COMMON __LL_ADC_COMMON_INSTANCE(0) #endif #if defined(STM32F0) || defined(STM32L0) diff --git a/ports/stm32/mphalport.h b/ports/stm32/mphalport.h index 450e7098a6..6cfa9b9270 100644 --- a/ports/stm32/mphalport.h +++ b/ports/stm32/mphalport.h @@ -2,21 +2,25 @@ #include STM32_HAL_H #include "pin.h" -// F0-1.9.0+F4-1.16.0+F7-1.7.0+H7-1.6.0+L0-1.11.2+L4-1.8.1+WB-1.10.0 +// F0-1.9.0+F4-1.16.0+F7-1.7.0+G4-1.3.0+H7-1.6.0+L0-1.11.2+L4-1.17.0+WB-1.10.0+WL-1.1.0 #if defined(STM32F0) #define MICROPY_PLATFORM_VERSION "HAL1.9.0" #elif defined(STM32F4) #define MICROPY_PLATFORM_VERSION "HAL1.16.0" #elif defined(STM32F7) #define MICROPY_PLATFORM_VERSION "HAL1.7.0" +#elif defined(STM32G4) +#define MICROPY_PLATFORM_VERSION "HAL1.3.0" #elif defined(STM32H7) #define MICROPY_PLATFORM_VERSION "HAL1.6.0" #elif defined(STM32L0) #define MICROPY_PLATFORM_VERSION "HAL1.11.2" #elif defined(STM32L4) -#define MICROPY_PLATFORM_VERSION "HAL1.8.1" +#define MICROPY_PLATFORM_VERSION "HAL1.17.0" #elif defined(STM32WB) #define MICROPY_PLATFORM_VERSION "HAL1.10.0" +#elif defined(STM32WL) +#define MICROPY_PLATFORM_VERSION "HAL1.1.0" #endif extern const unsigned char mp_hal_status_to_errno_table[4]; diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c index ed97c4fe0b..fe9b606225 100644 --- a/ports/stm32/stm32_it.c +++ b/ports/stm32/stm32_it.c @@ -395,7 +395,9 @@ void OTG_FS_WKUP_IRQHandler(void) { OTG_CMD_WKUP_Handler(&pcd_fs_handle); - #if !defined(STM32H7) + #if defined(STM32L4) + EXTI->PR1 = USB_OTG_FS_WAKEUP_EXTI_LINE; + #elif !defined(STM32H7) /* Clear EXTI pending Bit*/ __HAL_USB_FS_EXTI_CLEAR_FLAG(); #endif From 9a1ab2286ded9a8d83f4fef3b2eaa5e857dbded0 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 14 Dec 2021 00:03:08 +1100 Subject: [PATCH 234/335] stm32/main: Call sdcard_init when only MICROPY_HW_ENABLE_MMCARD enabled. Otherwise, if MMCARD is enabled and not SDCARD, then the GPIO will not be configured for SDIO. Signed-off-by: Damien George --- ports/stm32/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 974602cb05..7a7f80467b 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -419,7 +419,7 @@ void stm32_main(uint32_t reset_mode) { #if MICROPY_PY_PYB_LEGACY && MICROPY_HW_ENABLE_HW_I2C i2c_init0(); #endif - #if MICROPY_HW_ENABLE_SDCARD + #if MICROPY_HW_ENABLE_SDCARD || MICROPY_HW_ENABLE_MMCARD sdcard_init(); #endif #if MICROPY_HW_ENABLE_STORAGE From b26704aac5dbeffe54c575c29a786879e439e72a Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 14 Dec 2021 00:04:57 +1100 Subject: [PATCH 235/335] stm32/sdcard: Support 8-bit wide SDIO bus. Signed-off-by: Damien George --- ports/stm32/sdcard.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/ports/stm32/sdcard.c b/ports/stm32/sdcard.c index ea69e7285b..4e461749ac 100644 --- a/ports/stm32/sdcard.c +++ b/ports/stm32/sdcard.c @@ -60,6 +60,10 @@ #define STATIC_AF_SDCARD_D1 STATIC_AF_SDMMC2_D1 #define STATIC_AF_SDCARD_D2 STATIC_AF_SDMMC2_D2 #define STATIC_AF_SDCARD_D3 STATIC_AF_SDMMC2_D3 +#define STATIC_AF_SDCARD_D4 STATIC_AF_SDMMC2_D4 +#define STATIC_AF_SDCARD_D5 STATIC_AF_SDMMC2_D5 +#define STATIC_AF_SDCARD_D6 STATIC_AF_SDMMC2_D6 +#define STATIC_AF_SDCARD_D7 STATIC_AF_SDMMC2_D7 #else #define SDIO SDMMC1 #define SDMMC_IRQHandler SDMMC1_IRQHandler @@ -75,6 +79,10 @@ #define STATIC_AF_SDCARD_D1 STATIC_AF_SDMMC1_D1 #define STATIC_AF_SDCARD_D2 STATIC_AF_SDMMC1_D2 #define STATIC_AF_SDCARD_D3 STATIC_AF_SDMMC1_D3 +#define STATIC_AF_SDCARD_D4 STATIC_AF_SDMMC1_D4 +#define STATIC_AF_SDCARD_D5 STATIC_AF_SDMMC1_D5 +#define STATIC_AF_SDCARD_D6 STATIC_AF_SDMMC1_D6 +#define STATIC_AF_SDCARD_D7 STATIC_AF_SDMMC1_D7 #endif // The F7 & L4 series calls the peripheral SDMMC rather than SDIO, so provide some @@ -120,6 +128,10 @@ #define STATIC_AF_SDCARD_D1 STATIC_AF_SDIO_D1 #define STATIC_AF_SDCARD_D2 STATIC_AF_SDIO_D2 #define STATIC_AF_SDCARD_D3 STATIC_AF_SDIO_D3 +#define STATIC_AF_SDCARD_D4 STATIC_AF_SDIO_D4 +#define STATIC_AF_SDCARD_D5 STATIC_AF_SDIO_D5 +#define STATIC_AF_SDCARD_D6 STATIC_AF_SDIO_D6 +#define STATIC_AF_SDCARD_D7 STATIC_AF_SDIO_D7 #endif @@ -133,6 +145,13 @@ #define MICROPY_HW_SDCARD_CMD (pin_D2) #endif +// Define a constant to select the bus width. +#if MICROPY_HW_SDCARD_BUS_WIDTH == 4 +#define SDIO_BUS_WIDE_VALUE SDIO_BUS_WIDE_4B +#elif MICROPY_HW_SDCARD_BUS_WIDTH == 8 +#define SDIO_BUS_WIDE_VALUE SDIO_BUS_WIDE_8B +#endif + #define PYB_SDMMC_FLAG_SD (0x01) #define PYB_SDMMC_FLAG_MMC (0x02) #define PYB_SDMMC_FLAG_ACTIVE (0x04) @@ -162,10 +181,16 @@ void sdcard_init(void) { mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_CK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_CK); mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_CMD, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_CMD); mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_D0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_D0); - #if MICROPY_HW_SDCARD_BUS_WIDTH == 4 + #if MICROPY_HW_SDCARD_BUS_WIDTH >= 4 mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_D1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_D1); mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_D2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_D2); mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_D3, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_D3); + #if MICROPY_HW_SDCARD_BUS_WIDTH == 8 + mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_D4, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_D4); + mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_D5, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_D5); + mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_D6, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_D6); + mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_D7, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_D7); + #endif #endif // configure the SD card detect pin @@ -252,9 +277,9 @@ STATIC HAL_StatusTypeDef sdmmc_init_sd(void) { mp_hal_delay_ms(50); } - #if MICROPY_HW_SDCARD_BUS_WIDTH == 4 - // configure the SD bus width for 4-bit wide operation - status = HAL_SD_ConfigWideBusOperation(&sdmmc_handle.sd, SDIO_BUS_WIDE_4B); + #if MICROPY_HW_SDCARD_BUS_WIDTH >= 4 + // configure the SD bus width for 4/8-bit wide operation + status = HAL_SD_ConfigWideBusOperation(&sdmmc_handle.sd, SDIO_BUS_WIDE_VALUE); if (status != HAL_OK) { HAL_SD_DeInit(&sdmmc_handle.sd); return status; @@ -287,12 +312,12 @@ STATIC HAL_StatusTypeDef sdmmc_init_mmc(void) { // As this is an eMMC card, overwrite LogBlockNbr with actual value sdmmc_handle.mmc.MmcCard.LogBlockNbr = 7469056 + 2048; - #if MICROPY_HW_SDCARD_BUS_WIDTH == 4 - // Configure the SDIO bus width for 4-bit wide operation + #if MICROPY_HW_SDCARD_BUS_WIDTH >= 4 + // Configure the SDIO bus width for 4/8-bit wide operation #ifdef STM32F7 sdmmc_handle.mmc.Init.ClockBypass = SDIO_CLOCK_BYPASS_ENABLE; #endif - status = HAL_MMC_ConfigWideBusOperation(&sdmmc_handle.mmc, SDIO_BUS_WIDE_4B); + status = HAL_MMC_ConfigWideBusOperation(&sdmmc_handle.mmc, SDIO_BUS_WIDE_VALUE); if (status != HAL_OK) { HAL_MMC_DeInit(&sdmmc_handle.mmc); return status; From 6995cf03dda98f490ab95ff90bf395a5667067d6 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 14 Dec 2021 00:07:34 +1100 Subject: [PATCH 236/335] stm32/sdcard: Add config option to force MM card capacity. The current ST HAL does not support reading the extended CSD so cannot correctly detect the capacity of high-capacity cards. As a workaround, the capacity can be forced via the MICROPY_HW_MMCARD_LOG_BLOCK_NBR config option. Signed-off-by: Damien George --- ports/stm32/boards/PYBD_SF2/mpconfigboard.h | 3 +++ ports/stm32/sdcard.c | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h index ea0abc6ea5..9ac789a83b 100644 --- a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h +++ b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h @@ -181,6 +181,9 @@ extern struct _spi_bdev_t spi_bdev2; #define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) #define MICROPY_HW_SDCARD_MOUNT_AT_BOOT (0) +// MM card: the size is hard-coded to support the WBUS-EMMC add-on +#define MICROPY_HW_MMCARD_LOG_BLOCK_NBR (7469056 + 2048) + // USB config #define MICROPY_HW_USB_FS (1) #define MICROPY_HW_USB_HS (1) diff --git a/ports/stm32/sdcard.c b/ports/stm32/sdcard.c index 4e461749ac..cb773f29db 100644 --- a/ports/stm32/sdcard.c +++ b/ports/stm32/sdcard.c @@ -309,8 +309,12 @@ STATIC HAL_StatusTypeDef sdmmc_init_mmc(void) { return status; } - // As this is an eMMC card, overwrite LogBlockNbr with actual value - sdmmc_handle.mmc.MmcCard.LogBlockNbr = 7469056 + 2048; + #ifdef MICROPY_HW_MMCARD_LOG_BLOCK_NBR + // A board can override the number of logical blocks (card capacity) if needed. + // This is needed when a card is high capacity because the extended CSD command + // is not supported by the current version of the HAL. + sdmmc_handle.mmc.MmcCard.LogBlockNbr = MICROPY_HW_MMCARD_LOG_BLOCK_NBR; + #endif #if MICROPY_HW_SDCARD_BUS_WIDTH >= 4 // Configure the SDIO bus width for 4/8-bit wide operation From 5adb1fa40e95d938a713a3ed9a3b80615edf90fa Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 10 Dec 2021 23:28:46 +1100 Subject: [PATCH 237/335] esp32,esp8266: Extract qstr from object when comparing keys in config(). Following on from a previous fix for the same problem made in 3a431fba50c96cc47d8273a6934e200993197b14. Fixes issue #8052. Signed-off-by: Damien George --- ports/esp32/network_lan.c | 9 ++++---- ports/esp32/network_wlan.c | 42 +++++++++++++++++--------------------- ports/esp8266/modnetwork.c | 18 ++++++++-------- 3 files changed, 31 insertions(+), 38 deletions(-) diff --git a/ports/esp32/network_lan.c b/ports/esp32/network_lan.c index 34e5cba258..f302d70fec 100644 --- a/ports/esp32/network_lan.c +++ b/ports/esp32/network_lan.c @@ -249,14 +249,13 @@ STATIC mp_obj_t lan_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs mp_raise_TypeError(MP_ERROR_TEXT("either pos or kw args are allowed")); } lan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); - #define QS(x) (uintptr_t)MP_OBJ_NEW_QSTR(x) if (kwargs->used != 0) { for (size_t i = 0; i < kwargs->alloc; i++) { if (mp_map_slot_is_filled(kwargs, i)) { - switch ((uintptr_t)kwargs->table[i].key) { - case QS(MP_QSTR_mac): { + switch (mp_obj_str_get_qstr(kwargs->table[i].key)) { + case MP_QSTR_mac: { mp_buffer_info_t bufinfo; mp_get_buffer_raise(kwargs->table[i].value, &bufinfo, MP_BUFFER_READ); if (bufinfo.len != 6) { @@ -279,8 +278,8 @@ STATIC mp_obj_t lan_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs mp_obj_t val = mp_const_none; - switch ((uintptr_t)args[1]) { - case QS(MP_QSTR_mac): { + switch (mp_obj_str_get_qstr(args[1])) { + case MP_QSTR_mac: { uint8_t mac[6]; esp_eth_ioctl(self->eth_handle, ETH_CMD_G_MAC_ADDR, mac); return mp_obj_new_bytes(mac, sizeof(mac)); diff --git a/ports/esp32/network_wlan.c b/ports/esp32/network_wlan.c index 3af7225440..8702ca7704 100644 --- a/ports/esp32/network_wlan.c +++ b/ports/esp32/network_wlan.c @@ -391,8 +391,6 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_ esp_exceptions(esp_wifi_get_config(self->if_id, &cfg)); } - #define QS(x) (uintptr_t)MP_OBJ_NEW_QSTR(x) - if (kwargs->used != 0) { if (!is_wifi) { goto unknown; @@ -402,8 +400,8 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_ if (mp_map_slot_is_filled(kwargs, i)) { int req_if = -1; - switch ((uintptr_t)kwargs->table[i].key) { - case QS(MP_QSTR_mac): { + switch (mp_obj_str_get_qstr(kwargs->table[i].key)) { + case MP_QSTR_mac: { mp_buffer_info_t bufinfo; mp_get_buffer_raise(kwargs->table[i].value, &bufinfo, MP_BUFFER_READ); if (bufinfo.len != 6) { @@ -412,7 +410,7 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_ esp_exceptions(esp_wifi_set_mac(self->if_id, bufinfo.buf)); break; } - case QS(MP_QSTR_essid): { + case MP_QSTR_essid: { req_if = WIFI_IF_AP; size_t len; const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len); @@ -421,17 +419,17 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_ cfg.ap.ssid_len = len; break; } - case QS(MP_QSTR_hidden): { + case MP_QSTR_hidden: { req_if = WIFI_IF_AP; cfg.ap.ssid_hidden = mp_obj_is_true(kwargs->table[i].value); break; } - case QS(MP_QSTR_authmode): { + case MP_QSTR_authmode: { req_if = WIFI_IF_AP; cfg.ap.authmode = mp_obj_get_int(kwargs->table[i].value); break; } - case QS(MP_QSTR_password): { + case MP_QSTR_password: { req_if = WIFI_IF_AP; size_t len; const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len); @@ -440,22 +438,22 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_ cfg.ap.password[len] = 0; break; } - case QS(MP_QSTR_channel): { + case MP_QSTR_channel: { req_if = WIFI_IF_AP; cfg.ap.channel = mp_obj_get_int(kwargs->table[i].value); break; } - case QS(MP_QSTR_dhcp_hostname): { + case MP_QSTR_dhcp_hostname: { const char *s = mp_obj_str_get_str(kwargs->table[i].value); esp_exceptions(tcpip_adapter_set_hostname(self->if_id, s)); break; } - case QS(MP_QSTR_max_clients): { + case MP_QSTR_max_clients: { req_if = WIFI_IF_AP; cfg.ap.max_connection = mp_obj_get_int(kwargs->table[i].value); break; } - case QS(MP_QSTR_reconnects): { + case MP_QSTR_reconnects: { int reconnects = mp_obj_get_int(kwargs->table[i].value); req_if = WIFI_IF_STA; // parameter reconnects == -1 means to retry forever. @@ -488,8 +486,8 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_ int req_if = -1; mp_obj_t val = mp_const_none; - switch ((uintptr_t)args[1]) { - case QS(MP_QSTR_mac): { + switch (mp_obj_str_get_qstr(args[1])) { + case MP_QSTR_mac: { uint8_t mac[6]; switch (self->if_id) { case WIFI_IF_AP: // fallthrough intentional @@ -500,7 +498,7 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_ goto unknown; } } - case QS(MP_QSTR_essid): + case MP_QSTR_essid: switch (self->if_id) { case WIFI_IF_STA: val = mp_obj_new_str((char *)cfg.sta.ssid, strlen((char *)cfg.sta.ssid)); @@ -512,29 +510,29 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_ req_if = WIFI_IF_AP; } break; - case QS(MP_QSTR_hidden): + case MP_QSTR_hidden: req_if = WIFI_IF_AP; val = mp_obj_new_bool(cfg.ap.ssid_hidden); break; - case QS(MP_QSTR_authmode): + case MP_QSTR_authmode: req_if = WIFI_IF_AP; val = MP_OBJ_NEW_SMALL_INT(cfg.ap.authmode); break; - case QS(MP_QSTR_channel): + case MP_QSTR_channel: req_if = WIFI_IF_AP; val = MP_OBJ_NEW_SMALL_INT(cfg.ap.channel); break; - case QS(MP_QSTR_dhcp_hostname): { + case MP_QSTR_dhcp_hostname: { const char *s; esp_exceptions(tcpip_adapter_get_hostname(self->if_id, &s)); val = mp_obj_new_str(s, strlen(s)); break; } - case QS(MP_QSTR_max_clients): { + case MP_QSTR_max_clients: { val = MP_OBJ_NEW_SMALL_INT(cfg.ap.max_connection); break; } - case QS(MP_QSTR_reconnects): + case MP_QSTR_reconnects: req_if = WIFI_IF_STA; int rec = conf_wifi_sta_reconnects - 1; val = MP_OBJ_NEW_SMALL_INT(rec); @@ -543,8 +541,6 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_ goto unknown; } -#undef QS - // We post-check interface requirements to save on code size if (req_if >= 0) { require_if(args[0], req_if); diff --git a/ports/esp8266/modnetwork.c b/ports/esp8266/modnetwork.c index f0cd83aeec..6988e09bd1 100644 --- a/ports/esp8266/modnetwork.c +++ b/ports/esp8266/modnetwork.c @@ -351,9 +351,8 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs for (mp_uint_t i = 0; i < kwargs->alloc; i++) { if (mp_map_slot_is_filled(kwargs, i)) { - #define QS(x) (uintptr_t)MP_OBJ_NEW_QSTR(x) - switch ((uintptr_t)kwargs->table[i].key) { - case QS(MP_QSTR_mac): { + switch (mp_obj_str_get_qstr(kwargs->table[i].key)) { + case MP_QSTR_mac: { mp_buffer_info_t bufinfo; mp_get_buffer_raise(kwargs->table[i].value, &bufinfo, MP_BUFFER_READ); if (bufinfo.len != 6) { @@ -362,7 +361,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs wifi_set_macaddr(self->if_id, bufinfo.buf); break; } - case QS(MP_QSTR_essid): { + case MP_QSTR_essid: { req_if = SOFTAP_IF; size_t len; const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len); @@ -371,17 +370,17 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs cfg.ap.ssid_len = len; break; } - case QS(MP_QSTR_hidden): { + case MP_QSTR_hidden: { req_if = SOFTAP_IF; cfg.ap.ssid_hidden = mp_obj_is_true(kwargs->table[i].value); break; } - case QS(MP_QSTR_authmode): { + case MP_QSTR_authmode: { req_if = SOFTAP_IF; cfg.ap.authmode = mp_obj_get_int(kwargs->table[i].value); break; } - case QS(MP_QSTR_password): { + case MP_QSTR_password: { req_if = SOFTAP_IF; size_t len; const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len); @@ -390,12 +389,12 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs cfg.ap.password[len] = 0; break; } - case QS(MP_QSTR_channel): { + case MP_QSTR_channel: { req_if = SOFTAP_IF; cfg.ap.channel = mp_obj_get_int(kwargs->table[i].value); break; } - case QS(MP_QSTR_dhcp_hostname): { + case MP_QSTR_dhcp_hostname: { req_if = STATION_IF; if (self->if_id == STATION_IF) { const char *s = mp_obj_str_get_str(kwargs->table[i].value); @@ -406,7 +405,6 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs default: goto unknown; } -#undef QS } } From f21c5655835ba3703deeb1f0fa375d6a706b03cc Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 10 Dec 2021 01:27:45 +0200 Subject: [PATCH 238/335] rp2/machine_uart: Handle and clear UART RX timeout IRQ. The pico-sdk 1.3.0 update in 97a7cc243b028833bdcb8ce0bc19b2bce7545851 introduced a change that broke RP2 Bluetooth UART, and possibly UART in general, which stops working right after UART is initialized. The commit raspberrypi/pico-sdk@2622e9b enables the UART receive timeout (RTIM) IRQ, which is asserted when the receive FIFO is not empty, and no more characters are received for a period of time. This commit makes sure the RTIM IRQ is handled and cleared in uart_service_interrupt. --- ports/rp2/machine_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/rp2/machine_uart.c b/ports/rp2/machine_uart.c index a8ec149f4b..887954276e 100644 --- a/ports/rp2/machine_uart.c +++ b/ports/rp2/machine_uart.c @@ -126,7 +126,7 @@ STATIC void uart_fill_tx_fifo(machine_uart_obj_t *self) { } STATIC inline void uart_service_interrupt(machine_uart_obj_t *self) { - if (uart_get_hw(self->uart)->mis & UART_UARTMIS_RXMIS_BITS) { // rx interrupt? + if (uart_get_hw(self->uart)->mis & (UART_UARTMIS_RXMIS_BITS | UART_UARTMIS_RTMIS_BITS)) { // rx interrupt? // clear all interrupt bits but tx uart_get_hw(self->uart)->icr = UART_UARTICR_BITS & (~UART_UARTICR_TXIC_BITS); if (!self->read_lock) { From 1b7eee24eb024ee3822db341c3447423a684b84f Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Mon, 22 Nov 2021 17:13:28 +0200 Subject: [PATCH 239/335] extmod/network_ninaw10: Fix config of AP mode. * Fix missing call to connect to configure module in AP mode. * Use enum for config/connect args indices. --- extmod/network_ninaw10.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/extmod/network_ninaw10.c b/extmod/network_ninaw10.c index e256188eb3..f5f9967397 100644 --- a/extmod/network_ninaw10.c +++ b/extmod/network_ninaw10.c @@ -140,9 +140,10 @@ STATIC mp_obj_t network_ninaw10_scan(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_ninaw10_scan_obj, network_ninaw10_scan); STATIC mp_obj_t network_ninaw10_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_essid, ARG_key, ARG_security, ARG_channel }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_essid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_key, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_essid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_key, MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NINA_SEC_WPA_PSK} }, { MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, }; @@ -153,7 +154,7 @@ STATIC mp_obj_t network_ninaw10_connect(mp_uint_t n_args, const mp_obj_t *pos_ar mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); // get ssid - const char *ssid = mp_obj_str_get_str(args[0].u_obj); + const char *ssid = mp_obj_str_get_str(args[ARG_essid].u_obj); if (strlen(ssid) == 0) { mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("SSID can't be empty!")); @@ -163,9 +164,9 @@ STATIC mp_obj_t network_ninaw10_connect(mp_uint_t n_args, const mp_obj_t *pos_ar const char *key = NULL; mp_uint_t security = NINA_SEC_OPEN; - if (args[1].u_obj != mp_const_none) { - key = mp_obj_str_get_str(args[1].u_obj); - security = args[2].u_int; + if (args[ARG_key].u_obj != mp_const_none) { + key = mp_obj_str_get_str(args[ARG_key].u_obj); + security = args[ARG_security].u_int; } if (security != NINA_SEC_OPEN && strlen(key) == 0) { @@ -179,7 +180,7 @@ STATIC mp_obj_t network_ninaw10_connect(mp_uint_t n_args, const mp_obj_t *pos_ar MP_ERROR_TEXT("could not connect to ssid=%s, sec=%d, key=%s\n"), ssid, security, key); } } else { - mp_uint_t channel = args[3].u_int; + mp_uint_t channel = args[ARG_channel].u_int; if (security != NINA_SEC_OPEN && security != NINA_SEC_WEP) { mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("AP mode supports WEP security only.")); @@ -271,9 +272,11 @@ STATIC mp_obj_t network_ninaw10_config(size_t n_args, const mp_obj_t *args, mp_m mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); } } else { - // Set config value(s) - // Not supported. - mp_raise_ValueError(MP_ERROR_TEXT("setting config values is not supported")); + if (self->itf != MOD_NETWORK_AP_IF) { + mp_raise_ValueError(MP_ERROR_TEXT("AP required")); + } + // Call connect to set WiFi access point. + return network_ninaw10_connect(n_args, args, kwargs); } return mp_const_none; From bc1b0fd2c1d16745ff5c353a933a51cca6d32403 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 3 Nov 2021 15:57:48 +0100 Subject: [PATCH 240/335] mimxrt: Define UART 0 on MIMXRT boards. UART 0 is attached to the Debug USB port. The settings are 115200 Baud, 8N1. For MIMXRT1010_EVK this is identical to UART1. For the other boards, this is an additional UART. --- .../boards/MIMXRT1010_EVK/mpconfigboard.h | 9 +++++---- .../boards/MIMXRT1020_EVK/mpconfigboard.h | 17 +++++++++-------- .../boards/MIMXRT1050_EVK/mpconfigboard.h | 13 +++++++------ .../boards/MIMXRT1060_EVK/mpconfigboard.h | 13 +++++++------ .../boards/MIMXRT1064_EVK/mpconfigboard.h | 13 +++++++------ ports/mimxrt/machine_uart.c | 14 +++++++++----- 6 files changed, 44 insertions(+), 35 deletions(-) diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h index 7b2d2a8a63..9a74a1c9c8 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h @@ -9,12 +9,13 @@ #define MICROPY_HW_NUM_PIN_IRQS (2 * 32) // Define mapping logical UART # to hardware UART # -// LPUART1 on D0/D1 -> 1 -// LPUART3 on A0/D4 -> 3 -// LPUART4 on D6/D7 -> 2 +// LPUART1 on USB_DBG -> 0 +// LPUART1 on D0/D1 -> 1 +// LPUART3 on A0/D4 -> 3 +// LPUART4 on D6/D7 -> 2 #define MICROPY_HW_UART_NUM (sizeof(uart_index_table) / sizeof(uart_index_table)[0]) -#define MICROPY_HW_UART_INDEX { 0, 1, 4 } +#define MICROPY_HW_UART_INDEX { 1, 1, 4, 3 } #define IOMUX_TABLE_UART \ { IOMUXC_GPIO_10_LPUART1_TXD }, { IOMUXC_GPIO_09_LPUART1_RXD }, \ diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h index b546700e7a..5f5de5a3ed 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h @@ -10,16 +10,17 @@ #define MICROPY_HW_NUM_PIN_IRQS (3 * 32) // Define mapping logical UART # to hardware UART # -// RX/TX HW-UART Logical UART -// D3/D5 LPUART1 Not usable, Since D3 is blocked. -// D0/D1 LPUART2 -> 1 -// D6/D9 LPUART3 -> 2 -// D10/D12 LPUART5 -> 3 -// D14/D15 LPUART8 -> 4 -// A0/A1 LPUART4 -> 5 +// RX/TX HW-UART Logical UART +// DEBUG USB LPUART1 -> 0 +// D3/D5 LPUART1 Not usable, Since D3 is blocked. +// D0/D1 LPUART2 -> 1 +// D6/D9 LPUART3 -> 2 +// D10/D12 LPUART5 -> 3 +// D14/D15 LPUART8 -> 4 +// A0/A1 LPUART4 -> 5 #define MICROPY_HW_UART_NUM (sizeof(uart_index_table) / sizeof(uart_index_table)[0]) -#define MICROPY_HW_UART_INDEX { 0, 2, 3, 5, 8, 4 } +#define MICROPY_HW_UART_INDEX { 1, 2, 3, 5, 8, 4 } #define IOMUX_TABLE_UART \ { IOMUXC_GPIO_AD_B0_06_LPUART1_TX }, { IOMUXC_GPIO_AD_B0_07_LPUART1_RX }, \ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h index 3837315f7d..aa9ab8d95c 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h @@ -9,16 +9,17 @@ #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) // Define mapping logical UART # to hardware UART # -// LPUART3 on D0/D1 -> 1 -// LPUART2 on D7/D6 -> 2 -// LPUART6 on D8/D9 -> 3 -// LPUART8 on A1/A0 -> 4 +// LPUART1 on USB_DBG -> 0 +// LPUART3 on D0/D1 -> 1 +// LPUART2 on D7/D6 -> 2 +// LPUART6 on D8/D9 -> 3 +// LPUART8 on A1/A0 -> 4 #define MICROPY_HW_UART_NUM (sizeof(uart_index_table) / sizeof(uart_index_table)[0]) -#define MICROPY_HW_UART_INDEX { 0, 3, 2, 6, 8 } +#define MICROPY_HW_UART_INDEX { 1, 3, 2, 6, 8 } #define IOMUX_TABLE_UART \ - { 0 }, { 0 }, \ + { IOMUXC_GPIO_AD_B0_12_LPUART1_TX }, { IOMUXC_GPIO_AD_B0_13_LPUART1_RX }, \ { IOMUXC_GPIO_AD_B1_02_LPUART2_TX }, { IOMUXC_GPIO_AD_B1_03_LPUART2_RX }, \ { IOMUXC_GPIO_AD_B1_06_LPUART3_TX }, { IOMUXC_GPIO_AD_B1_07_LPUART3_RX }, \ { 0 }, { 0 }, \ diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h index a66fcf9ae9..b108122ffc 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h @@ -9,16 +9,17 @@ #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) // Define mapping logical UART # to hardware UART # -// LPUART3 on D0/D1 -> 1 -// LPUART2 on D7/D6 -> 2 -// LPUART6 on D8/D9 -> 3 -// LPUART8 on A1/A0 -> 4 +// LPUART1 on USB_DBG -> 0 +// LPUART3 on D0/D1 -> 1 +// LPUART2 on D7/D6 -> 2 +// LPUART6 on D8/D9 -> 3 +// LPUART8 on A1/A0 -> 4 #define MICROPY_HW_UART_NUM (sizeof(uart_index_table) / sizeof(uart_index_table)[0]) -#define MICROPY_HW_UART_INDEX { 0, 3, 2, 6, 8 } +#define MICROPY_HW_UART_INDEX { 1, 3, 2, 6, 8 } #define IOMUX_TABLE_UART \ - { 0 }, { 0 }, \ + { IOMUXC_GPIO_AD_B0_12_LPUART1_TX }, { IOMUXC_GPIO_AD_B0_13_LPUART1_RX }, \ { IOMUXC_GPIO_AD_B1_02_LPUART2_TX }, { IOMUXC_GPIO_AD_B1_03_LPUART2_RX }, \ { IOMUXC_GPIO_AD_B1_06_LPUART3_TX }, { IOMUXC_GPIO_AD_B1_07_LPUART3_RX }, \ { 0 }, { 0 }, \ diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h index 1dcdd378a2..3c724868f7 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h @@ -9,16 +9,17 @@ #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) // Define mapping logical UART # to hardware UART # -// LPUART3 on D0/D1 -> 1 -// LPUART2 on D7/D6 -> 2 -// LPUART6 on D8/D9 -> 3 -// LPUART8 on A1/A0 -> 4 +// LPUART1 on USB_DBG -> 0 +// LPUART3 on D0/D1 -> 1 +// LPUART2 on D7/D6 -> 2 +// LPUART6 on D8/D9 -> 3 +// LPUART8 on A1/A0 -> 4 #define MICROPY_HW_UART_NUM (sizeof(uart_index_table) / sizeof(uart_index_table)[0]) -#define MICROPY_HW_UART_INDEX { 0, 3, 2, 6, 8 } +#define MICROPY_HW_UART_INDEX { 1, 3, 2, 6, 8 } #define IOMUX_TABLE_UART \ - { 0 }, { 0 }, \ + { IOMUXC_GPIO_AD_B0_12_LPUART1_TX }, { IOMUXC_GPIO_AD_B0_13_LPUART1_RX }, \ { IOMUXC_GPIO_AD_B1_02_LPUART2_TX }, { IOMUXC_GPIO_AD_B1_03_LPUART2_RX }, \ { IOMUXC_GPIO_AD_B1_06_LPUART3_TX }, { IOMUXC_GPIO_AD_B1_07_LPUART3_RX }, \ { 0 }, { 0 }, \ diff --git a/ports/mimxrt/machine_uart.c b/ports/mimxrt/machine_uart.c index abdb7ed97e..9aa8a0c742 100644 --- a/ports/mimxrt/machine_uart.c +++ b/ports/mimxrt/machine_uart.c @@ -269,7 +269,7 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, // Get UART bus. int uart_id = mp_obj_get_int(args[0]); - if (uart_id < 1 || uart_id > MICROPY_HW_UART_NUM) { + if (uart_id < 0 || uart_id > MICROPY_HW_UART_NUM || uart_index_table[uart_id] == 0) { mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%d) doesn't exist"), uart_id); } @@ -286,11 +286,15 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, LPUART_GetDefaultConfig(&self->config); // Configure board-specific pin MUX based on the hardware device number. - lpuart_set_iomux(uart_hw_id); + bool uart_present = lpuart_set_iomux(uart_hw_id); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - return machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args); + if (uart_present) { + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + return machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args); + } else { + return mp_const_none; + } } // uart.init(baud, [kwargs]) From bbe25f47043e97a9539298b714be616b3815b492 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 4 Nov 2021 21:54:44 +0100 Subject: [PATCH 241/335] mimxrt: Support selection of PHY type and address. Useful for boards without a PHY interface, where that has to be attached. Like the Seed ARCH MIX board or Vision SOM. Phy drivers supported so far are: - KSZ8081 - DP83825 - LAN8720 More to come. Usage e.g.: lan = LAN(phy_type=LAN.PHY_LAN8720, phy_addr=1) The default values are those set in mpconfigboard.h. --- ports/mimxrt/eth.c | 17 +++++++----- ports/mimxrt/eth.h | 8 +++++- ports/mimxrt/mphalport.h | 1 + ports/mimxrt/network_lan.c | 57 ++++++++++++++++++++++++++++++++++---- 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/ports/mimxrt/eth.c b/ports/mimxrt/eth.c index 414e8d51f2..d14c713961 100644 --- a/ports/mimxrt/eth.c +++ b/ports/mimxrt/eth.c @@ -33,7 +33,6 @@ #if defined(MICROPY_HW_ETH_MDC) -#include "eth.h" #include "pin.h" #include "shared/netutils/netutils.h" #include "extmod/modnetwork.h" @@ -46,6 +45,7 @@ #include "hal/phy/device/phydp83825/fsl_phydp83825.h" #include "hal/phy/device/phylan8720/fsl_phylan8720.h" +#include "eth.h" #include "lwip/etharp.h" #include "lwip/dns.h" #include "lwip/dhcp.h" @@ -167,22 +167,24 @@ void eth_irq_handler(ENET_Type *base, enet_handle_t *handle, enet_event_t event, if (event == kENET_RxEvent) { do { - status = ENET_GetRxFrameSize(&g_handle, &length); + status = ENET_GetRxFrameSize(handle, &length); if (status == kStatus_Success) { // Get the data - ENET_ReadFrame(ENET, &g_handle, g_rx_frame, length); + ENET_ReadFrame(base, handle, g_rx_frame, length); eth_process_frame(self, g_rx_frame, length); } else if (status == kStatus_ENET_RxFrameError) { - ENET_ReadFrame(ENET, &g_handle, NULL, 0); + ENET_ReadFrame(base, handle, NULL, 0); } } while (status != kStatus_ENET_RxFrameEmpty); } else { - ENET_ClearInterruptStatus(ENET, kENET_TxFrameInterrupt); + ENET_ClearInterruptStatus(base, kENET_TxFrameInterrupt); } } // eth_init: Set up GPIO and the transceiver -void eth_init(eth_t *self, int mac_idx) { +void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr) { + + self->netif.num = mac_idx; // Set the interface number CLOCK_EnableClock(kCLOCK_Iomuxc); @@ -242,6 +244,8 @@ void eth_init(eth_t *self, int mac_idx) { mp_hal_get_mac(0, hw_addr); + phyHandle.ops = phy_ops; + phyConfig.phyAddr = phy_addr; phyConfig.autoNeg = true; mdioHandle.resource.base = ENET; mdioHandle.resource.csrClock_Hz = CLOCK_GetFreq(kCLOCK_IpgClk); @@ -252,7 +256,6 @@ void eth_init(eth_t *self, int mac_idx) { phy_speed_t speed = kENET_MiiSpeed100M; phy_duplex_t duplex = kENET_MiiFullDuplex; - phyConfig.phyAddr = ENET_PHY_ADDRESS; status_t status = PHY_Init(&phyHandle, &phyConfig); if (status == kStatus_Success) { diff --git a/ports/mimxrt/eth.h b/ports/mimxrt/eth.h index 56327d08ae..962b6c88cb 100644 --- a/ports/mimxrt/eth.h +++ b/ports/mimxrt/eth.h @@ -30,7 +30,7 @@ typedef struct _eth_t eth_t; extern eth_t eth_instance; -void eth_init(eth_t *self, int mac_idx); +void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr); void eth_set_trace(eth_t *self, uint32_t value); struct netif *eth_netif(eth_t *self); int eth_link_status(eth_t *self); @@ -38,4 +38,10 @@ int eth_start(eth_t *self); int eth_stop(eth_t *self); void eth_low_power_mode(eth_t *self, bool enable); +enum { + PHY_KSZ8081 = 0, + PHY_DP83825, + PHY_LAN8720, +}; + #endif // MICROPY_INCLUDED_MIMXRT_ETH_H diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index 0dc49f01a5..5210ff44a3 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -97,6 +97,7 @@ enum { MP_HAL_MAC_WLAN1, MP_HAL_MAC_BDADDR, MP_HAL_MAC_ETH0, + MP_HAL_MAC_ETH1, }; void mp_hal_generate_laa_mac(int idx, uint8_t buf[6]); diff --git a/ports/mimxrt/network_lan.c b/ports/mimxrt/network_lan.c index c0d6e41362..7b725276a1 100644 --- a/ports/mimxrt/network_lan.c +++ b/ports/mimxrt/network_lan.c @@ -27,10 +27,15 @@ #include "py/runtime.h" #include "py/mphal.h" #include "extmod/modnetwork.h" -#include "eth.h" #if defined(MICROPY_HW_ETH_MDC) +#include "fsl_phy.h" +#include "eth.h" +#include "hal/phy/device/phyksz8081/fsl_phyksz8081.h" +#include "hal/phy/device/phydp83825/fsl_phydp83825.h" +#include "hal/phy/device/phylan8720/fsl_phylan8720.h" + #include "lwip/netif.h" typedef struct _network_lan_obj_t { @@ -53,10 +58,48 @@ STATIC void network_lan_print(const mp_print_t *print, mp_obj_t self_in, mp_prin ); } -STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 0, false); - const network_lan_obj_t *self = &network_lan_eth0; - eth_init(self->eth, MP_HAL_MAC_ETH0); +STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_id, ARG_phy_type, ARG_phy_addr}; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_phy_type, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_phy_addr, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = ENET_PHY_ADDRESS} }, + }; + // Parse args. + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const phy_operations_t *phy_ops = &ENET_PHY_OPS; + + // Select PHY driver + int phy_type = args[ARG_phy_type].u_int; + if (phy_type != -1) { + if (phy_type == PHY_KSZ8081) { + phy_ops = &phyksz8081_ops; + } else if (phy_type == PHY_DP83825) { + phy_ops = &phydp83825_ops; + } else if (phy_type == PHY_LAN8720) { + phy_ops = &phylan8720_ops; + } else { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid value %d for phy"), phy_type); + } + } + int phy_addr = args[ARG_phy_addr].u_int; + + // Prepare for two ETH interfaces. + const network_lan_obj_t *self; + int mac_id = args[ARG_id].u_int; + if (mac_id == 0) { + self = &network_lan_eth0; + mac_id = MP_HAL_MAC_ETH0; + } else if (mac_id == 1) { + self = &network_lan_eth0; + mac_id = MP_HAL_MAC_ETH1; + } else { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid LAN interface %d"), mac_id); + } + + eth_init(self->eth, mac_id, phy_ops, phy_addr); // register with network module mod_network_register_nic((mp_obj_t *)self); return MP_OBJ_FROM_PTR(self); @@ -157,6 +200,10 @@ STATIC const mp_rom_map_elem_t network_lan_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_lan_ifconfig_obj) }, { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_lan_status_obj) }, { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_lan_config_obj) }, + + { MP_ROM_QSTR(MP_QSTR_PHY_KSZ8081), MP_ROM_INT(PHY_KSZ8081) }, + { MP_ROM_QSTR(MP_QSTR_PHY_DP83825), MP_ROM_INT(PHY_DP83825) }, + { MP_ROM_QSTR(MP_QSTR_PHY_LAN8720), MP_ROM_INT(PHY_LAN8720) }, }; STATIC MP_DEFINE_CONST_DICT(network_lan_locals_dict, network_lan_locals_dict_table); From ea09dccfea0503534688dd790c40d33c5399e7d8 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 9 Nov 2021 13:58:45 +0100 Subject: [PATCH 242/335] mimxrt: Re-Enable eth checksum creation by HW. The initial problem with a wrong ICMP checksum was caused by the test code setting a checksum and the HW taking that probably as the start value and ending up with 0xffff. With a checksum field of 0 set by the test code the HW creates the proper checksum. --- ports/mimxrt/eth.c | 10 +--------- ports/mimxrt/lwip_inc/lwipopts.h | 5 +---- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/ports/mimxrt/eth.c b/ports/mimxrt/eth.c index d14c713961..9c036cd056 100644 --- a/ports/mimxrt/eth.c +++ b/ports/mimxrt/eth.c @@ -285,10 +285,7 @@ void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy enet_config.miiDuplex = (enet_mii_duplex_t)duplex; enet_config.miiMode = kENET_RmiiMode; // Enable checksum generation by the ENET controller - // Note: Disabled due to problems with the checksum on ICMP requests - // Maybe caused by LWIP inserting 0xffff instead of 0x0000 - // Keep the code for now until it may be fixed. - // enet_config.txAccelerConfig = kENET_TxAccelIpCheckEnabled | kENET_TxAccelProtoCheckEnabled; + enet_config.txAccelerConfig = kENET_TxAccelIpCheckEnabled | kENET_TxAccelProtoCheckEnabled; // Set interrupt enet_config.interrupt |= ENET_TX_INTERRUPT | ENET_RX_INTERRUPT; @@ -351,11 +348,6 @@ STATIC err_t eth_netif_init(struct netif *netif) { | NETIF_CHECKSUM_CHECK_TCP | NETIF_CHECKSUM_CHECK_ICMP | NETIF_CHECKSUM_CHECK_ICMP6 - | NETIF_CHECKSUM_GEN_IP - | NETIF_CHECKSUM_GEN_UDP - | NETIF_CHECKSUM_GEN_TCP - | NETIF_CHECKSUM_GEN_ICMP - | NETIF_CHECKSUM_GEN_ICMP6 ); return ERR_OK; } diff --git a/ports/mimxrt/lwip_inc/lwipopts.h b/ports/mimxrt/lwip_inc/lwipopts.h index 42dc9fc5db..2401c05f95 100644 --- a/ports/mimxrt/lwip_inc/lwipopts.h +++ b/ports/mimxrt/lwip_inc/lwipopts.h @@ -13,11 +13,8 @@ #define MEM_ALIGNMENT 4 #define LWIP_CHKSUM_ALGORITHM 3 -// Chksum generaration by HW fails for ICMP -// Maybe caused by LWIP inserting ffff instead of 0000 // The checksum flags are set in eth.c -#define LWIP_CHECKSUM_CTRL_PER_NETIF 0 -#define LWIP_CHECKSUM_ON_COPY 0 +#define LWIP_CHECKSUM_CTRL_PER_NETIF 1 #define LWIP_ARP 1 #define LWIP_ETHERNET 1 From 5d8941ec85ba992349576957a7ef2f65b091ba7c Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 25 Nov 2021 08:39:58 +0100 Subject: [PATCH 243/335] mimxrt: Fix a tiny unnoticed bug in sdcard.c. This code line will hardly ever be compiled and executed, but since it is there, it must be correct. --- ports/mimxrt/sdcard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/mimxrt/sdcard.c b/ports/mimxrt/sdcard.c index 14a78e94a5..fd3c910835 100644 --- a/ports/mimxrt/sdcard.c +++ b/ports/mimxrt/sdcard.c @@ -1013,7 +1013,7 @@ bool sdcard_detect(mimxrt_sdcard_obj_t *card) { #if defined MICROPY_USDHC2 && USDHC2_AVAIL if (card->usdhc_inst == USDHC2) { sdcard_usdhc2_state.inserted = detect; - sdcard_usdhc2_state.initialized = detect ? sdcard_usdhc1_state.initialized : false; + sdcard_usdhc2_state.initialized = detect ? sdcard_usdhc2_state.initialized : false; } #endif From 1e9eaa7af55bb67da4aced33d527d73d8d7b7c31 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 30 Nov 2021 15:22:42 +0100 Subject: [PATCH 244/335] mimxrt: Add a driver for the DP83848 PHY device. Just another choice for the PHY interface. Added: Keyword option phy_clock=LAN.IN or LAN.OUT to define the source of the 50MHZ clock for the PHY interface. The RMII clock is not enabled if it is generated by a PYH board. Constants: LAN.IN The clock is provided by the PHY board. LAN.OUT The clock is provided by the MCU board. The default is LAN.OUT or the value set in mpconfigboard.h, which is currently set to IN only for the SEEED ARCH MIX board. Usage etc: lan = LAN(phy_type=LAN.PHY_DP83848, phy_clock=LAN.IN) --- ports/mimxrt/Makefile | 1 + ports/mimxrt/eth.c | 11 +- ports/mimxrt/eth.h | 8 +- .../phy/device/phydp83825/fsl_phydp83825.c | 12 +- .../phy/device/phydp83848/fsl_phydp83848.c | 254 ++++++++++++++++++ .../phy/device/phydp83848/fsl_phydp83848.h | 163 +++++++++++ .../phy/device/phylan8720/fsl_phylan8720.c | 8 +- ports/mimxrt/network_lan.c | 17 +- 8 files changed, 454 insertions(+), 20 deletions(-) create mode 100644 ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.c create mode 100644 ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.h diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index eeab29ddc3..574aebb4cd 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -145,6 +145,7 @@ SRC_MOD := $(filter-out %/mbedtls/library/error.c, $(SRC_MOD)) SRC_ETH_C += \ hal/phy/mdio/enet/fsl_enet_mdio.c \ hal/phy/device/phydp83825/fsl_phydp83825.c \ + hal/phy/device/phydp83848/fsl_phydp83848.c \ hal/phy/device/phyksz8081/fsl_phyksz8081.c \ hal/phy/device/phylan8720/fsl_phylan8720.c \ lib/mbedtls_errors/mp_mbedtls_errors.c \ diff --git a/ports/mimxrt/eth.c b/ports/mimxrt/eth.c index 9c036cd056..1a8210cb11 100644 --- a/ports/mimxrt/eth.c +++ b/ports/mimxrt/eth.c @@ -113,9 +113,6 @@ static const iomux_table_t iomux_table_enet[] = { }; #define IOTE (iomux_table_enet[i]) -#ifndef ENET_TX_CLK_OUTPUT -#define ENET_TX_CLK_OUTPUT true -#endif #define TRACE_ASYNC_EV (0x0001) #define TRACE_ETH_TX (0x0002) @@ -182,7 +179,7 @@ void eth_irq_handler(ENET_Type *base, enet_handle_t *handle, enet_event_t event, } // eth_init: Set up GPIO and the transceiver -void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr) { +void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr, bool phy_clock) { self->netif.num = mac_idx; // Set the interface number @@ -222,12 +219,12 @@ void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy } const clock_enet_pll_config_t config = { - .enableClkOutput = true, .enableClkOutput25M = false, .loopDivider = 1 + .enableClkOutput = phy_clock, .enableClkOutput25M = false, .loopDivider = 1 }; CLOCK_InitEnetPll(&config); - IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1RefClkMode, false); // Drive ENET_REF_CLK from PAD - IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, ENET_TX_CLK_OUTPUT); // Enable output driver + IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1RefClkMode, false); // Do not use the 25 MHz MII clock + IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, phy_clock); // Set the clock pad direction // Reset transceiver // pull up the ENET_INT before RESET. diff --git a/ports/mimxrt/eth.h b/ports/mimxrt/eth.h index 962b6c88cb..b225d00492 100644 --- a/ports/mimxrt/eth.h +++ b/ports/mimxrt/eth.h @@ -30,7 +30,7 @@ typedef struct _eth_t eth_t; extern eth_t eth_instance; -void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr); +void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr, bool phy_clock); void eth_set_trace(eth_t *self, uint32_t value); struct netif *eth_netif(eth_t *self); int eth_link_status(eth_t *self); @@ -41,7 +41,13 @@ void eth_low_power_mode(eth_t *self, bool enable); enum { PHY_KSZ8081 = 0, PHY_DP83825, + PHY_DP83848, PHY_LAN8720, }; +enum { + PHY_TX_CLK_IN = false, + PHY_TX_CLK_OUT = true, +}; + #endif // MICROPY_INCLUDED_MIMXRT_ETH_H diff --git a/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.c b/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.c index 2aca609a05..309755f860 100644 --- a/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.c +++ b/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.c @@ -12,9 +12,9 @@ ******************************************************************************/ /*! @brief Defines the PHY PD83825 vendor defined registers. */ -#define PHY_PHYSTS_REG 0x10U // Phy status register -#define PHY_BISCR_REG 0x16U // RMII Config register. -#define PHY_RCSR_REG 0x17U // RMII Config register. +#define PHY_PHYSTS_REG 0x10U /* Phy status register */ +#define PHY_BISCR_REG 0x16U /* RMII Config register. */ +#define PHY_RCSR_REG 0x17U /* RMII Config register. */ #define PHY_CONTROL2_REG 0x1FU /*!< The PHY control register 2. */ /*! @brief Defines the PHY DP82825 ID number. */ @@ -26,9 +26,9 @@ #define PHY_PHYSTS_100M_MASK 0x0002U /*!< The PHY 100M mask. */ #define PHY_PHYSTS_LINK_MASK 0x0001U /*!< The PHY link up mask. */ -#define PYH_RMII_CLOCK_SELECT 0x80 // Select 50MHz clock -#define PHY_BISCR_REMOTELOOP_MASK 0x1FU // !< The PHY remote loopback mask. -#define PHY_BISCR_REMOTELOOP_MODE 0x08U // !< The PHY remote loopback mode. +#define PYH_RMII_CLOCK_SELECT 0x80 /* Select 50MHz clock */ +#define PHY_BISCR_REMOTELOOP_MASK 0x1FU /* !< The PHY remote loopback mask. */ +#define PHY_BISCR_REMOTELOOP_MODE 0x08U /* !< The PHY remote loopback mode. */ /*! @brief Defines the timeout macro. */ #define PHY_READID_TIMEOUT_COUNT 1000U diff --git a/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.c b/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.c new file mode 100644 index 0000000000..0ef618d421 --- /dev/null +++ b/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.c @@ -0,0 +1,254 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_phydp83848.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Defines the PHY PD83848 vendor defined registers. */ +#define PHY_PHYSTS_REG 0x10U /* Phy status register */ +#define PHY_RBR_REG 0x17U /* RMII Config register. */ + +/*! @brief Defines the PHY DP82825 ID number. */ +#define PHY_CONTROL_ID1 0x2000U /*!< The PHY ID1 */ + +/*! @brief Defines the mask flag of operation mode in control registers */ +#define PHY_PHYSTS_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */ +#define PHY_PHYSTS_DUPLEX_MASK 0x0004U /*!< The PHY full duplex mask. */ +#define PHY_PHYSTS_100M_MASK 0x0002U /*!< The PHY 100M mask. */ +#define PHY_PHYSTS_LINK_MASK 0x0001U /*!< The PHY link up mask. */ + +#define PHY_RMII_MODE 0x20 +#define PHY_RMII_REV1_0 0x10 + +/*! @brief Defines the timeout macro. */ +#define PHY_READID_TIMEOUT_COUNT 1000U + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +const phy_operations_t phydp83848_ops = {.phyInit = PHY_DP83848_Init, + .phyWrite = PHY_DP83848_Write, + .phyRead = PHY_DP83848_Read, + .getAutoNegoStatus = PHY_DP83848_GetAutoNegotiationStatus, + .getLinkStatus = PHY_DP83848_GetLinkStatus, + .getLinkSpeedDuplex = PHY_DP83848_GetLinkSpeedDuplex, + .setLinkSpeedDuplex = PHY_DP83848_SetLinkSpeedDuplex, + .enableLoopback = PHY_DP83848_EnableLoopback}; + +/******************************************************************************* + * Code + ******************************************************************************/ + +status_t PHY_DP83848_Init(phy_handle_t *handle, const phy_config_t *config) { + uint32_t counter = PHY_READID_TIMEOUT_COUNT; + status_t result = kStatus_Success; + uint32_t regValue = 0; + + /* Init MDIO interface. */ + MDIO_Init(handle->mdioHandle); + + /* Assign phy address. */ + handle->phyAddr = config->phyAddr; + + /* Check PHY ID. */ + do + { + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_ID1_REG, ®Value); + if (result != kStatus_Success) { + return result; + } + counter--; + } while ((regValue != PHY_CONTROL_ID1) && (counter != 0U)); + + if (counter == 0U) { + return kStatus_Fail; + } + + /* Reset PHY. */ + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK); + if (result == kStatus_Success) { + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_RBR_REG, ®Value); + if (result != kStatus_Success) { + return result; + } + result = + MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_RBR_REG, (regValue | PHY_RMII_MODE | PHY_RMII_REV1_0)); + if (result != kStatus_Success) { + return result; + } + + if (config->autoNeg) { + /* Set the auto-negotiation then start it. */ + result = + MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_AUTONEG_ADVERTISE_REG, + (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK | + PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | PHY_IEEE802_3_SELECTOR_MASK)); + if (result == kStatus_Success) { + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, + (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK)); + } + } else { + /* This PHY only supports 10/100M speed. */ + assert(config->speed <= kPHY_Speed100M); + + /* Disable isolate mode */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); + if (result != kStatus_Success) { + return result; + } + regValue &= ~PHY_BCTL_ISOLATE_MASK; + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + if (result != kStatus_Success) { + return result; + } + + /* Disable the auto-negotiation and set user-defined speed/duplex configuration. */ + result = PHY_DP83848_SetLinkSpeedDuplex(handle, config->speed, config->duplex); + } + } + return result; +} + +status_t PHY_DP83848_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data) { + return MDIO_Write(handle->mdioHandle, handle->phyAddr, phyReg, data); +} + +status_t PHY_DP83848_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr) { + return MDIO_Read(handle->mdioHandle, handle->phyAddr, phyReg, dataPtr); +} + +status_t PHY_DP83848_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status) { + assert(status); + + status_t result; + uint32_t regValue; + + *status = false; + + /* Check auto negotiation complete. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, ®Value); + if (result == kStatus_Success) { + if ((regValue & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0U) { + *status = true; + } + } + return result; +} + +status_t PHY_DP83848_GetLinkStatus(phy_handle_t *handle, bool *status) { + assert(status); + + status_t result; + uint32_t regValue; + + /* Read the basic status register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, ®Value); + if (result == kStatus_Success) { + if ((PHY_BSTATUS_LINKSTATUS_MASK & regValue) != 0U) { + /* Link up. */ + *status = true; + } else { + /* Link down. */ + *status = false; + } + } + return result; +} + +status_t PHY_DP83848_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex) { + assert(!((speed == NULL) && (duplex == NULL))); + + status_t result; + uint32_t regValue; + uint32_t flag; + + /* Read the control register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_PHYSTS_REG, ®Value); + if (result == kStatus_Success) { + if (speed != NULL) { + flag = regValue & PHY_PHYSTS_100M_MASK; + if (flag) { + *speed = kPHY_Speed10M; + } else { + *speed = kPHY_Speed100M; + } + } + + if (duplex != NULL) { + flag = regValue & PHY_PHYSTS_DUPLEX_MASK; + if (flag) { + *duplex = kPHY_FullDuplex; + } else { + *duplex = kPHY_HalfDuplex; + } + } + } + return result; +} + +status_t PHY_DP83848_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex) { + /* This PHY only supports 10/100M speed. */ + assert(speed <= kPHY_Speed100M); + + status_t result; + uint32_t regValue; + + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); + if (result == kStatus_Success) { + /* Disable the auto-negotiation and set according to user-defined configuration. */ + regValue &= ~PHY_BCTL_AUTONEG_MASK; + if (speed == kPHY_Speed100M) { + regValue |= PHY_BCTL_SPEED0_MASK; + } else { + regValue &= ~PHY_BCTL_SPEED0_MASK; + } + if (duplex == kPHY_FullDuplex) { + regValue |= PHY_BCTL_DUPLEX_MASK; + } else { + regValue &= ~PHY_BCTL_DUPLEX_MASK; + } + result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + } + return result; +} +status_t PHY_DP83848_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable) { + /* This PHY only supports local/remote loopback and 10/100M speed. */ + assert(mode <= kPHY_RemoteLoop); + assert(speed <= kPHY_Speed100M); + + status_t result = kStatus_Success; + uint32_t regValue; + + /* Set the loop mode. */ + if (enable) { + if (mode == kPHY_LocalLoop) { + if (speed == kPHY_Speed100M) { + regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + } else { + regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + } + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); + } + } else { + /* First read the current status in control register. */ + result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); + if (result == kStatus_Success) { + regValue &= ~PHY_BCTL_LOOP_MASK; + return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, + (regValue | PHY_BCTL_RESTART_AUTONEG_MASK)); + } + } + + return result; +} diff --git a/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.h b/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.h new file mode 100644 index 0000000000..7ccc260f7b --- /dev/null +++ b/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.h @@ -0,0 +1,163 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/***************************************************************************** + * PHY DP83848 driver change log + *****************************************************************************/ + +/*! +@page driver_log Driver Change Log + +@section phyksz8081 PHYDP83848 + The current PHYDP83848 driver version is 2.0.0. + + - 2.0.0 + - Initial version. +*/ + +#ifndef _FSL_DP83848_H_ +#define _FSL_DP83848_H_ + +#include "fsl_phy.h" + +/*! + * @addtogroup phy_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief PHY driver version */ +#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) + +/*! @brief PHY operations structure. */ +extern const phy_operations_t phydp83848_ops; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name PHY Driver + * @{ + */ + +/*! + * @brief Initializes PHY. + * + * This function initialize PHY. + * + * @param handle PHY device handle. + * @param config Pointer to structure of phy_config_t. + * @retval kStatus_Success PHY initialization succeeds + * @retval kStatus_Fail PHY initialization fails + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83848_Init(phy_handle_t *handle, const phy_config_t *config); + +/*! + * @brief PHY Write function. This function writes data over the SMI to + * the specified PHY register. This function is called by all PHY interfaces. + * + * @param handle PHY device handle. + * @param phyReg The PHY register. + * @param data The data written to the PHY register. + * @retval kStatus_Success PHY write success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83848_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data); + +/*! + * @brief PHY Read function. This interface read data over the SMI from the + * specified PHY register. This function is called by all PHY interfaces. + * + * @param handle PHY device handle. + * @param phyReg The PHY register. + * @param dataPtr The address to store the data read from the PHY register. + * @retval kStatus_Success PHY read success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83848_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr); + +/*! + * @brief Gets the PHY auto-negotiation status. + * + * @param handle PHY device handle. + * @param status The auto-negotiation status of the PHY. + * - true the auto-negotiation is over. + * - false the auto-negotiation is on-going or not started. + * @retval kStatus_Success PHY gets status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83848_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status); + +/*! + * @brief Gets the PHY link status. + * + * @param handle PHY device handle. + * @param status The link up or down status of the PHY. + * - true the link is up. + * - false the link is down. + * @retval kStatus_Success PHY gets link status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83848_GetLinkStatus(phy_handle_t *handle, bool *status); + +/*! + * @brief Gets the PHY link speed and duplex. + * + * @brief This function gets the speed and duplex mode of PHY. User can give one of speed + * and duplex address paramter and set the other as NULL if only wants to get one of them. + * + * @param handle PHY device handle. + * @param speed The address of PHY link speed. + * @param duplex The link duplex of PHY. + * @retval kStatus_Success PHY gets link speed and duplex success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83848_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex); + +/*! + * @brief Sets the PHY link speed and duplex. + * + * @param handle PHY device handle. + * @param speed Specified PHY link speed. + * @param duplex Specified PHY link duplex. + * @retval kStatus_Success PHY gets status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83848_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex); + +/*! + * @brief Enables/disables PHY loopback. + * + * @param handle PHY device handle. + * @param mode The loopback mode to be enabled, please see "phy_loop_t". + * All loopback modes should not be set together, when one loopback mode is set + * another should be disabled. + * @param speed PHY speed for loopback mode. + * @param enable True to enable, false to disable. + * @retval kStatus_Success PHY loopback success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_DP83848_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_DP83848_H_ */ diff --git a/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.c b/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.c index b7435c2d05..e141ebd513 100644 --- a/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.c +++ b/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.c @@ -12,8 +12,8 @@ ******************************************************************************/ /*! @brief Defines the PHY LAN8720 vendor defined registers. */ -#define PHY_PHYSTS_REG 0x1FU // Phy status register -#define PHY_MCSR_REG 0x11U // Mode Control/Status Register for loopback +#define PHY_PHYSTS_REG 0x1FU /* Phy status register */ +#define PHY_MCSR_REG 0x11U /* Mode Control/Status Register for loopback */ /*! @brief Defines the PHY LAN8720 ID number. */ #define PHY_CONTROL_ID1 0x07U /*!< The PHY ID1 */ @@ -25,8 +25,8 @@ #define PHY_PHYSTS_100M_FLAG 0x0008U /*!< The PHY 100M flag. */ #define PHY_PHYSTS_LINK_MASK 0x0001U /*!< The PHY link up mask. */ -#define PHY_MCSR_REMOTELOOP_MASK 0x100U // !< The PHY remote loopback mask. -#define PHY_MCSR_REMOTELOOP_MODE 0x100U // !< The PHY remote loopback mode. +#define PHY_MCSR_REMOTELOOP_MASK 0x100U /* !< The PHY remote loopback mask. */ +#define PHY_MCSR_REMOTELOOP_MODE 0x100U /* !< The PHY remote loopback mode. */ /*! @brief Defines the timeout macro. */ #define PHY_READID_TIMEOUT_COUNT 1000U diff --git a/ports/mimxrt/network_lan.c b/ports/mimxrt/network_lan.c index 7b725276a1..5517b54bd0 100644 --- a/ports/mimxrt/network_lan.c +++ b/ports/mimxrt/network_lan.c @@ -34,10 +34,15 @@ #include "eth.h" #include "hal/phy/device/phyksz8081/fsl_phyksz8081.h" #include "hal/phy/device/phydp83825/fsl_phydp83825.h" +#include "hal/phy/device/phydp83848/fsl_phydp83848.h" #include "hal/phy/device/phylan8720/fsl_phylan8720.h" #include "lwip/netif.h" +#ifndef ENET_TX_CLK_OUTPUT +#define ENET_TX_CLK_OUTPUT true +#endif + typedef struct _network_lan_obj_t { mp_obj_base_t base; eth_t *eth; @@ -59,11 +64,12 @@ STATIC void network_lan_print(const mp_print_t *print, mp_obj_t self_in, mp_prin } STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - enum { ARG_id, ARG_phy_type, ARG_phy_addr}; + enum { ARG_id, ARG_phy_type, ARG_phy_addr, ARG_phy_clock}; static const mp_arg_t allowed_args[] = { { MP_QSTR_id, MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_phy_type, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_phy_addr, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = ENET_PHY_ADDRESS} }, + { MP_QSTR_phy_clock, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = ENET_TX_CLK_OUTPUT} }, }; // Parse args. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -78,6 +84,8 @@ STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, s phy_ops = &phyksz8081_ops; } else if (phy_type == PHY_DP83825) { phy_ops = &phydp83825_ops; + } else if (phy_type == PHY_DP83848) { + phy_ops = &phydp83848_ops; } else if (phy_type == PHY_LAN8720) { phy_ops = &phylan8720_ops; } else { @@ -86,6 +94,8 @@ STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, s } int phy_addr = args[ARG_phy_addr].u_int; + bool phy_clock = args[ARG_phy_clock].u_int; + // Prepare for two ETH interfaces. const network_lan_obj_t *self; int mac_id = args[ARG_id].u_int; @@ -99,7 +109,7 @@ STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, s mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid LAN interface %d"), mac_id); } - eth_init(self->eth, mac_id, phy_ops, phy_addr); + eth_init(self->eth, mac_id, phy_ops, phy_addr, phy_clock); // register with network module mod_network_register_nic((mp_obj_t *)self); return MP_OBJ_FROM_PTR(self); @@ -203,7 +213,10 @@ STATIC const mp_rom_map_elem_t network_lan_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_PHY_KSZ8081), MP_ROM_INT(PHY_KSZ8081) }, { MP_ROM_QSTR(MP_QSTR_PHY_DP83825), MP_ROM_INT(PHY_DP83825) }, + { MP_ROM_QSTR(MP_QSTR_PHY_DP83848), MP_ROM_INT(PHY_DP83848) }, { MP_ROM_QSTR(MP_QSTR_PHY_LAN8720), MP_ROM_INT(PHY_LAN8720) }, + { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(PHY_TX_CLK_IN) }, + { MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(PHY_TX_CLK_OUT) }, }; STATIC MP_DEFINE_CONST_DICT(network_lan_locals_dict, network_lan_locals_dict_table); From 74e8db0ed15ec0dc7ed5408dfe84f2a9a675d231 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 30 Nov 2021 20:23:03 +0100 Subject: [PATCH 245/335] mimxrt: Refactor the reading of the machine id. The ID is read in a single function and used for: - machine.unique_id() - Ethernet MAC addresses. - ... That facilitates use of other MCU using a different access method for the ID (e.g. i.MX RT1176). --- ports/mimxrt/modmachine.c | 5 +---- ports/mimxrt/mphalport.c | 18 +++++++++++++++--- ports/mimxrt/mphalport.h | 1 + 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/ports/mimxrt/modmachine.c b/ports/mimxrt/modmachine.c index e7f0961344..63cec05507 100644 --- a/ports/mimxrt/modmachine.c +++ b/ports/mimxrt/modmachine.c @@ -37,7 +37,6 @@ #include "pin.h" #include "modmachine.h" #include "fsl_clock.h" -#include "fsl_ocotp.h" #include "fsl_wdog.h" #include CPU_HEADER_H @@ -52,9 +51,7 @@ typedef enum { STATIC mp_obj_t machine_unique_id(void) { unsigned char id[8]; - OCOTP_Init(OCOTP, CLOCK_GetFreq(kCLOCK_IpgClk)); - *(uint32_t *)&id[0] = OCOTP->CFG0; - *(uint32_t *)&id[4] = OCOTP->CFG1; + mp_hal_get_unique_id(id); return mp_obj_new_bytes(id, sizeof(id)); } MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id); diff --git a/ports/mimxrt/mphalport.c b/ports/mimxrt/mphalport.c index 66498d7b27..17a6898c40 100644 --- a/ports/mimxrt/mphalport.c +++ b/ports/mimxrt/mphalport.c @@ -123,13 +123,25 @@ uint64_t mp_hal_time_ns(void) { /*******************************************************************************/ // MAC address +void mp_hal_get_unique_id(uint8_t id[]) { + OCOTP_Init(OCOTP, CLOCK_GetFreq(kCLOCK_IpgClk)); + *(uint32_t *)&id[0] = OCOTP->CFG0; + *(uint32_t *)&id[4] = OCOTP->CFG1; +} + // Generate a random locally administered MAC address (LAA) void mp_hal_generate_laa_mac(int idx, uint8_t buf[6]) { // Take the MAC addr from the OTP's Configuration and Manufacturing Info - OCOTP_Init(OCOTP, CLOCK_GetFreq(kCLOCK_IpgClk)); + unsigned char id[8]; + mp_hal_get_unique_id(id); + + uint32_t pt1 = *(uint32_t *)&id[0]; + uint32_t pt2 = *(uint32_t *)&id[4]; + buf[0] = 0x02; // Locally Administered MAC - *(uint32_t *)&buf[1] = OCOTP->CFG0 ^ (OCOTP->CFG0 >> 8); - *(uint16_t *)&buf[4] = (uint16_t)(OCOTP->CFG1 ^ (OCOTP->CFG1 >> 16)); + *(uint32_t *)&buf[1] = pt1 ^ (pt1 >> 8); + *(uint16_t *)&buf[4] = (uint16_t)(pt2 ^ pt2 >> 16); + buf[5] ^= (uint8_t)idx; } // A board can override this if needed diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index 5210ff44a3..124b905604 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -103,5 +103,6 @@ enum { void mp_hal_generate_laa_mac(int idx, uint8_t buf[6]); void mp_hal_get_mac(int idx, uint8_t buf[6]); void mp_hal_get_mac_ascii(int idx, size_t chr_off, size_t chr_len, char *dest); +void mp_hal_get_unique_id(uint8_t id[]); #endif // MICROPY_INCLUDED_MIMXRT_MPHALPORT_H From 64aa0bcb88cda556e77df4ab66d4005b1ec6a8e5 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 7 Dec 2021 11:38:37 +0100 Subject: [PATCH 246/335] mimxrt: Enable ticks_cpu at boot time for NDEBUG builds only. Otherwise, it get's in trouble with a Debugger. Reason to be found. Also: Increase code segment to 2 MB for the MIMXRT1050_EVK build. --- ports/mimxrt/boards/MIMXRT1052.ld | 2 +- ports/mimxrt/ticks.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ports/mimxrt/boards/MIMXRT1052.ld b/ports/mimxrt/boards/MIMXRT1052.ld index 78d21ef3c4..f7c60d24f4 100644 --- a/ports/mimxrt/boards/MIMXRT1052.ld +++ b/ports/mimxrt/boards/MIMXRT1052.ld @@ -19,7 +19,7 @@ ivt_size = 0x00001000; interrupts_start = flash_start + 0x00002000; interrupts_size = 0x00000400; text_start = flash_start + 0x00002400; -vfs_start = flash_start + 0x00100000; +vfs_start = flash_start + 0x00200000; text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); itcm_start = 0x00000000; diff --git a/ports/mimxrt/ticks.c b/ports/mimxrt/ticks.c index 5ae6f7f13b..0fc9babc04 100644 --- a/ports/mimxrt/ticks.c +++ b/ports/mimxrt/ticks.c @@ -56,7 +56,9 @@ void ticks_init(void) { NVIC_EnableIRQ(GPTx_IRQn); GPT_StartTimer(GPTx); + #ifdef NDEBUG mp_hal_ticks_cpu_enable(); + #endif } void GPTx_IRQHandler(void) { From c5dbbf71c0021e03bf39aeedf31561be81b61978 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 9 Dec 2021 08:44:26 +0100 Subject: [PATCH 247/335] mimxrt: Use -Og instead of -O0 for DEBUG builds. Thanks for the hint, Damien. The DEBUG build got very large recently. The major difference is, that inline function are now inlined and not included as a function. That's good and maybe bad. The good thing is, that the code speed si now close to the final code. It could be worse in single step debugging. I'll see. Setting this option caused a new warning and a formatting error to pop up at different places. Fixed as well. --- ports/mimxrt/Makefile | 2 +- ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.c | 2 +- ports/mimxrt/mimxrt_flash.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 574aebb4cd..680e87cac4 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -125,7 +125,7 @@ LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) # Tune for Debugging or Optimization ifeq ($(DEBUG),1) -CFLAGS += -O0 -ggdb +CFLAGS += -Og -ggdb LDFLAGS += --gc-sections CFLAGS += -fdata-sections -ffunction-sections else diff --git a/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.c b/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.c index 0ef618d421..07ce6d1f7f 100644 --- a/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.c +++ b/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.c @@ -25,7 +25,7 @@ #define PHY_PHYSTS_LINK_MASK 0x0001U /*!< The PHY link up mask. */ #define PHY_RMII_MODE 0x20 -#define PHY_RMII_REV1_0 0x10 +#define PHY_RMII_REV1_0 0x10 /*! @brief Defines the timeout macro. */ #define PHY_READID_TIMEOUT_COUNT 1000U diff --git a/ports/mimxrt/mimxrt_flash.c b/ports/mimxrt/mimxrt_flash.c index 25a11ab7ca..27ab987ed1 100644 --- a/ports/mimxrt/mimxrt_flash.c +++ b/ports/mimxrt/mimxrt_flash.c @@ -79,7 +79,7 @@ status_t flash_erase_block(uint32_t erase_addr) { // the vfs driver takes care for erasing the sector if required status_t flash_write_block(uint32_t dest_addr, const uint8_t *src, uint32_t length) __attribute__((section(".ram_functions"))); status_t flash_write_block(uint32_t dest_addr, const uint8_t *src, uint32_t length) { - status_t status; + status_t status = 0; uint32_t size; uint32_t next_addr; From 5ca56aaf166c3e7cda178dfe809f8caf599b1dff Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 5 Oct 2021 20:59:47 +0200 Subject: [PATCH 248/335] mimxrt: Tidy up the board flash related files. - Move the qspi_xxxx_flash_config.c files to hal. It turned out that they are less board than flash type specific. - Change to a common flexspi_flash_config.h header file. --- ports/mimxrt/Makefile | 5 +- .../MIMXRT1010_EVK_flexspi_nor_config.h | 257 ----------------- .../MIMXRT1010_EVK/qspi_nor_flash_config.c | 124 -------- .../MIMXRT1020_EVK_flexspi_nor_config.h | 258 ----------------- .../MIMXRT1050_EVK/qspi_hyper_flash_config.c | 186 ------------ .../MIMXRT1050_EVK/qspi_nor_flash_config.c | 129 --------- .../MIMXRT1060_EVK_flexspi_nor_config.h | 264 ------------------ .../MIMXRT1060_EVK/qspi_hyper_flash_config.c | 186 ------------ .../MIMXRT1060_EVK/qspi_nor_flash_config.c | 129 --------- .../MIMXRT1064_EVK_flexspi_nor_config.h | 264 ------------------ .../MIMXRT1064_EVK/qspi_nor_flash_config.c | 129 --------- .../TEENSY40/TEENSY40_flexspi_nor_config.h | 259 ----------------- .../boards/TEENSY40/qspi_nor_flash_config.c | 144 ---------- .../TEENSY41/TEENSY41_flexspi_nor_config.h | 259 ----------------- .../boards/TEENSY41/qspi_nor_flash_config.c | 144 ---------- .../flexspi_flash_config.h} | 6 +- ports/mimxrt/hal/flexspi_hyper_flash.h | 2 +- ports/mimxrt/hal/flexspi_nor_flash.h | 2 +- .../qspi_hyper_flash_config.c | 2 +- .../qspi_nor_flash_config.c | 4 +- 20 files changed, 10 insertions(+), 2743 deletions(-) delete mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK_flexspi_nor_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/qspi_nor_flash_config.c delete mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK_flexspi_nor_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/qspi_hyper_flash_config.c delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/qspi_nor_flash_config.c delete mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK_flexspi_nor_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/qspi_hyper_flash_config.c delete mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/qspi_nor_flash_config.c delete mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK_flexspi_nor_config.h delete mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/qspi_nor_flash_config.c delete mode 100644 ports/mimxrt/boards/TEENSY40/TEENSY40_flexspi_nor_config.h delete mode 100644 ports/mimxrt/boards/TEENSY40/qspi_nor_flash_config.c delete mode 100644 ports/mimxrt/boards/TEENSY41/TEENSY41_flexspi_nor_config.h delete mode 100644 ports/mimxrt/boards/TEENSY41/qspi_nor_flash_config.c rename ports/mimxrt/{boards/MIMXRT1050_EVK/MIMXRT1050_EVK_flexspi_nor_config.h => hal/flexspi_flash_config.h} (98%) rename ports/mimxrt/{boards/MIMXRT1064_EVK => hal}/qspi_hyper_flash_config.c (99%) rename ports/mimxrt/{boards/MIMXRT1020_EVK => hal}/qspi_nor_flash_config.c (98%) diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 680e87cac4..32b1145230 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -90,7 +90,6 @@ CFLAGS += -DXIP_EXTERNAL_FLASH=1 \ -DCPU_HEADER_H='<$(MCU_SERIES).h>' \ -DBOARD_FLASH_SIZE=$(MICROPY_HW_FLASH_SIZE) \ -DMICROPY_HW_FLASH_SIZE=$(MICROPY_HW_FLASH_SIZE) \ - -DBOARD_FLASH_CONFIG_HEADER_H=\"$(BOARD)_flexspi_nor_config.h\" ifeq ($(MICROPY_HW_FLASH_TYPE), qspi_nor) CFLAGS += -DBOARD_FLASH_OPS_HEADER_H=\"hal/flexspi_nor_flash.h\" @@ -277,11 +276,11 @@ SRC_C += \ ifeq ($(MICROPY_HW_FLASH_TYPE), qspi_nor) SRC_C += \ hal/flexspi_nor_flash.c \ - $(BOARD_DIR)/qspi_nor_flash_config.c + hal/qspi_nor_flash_config.c else ifeq ($(MICROPY_HW_FLASH_TYPE), hyperflash) SRC_C += \ hal/flexspi_hyper_flash.c \ - $(BOARD_DIR)/qspi_hyper_flash_config.c + hal/qspi_hyper_flash_config.c else $(error Error: Unknown board flash type $(MICROPY_HW_FLASH_TYPE)) endif diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK_flexspi_nor_config.h deleted file mode 100644 index aeb5f356ea..0000000000 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK_flexspi_nor_config.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1010_flexspi_nor_config.h - -#ifndef __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ -#define __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_common.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related defintions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -// !@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_120MHz = 7, - kFlexSpiSerialClk_133MHz = 8, -} flexspi_serial_clk_freq_t; - -// !@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, // !< Clock configure for SDR mode - kFlexSpiClk_DDR, // !< Clock configurat for DDR mode -}; - -// !@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -// !@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. -}; - -// !@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -// !@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -// !@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; // !< Sequence Number, valid number: 1-16 - uint8_t seqId; // !< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -// !@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, // !< Reset device command -}; - -// !@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - // ! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - // ! Generic configuration, etc. - uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - // ! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - // ! sequence number, [31:16] Reserved - uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - // ! details - uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - // ! Chapter for more details - uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - // ! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI - uint32_t pageSize; // !< Page size of Serial NOR - uint32_t sectorSize; // !< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command - uint8_t isUniformBlockSize; // !< Sector/Block size is the same - uint8_t reserved0[2]; // !< Reserved for future use - uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; // !< Block size - uint32_t reserve2[11]; // !< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1010_EVK/qspi_nor_flash_config.c deleted file mode 100644 index 60d435433a..0000000000 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/qspi_nor_flash_config.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1010_flexspi_nor_config.c - -#include BOARD_FLASH_CONFIG_HEADER_H - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_100MHz, - .sflashA1Size = MICROPY_HW_FLASH_SIZE, - .lookupTable = - { - // 0 Read LUTs 0 -> 0 - 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), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 1 Read status register -> 1 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 2 Fast read quad mode - SDR - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 3 Write Enable -> 3 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 4 Read extend parameters - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 5 Erase Sector -> 5 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 6 Write Status Reg - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 7 Page Program - quad mode (-> 9) - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 8 Read ID - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 9 Page Program - single mode -> 9 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 10 Enter QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 11 Erase Chip - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 12 Exit QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - }, - }, - .pageSize = 256u, - .sectorSize = 4u * 1024u, - .blockSize = 256u * 1024u, - .isUniformBlockSize = false, -}; -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK_flexspi_nor_config.h deleted file mode 100644 index 26ed3de36f..0000000000 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK_flexspi_nor_config.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2019 NXP. - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1020_flexspi_nor_config.h - -#ifndef __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ -#define __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_common.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related defintions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -// !@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_133MHz = 7, - kFlexSpiSerialClk_166MHz = 8, - kFlexSpiSerialClk_200MHz = 9, -} flexspi_serial_clk_freq_t; - -// !@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, // !< Clock configure for SDR mode - kFlexSpiClk_DDR, // !< Clock configurat for DDR mode -}; - -// !@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -// !@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. -}; - -// !@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -// !@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -// !@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; // !< Sequence Number, valid number: 1-16 - uint8_t seqId; // !< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -// !@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, // !< Reset device command -}; - -// !@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - // ! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - // ! Generic configuration, etc. - uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - // ! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - // ! sequence number, [31:16] Reserved - uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - // ! details - uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - // ! Chapter for more details - uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - // ! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI - uint32_t pageSize; // !< Page size of Serial NOR - uint32_t sectorSize; // !< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command - uint8_t isUniformBlockSize; // !< Sector/Block size is the same - uint8_t reserved0[2]; // !< Reserved for future use - uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; // !< Block size - uint32_t reserve2[11]; // !< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_hyper_flash_config.c b/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_hyper_flash_config.c deleted file mode 100644 index f5ffbe8413..0000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_hyper_flash_config.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include BOARD_FLASH_CONFIG_HEADER_H - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - .columnAddressWidth = 3u, - // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock - .controllerMiscOption = - (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | - (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), - .sflashPadType = kSerialFlash_8Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = MICROPY_HW_FLASH_SIZE, - .dataValidTime = {16u, 16u}, - .lookupTable = - { - /* 0 Read Data */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04), - - /* 1 Write Data */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02), - - /* 2 Read Status */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x70), // DATA 0x70 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 5] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x0B), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0), - - /* 4 Write Enable */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // DATA 0xAA - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 7] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - - /* 6 Erase Sector */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), // DATA 0x80 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 7] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - // +2 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 8] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 9] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 10] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 11] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - // +3 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 12] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 13] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 14] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x30, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), - - /* 10 program page with word program command sequence */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0), // DATA 0xA0 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 5] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x80), - - /* 12 Erase chip */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 1] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 3] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 7] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - // +2 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 8] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 9] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 10] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 11] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - // +3 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 12] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 13] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 14] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 15] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10), - }, - }, - .pageSize = 512u, - .sectorSize = 256u * 1024u, - .blockSize = 256u * 1024u, - .isUniformBlockSize = true, -}; - -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_nor_flash_config.c deleted file mode 100644 index 73525b5dfc..0000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/qspi_nor_flash_config.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include BOARD_FLASH_CONFIG_HEADER_H - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - .columnAddressWidth = 3u, - // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock - .controllerMiscOption = - (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | - (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), - .sflashPadType = kSerialFlash_8Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = MICROPY_HW_FLASH_SIZE, - .dataValidTime = {16u, 16u}, - .lookupTable = - { - // 0 Read LUTs 0 -> 0 - 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), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 1 Read status register -> 1 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 2 Fast read quad mode - SDR - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 3 Write Enable -> 3 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 4 Read extend parameters - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 5 Erase Sector -> 5 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 6 Write Status Reg - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 7 Page Program - quad mode (-> 9) - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 8 Read ID - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 9 Page Program - single mode -> 9 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 10 Enter QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 11 Erase Chip - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 12 Exit QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - }, - }, - .pageSize = 512u, - .sectorSize = 256u * 1024u, - .blockSize = 256u * 1024u, - .isUniformBlockSize = true, -}; - -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK_flexspi_nor_config.h deleted file mode 100644 index e447733f06..0000000000 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK_flexspi_nor_config.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ -#define __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_flexspi.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related defintions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -// !@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_120MHz = 7, - kFlexSpiSerialClk_133MHz = 8, - kFlexSpiSerialClk_166MHz = 9, -} flexspi_serial_clk_freq_t; - -// !@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, // !< Clock configure for SDR mode - kFlexSpiClk_DDR, // !< Clock configurat for DDR mode -}; - -// !@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -// !@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. -}; - -// !@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -// !@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -// !@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; // !< Sequence Number, valid number: 1-16 - uint8_t seqId; // !< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -// !@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, // !< Reset device command -}; - -// !@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - // ! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - // ! Generic configuration, etc. - uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - // ! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - // ! sequence number, [31:16] Reserved - uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - // ! details - uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - // ! Chapter for more details - uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - // ! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -#define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI - uint32_t pageSize; // !< Page size of Serial NOR - uint32_t sectorSize; // !< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command - uint8_t isUniformBlockSize; // !< Sector/Block size is the same - uint8_t reserved0[2]; // !< Reserved for future use - uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; // !< Block size - uint32_t reserve2[11]; // !< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_hyper_flash_config.c b/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_hyper_flash_config.c deleted file mode 100644 index f5ffbe8413..0000000000 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_hyper_flash_config.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include BOARD_FLASH_CONFIG_HEADER_H - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - .columnAddressWidth = 3u, - // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock - .controllerMiscOption = - (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | - (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), - .sflashPadType = kSerialFlash_8Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = MICROPY_HW_FLASH_SIZE, - .dataValidTime = {16u, 16u}, - .lookupTable = - { - /* 0 Read Data */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04), - - /* 1 Write Data */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02), - - /* 2 Read Status */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x70), // DATA 0x70 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 5] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x0B), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0), - - /* 4 Write Enable */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // DATA 0xAA - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 7] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - - /* 6 Erase Sector */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), // DATA 0x80 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 7] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - // +2 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 8] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 9] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 10] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 11] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - // +3 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 12] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 13] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 14] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x30, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), - - /* 10 program page with word program command sequence */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 3] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0), // DATA 0xA0 - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 5] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x80), - - /* 12 Erase chip */ - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 1] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 2] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 3] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), - // +1 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 4] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 5] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 6] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 7] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - // +2 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 8] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 9] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 10] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 11] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - // +3 - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 12] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 13] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 14] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), - [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 15] = - FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10), - }, - }, - .pageSize = 512u, - .sectorSize = 256u * 1024u, - .blockSize = 256u * 1024u, - .isUniformBlockSize = true, -}; - -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_nor_flash_config.c deleted file mode 100644 index 73525b5dfc..0000000000 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/qspi_nor_flash_config.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include BOARD_FLASH_CONFIG_HEADER_H - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - .columnAddressWidth = 3u, - // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock - .controllerMiscOption = - (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | - (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), - .sflashPadType = kSerialFlash_8Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = MICROPY_HW_FLASH_SIZE, - .dataValidTime = {16u, 16u}, - .lookupTable = - { - // 0 Read LUTs 0 -> 0 - 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), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 1 Read status register -> 1 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 2 Fast read quad mode - SDR - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 3 Write Enable -> 3 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 4 Read extend parameters - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 5 Erase Sector -> 5 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 6 Write Status Reg - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 7 Page Program - quad mode (-> 9) - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 8 Read ID - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 9 Page Program - single mode -> 9 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 10 Enter QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 11 Erase Chip - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 12 Exit QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - }, - }, - .pageSize = 512u, - .sectorSize = 256u * 1024u, - .blockSize = 256u * 1024u, - .isUniformBlockSize = true, -}; - -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK_flexspi_nor_config.h deleted file mode 100644 index 01b3194e31..0000000000 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK_flexspi_nor_config.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ -#define __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_flexspi.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related defintions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -// !@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_120MHz = 7, - kFlexSpiSerialClk_133MHz = 8, - kFlexSpiSerialClk_166MHz = 9, -} flexspi_serial_clk_freq_t; - -// !@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, // !< Clock configure for SDR mode - kFlexSpiClk_DDR, // !< Clock configurat for DDR mode -}; - -// !@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -// !@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. -}; - -// !@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -// !@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -// !@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; // !< Sequence Number, valid number: 1-16 - uint8_t seqId; // !< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -// !@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, // !< Reset device command -}; - -// !@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - // ! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - // ! Generic configuration, etc. - uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - // ! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - // ! sequence number, [31:16] Reserved - uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - // ! details - uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - // ! Chapter for more details - uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - // ! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -#define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10 -#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI - uint32_t pageSize; // !< Page size of Serial NOR - uint32_t sectorSize; // !< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command - uint8_t isUniformBlockSize; // !< Sector/Block size is the same - uint8_t reserved0[2]; // !< Reserved for future use - uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; // !< Block size - uint32_t reserve2[11]; // !< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_nor_flash_config.c b/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_nor_flash_config.c deleted file mode 100644 index 73525b5dfc..0000000000 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_nor_flash_config.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include BOARD_FLASH_CONFIG_HEADER_H - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - .columnAddressWidth = 3u, - // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock - .controllerMiscOption = - (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | - (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), - .sflashPadType = kSerialFlash_8Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, - .sflashA1Size = MICROPY_HW_FLASH_SIZE, - .dataValidTime = {16u, 16u}, - .lookupTable = - { - // 0 Read LUTs 0 -> 0 - 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), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 1 Read status register -> 1 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 2 Fast read quad mode - SDR - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 3 Write Enable -> 3 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 4 Read extend parameters - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 5 Erase Sector -> 5 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 6 Write Status Reg - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 7 Page Program - quad mode (-> 9) - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 8 Read ID - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 9 Page Program - single mode -> 9 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 10 Enter QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 11 Erase Chip - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 12 Exit QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - }, - }, - .pageSize = 512u, - .sectorSize = 256u * 1024u, - .blockSize = 256u * 1024u, - .isUniformBlockSize = true, -}; - -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/TEENSY40/TEENSY40_flexspi_nor_config.h b/ports/mimxrt/boards/TEENSY40/TEENSY40_flexspi_nor_config.h deleted file mode 100644 index b06def76c0..0000000000 --- a/ports/mimxrt/boards/TEENSY40/TEENSY40_flexspi_nor_config.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.h - -#ifndef __TEENSY40_FLEXSPI_NOR_CONFIG__ -#define __TEENSY40_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_common.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related definitions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_ERASE 5 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -// !@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_120MHz = 7, - kFlexSpiSerialClk_133MHz = 8, - kFlexSpiSerialClk_166MHz = 9, -} flexspi_serial_clk_freq_t; - -// !@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, // !< Clock configure for SDR mode - kFlexSpiClk_DDR, // !< Clock configurat for DDR mode -}; - -// !@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -// !@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. -}; - -// !@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -// !@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -// !@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; // !< Sequence Number, valid number: 1-16 - uint8_t seqId; // !< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -// !@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, // !< Reset device command -}; - -// !@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - // ! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - // ! Generic configuration, etc. - uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - // ! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - // ! sequence number, [31:16] Reserved - uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - // ! details - uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - // ! Chapter for more details - uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - // ! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI - uint32_t pageSize; // !< Page size of Serial NOR - uint32_t sectorSize; // !< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command - uint8_t isUniformBlockSize; // !< Sector/Block size is the same - uint8_t reserved0[2]; // !< Reserved for future use - uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; // !< Block size - uint32_t reserve2[11]; // !< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/TEENSY40/qspi_nor_flash_config.c b/ports/mimxrt/boards/TEENSY40/qspi_nor_flash_config.c deleted file mode 100644 index 69135f6b47..0000000000 --- a/ports/mimxrt/boards/TEENSY40/qspi_nor_flash_config.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.c - -#include BOARD_FLASH_CONFIG_HEADER_H - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - - .busyOffset = FLASH_BUSY_STATUS_OFFSET, // Status bit 0 indicates busy. - .busyBitPolarity = FLASH_BUSY_STATUS_POL, // Busy when the bit is 1. - - .deviceModeCfgEnable = 1u, - .deviceModeType = kDeviceConfigCmdType_QuadEnable, - .deviceModeSeq = { - .seqId = 4u, - .seqNum = 1u, - }, - .deviceModeArg = 0x0200, - .configCmdEnable = 1u, - .configModeType[0] = kDeviceConfigCmdType_Generic, - .configCmdSeqs[0] = { - .seqId = 2u, - .seqNum = 1u, - }, - .deviceType = kFlexSpiDeviceType_SerialNOR, - // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock - .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, - .sflashA1Size = MICROPY_HW_FLASH_SIZE, - .lookupTable = - { - // 0 Read LUTs 0 -> 0 - 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), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 1 Read status register -> 1 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 2 Fast read quad mode - SDR - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 3 Write Enable -> 3 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 4 Read extend parameters - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 5 Erase Sector -> 5 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 6 Write Status Reg - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 7 Page Program - quad mode (-> 9) - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 8 Read ID - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 9 Page Program - single mode -> 9 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 10 Enter QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 11 Erase Chip - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 12 Exit QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - }, - }, - .pageSize = 256u, - .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, - .blockSize = 0x00010000, - .isUniformBlockSize = false, -}; -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/TEENSY41/TEENSY41_flexspi_nor_config.h b/ports/mimxrt/boards/TEENSY41/TEENSY41_flexspi_nor_config.h deleted file mode 100644 index b06def76c0..0000000000 --- a/ports/mimxrt/boards/TEENSY41/TEENSY41_flexspi_nor_config.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.h - -#ifndef __TEENSY40_FLEXSPI_NOR_CONFIG__ -#define __TEENSY40_FLEXSPI_NOR_CONFIG__ - -#include -#include -#include "fsl_common.h" - -/*! @name Driver version */ -/*@{*/ -/*! @brief XIP_BOARD driver version 2.0.0. */ -#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian -#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) - -/* FLEXSPI Feature related definitions */ -#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 - -/* Lookup table related definitions */ -#define CMD_INDEX_READ 0 -#define CMD_INDEX_READSTATUS 1 -#define CMD_INDEX_WRITEENABLE 2 -#define CMD_INDEX_WRITE 4 - -#define CMD_LUT_SEQ_IDX_READ 0 -#define CMD_LUT_SEQ_IDX_READSTATUS 1 -#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define CMD_LUT_SEQ_IDX_ERASE 5 -#define CMD_LUT_SEQ_IDX_WRITE 9 - -#define CMD_SDR 0x01 -#define CMD_DDR 0x21 -#define RADDR_SDR 0x02 -#define RADDR_DDR 0x22 -#define CADDR_SDR 0x03 -#define CADDR_DDR 0x23 -#define MODE1_SDR 0x04 -#define MODE1_DDR 0x24 -#define MODE2_SDR 0x05 -#define MODE2_DDR 0x25 -#define MODE4_SDR 0x06 -#define MODE4_DDR 0x26 -#define MODE8_SDR 0x07 -#define MODE8_DDR 0x27 -#define WRITE_SDR 0x08 -#define WRITE_DDR 0x28 -#define READ_SDR 0x09 -#define READ_DDR 0x29 -#define LEARN_SDR 0x0A -#define LEARN_DDR 0x2A -#define DATSZ_SDR 0x0B -#define DATSZ_DDR 0x2B -#define DUMMY_SDR 0x0C -#define DUMMY_DDR 0x2C -#define DUMMY_RWDS_SDR 0x0D -#define DUMMY_RWDS_DDR 0x2D -#define JMP_ON_CS 0x1F -#define STOP 0 - -#define FLEXSPI_1PAD 0 -#define FLEXSPI_2PAD 1 -#define FLEXSPI_4PAD 2 -#define FLEXSPI_8PAD 3 - -#define 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)) - -// !@brief Definitions for FlexSPI Serial Clock Frequency -typedef enum _FlexSpiSerialClockFreq -{ - kFlexSpiSerialClk_30MHz = 1, - kFlexSpiSerialClk_50MHz = 2, - kFlexSpiSerialClk_60MHz = 3, - kFlexSpiSerialClk_75MHz = 4, - kFlexSpiSerialClk_80MHz = 5, - kFlexSpiSerialClk_100MHz = 6, - kFlexSpiSerialClk_120MHz = 7, - kFlexSpiSerialClk_133MHz = 8, - kFlexSpiSerialClk_166MHz = 9, -} flexspi_serial_clk_freq_t; - -// !@brief FlexSPI clock configuration type -enum -{ - kFlexSpiClk_SDR, // !< Clock configure for SDR mode - kFlexSpiClk_DDR, // !< Clock configurat for DDR mode -}; - -// !@brief FlexSPI Read Sample Clock Source definition -typedef enum _FlashReadSampleClkSource -{ - kFlexSPIReadSampleClk_LoopbackInternally = 0, - kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, - kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, - kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, -} flexspi_read_sample_clk_t; - -// !@brief Misc feature bit definitions -enum -{ - kFlexSpiMiscOffset_DiffClkEnable = 0, // !< Bit for Differential clock enable - kFlexSpiMiscOffset_Ck2Enable = 1, // !< Bit for CK2 enable - kFlexSpiMiscOffset_ParallelEnable = 2, // !< Bit for Parallel mode enable - kFlexSpiMiscOffset_WordAddressableEnable = 3, // !< Bit for Word Addressable enable - kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, // !< Bit for Safe Configuration Frequency enable - kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, // !< Bit for Pad setting override enable - kFlexSpiMiscOffset_DdrModeEnable = 6, // !< Bit for DDR clock confiuration indication. -}; - -// !@brief Flash Type Definition -enum -{ - kFlexSpiDeviceType_SerialNOR = 1, // !< Flash devices are Serial NOR - kFlexSpiDeviceType_SerialNAND = 2, // !< Flash devices are Serial NAND - kFlexSpiDeviceType_SerialRAM = 3, // !< Flash devices are Serial RAM/HyperFLASH - kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, // !< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND - kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, // !< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs -}; - -// !@brief Flash Pad Definitions -enum -{ - kSerialFlash_1Pad = 1, - kSerialFlash_2Pads = 2, - kSerialFlash_4Pads = 4, - kSerialFlash_8Pads = 8, -}; - -// !@brief FlexSPI LUT Sequence structure -typedef struct _lut_sequence -{ - uint8_t seqNum; // !< Sequence Number, valid number: 1-16 - uint8_t seqId; // !< Sequence Index, valid number: 0-15 - uint16_t reserved; -} flexspi_lut_seq_t; - -// !@brief Flash Configuration Command Type -enum -{ - kDeviceConfigCmdType_Generic, // !< Generic command, for example: configure dummy cycles, drive strength, etc - kDeviceConfigCmdType_QuadEnable, // !< Quad Enable command - kDeviceConfigCmdType_Spi2Xpi, // !< Switch from SPI to DPI/QPI/OPI mode - kDeviceConfigCmdType_Xpi2Spi, // !< Switch from DPI/QPI/OPI to SPI mode - kDeviceConfigCmdType_Spi2NoCmd, // !< Switch to 0-4-4/0-8-8 mode - kDeviceConfigCmdType_Reset, // !< Reset device command -}; - -// !@brief FlexSPI Memory Configuration Block -typedef struct _FlexSPIConfig -{ - uint32_t tag; // !< [0x000-0x003] Tag, fixed value 0x42464346UL - uint32_t version; // !< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix - uint32_t reserved0; // !< [0x008-0x00b] Reserved for future use - uint8_t readSampleClkSrc; // !< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 - uint8_t csHoldTime; // !< [0x00d-0x00d] CS hold time, default value: 3 - uint8_t csSetupTime; // !< [0x00e-0x00e] CS setup time, default value: 3 - uint8_t columnAddressWidth; // !< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For - // ! Serial NAND, need to refer to datasheet - uint8_t deviceModeCfgEnable; // !< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable - uint8_t deviceModeType; // !< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, - // ! Generic configuration, etc. - uint16_t waitTimeCfgCommands; // !< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for - // ! DPI/QPI/OPI switch or reset command - flexspi_lut_seq_t deviceModeSeq; // !< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt - // ! sequence number, [31:16] Reserved - uint32_t deviceModeArg; // !< [0x018-0x01b] Argument/Parameter for device configuration - uint8_t configCmdEnable; // !< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable - uint8_t configModeType[3]; // !< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe - flexspi_lut_seq_t - configCmdSeqs[3]; // !< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq - uint32_t reserved1; // !< [0x02c-0x02f] Reserved for future use - uint32_t configCmdArgs[3]; // !< [0x030-0x03b] Arguments/Parameters for device Configuration commands - uint32_t reserved2; // !< [0x03c-0x03f] Reserved for future use - uint32_t controllerMiscOption; // !< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more - // ! details - uint8_t deviceType; // !< [0x044-0x044] Device Type: See Flash Type Definition for more details - uint8_t sflashPadType; // !< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal - uint8_t serialClkFreq; // !< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot - // ! Chapter for more details - uint8_t lutCustomSeqEnable; // !< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot - // ! be done using 1 LUT sequence, currently, only applicable to HyperFLASH - uint32_t reserved3[2]; // !< [0x048-0x04f] Reserved for future use - uint32_t sflashA1Size; // !< [0x050-0x053] Size of Flash connected to A1 - uint32_t sflashA2Size; // !< [0x054-0x057] Size of Flash connected to A2 - uint32_t sflashB1Size; // !< [0x058-0x05b] Size of Flash connected to B1 - uint32_t sflashB2Size; // !< [0x05c-0x05f] Size of Flash connected to B2 - uint32_t csPadSettingOverride; // !< [0x060-0x063] CS pad setting override value - uint32_t sclkPadSettingOverride; // !< [0x064-0x067] SCK pad setting override value - uint32_t dataPadSettingOverride; // !< [0x068-0x06b] data pad setting override value - uint32_t dqsPadSettingOverride; // !< [0x06c-0x06f] DQS pad setting override value - uint32_t timeoutInMs; // !< [0x070-0x073] Timeout threshold for read status command - uint32_t commandInterval; // !< [0x074-0x077] CS deselect interval between two commands - uint16_t dataValidTime[2]; // !< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns - uint16_t busyOffset; // !< [0x07c-0x07d] Busy offset, valid value: 0-31 - uint16_t busyBitPolarity; // !< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - - // ! busy flag is 0 when flash device is busy - uint32_t lookupTable[64]; // !< [0x080-0x17f] Lookup table holds Flash command sequences - flexspi_lut_seq_t lutCustomSeq[12]; // !< [0x180-0x1af] Customizable LUT Sequences - uint32_t reserved4[4]; // !< [0x1b0-0x1bf] Reserved for future use -} flexspi_mem_config_t; - -/* */ -#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 -#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 -#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 -#define NOR_CMD_LUT_SEQ_IDX_READID 8 -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 -#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 -#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 - -/* - * Serial NOR configuration block - */ -typedef struct _flexspi_nor_config -{ - flexspi_mem_config_t memConfig; // !< Common memory configuration info via FlexSPI - uint32_t pageSize; // !< Page size of Serial NOR - uint32_t sectorSize; // !< Sector size of Serial NOR - uint8_t ipcmdSerialClkFreq; // !< Clock frequency for IP command - uint8_t isUniformBlockSize; // !< Sector/Block size is the same - uint8_t reserved0[2]; // !< Reserved for future use - uint8_t serialNorType; // !< Serial NOR Flash type: 0/1/2/3 - uint8_t needExitNoCmdMode; // !< Need to exit NoCmd mode before other IP command - uint8_t halfClkForNonReadCmd; // !< Half the Serial Clock for non-read command: true/false - uint8_t needRestoreNoCmdMode; // !< Need to Restore NoCmd mode after IP commmand execution - uint32_t blockSize; // !< Block size - uint32_t reserve2[11]; // !< Reserved for future use -} flexspi_nor_config_t; - -#define FLASH_BUSY_STATUS_POL 0 -#define FLASH_BUSY_STATUS_OFFSET 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/boards/TEENSY41/qspi_nor_flash_config.c b/ports/mimxrt/boards/TEENSY41/qspi_nor_flash_config.c deleted file mode 100644 index 69135f6b47..0000000000 --- a/ports/mimxrt/boards/TEENSY41/qspi_nor_flash_config.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.c - -#include BOARD_FLASH_CONFIG_HEADER_H - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_board" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) -#elif defined(__ICCARM__) -#pragma location = ".boot_hdr.conf" -#endif - -const flexspi_nor_config_t qspiflash_config = { - .memConfig = - { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - - .busyOffset = FLASH_BUSY_STATUS_OFFSET, // Status bit 0 indicates busy. - .busyBitPolarity = FLASH_BUSY_STATUS_POL, // Busy when the bit is 1. - - .deviceModeCfgEnable = 1u, - .deviceModeType = kDeviceConfigCmdType_QuadEnable, - .deviceModeSeq = { - .seqId = 4u, - .seqNum = 1u, - }, - .deviceModeArg = 0x0200, - .configCmdEnable = 1u, - .configModeType[0] = kDeviceConfigCmdType_Generic, - .configCmdSeqs[0] = { - .seqId = 2u, - .seqNum = 1u, - }, - .deviceType = kFlexSpiDeviceType_SerialNOR, - // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock - .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, - .sflashA1Size = MICROPY_HW_FLASH_SIZE, - .lookupTable = - { - // 0 Read LUTs 0 -> 0 - 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), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 1 Read status register -> 1 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 2 Fast read quad mode - SDR - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 3 Write Enable -> 3 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 4 Read extend parameters - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 5 Erase Sector -> 5 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 6 Write Status Reg - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 7 Page Program - quad mode (-> 9) - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 8 Read ID - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 9 Page Program - single mode -> 9 - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 10 Enter QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 11 Erase Chip - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - - // 12 Exit QPI mode - FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler - }, - }, - .pageSize = 256u, - .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, - .blockSize = 0x00010000, - .isUniformBlockSize = false, -}; -#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK_flexspi_nor_config.h b/ports/mimxrt/hal/flexspi_flash_config.h similarity index 98% rename from ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK_flexspi_nor_config.h rename to ports/mimxrt/hal/flexspi_flash_config.h index b4e9217416..3c21eb609a 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK_flexspi_nor_config.h +++ b/ports/mimxrt/hal/flexspi_flash_config.h @@ -5,8 +5,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef __EVKMIMXRT1050_FLEXSPI_NOR_CONFIG__ -#define __EVKMIMXRT1050_FLEXSPI_NOR_CONFIG__ +#ifndef __FLEXSPI_FLASH_CONFIG__ +#define __FLEXSPI_FLASH_CONFIG__ #include #include @@ -260,4 +260,4 @@ extern "C" { #ifdef __cplusplus } #endif -#endif /* __EVKMIMXRT1050_FLEXSPI_NOR_CONFIG__ */ +#endif /* __FLEXSPI_FLASH_CONFIG__ */ diff --git a/ports/mimxrt/hal/flexspi_hyper_flash.h b/ports/mimxrt/hal/flexspi_hyper_flash.h index dbd028fd6f..f340aec10a 100644 --- a/ports/mimxrt/hal/flexspi_hyper_flash.h +++ b/ports/mimxrt/hal/flexspi_hyper_flash.h @@ -28,7 +28,7 @@ #include "fsl_flexspi.h" #include "mpconfigboard.h" -#include BOARD_FLASH_CONFIG_HEADER_H +#include "flexspi_flash_config.h" // Defined in boards flash_config.c extern flexspi_nor_config_t qspiflash_config; diff --git a/ports/mimxrt/hal/flexspi_nor_flash.h b/ports/mimxrt/hal/flexspi_nor_flash.h index f8c31488a9..c2c30876c7 100644 --- a/ports/mimxrt/hal/flexspi_nor_flash.h +++ b/ports/mimxrt/hal/flexspi_nor_flash.h @@ -28,7 +28,7 @@ #include "fsl_flexspi.h" #include "mpconfigboard.h" -#include BOARD_FLASH_CONFIG_HEADER_H +#include "flexspi_flash_config.h" // Defined in boards flash_config.c extern flexspi_nor_config_t qspiflash_config; diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_hyper_flash_config.c b/ports/mimxrt/hal/qspi_hyper_flash_config.c similarity index 99% rename from ports/mimxrt/boards/MIMXRT1064_EVK/qspi_hyper_flash_config.c rename to ports/mimxrt/hal/qspi_hyper_flash_config.c index f5ffbe8413..17a952b689 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/qspi_hyper_flash_config.c +++ b/ports/mimxrt/hal/qspi_hyper_flash_config.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include BOARD_FLASH_CONFIG_HEADER_H +#include "flexspi_flash_config.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/qspi_nor_flash_config.c b/ports/mimxrt/hal/qspi_nor_flash_config.c similarity index 98% rename from ports/mimxrt/boards/MIMXRT1020_EVK/qspi_nor_flash_config.c rename to ports/mimxrt/hal/qspi_nor_flash_config.c index fc4d3c10c1..4ae5093c82 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/qspi_nor_flash_config.c +++ b/ports/mimxrt/hal/qspi_nor_flash_config.c @@ -7,7 +7,7 @@ // Based on tinyusb/hw/bsp/teensy_40/evkmimxrt1010_flexspi_nor_config.c -#include BOARD_FLASH_CONFIG_HEADER_H +#include "flexspi_flash_config.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID @@ -129,7 +129,7 @@ const flexspi_nor_config_t qspiflash_config = { }, .pageSize = 256u, .sectorSize = 4u * 1024u, - .blockSize = 256u * 1024u, + .blockSize = 64u * 1024u, .isUniformBlockSize = false, // .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, }; From d9d67adef1113ab18f1bb3c0c6204ccb210a27be Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 15 Dec 2021 11:49:22 +1100 Subject: [PATCH 249/335] docs: Remove trailing spaces and convert tabs to spaces. Signed-off-by: Damien George --- docs/develop/extendingmicropython.rst | 1 - docs/develop/gettingstarted.rst | 28 +++--- docs/develop/index.rst | 3 +- docs/develop/qstr.rst | 2 +- docs/esp32/quickref.rst | 8 +- docs/esp32/tutorial/intro.rst | 4 +- docs/esp8266/tutorial/intro.rst | 6 +- docs/library/esp.rst | 2 +- docs/library/heapq.rst | 2 +- docs/library/lcd160cr.rst | 2 +- docs/library/machine.ADCWiPy.rst | 10 +-- docs/library/machine.I2S.rst | 104 +++++++++++------------ docs/library/machine.SD.rst | 2 +- docs/library/machine.SDCard.rst | 2 +- docs/library/machine.TimerWiPy.rst | 6 +- docs/library/machine.UART.rst | 2 +- docs/library/machine.WDT.rst | 2 +- docs/library/machine.rst | 2 +- docs/library/pyb.Pin.rst | 2 +- docs/pyboard/quickref.rst | 16 ++-- docs/pyboard/tutorial/accel.rst | 6 +- docs/pyboard/tutorial/leds.rst | 2 +- docs/pyboard/tutorial/repl.rst | 2 +- docs/pyboard/tutorial/reset.rst | 2 +- docs/reference/asm_thumb2_hints_tips.rst | 6 +- docs/reference/constrained.rst | 2 +- docs/reference/speed_python.rst | 8 +- docs/wipy/quickref.rst | 4 +- docs/wipy/tutorial/reset.rst | 6 +- docs/wipy/tutorial/timer.rst | 2 +- docs/wipy/tutorial/wlan.rst | 6 +- 31 files changed, 125 insertions(+), 127 deletions(-) diff --git a/docs/develop/extendingmicropython.rst b/docs/develop/extendingmicropython.rst index 7fb1ae47a0..b4029c421c 100644 --- a/docs/develop/extendingmicropython.rst +++ b/docs/develop/extendingmicropython.rst @@ -16,4 +16,3 @@ live in the main MicroPython repository. cmodules.rst natmod.rst - \ No newline at end of file diff --git a/docs/develop/gettingstarted.rst b/docs/develop/gettingstarted.rst index 30b26071ea..36062ddc00 100644 --- a/docs/develop/gettingstarted.rst +++ b/docs/develop/gettingstarted.rst @@ -4,7 +4,7 @@ Getting Started =============== This guide covers a step-by-step process on setting up version control, obtaining and building -a copy of the source code for a port, building the documentation, running tests, and a description of the +a copy of the source code for a port, building the documentation, running tests, and a description of the directory structure of the MicroPython code base. Source control with git @@ -16,7 +16,7 @@ code is pulled and pushed to and from the main repository. Install the respectiv of Git for your operating system to follow through the rest of the steps. .. note:: - For a reference on the installation instructions, please refer to + For a reference on the installation instructions, please refer to the `Git installation instructions `_. Learn about the basic git commands in this `Git Handbook `_ or any other sources on the internet. @@ -58,12 +58,12 @@ MicroPython repository. After the above configuration, your setup should be similar to this: .. code-block:: bash - + $ git remote -v - origin https://github.com//micropython (fetch) - origin https://github.com//micropython (push) - upstream https://github.com/micropython/micropython (fetch) - upstream https://github.com/micropython/micropython (push) + origin https://github.com//micropython (fetch) + origin https://github.com//micropython (push) + upstream https://github.com/micropython/micropython (fetch) + upstream https://github.com/micropython/micropython (push) You should now have a copy of the source code. By default, you are pointing to the master branch. To prepare for further development, it is recommended @@ -73,7 +73,7 @@ to work on a development branch. $ git checkout -b dev-branch -You can give it any name. You will have to compile MicroPython whenever you change +You can give it any name. You will have to compile MicroPython whenever you change to a different branch. Compile and build the code @@ -140,8 +140,8 @@ If it built successfully, you should see a message similar to this: .. code-block:: bash LINK mpy-cross - text data bss dec hex filename - 279328 776 880 280984 44998 mpy-cross + text data bss dec hex filename + 279328 776 880 280984 44998 mpy-cross .. note:: @@ -181,8 +181,8 @@ If MicroPython built correctly, you should see the following: .. code-block:: bash LINK micropython - text data bss dec hex filename - 412033 5680 2496 420209 66971 micropython + text data bss dec hex filename + 412033 5680 2496 420209 66971 micropython Now run it: @@ -215,7 +215,7 @@ as detailed in the :ref:`required_dependencies` section, then build: $ make submodules $ make -Please refer to the `stm32 documentation `_ +Please refer to the `stm32 documentation `_ for more details on flashing the firmware. .. note:: @@ -259,7 +259,7 @@ Build the docs: $ make html -Open ``docs/build/html/index.html`` in your browser to view the docs locally. Refer to the +Open ``docs/build/html/index.html`` in your browser to view the docs locally. Refer to the documentation on `importing your documentation `_ to use Read the Docs. diff --git a/docs/develop/index.rst b/docs/develop/index.rst index 7a6a6be67c..327038f197 100644 --- a/docs/develop/index.rst +++ b/docs/develop/index.rst @@ -5,7 +5,7 @@ This chapter covers a tour of MicroPython from the perspective of a developer, c to MicroPython. It acts as a comprehensive resource on the implementation details of MicroPython for both novice and expert contributors. -Development around MicroPython usually involves modifying the core runtime, porting or +Development around MicroPython usually involves modifying the core runtime, porting or maintaining a new library. This guide describes at great depth, the implementation details of MicroPython including a getting started guide, compiler internals, porting MicroPython to a new platform and implementing a core MicroPython library. @@ -24,4 +24,3 @@ MicroPython to a new platform and implementing a core MicroPython library. publiccapi.rst extendingmicropython.rst porting.rst - \ No newline at end of file diff --git a/docs/develop/qstr.rst b/docs/develop/qstr.rst index cd1fc47862..5d1ac5bb4a 100644 --- a/docs/develop/qstr.rst +++ b/docs/develop/qstr.rst @@ -59,7 +59,7 @@ Processing happens in the following stages: information. Note that this step only uses files that have changed, which means that ``qstr.i.last`` will only contain data from files that have changed since the last compile. - + 2. ``qstr.split`` is an empty file created after running ``makeqstrdefs.py split`` on qstr.i.last. It's just used as a dependency to indicate that the step ran. This script outputs one file per input C file, ``genhdr/qstr/...file.c.qstr``, diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index 97b6fba38d..41c2fd6c65 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -415,14 +415,14 @@ I2S bus See :ref:`machine.I2S `. :: from machine import I2S, Pin - + i2s = I2S(0, sck=Pin(13), ws=Pin(14), sd=Pin(34), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=44100, ibuf=40000) # create I2S object i2s.write(buf) # write buffer of audio samples to I2S device - + i2s = I2S(1, sck=Pin(33), ws=Pin(25), sd=Pin(32), mode=I2S.RX, bits=16, format=I2S.MONO, rate=22050, ibuf=40000) # create I2S object i2s.readinto(buf) # fill buffer with audio samples from I2S device - -The I2S class is currently available as a Technical Preview. During the preview period, feedback from + +The I2S class is currently available as a Technical Preview. During the preview period, feedback from users is encouraged. Based on this feedback, the I2S class API and implementation may be changed. ESP32 has two I2S buses with id=0 and id=1 diff --git a/docs/esp32/tutorial/intro.rst b/docs/esp32/tutorial/intro.rst index 4c56738347..8ed42dbd3d 100644 --- a/docs/esp32/tutorial/intro.rst +++ b/docs/esp32/tutorial/intro.rst @@ -34,8 +34,8 @@ Please refer to the documentation for your board for further details. Getting the firmware -------------------- -The first thing you need to do is download the most recent MicroPython firmware -.bin file to load onto your ESP32 device. You can download it from the +The first thing you need to do is download the most recent MicroPython firmware +.bin file to load onto your ESP32 device. You can download it from the `MicroPython downloads page `_. From here, you have 3 main choices: diff --git a/docs/esp8266/tutorial/intro.rst b/docs/esp8266/tutorial/intro.rst index a5deb3532f..ac46e68b5a 100644 --- a/docs/esp8266/tutorial/intro.rst +++ b/docs/esp8266/tutorial/intro.rst @@ -41,8 +41,8 @@ Please refer to the documentation for your board for further details. Getting the firmware -------------------- -The first thing you need to do is download the most recent MicroPython firmware -.bin file to load onto your ESP8266 device. You can download it from the +The first thing you need to do is download the most recent MicroPython firmware +.bin file to load onto your ESP8266 device. You can download it from the `MicroPython downloads page `_. From here, you have 3 main choices @@ -64,7 +64,7 @@ such, only daily builds for 512kb modules are provided. Deploying the firmware ---------------------- -Once you have the MicroPython firmware (compiled code), you need to load it onto +Once you have the MicroPython firmware (compiled code), you need to load it onto your ESP8266 device. There are two main steps to do this: first you need to put your device in boot-loader mode, and second you need to copy across the firmware. The exact procedure for these steps is highly dependent on the diff --git a/docs/library/esp.rst b/docs/library/esp.rst index b9ae57bd97..5fb370065f 100644 --- a/docs/library/esp.rst +++ b/docs/library/esp.rst @@ -4,7 +4,7 @@ .. module:: esp :synopsis: functions related to the ESP8266 and ESP32 -The ``esp`` module contains specific functions related to both the ESP8266 and +The ``esp`` module contains specific functions related to both the ESP8266 and ESP32 modules. Some functions are only available on one or the other of these ports. diff --git a/docs/library/heapq.rst b/docs/library/heapq.rst index 5e808d544a..673871c5fc 100644 --- a/docs/library/heapq.rst +++ b/docs/library/heapq.rst @@ -23,7 +23,7 @@ Functions Pop the first item from the ``heap``, and return it. Raise ``IndexError`` if ``heap`` is empty. - + The returned item will be the smallest item in the ``heap``. .. function:: heapify(x) diff --git a/docs/library/lcd160cr.rst b/docs/library/lcd160cr.rst index 85e4b8f07a..25903eb22b 100644 --- a/docs/library/lcd160cr.rst +++ b/docs/library/lcd160cr.rst @@ -313,7 +313,7 @@ Advanced commands specified by :meth:`LCD160CR.set_spi_win`, starting from the top-left corner. The `framebuf `_ module can be used to construct frame buffers - and provides drawing primitives. Using a frame buffer will improve + and provides drawing primitives. Using a frame buffer will improve performance of animations when compared to drawing directly to the screen. .. method:: LCD160CR.set_scroll(on) diff --git a/docs/library/machine.ADCWiPy.rst b/docs/library/machine.ADCWiPy.rst index e500d00890..d4ccde2056 100644 --- a/docs/library/machine.ADCWiPy.rst +++ b/docs/library/machine.ADCWiPy.rst @@ -27,13 +27,13 @@ Constructors Create an ADC object associated with the given pin. This allows you to then read analog values on that pin. For more info check the `pinout and alternate functions - table. `_ + table. `_ - .. warning:: + .. warning:: - ADC pin input range is 0-1.4V (being 1.8V the absolute maximum that it - can withstand). When GP2, GP3, GP4 or GP5 are remapped to the - ADC block, 1.8 V is the maximum. If these pins are used in digital mode, + ADC pin input range is 0-1.4V (being 1.8V the absolute maximum that it + can withstand). When GP2, GP3, GP4 or GP5 are remapped to the + ADC block, 1.8 V is the maximum. If these pins are used in digital mode, then the maximum allowed input is 3.6V. Methods diff --git a/docs/library/machine.I2S.rst b/docs/library/machine.I2S.rst index d64fba33e4..abfbb08780 100644 --- a/docs/library/machine.I2S.rst +++ b/docs/library/machine.I2S.rst @@ -4,91 +4,91 @@ class I2S -- Inter-IC Sound bus protocol ======================================== -I2S is a synchronous serial protocol used to connect digital audio devices. +I2S is a synchronous serial protocol used to connect digital audio devices. At the physical level, a bus consists of 3 lines: SCK, WS, SD. The I2S class supports controller operation. Peripheral operation is not supported. -The I2S class is currently available as a Technical Preview. During the preview period, feedback from +The I2S class is currently available as a Technical Preview. During the preview period, feedback from users is encouraged. Based on this feedback, the I2S class API and implementation may be changed. I2S objects can be created and initialized using:: from machine import I2S from machine import Pin - + # ESP32 sck_pin = Pin(14) # Serial clock output ws_pin = Pin(13) # Word clock output sd_pin = Pin(12) # Serial data output - + or - + # PyBoards sck_pin = Pin("Y6") # Serial clock output ws_pin = Pin("Y5") # Word clock output sd_pin = Pin("Y8") # Serial data output - - audio_out = I2S(2, + + audio_out = I2S(2, sck=sck_pin, ws=ws_pin, sd=sd_pin, - mode=I2S.TX, - bits=16, + mode=I2S.TX, + bits=16, format=I2S.MONO, - rate=44100, + rate=44100, ibuf=20000) - - audio_in = I2S(2, + + audio_in = I2S(2, sck=sck_pin, ws=ws_pin, sd=sd_pin, - mode=I2S.RX, - bits=32, + mode=I2S.RX, + bits=32, format=I2S.STEREO, - rate=22050, + rate=22050, ibuf=20000) - + 3 modes of operation are supported: - - blocking - - non-blocking + - blocking + - non-blocking - uasyncio - + blocking:: - + num_written = audio_out.write(buf) # blocks until buf emptied num_read = audio_in.readinto(buf) # blocks until buf filled - + non-blocking:: - + audio_out.irq(i2s_callback) # i2s_callback is called when buf is emptied num_written = audio_out.write(buf) # returns immediately - + audio_in.irq(i2s_callback) # i2s_callback is called when buf is filled - num_read = audio_in.readinto(buf) # returns immediately - + num_read = audio_in.readinto(buf) # returns immediately + uasyncio:: - + swriter = uasyncio.StreamWriter(audio_out) swriter.write(buf) await swriter.drain() - + sreader = uasyncio.StreamReader(audio_in) num_read = await sreader.readinto(buf) - + Constructor ----------- .. class:: I2S(id, *, sck, ws, sd, mode, bits, format, rate, ibuf) Construct an I2S object of the given id: - - - ``id`` identifies a particular I2S bus. + + - ``id`` identifies a particular I2S bus. ``id`` is board and port specific: - + - PYBv1.0/v1.1: has one I2S bus with id=2. - - PYBD-SFxW: has two I2S buses with id=1 and id=2. - - ESP32: has two I2S buses with id=0 and id=1. - + - PYBD-SFxW: has two I2S buses with id=1 and id=2. + - ESP32: has two I2S buses with id=0 and id=1. + Keyword-only parameters that are supported on all ports: - + - ``sck`` is a pin object for the serial clock line - ``ws`` is a pin object for the word select line - ``sd`` is a pin object for the serial data line @@ -97,9 +97,9 @@ Constructor - ``format`` specifies channel format, STEREO or MONO - ``rate`` specifies audio sampling rate (samples/s) - ``ibuf`` specifies internal buffer length (bytes) - - For all ports, DMA runs continuously in the background and allows user applications to perform other operations while - sample data is transfered between the internal buffer and the I2S peripheral unit. + + For all ports, DMA runs continuously in the background and allows user applications to perform other operations while + sample data is transfered between the internal buffer and the I2S peripheral unit. Increasing the size of the internal buffer has the potential to increase the time that user applications can perform non-I2S operations before underflow (e.g. ``write`` method) or overflow (e.g. ``readinto`` method). @@ -109,37 +109,37 @@ Methods .. method:: I2S.init(sck, ...) see Constructor for argument descriptions - + .. method:: I2S.deinit() Deinitialize the I2S bus - + .. method:: I2S.readinto(buf) - Read audio samples into the buffer specified by ``buf``. ``buf`` must support the buffer protocol, such as bytearray or array. - "buf" byte ordering is little-endian. For Stereo format, left channel sample precedes right channel sample. For Mono format, + Read audio samples into the buffer specified by ``buf``. ``buf`` must support the buffer protocol, such as bytearray or array. + "buf" byte ordering is little-endian. For Stereo format, left channel sample precedes right channel sample. For Mono format, the left channel sample data is used. - Returns number of bytes read - + Returns number of bytes read + .. method:: I2S.write(buf) Write audio samples contained in ``buf``. ``buf`` must support the buffer protocol, such as bytearray or array. - "buf" byte ordering is little-endian. For Stereo format, left channel sample precedes right channel sample. For Mono format, + "buf" byte ordering is little-endian. For Stereo format, left channel sample precedes right channel sample. For Mono format, the sample data is written to both the right and left channels. - Returns number of bytes written - + Returns number of bytes written + .. method:: I2S.irq(handler) - Set a callback. ``handler`` is called when ``buf`` is emptied (``write`` method) or becomes full (``readinto`` method). + Set a callback. ``handler`` is called when ``buf`` is emptied (``write`` method) or becomes full (``readinto`` method). Setting a callback changes the ``write`` and ``readinto`` methods to non-blocking operation. ``handler`` is called in the context of the MicroPython scheduler. - + .. staticmethod:: I2S.shift(*, buf, bits, shift) - bitwise shift of all samples contained in ``buf``. ``bits`` specifies sample size in bits. ``shift`` specifies the number of bits to shift each sample. - Positive for left shift, negative for right shift. + bitwise shift of all samples contained in ``buf``. ``bits`` specifies sample size in bits. ``shift`` specifies the number of bits to shift each sample. + Positive for left shift, negative for right shift. Typically used for volume control. Each bit shift changes sample volume by 6dB. - + Constants --------- diff --git a/docs/library/machine.SD.rst b/docs/library/machine.SD.rst index d985db231a..c736dc4d28 100644 --- a/docs/library/machine.SD.rst +++ b/docs/library/machine.SD.rst @@ -32,7 +32,7 @@ Constructors .. class:: SD(id,... ) - Create a SD card object. See ``init()`` for parameters if initialization. + Create a SD card object. See ``init()`` for parameters if initialization. Methods ------- diff --git a/docs/library/machine.SDCard.rst b/docs/library/machine.SDCard.rst index 96fb5b01c8..b07ad37d39 100644 --- a/docs/library/machine.SDCard.rst +++ b/docs/library/machine.SDCard.rst @@ -50,7 +50,7 @@ vary from platform to platform. - *mosi* can be used to specify an SPI mosi pin. - *cs* can be used to specify an SPI chip select pin. - + - *freq* selects the SD/MMC interface frequency in Hz (only supported on the ESP32). Implementation-specific details diff --git a/docs/library/machine.TimerWiPy.rst b/docs/library/machine.TimerWiPy.rst index 39afc23bc5..f8c8bb29da 100644 --- a/docs/library/machine.TimerWiPy.rst +++ b/docs/library/machine.TimerWiPy.rst @@ -50,9 +50,9 @@ Methods - ``mode`` can be one of: - - ``TimerWiPy.ONE_SHOT`` - The timer runs once until the configured + - ``TimerWiPy.ONE_SHOT`` - The timer runs once until the configured period of the channel expires. - - ``TimerWiPy.PERIODIC`` - The timer runs periodically at the configured + - ``TimerWiPy.PERIODIC`` - The timer runs periodically at the configured frequency of the channel. - ``TimerWiPy.PWM`` - Output a PWM signal on a pin. @@ -74,7 +74,7 @@ Methods The operating mode is is the one configured to the Timer object that was used to create the channel. - - ``channel`` if the width of the timer is 16-bit, then must be either ``TIMER.A``, ``TIMER.B``. + - ``channel`` if the width of the timer is 16-bit, then must be either ``TIMER.A``, ``TIMER.B``. If the width is 32-bit then it **must be** ``TIMER.A | TIMER.B``. Keyword only arguments: diff --git a/docs/library/machine.UART.rst b/docs/library/machine.UART.rst index 2eb2e20cb3..8fb42cfe87 100644 --- a/docs/library/machine.UART.rst +++ b/docs/library/machine.UART.rst @@ -64,7 +64,7 @@ Methods - *timeout_char* specifies the time to wait between characters (in ms). - *invert* specifies which lines to invert. - *flow* specifies which hardware flow control signals to use. The value - is a bitmask. + is a bitmask. - ``0`` will ignore hardware flow control signals. - ``UART.RTS`` will enable receive flow control by using the RTS output pin to diff --git a/docs/library/machine.WDT.rst b/docs/library/machine.WDT.rst index 612f23ba38..3c799583e6 100644 --- a/docs/library/machine.WDT.rst +++ b/docs/library/machine.WDT.rst @@ -24,7 +24,7 @@ Constructors Create a WDT object and start it. The timeout must be given in milliseconds. Once it is running the timeout cannot be changed and the WDT cannot be stopped either. - + Notes: On the esp32 the minimum timeout is 1 second. On the esp8266 a timeout cannot be specified, it is determined by the underlying system. diff --git a/docs/library/machine.rst b/docs/library/machine.rst index c2a6b39001..5f45168ed6 100644 --- a/docs/library/machine.rst +++ b/docs/library/machine.rst @@ -203,7 +203,7 @@ Classes machine.UART.rst machine.SPI.rst machine.I2C.rst - machine.I2S.rst + machine.I2S.rst machine.RTC.rst machine.Timer.rst machine.WDT.rst diff --git a/docs/library/pyb.Pin.rst b/docs/library/pyb.Pin.rst index 6465653f74..97dfbffbcf 100644 --- a/docs/library/pyb.Pin.rst +++ b/docs/library/pyb.Pin.rst @@ -120,7 +120,7 @@ Methods - *value* if not None will set the port output value before enabling the pin. - *alt* can be used when mode is ``Pin.AF_PP`` or ``Pin.AF_OD`` to set the - index or name of one of the alternate functions associated with a pin. + index or name of one of the alternate functions associated with a pin. This arg was previously called *af* which can still be used if needed. Returns: ``None``. diff --git a/docs/pyboard/quickref.rst b/docs/pyboard/quickref.rst index ed56811ddb..62157bff0a 100644 --- a/docs/pyboard/quickref.rst +++ b/docs/pyboard/quickref.rst @@ -225,20 +225,20 @@ I2S bus See :ref:`machine.I2S `. :: from machine import I2S, Pin - + i2s = I2S(2, sck=Pin('Y6'), ws=Pin('Y5'), sd=Pin('Y8'), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=44100, ibuf=40000) # create I2S object i2s.write(buf) # write buffer of audio samples to I2S device - + i2s = I2S(1, sck=Pin('X5'), ws=Pin('X6'), sd=Pin('Y4'), mode=I2S.RX, bits=16, format=I2S.MONO, rate=22050, ibuf=40000) # create I2S object i2s.readinto(buf) # fill buffer with audio samples from I2S device - -The I2S class is currently available as a Technical Preview. During the preview period, feedback from + +The I2S class is currently available as a Technical Preview. During the preview period, feedback from users is encouraged. Based on this feedback, the I2S class API and implementation may be changed. -PYBv1.0/v1.1 has one I2S bus with id=2. -PYBD-SFxW has two I2S buses with id=1 and id=2. -I2S is shared with SPI. - +PYBv1.0/v1.1 has one I2S bus with id=2. +PYBD-SFxW has two I2S buses with id=1 and id=2. +I2S is shared with SPI. + CAN bus (controller area network) --------------------------------- diff --git a/docs/pyboard/tutorial/accel.rst b/docs/pyboard/tutorial/accel.rst index 58170e74ff..dff71f2ee5 100644 --- a/docs/pyboard/tutorial/accel.rst +++ b/docs/pyboard/tutorial/accel.rst @@ -29,7 +29,7 @@ We will start by using the accelerometer to turn on a light if it is not flat. : while True: x = accel.x() - if abs(x) > SENSITIVITY: + if abs(x) > SENSITIVITY: light.on() else: light.off() @@ -61,7 +61,7 @@ use the ``y()`` value and more LEDs we can turn the pyboard into a spirit level. while True: x = accel.x() - if x > SENSITIVITY: + if x > SENSITIVITY: xlights[0].on() xlights[1].off() elif x < -SENSITIVITY: @@ -72,7 +72,7 @@ use the ``y()`` value and more LEDs we can turn the pyboard into a spirit level. xlights[1].off() y = accel.y() - if y > SENSITIVITY: + if y > SENSITIVITY: ylights[0].on() ylights[1].off() elif y < -SENSITIVITY: diff --git a/docs/pyboard/tutorial/leds.rst b/docs/pyboard/tutorial/leds.rst index 05f3b619e3..63acc63cee 100644 --- a/docs/pyboard/tutorial/leds.rst +++ b/docs/pyboard/tutorial/leds.rst @@ -47,7 +47,7 @@ Here, n keeps track of the current LED and every time the loop is executed we cy One problem you might find is that if you stop the script and then start it again that the LEDs are stuck on from the previous run, ruining our carefully choreographed disco. We can fix this by turning all the LEDs off when we initialise the script and then using a try/finally block. When you press CTRL-C, MicroPython generates a VCPInterrupt exception. Exceptions normally mean something has gone wrong and you can use a try: command to "catch" an exception. In this case it is just the user interrupting the script, so we don't need to catch the error but just tell MicroPython what to do when we exit. The finally block does this, and we use it to make sure all the LEDs are off. The full code is:: leds = [pyb.LED(i) for i in range(1,5)] - for l in leds: + for l in leds: l.off() n = 0 diff --git a/docs/pyboard/tutorial/repl.rst b/docs/pyboard/tutorial/repl.rst index 973d1846a0..b28d9cd57e 100644 --- a/docs/pyboard/tutorial/repl.rst +++ b/docs/pyboard/tutorial/repl.rst @@ -73,7 +73,7 @@ indicate that you should type the text after it at the prompt. In the end, once you have entered the text ``print("hello pyboard!")`` and pressed Enter, the output on your screen should look like it does above. -If you already know some python you can now try some basic commands here. +If you already know some python you can now try some basic commands here. If any of this is not working you can try either a hard reset or a soft reset; see below. diff --git a/docs/pyboard/tutorial/reset.rst b/docs/pyboard/tutorial/reset.rst index 0cd5ac21c8..59a3cd82ae 100644 --- a/docs/pyboard/tutorial/reset.rst +++ b/docs/pyboard/tutorial/reset.rst @@ -21,7 +21,7 @@ To enter safe mode, do the following steps: 4. The LEDs will then cycle green to orange to green+orange and back again. 5. Keep holding down USR until *only the orange LED is lit*, and then let go of the USR switch. -6. The orange LED should flash quickly 4 times, and then turn off. +6. The orange LED should flash quickly 4 times, and then turn off. 7. You are now in safe mode. In safe mode, the ``boot.py`` and ``main.py`` files are not executed, and so diff --git a/docs/reference/asm_thumb2_hints_tips.rst b/docs/reference/asm_thumb2_hints_tips.rst index 062a3c8448..361e44380b 100644 --- a/docs/reference/asm_thumb2_hints_tips.rst +++ b/docs/reference/asm_thumb2_hints_tips.rst @@ -3,7 +3,7 @@ Hints and tips The following are some examples of the use of the inline assembler and some information on how to work around its limitations. In this document the term -"assembler function" refers to a function declared in Python with the +"assembler function" refers to a function declared in Python with the ``@micropython.asm_thumb`` decorator, whereas "subroutine" refers to assembler code called from within an assembler function. @@ -106,8 +106,8 @@ function can return multiple values by assigning them to array elements. Assembler functions have no means of determining the length of an array: this will need to be passed to the function. -This use of arrays can be extended to enable more than three arrays to be used. -This is done using indirection: the ``uctypes`` module supports ``addressof()`` +This use of arrays can be extended to enable more than three arrays to be used. +This is done using indirection: the ``uctypes`` module supports ``addressof()`` which will return the address of an array passed as its argument. Thus you can populate an integer array with the addresses of other arrays: diff --git a/docs/reference/constrained.rst b/docs/reference/constrained.rst index 2a5f9d7fdb..816a20f9da 100644 --- a/docs/reference/constrained.rst +++ b/docs/reference/constrained.rst @@ -144,7 +144,7 @@ store constant data: As in the string example, at runtime a reference to the arbitrarily large integer is assigned to the variable ``bar``. That reference occupies a -single machine word. +single machine word. It might be expected that tuples of integers could be employed for the purpose of storing constant data with minimal RAM use. With the current compiler this diff --git a/docs/reference/speed_python.rst b/docs/reference/speed_python.rst index 85e956e8e6..834a53b0a7 100644 --- a/docs/reference/speed_python.rst +++ b/docs/reference/speed_python.rst @@ -36,7 +36,7 @@ Algorithms ~~~~~~~~~~ The most important aspect of designing any routine for performance is ensuring that -the best algorithm is employed. This is a topic for textbooks rather than for a +the best algorithm is employed. This is a topic for textbooks rather than for a MicroPython guide but spectacular performance gains can sometimes be achieved by adopting algorithms known for their efficiency. @@ -210,7 +210,7 @@ no adaptation (but see below). It is invoked by means of a function decorator: buf = self.linebuf # Cached object # code -There are certain limitations in the current implementation of the native code emitter. +There are certain limitations in the current implementation of the native code emitter. * Context managers are not supported (the ``with`` statement). * Generators are not supported. @@ -222,7 +222,7 @@ increase in compiled code size. The Viper code emitter ---------------------- -The optimisations discussed above involve standards-compliant Python code. The +The optimisations discussed above involve standards-compliant Python code. The Viper code emitter is not fully compliant. It supports special Viper native data types in pursuit of performance. Integer processing is non-compliant because it uses machine words: arithmetic on 32 bit hardware is performed modulo 2**32. @@ -237,7 +237,7 @@ bit manipulations. It is invoked using a decorator: def foo(self, arg: int) -> int: # code -As the above fragment illustrates it is beneficial to use Python type hints to assist the Viper optimiser. +As the above fragment illustrates it is beneficial to use Python type hints to assist the Viper optimiser. Type hints provide information on the data types of arguments and of the return value; these are a standard Python language feature formally defined here `PEP0484 `_. Viper supports its own set of types namely ``int``, ``uint`` (unsigned integer), ``ptr``, ``ptr8``, diff --git a/docs/wipy/quickref.rst b/docs/wipy/quickref.rst index f9ea3d501e..4c3b969bd1 100644 --- a/docs/wipy/quickref.rst +++ b/docs/wipy/quickref.rst @@ -154,7 +154,7 @@ See :ref:`machine.RTC ` :: pass # do some non blocking operations # warning printing on an irq via telnet is not - # possible, only via UART + # possible, only via UART # create a RTC alarm that expires after 5 seconds rtc.alarm(time=5000, repeat=False) @@ -179,7 +179,7 @@ See :ref:`machine.SD `. :: sd = SD() os.mount(sd, '/sd') -WLAN (WiFi) +WLAN (WiFi) ----------- See :ref:`network.WLAN ` and :mod:`machine`. :: diff --git a/docs/wipy/tutorial/reset.rst b/docs/wipy/tutorial/reset.rst index ece28498b8..1715d3e297 100644 --- a/docs/wipy/tutorial/reset.rst +++ b/docs/wipy/tutorial/reset.rst @@ -1,10 +1,10 @@ Reset and boot modes ==================== -There are soft resets and hard resets. +There are soft resets and hard resets. - - A soft reset simply clears the state of the MicroPython virtual machine, - but leaves hardware peripherals unaffected. To do a soft reset, simply press + - A soft reset simply clears the state of the MicroPython virtual machine, + but leaves hardware peripherals unaffected. To do a soft reset, simply press **Ctrl+D** on the REPL, or within a script do:: import sys diff --git a/docs/wipy/tutorial/timer.rst b/docs/wipy/tutorial/timer.rst index c87ac44959..7cd7d0f134 100644 --- a/docs/wipy/tutorial/timer.rst +++ b/docs/wipy/tutorial/timer.rst @@ -5,7 +5,7 @@ Timers can be used for a great variety of tasks, calling a function periodically counting events, and generating a PWM signal are among the most common use cases. Each timer consists of two 16-bit channels and this channels can be tied together to form one 32-bit timer. The operating mode needs to be configured per timer, but then -the period (or the frequency) can be independently configured on each channel. +the period (or the frequency) can be independently configured on each channel. By using the callback method, the timer event can call a Python function. Example usage to toggle an LED at a fixed frequency:: diff --git a/docs/wipy/tutorial/wlan.rst b/docs/wipy/tutorial/wlan.rst index 434367cd93..bdfd3e0a54 100644 --- a/docs/wipy/tutorial/wlan.rst +++ b/docs/wipy/tutorial/wlan.rst @@ -13,9 +13,9 @@ You can check the current mode (which is always ``WLAN.AP`` after power up):: >>> wlan.mode() -.. warning:: - When you change the WLAN mode following the instructions below, your WLAN - connection to the WiPy will be broken. This means you will not be able +.. warning:: + When you change the WLAN mode following the instructions below, your WLAN + connection to the WiPy will be broken. This means you will not be able to run these commands interactively over the WLAN. There are two ways around this:: From e9f880482cbe21002e9568aa82893b2b98956a56 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Fri, 26 Nov 2021 16:18:11 +0100 Subject: [PATCH 250/335] tools/upip.py: Support == to specify exact package version. --- tools/upip.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/upip.py b/tools/upip.py index 728b843c94..a6d4c93ae3 100644 --- a/tools/upip.py +++ b/tools/upip.py @@ -192,9 +192,13 @@ def fatal(msg, exc=None): def install_pkg(pkg_spec, install_path): - data = get_pkg_metadata(pkg_spec) + package = pkg_spec.split("==") + data = get_pkg_metadata(package[0]) - latest_ver = data["info"]["version"] + if len(package) == 1: + latest_ver = data["info"]["version"] + else: + latest_ver = package[1] packages = data["releases"][latest_ver] del data gc.collect() From f9733705a907a9e9c3b3e6ab613cc1d7f63b51a6 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Thu, 20 May 2021 19:15:52 +0200 Subject: [PATCH 251/335] esp32/machine_pin: Make GPIO 26 usable for S2,S3 if SPIRAM not config'd. Signed-off-by: Tomas Vanek --- ports/esp32/machine_pin.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ports/esp32/machine_pin.c b/ports/esp32/machine_pin.c index 42c4194269..c0c7ddb705 100644 --- a/ports/esp32/machine_pin.c +++ b/ports/esp32/machine_pin.c @@ -177,7 +177,11 @@ STATIC const machine_pin_obj_t machine_pin_obj[] = { {{NULL}, -1}, // 23 not a pin {{NULL}, -1}, // 24 not a pin {{NULL}, -1}, // 25 not a pin - {{NULL}, -1}, // 26 FLASH/PSRAM + #if CONFIG_SPIRAM + {{NULL}, -1}, // 26 PSRAM + #else + {{&machine_pin_type}, GPIO_NUM_26}, + #endif {{NULL}, -1}, // 27 FLASH/PSRAM {{NULL}, -1}, // 28 FLASH/PSRAM {{NULL}, -1}, // 29 FLASH/PSRAM @@ -618,7 +622,11 @@ STATIC const machine_pin_irq_obj_t machine_pin_irq_object[] = { {{NULL}, -1}, // 23 not a pin {{NULL}, -1}, // 24 not a pin {{NULL}, -1}, // 25 not a pin - {{NULL}, -1}, // 26 FLASH/PSRAM + #if CONFIG_SPIRAM + {{NULL}, -1}, // 26 PSRAM + #else + {{&machine_pin_irq_type}, GPIO_NUM_26}, + #endif {{NULL}, -1}, // 27 FLASH/PSRAM {{NULL}, -1}, // 28 FLASH/PSRAM {{NULL}, -1}, // 29 FLASH/PSRAM From 3305ec44a2f45f9afbae029d157d49d1270cf21d Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Wed, 1 Dec 2021 18:34:39 +0100 Subject: [PATCH 252/335] esp32/machine_hw_spi: Fix SPI default pins reordering on ESP32-S2/S3. The index of machine_hw_spi_obj and machine_hw_spi_default_pins arrays is assigned to 0 for ARG_id==HSPI_HOST and 1 for another SPI. On ESP32S2 and S3 HSPI_HOST=2 so the first set (idx=0) of default pins is used for SPI(id=2) aka HSPI/SPI3 and the second set (idx=1) for SPI(id=1) aka FSPI/SPI2. This makes a misleading mess in MICROPY_HW_SPIxxxx definitions and it is also in contradiction to the comments around the definitions. Change the test of ARG_id to fix the order of machine_hw_spi_default_pins. This change might require adjusting MICROPY_HW_SPIxxxx definitions in mpconfigboard.h of S2/S3 based boards. Signed-off-by: Tomas Vanek --- ports/esp32/machine_hw_spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/esp32/machine_hw_spi.c b/ports/esp32/machine_hw_spi.c index 467bff7ccb..27afa60afd 100644 --- a/ports/esp32/machine_hw_spi.c +++ b/ports/esp32/machine_hw_spi.c @@ -458,7 +458,7 @@ mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_ machine_hw_spi_obj_t *self; const machine_hw_spi_default_pins_t *default_pins; - if (args[ARG_id].u_int == HSPI_HOST) { + if (args[ARG_id].u_int == 1) { // SPI2_HOST which is FSPI_HOST on ESP32Sx, HSPI_HOST on others self = &machine_hw_spi_obj[0]; default_pins = &machine_hw_spi_default_pins[0]; } else { From d08886558b2033c200a136620de039cd48abe86e Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 29 Nov 2021 12:57:28 +0100 Subject: [PATCH 253/335] esp32/machine_hw_spi: Set proper default SPI(id=1) pins on S2,S3 and C3. Use IO_MUX pins as defined by ESP IDF in soc/esp32*/include/soc/spi_pins.h Alternatively use now deprecated HSPI_IOMUX_PIN_NUM_xxx (or FSPI_IOMUX_PIN_NUM_xxx for ESP32S2) for compatibility with IDF 4.2 and older. Signed-off-by: Tomas Vanek --- ports/esp32/machine_hw_spi.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/ports/esp32/machine_hw_spi.c b/ports/esp32/machine_hw_spi.c index 27afa60afd..acdabcb2a0 100644 --- a/ports/esp32/machine_hw_spi.c +++ b/ports/esp32/machine_hw_spi.c @@ -36,11 +36,31 @@ #include "driver/spi_master.h" -// Default pins for SPI(1), can be overridden by a board +// SPI mappings by device, naming used by IDF old/new +// upython | ESP32 | ESP32S2 | ESP32S3 | ESP32C3 +// ----------+-----------+-----------+---------+--------- +// SPI(id=1) | HSPI/SPI2 | FSPI/SPI2 | SPI2 | SPI2 +// SPI(id=2) | VSPI/SPI3 | HSPI/SPI3 | SPI3 | err + +// Default pins for SPI(id=1) aka IDF SPI2, can be overridden by a board #ifndef MICROPY_HW_SPI1_SCK -#define MICROPY_HW_SPI1_SCK (14) -#define MICROPY_HW_SPI1_MOSI (13) -#define MICROPY_HW_SPI1_MISO (12) +#ifdef SPI2_IOMUX_PIN_NUM_CLK +// Use IO_MUX pins by default. +// If SPI lines are routed to other pins through GPIO matrix +// routing adds some delay and lower limit applies to SPI clk freq +#define MICROPY_HW_SPI1_SCK SPI2_IOMUX_PIN_NUM_CLK // pin 14 on ESP32 +#define MICROPY_HW_SPI1_MOSI SPI2_IOMUX_PIN_NUM_MOSI // pin 13 on ESP32 +#define MICROPY_HW_SPI1_MISO SPI2_IOMUX_PIN_NUM_MISO // pin 12 on ESP32 +// Only for compatibility with IDF 4.2 and older +#elif CONFIG_IDF_TARGET_ESP32S2 +#define MICROPY_HW_SPI1_SCK FSPI_IOMUX_PIN_NUM_CLK +#define MICROPY_HW_SPI1_MOSI FSPI_IOMUX_PIN_NUM_MOSI +#define MICROPY_HW_SPI1_MISO FSPI_IOMUX_PIN_NUM_MISO +#else +#define MICROPY_HW_SPI1_SCK HSPI_IOMUX_PIN_NUM_CLK +#define MICROPY_HW_SPI1_MOSI HSPI_IOMUX_PIN_NUM_MOSI +#define MICROPY_HW_SPI1_MISO HSPI_IOMUX_PIN_NUM_MISO +#endif #endif // Default pins for SPI(2), can be overridden by a board From e761152d723ccbc472ec4f29ebb60a1ff6d34827 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 29 Nov 2021 16:49:11 +0100 Subject: [PATCH 254/335] esp32/machine_hw_spi: Set proper default SPI(id=2) pins on S2 and S3. Use IO_MUX pins as defined by ESP IDF in soc/esp32/include/soc/spi_pins.h ESP32S2 and S3 don't have IO_MUX pins for SPI3, GPIO matrix is always used. Choose suitable defaults for S2 and S3. ESP32C3 does not have SPI3 at all. Don't define pin mappings for it. Signed-off-by: Tomas Vanek --- ports/esp32/machine_hw_spi.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/ports/esp32/machine_hw_spi.c b/ports/esp32/machine_hw_spi.c index acdabcb2a0..1515b00744 100644 --- a/ports/esp32/machine_hw_spi.c +++ b/ports/esp32/machine_hw_spi.c @@ -63,11 +63,20 @@ #endif #endif -// Default pins for SPI(2), can be overridden by a board +// Default pins for SPI(id=2) aka IDF SPI3, can be overridden by a board #ifndef MICROPY_HW_SPI2_SCK -#define MICROPY_HW_SPI2_SCK (18) -#define MICROPY_HW_SPI2_MOSI (23) -#define MICROPY_HW_SPI2_MISO (19) +#if CONFIG_IDF_TARGET_ESP32 +// ESP32 has IO_MUX pins for VSPI/SPI3 lines, use them as defaults +#define MICROPY_HW_SPI2_SCK VSPI_IOMUX_PIN_NUM_CLK // pin 18 +#define MICROPY_HW_SPI2_MOSI VSPI_IOMUX_PIN_NUM_MOSI // pin 23 +#define MICROPY_HW_SPI2_MISO VSPI_IOMUX_PIN_NUM_MISO // pin 19 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +// ESP32S2 and S3 uses GPIO matrix for SPI3 pins, no IO_MUX possible +// Set defaults to the pins used by SPI2 in Octal mode +#define MICROPY_HW_SPI2_SCK (36) +#define MICROPY_HW_SPI2_MOSI (35) +#define MICROPY_HW_SPI2_MISO (37) +#endif #endif #define MP_HW_SPI_MAX_XFER_BYTES (4092) @@ -108,7 +117,9 @@ typedef struct _machine_hw_spi_obj_t { // Default pin mappings for the hardware SPI instances STATIC const machine_hw_spi_default_pins_t machine_hw_spi_default_pins[2] = { { .sck = MICROPY_HW_SPI1_SCK, .mosi = MICROPY_HW_SPI1_MOSI, .miso = MICROPY_HW_SPI1_MISO }, + #ifdef MICROPY_HW_SPI2_SCK { .sck = MICROPY_HW_SPI2_SCK, .mosi = MICROPY_HW_SPI2_MOSI, .miso = MICROPY_HW_SPI2_MISO }, + #endif }; // Static objects mapping to HSPI and VSPI hardware peripherals From 9aa151e3f355dea6e14d77053f40691365e60d96 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Wed, 1 Dec 2021 22:09:28 +0100 Subject: [PATCH 255/335] esp32/boards: Remove SPI pin defaults from GENERIC S2/S3 boards. Default SPI pins are now correctly assigned by machine_hw_spi.c even for S2 and S3. mpconfigboard.h files define defaults with flipped SPI(1) and SPI(2) to workaround a bug in machine_hw_spi.c - the bug is fixed. Signed-off-by: Tomas Vanek --- ports/esp32/boards/ESP32_S2_WROVER/mpconfigboard.h | 7 ------- ports/esp32/boards/GENERIC_S3/mpconfigboard.h | 4 ---- ports/esp32/boards/GENERIC_S3_SPIRAM/mpconfigboard.h | 4 ---- 3 files changed, 15 deletions(-) diff --git a/ports/esp32/boards/ESP32_S2_WROVER/mpconfigboard.h b/ports/esp32/boards/ESP32_S2_WROVER/mpconfigboard.h index f9219c8767..a96262c607 100644 --- a/ports/esp32/boards/ESP32_S2_WROVER/mpconfigboard.h +++ b/ports/esp32/boards/ESP32_S2_WROVER/mpconfigboard.h @@ -6,10 +6,3 @@ #define MICROPY_HW_I2C0_SCL (7) #define MICROPY_HW_I2C0_SDA (6) - -#define MICROPY_HW_SPI1_MOSI (35) -#define MICROPY_HW_SPI1_MISO (37) -#define MICROPY_HW_SPI1_SCK (36) -#define MICROPY_HW_SPI2_MOSI (11) -#define MICROPY_HW_SPI2_MISO (13) -#define MICROPY_HW_SPI2_SCK (12) diff --git a/ports/esp32/boards/GENERIC_S3/mpconfigboard.h b/ports/esp32/boards/GENERIC_S3/mpconfigboard.h index f41917ff07..3540e5a855 100644 --- a/ports/esp32/boards/GENERIC_S3/mpconfigboard.h +++ b/ports/esp32/boards/GENERIC_S3/mpconfigboard.h @@ -5,7 +5,3 @@ #define MICROPY_HW_I2C0_SCL (9) #define MICROPY_HW_I2C0_SDA (8) - -#define MICROPY_HW_SPI1_MOSI (35) -#define MICROPY_HW_SPI1_MISO (36) -#define MICROPY_HW_SPI1_SCK (37) diff --git a/ports/esp32/boards/GENERIC_S3_SPIRAM/mpconfigboard.h b/ports/esp32/boards/GENERIC_S3_SPIRAM/mpconfigboard.h index 10085ae789..beb796dd9e 100644 --- a/ports/esp32/boards/GENERIC_S3_SPIRAM/mpconfigboard.h +++ b/ports/esp32/boards/GENERIC_S3_SPIRAM/mpconfigboard.h @@ -6,7 +6,3 @@ #define MICROPY_HW_I2C0_SCL (9) #define MICROPY_HW_I2C0_SDA (8) - -#define MICROPY_HW_SPI1_MOSI (35) -#define MICROPY_HW_SPI1_MISO (36) -#define MICROPY_HW_SPI1_SCK (37) From 598618e8cf46ef716596bcf97d21a989c4ac15d3 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 15 Dec 2021 16:51:08 +1100 Subject: [PATCH 256/335] tools/makemanifest.py: Make str conversion compatible with Python 2. Signed-off-by: Damien George --- tools/makemanifest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/makemanifest.py b/tools/makemanifest.py index 7897a83c6e..fc608ed449 100644 --- a/tools/makemanifest.py +++ b/tools/makemanifest.py @@ -347,7 +347,7 @@ def main(): ) if res != 0: print("error freezing mpy {}:".format(mpy_files)) - print(str(output_mpy, "utf8")) + print(output_mpy.decode()) sys.exit(1) else: output_mpy = ( From d6dc4cb65a222bd05ec2746c37e457c56484e780 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 15 Dec 2021 16:54:47 +1100 Subject: [PATCH 257/335] py/showbc: Fix printing of raw bytecode header on nanbox builds. Signed-off-by: Damien George --- py/showbc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py/showbc.c b/py/showbc.c index f3bd5ea15e..da8077eccd 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -98,8 +98,8 @@ void mp_bytecode_print(const mp_print_t *print, const void *descr, const byte *i // raw bytecode dump size_t prelude_size = ip - mp_showbc_code_start + n_info + n_cell; - mp_printf(print, "Raw bytecode (code_info_size=" UINT_FMT ", bytecode_size=" UINT_FMT "):\n", - prelude_size, len - prelude_size); + mp_printf(print, "Raw bytecode (code_info_size=%u, bytecode_size=%u):\n", + (unsigned)prelude_size, (unsigned)(len - prelude_size)); for (mp_uint_t i = 0; i < len; i++) { if (i > 0 && i % 16 == 0) { mp_printf(print, "\n"); From cc23e99f320e5465db93b8cc021972a634692b63 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 8 Dec 2021 14:18:39 +1100 Subject: [PATCH 258/335] py/modio: Remove io.resource_stream function. This feature is not enabled on any port, it's not in CPython's io module, and functionality is better suited to the micropython-lib implementation of pkg_resources. --- .../unix/variants/coverage/mpconfigvariant.h | 1 - py/modio.c | 47 ------------------- py/mpconfig.h | 11 ----- tests/io/resource_stream.py | 15 ------ tests/io/resource_stream.py.exp | 2 - tests/unix/extra_coverage.py | 6 --- tests/unix/extra_coverage.py.exp | 1 - 7 files changed, 83 deletions(-) delete mode 100644 tests/io/resource_stream.py delete mode 100644 tests/io/resource_stream.py.exp diff --git a/ports/unix/variants/coverage/mpconfigvariant.h b/ports/unix/variants/coverage/mpconfigvariant.h index 942117608f..f033dddb10 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.h +++ b/ports/unix/variants/coverage/mpconfigvariant.h @@ -51,7 +51,6 @@ #define MICROPY_PY_MATH_FACTORIAL (1) #define MICROPY_PY_URANDOM_EXTRA_FUNCS (1) #define MICROPY_PY_IO_BUFFEREDWRITER (1) -#define MICROPY_PY_IO_RESOURCE_STREAM (1) #define MICROPY_PY_UASYNCIO (1) #define MICROPY_PY_URE_DEBUG (1) #define MICROPY_PY_URE_MATCH_GROUPS (1) diff --git a/py/modio.c b/py/modio.c index 7f0d13cdfa..e79d59e4e5 100644 --- a/py/modio.c +++ b/py/modio.c @@ -204,50 +204,6 @@ STATIC const mp_obj_type_t mp_type_bufwriter = { }; #endif // MICROPY_PY_IO_BUFFEREDWRITER -#if MICROPY_PY_IO_RESOURCE_STREAM -STATIC mp_obj_t resource_stream(mp_obj_t package_in, mp_obj_t path_in) { - VSTR_FIXED(path_buf, MICROPY_ALLOC_PATH_MAX); - size_t len; - - // As an extension to pkg_resources.resource_stream(), we support - // package parameter being None, the path_in is interpreted as a - // raw path. - if (package_in != mp_const_none) { - // Pass "True" as sentinel value in fromlist to force returning of leaf module - mp_obj_t pkg = mp_import_name(mp_obj_str_get_qstr(package_in), mp_const_true, MP_OBJ_NEW_SMALL_INT(0)); - - mp_obj_t dest[2]; - mp_load_method_maybe(pkg, MP_QSTR___path__, dest); - if (dest[0] == MP_OBJ_NULL) { - mp_raise_TypeError(NULL); - } - - const char *path = mp_obj_str_get_data(dest[0], &len); - vstr_add_strn(&path_buf, path, len); - vstr_add_byte(&path_buf, '/'); - } - - const char *path = mp_obj_str_get_data(path_in, &len); - vstr_add_strn(&path_buf, path, len); - - len = path_buf.len; - const char *data = mp_find_frozen_str(path_buf.buf, &len); - if (data != NULL) { - mp_obj_stringio_t *o = m_new_obj(mp_obj_stringio_t); - o->base.type = &mp_type_bytesio; - o->vstr = m_new_obj(vstr_t); - vstr_init_fixed_buf(o->vstr, len + 1, (char *)data); - o->vstr->len = len; - o->pos = 0; - return MP_OBJ_FROM_PTR(o); - } - - mp_obj_t path_out = mp_obj_new_str(path_buf.buf, path_buf.len); - return mp_builtin_open(1, &path_out, (mp_map_t *)&mp_const_empty_map); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(resource_stream_obj, resource_stream); -#endif - STATIC const mp_rom_map_elem_t mp_module_io_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uio) }, // Note: mp_builtin_open_obj should be defined by port, it's not @@ -256,9 +212,6 @@ STATIC const mp_rom_map_elem_t mp_module_io_globals_table[] = { #if MICROPY_PY_IO_IOBASE { MP_ROM_QSTR(MP_QSTR_IOBase), MP_ROM_PTR(&mp_type_iobase) }, #endif - #if MICROPY_PY_IO_RESOURCE_STREAM - { MP_ROM_QSTR(MP_QSTR_resource_stream), MP_ROM_PTR(&resource_stream_obj) }, - #endif #if MICROPY_PY_IO_FILEIO { MP_ROM_QSTR(MP_QSTR_FileIO), MP_ROM_PTR(&mp_type_fileio) }, #if MICROPY_CPYTHON_COMPAT diff --git a/py/mpconfig.h b/py/mpconfig.h index 308a776661..86e3e0f349 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1281,17 +1281,6 @@ typedef double mp_float_t; #define MICROPY_PY_IO_IOBASE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif -// Whether to provide "uio.resource_stream()" function with -// the semantics of CPython's pkg_resources.resource_stream() -// (allows to access binary resources in frozen source packages). -// Note that the same functionality can be achieved in "pure -// Python" by prepocessing binary resources into Python source -// and bytecode-freezing it (with a simple helper module available -// e.g. in micropython-lib). -#ifndef MICROPY_PY_IO_RESOURCE_STREAM -#define MICROPY_PY_IO_RESOURCE_STREAM (0) -#endif - // Whether to provide "io.FileIO" class #ifndef MICROPY_PY_IO_FILEIO #define MICROPY_PY_IO_FILEIO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) diff --git a/tests/io/resource_stream.py b/tests/io/resource_stream.py deleted file mode 100644 index b589ff99bf..0000000000 --- a/tests/io/resource_stream.py +++ /dev/null @@ -1,15 +0,0 @@ -import uio -import usys - -try: - uio.resource_stream -except AttributeError: - print("SKIP") - raise SystemExit - -buf = uio.resource_stream("data", "file2") -print(buf.read()) - -# resource_stream(None, ...) look ups from current dir, hence sys.path[0] hack -buf = uio.resource_stream(None, usys.path[0] + "/data/file2") -print(buf.read()) diff --git a/tests/io/resource_stream.py.exp b/tests/io/resource_stream.py.exp deleted file mode 100644 index 75404a347a..0000000000 --- a/tests/io/resource_stream.py.exp +++ /dev/null @@ -1,2 +0,0 @@ -1234 -1234 diff --git a/tests/unix/extra_coverage.py b/tests/unix/extra_coverage.py index b4808993a7..8ea27cbf2f 100644 --- a/tests/unix/extra_coverage.py +++ b/tests/unix/extra_coverage.py @@ -89,12 +89,6 @@ try: except ZeroDivisionError: print("ZeroDivisionError") -# test loading a resource from a frozen string -import uio - -buf = uio.resource_stream("frzstr_pkg2", "mod.py") -print(buf.read(21)) - # test for MP_QSTR_NULL regression from frzqstr import returns_NULL diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index ea91813fc6..8ee233a712 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -174,5 +174,4 @@ frzstr_pkg2.mod frzmpy_pkg2.mod 1 ZeroDivisionError -b'# test frozen package' NULL From f241db7efe1f2a27fcd17809a22fdf7385a0f75e Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 8 Dec 2021 16:02:42 +1100 Subject: [PATCH 259/335] teensy: Switch to use manifest.py instead of FROZEN_DIR. Signed-off-by: Jim Mussared --- ports/teensy/Makefile | 77 +++++++++++++++++++--------------------- ports/teensy/manifest.py | 1 + 2 files changed, 38 insertions(+), 40 deletions(-) create mode 100644 ports/teensy/manifest.py diff --git a/ports/teensy/Makefile b/ports/teensy/Makefile index d1ff421621..fe46b0e061 100644 --- a/ports/teensy/Makefile +++ b/ports/teensy/Makefile @@ -6,6 +6,42 @@ QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h # MicroPython feature configurations MICROPY_ROM_TEXT_COMPRESSION ?= 1 +USE_FROZEN = 1 +USE_MEMZIP = 0 + +ifeq ($(USE_MEMZIP),1) +SRC_C += \ + shared/memzip/import.c \ + shared/memzip/lexermemzip.c \ + shared/memzip/memzip.c \ + +OBJ += $(BUILD)/memzip-files.o + +MAKE_MEMZIP = $(TOP)/shared/memzip/make-memzip.py +ifeq ($(MEMZIP_DIR),) +MEMZIP_DIR = memzip_files +endif + +$(BUILD)/memzip-files.o: $(BUILD)/memzip-files.c + $(call compile_c) + +$(BUILD)/memzip-files.c: $(shell find ${MEMZIP_DIR} -type f) + @$(ECHO) "Creating $@" + $(Q)$(PYTHON) $(MAKE_MEMZIP) --zip-file $(BUILD)/memzip-files.zip --c-file $@ $(MEMZIP_DIR) + +endif # USE_MEMZIP + +ifeq ($(USE_FROZEN),1) + +FROZEN_MANIFEST ?= "manifest.py" + +CFLAGS += -DMICROPY_MODULE_FROZEN_STR + +SRC_C += \ + lexerfrozen.c + +endif # USE_FROZEN + # include py core make definitions include $(TOP)/py/py.mk @@ -76,10 +112,7 @@ endif CFLAGS += -fdata-sections -ffunction-sections LDFLAGS += -Wl,--gc-sections -USE_FROZEN = 1 -USE_MEMZIP = 0 - -SRC_C = \ +SRC_C += \ hal_ftm.c \ hal_gpio.c \ help.c \ @@ -127,42 +160,6 @@ OBJ += $(BUILD)/pins_gen.o all: hex hex: $(BUILD)/micropython.hex -ifeq ($(USE_MEMZIP),1) -SRC_C += \ - shared/memzip/import.c \ - shared/memzip/lexermemzip.c \ - shared/memzip/memzip.c \ - -OBJ += $(BUILD)/memzip-files.o - -MAKE_MEMZIP = $(TOP)/shared/memzip/make-memzip.py -ifeq ($(MEMZIP_DIR),) -MEMZIP_DIR = memzip_files -endif - -$(BUILD)/memzip-files.o: $(BUILD)/memzip-files.c - $(call compile_c) - -$(BUILD)/memzip-files.c: $(shell find ${MEMZIP_DIR} -type f) - @$(ECHO) "Creating $@" - $(Q)$(PYTHON) $(MAKE_MEMZIP) --zip-file $(BUILD)/memzip-files.zip --c-file $@ $(MEMZIP_DIR) - -endif # USE_MEMZIP - -ifeq ($(USE_FROZEN),1) - -ifeq ($(FROZEN_DIR),) -FROZEN_DIR = memzip_files -endif - -CFLAGS += -DMICROPY_MODULE_FROZEN_STR - -SRC_C += \ - lexerfrozen.c \ - $(BUILD)/frozen.c - -endif # USE_FROZEN - ifeq ($(ARDUINO),) post_compile: $(BUILD)/micropython.hex $(ECHO) "Please define ARDUINO (where TeensyDuino is installed)" diff --git a/ports/teensy/manifest.py b/ports/teensy/manifest.py new file mode 100644 index 0000000000..1fefd68687 --- /dev/null +++ b/ports/teensy/manifest.py @@ -0,0 +1 @@ +freeze_as_str("$(PORT_DIR)/memzip_files") From 92353c29110dba152dbf14c9f6359881866ec1de Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 8 Dec 2021 16:04:11 +1100 Subject: [PATCH 260/335] all: Remove support for FROZEN_DIR and FROZEN_MPY_DIR. These have been deprecated for over two years in favour of FROZEN_MANIFEST and manifest.py. Signed-off-by: Jim Mussared --- ports/esp8266/Makefile | 7 +---- ports/javascript/Makefile | 7 ----- ports/nrf/Makefile | 16 ++-------- ports/nrf/README.md | 14 --------- ports/stm32/Makefile | 11 ++----- ports/unix/Makefile | 9 ++---- py/mkrules.mk | 62 +++++---------------------------------- py/py.mk | 10 ------- 8 files changed, 15 insertions(+), 121 deletions(-) diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile index e771d8f7d3..d0afe73ea8 100644 --- a/ports/esp8266/Makefile +++ b/ports/esp8266/Makefile @@ -27,8 +27,6 @@ AXTLS_DEFS_EXTRA = -Dabort=abort_ -DRT_MAX_PLAIN_LENGTH=1024 -DRT_EXTRA=4096 BTREE_DEFS_EXTRA = -DDEFPSIZE=1024 -DMINCACHE=3 FROZEN_MANIFEST ?= boards/manifest.py -FROZEN_DIR ?= -FROZEN_MPY_DIR ?= # include py core make definitions include $(TOP)/py/py.mk @@ -196,12 +194,9 @@ $(BUILD)/uart.o: $(CONFVARS_FILE) FROZEN_EXTRA_DEPS = $(CONFVARS_FILE) -ifneq ($(FROZEN_MANIFEST)$(FROZEN_MPY_DIR),) +ifneq ($(FROZEN_MANIFEST),) CFLAGS += -DMICROPY_MODULE_FROZEN_MPY CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool -endif - -ifneq ($(FROZEN_MANIFEST)$(FROZEN_DIR),) CFLAGS += -DMICROPY_MODULE_FROZEN_STR endif diff --git a/ports/javascript/Makefile b/ports/javascript/Makefile index 3fac114f5e..ba2680b2a8 100644 --- a/ports/javascript/Makefile +++ b/ports/javascript/Makefile @@ -17,13 +17,6 @@ CFLAGS += -std=c99 -Wall -Werror -Wdouble-promotion -Wfloat-conversion CFLAGS += -O3 -DNDEBUG CFLAGS += $(INC) -ifneq ($(FROZEN_MPY_DIR),) -# To use frozen bytecode, put your .py files in a subdirectory (eg frozen/) and -# then invoke make with FROZEN_MPY_DIR=frozen (be sure to build from scratch). -CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool -CFLAGS += -DMICROPY_MODULE_FROZEN_MPY -endif - SRC_SHARED = $(addprefix shared/,\ runtime/interrupt_char.c \ runtime/stdout_helpers.c \ diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 423323a9c6..c32e09d2c9 100644 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -340,11 +340,6 @@ DRIVERS_SRC_C += $(addprefix modules/,\ SRC_C += \ device/startup_$(MCU_SUB_VARIANT).c \ -ifneq ($(FROZEN_MPY_DIR),) -FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py') -FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) -endif - LIBGCC_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) LIBS += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc @@ -542,17 +537,10 @@ GEN_PINS_QSTR = $(BUILD)/pins_qstr.h GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h GEN_PINS_AF_PY = $(BUILD)/pins_af.py -ifneq ($(FROZEN_MANIFEST)$(FROZEN_DIR),) -# To use frozen source modules, put your .py files in a subdirectory (eg scripts/) -# and then invoke make with FROZEN_DIR=scripts (be sure to build from scratch). -CFLAGS += -DMICROPY_MODULE_FROZEN_STR -endif - -ifneq ($(FROZEN_MANIFEST)$(FROZEN_MPY_DIR),) -# To use frozen bytecode, put your .py files in a subdirectory (eg frozen/) and -# then invoke make with FROZEN_MPY_DIR=frozen (be sure to build from scratch). +ifneq ($(FROZEN_MANIFEST),) CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool CFLAGS += -DMICROPY_MODULE_FROZEN_MPY +CFLAGS += -DMICROPY_MODULE_FROZEN_STR endif $(PY_BUILD)/nlr%.o: CFLAGS += -Os -fno-lto diff --git a/ports/nrf/README.md b/ports/nrf/README.md index aa8968ff92..a833f0f17c 100644 --- a/ports/nrf/README.md +++ b/ports/nrf/README.md @@ -96,20 +96,6 @@ The **make sd** will trigger a flash of the bluetooth stack before that applicat Note: further tuning of features to include in bluetooth or even setting up the device to use REPL over Bluetooth can be configured in the `bluetooth_conf.h`. -## Compile with frozen modules - -Frozen modules are Python modules compiled to bytecode and added to the firmware -image, as part of MicroPython. They can be imported as usual, using the `import` -statement. The advantage is that frozen modules use a lot less RAM as the -bytecode is stored in flash, not in RAM like when importing from a filesystem. -Also, frozen modules are available even when no filesystem is present to import -from. - -To use frozen modules, put them in a directory (e.g. `freeze/`) and supply -`make` with the given directory. For example: - - make BOARD=pca10040 FROZEN_MPY_DIR=freeze - ## Compile with freeze manifest Freeze manifests can be used by definining `FROZEN_MANIFEST` pointing to a diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index c5f159102e..290503937d 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -596,17 +596,10 @@ $(TOP)/lib/stm32lib/README.md: $(ECHO) "stm32lib submodule not found, fetching it now..." (cd $(TOP) && git submodule update --init lib/stm32lib) -ifneq ($(FROZEN_MANIFEST)$(FROZEN_DIR),) -# To use frozen source modules, put your .py files in a subdirectory (eg scripts/) -# and then invoke make with FROZEN_DIR=scripts (be sure to build from scratch). -CFLAGS += -DMICROPY_MODULE_FROZEN_STR -endif - -ifneq ($(FROZEN_MANIFEST)$(FROZEN_MPY_DIR),) -# To use frozen bytecode, put your .py files in a subdirectory (eg frozen/) and -# then invoke make with FROZEN_MPY_DIR=frozen (be sure to build from scratch). +ifneq ($(FROZEN_MANIFEST),) CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool CFLAGS += -DMICROPY_MODULE_FROZEN_MPY +CFLAGS += -DMICROPY_MODULE_FROZEN_STR endif define RUN_DFU diff --git a/ports/unix/Makefile b/ports/unix/Makefile index f829838ab3..cd8bb379c4 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -13,10 +13,8 @@ include ../../py/mkenv.mk -include mpconfigport.mk include $(VARIANT_DIR)/mpconfigvariant.mk -# use FROZEN_MANIFEST for new projects, others are legacy +# Use the default frozen manifest, variants may override this. FROZEN_MANIFEST ?= variants/manifest.py -FROZEN_DIR = -FROZEN_MPY_DIR = # This should be configured by the mpconfigvariant.mk PROG ?= micropython @@ -263,15 +261,12 @@ SRC_QSTR += $(SRC_C) $(SRC_CXX) $(SHARED_SRC_C) $(EXTMOD_SRC_C) # SRC_QSTR SRC_QSTR_AUTO_DEPS += -ifneq ($(FROZEN_MANIFEST)$(FROZEN_MPY_DIR),) +ifneq ($(FROZEN_MANIFEST),) # To use frozen code create a manifest.py file with a description of files to # freeze, then invoke make with FROZEN_MANIFEST=manifest.py (be sure to build from scratch). CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool CFLAGS += -DMICROPY_MODULE_FROZEN_MPY CFLAGS += -DMPZ_DIG_SIZE=16 # force 16 bits to work on both 32 and 64 bit archs -endif - -ifneq ($(FROZEN_MANIFEST)$(FROZEN_DIR),) CFLAGS += -DMICROPY_MODULE_FROZEN_STR endif diff --git a/py/mkrules.mk b/py/mkrules.mk index d0c0a53c26..963d70c2c3 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -142,43 +142,18 @@ $(MICROPY_MPYCROSS_DEPENDENCY): $(MAKE) -C $(dir $@) endif +ifneq ($(FROZEN_DIR),) +$(error Support for FROZEN_DIR was removed. Please use manifest.py instead, see https://docs.micropython.org/en/latest/reference/manifest.html) +endif + +ifneq ($(FROZEN_MPY_DIR),) +$(error Support for FROZEN_MPY_DIR was removed. Please use manifest.py instead, see https://docs.micropython.org/en/latest/reference/manifest.html) +endif + ifneq ($(FROZEN_MANIFEST),) # to build frozen_content.c from a manifest $(BUILD)/frozen_content.c: FORCE $(BUILD)/genhdr/qstrdefs.generated.h | $(MICROPY_MPYCROSS_DEPENDENCY) $(Q)$(MAKE_MANIFEST) -o $@ -v "MPY_DIR=$(TOP)" -v "MPY_LIB_DIR=$(MPY_LIB_DIR)" -v "PORT_DIR=$(shell pwd)" -v "BOARD_DIR=$(BOARD_DIR)" -b "$(BUILD)" $(if $(MPY_CROSS_FLAGS),-f"$(MPY_CROSS_FLAGS)",) --mpy-tool-flags="$(MPY_TOOL_FLAGS)" $(FROZEN_MANIFEST) - -ifneq ($(FROZEN_DIR),) -$(error FROZEN_DIR cannot be used in conjunction with FROZEN_MANIFEST) -endif - -ifneq ($(FROZEN_MPY_DIR),) -$(error FROZEN_MPY_DIR cannot be used in conjunction with FROZEN_MANIFEST) -endif -endif - -ifneq ($(FROZEN_DIR),) -$(info Warning: FROZEN_DIR is deprecated in favour of FROZEN_MANIFEST) -$(BUILD)/frozen.c: $(wildcard $(FROZEN_DIR)/*) $(HEADER_BUILD) $(FROZEN_EXTRA_DEPS) - $(ECHO) "GEN $@" - $(Q)$(MAKE_FROZEN) $(FROZEN_DIR) > $@ -endif - -ifneq ($(FROZEN_MPY_DIR),) -$(info Warning: FROZEN_MPY_DIR is deprecated in favour of FROZEN_MANIFEST) -# make a list of all the .py files that need compiling and freezing -FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py' | $(SED) -e 's=^$(FROZEN_MPY_DIR)/==') -FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/frozen_mpy/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) - -# to build .mpy files from .py files -$(BUILD)/frozen_mpy/%.mpy: $(FROZEN_MPY_DIR)/%.py | $(MICROPY_MPYCROSS_DEPENDENCY) - @$(ECHO) "MPY $<" - $(Q)$(MKDIR) -p $(dir $@) - $(Q)$(MICROPY_MPYCROSS) -o $@ -s $(<:$(FROZEN_MPY_DIR)/%=%) $(MPY_CROSS_FLAGS) $< - -# to build frozen_mpy.c from all .mpy files -$(BUILD)/frozen_mpy.c: $(FROZEN_MPY_MPY_FILES) $(BUILD)/genhdr/qstrdefs.generated.h - @$(ECHO) "GEN $@" - $(Q)$(MPY_TOOL) -f -q $(BUILD)/genhdr/qstrdefs.preprocessed.h $(FROZEN_MPY_MPY_FILES) > $@ endif ifneq ($(PROG),) @@ -234,27 +209,6 @@ clean: $(RM) -rf $(BUILD) $(CLEAN_EXTRA) .PHONY: clean -# Clean every non-git file from FROZEN_DIR/FROZEN_MPY_DIR, but making a backup. -# We run rmdir below to avoid empty backup dir (it will silently fail if backup -# is non-empty). -clean-frozen: - if [ -n "$(FROZEN_MPY_DIR)" ]; then \ - backup_dir=$(FROZEN_MPY_DIR).$$(date +%Y%m%dT%H%M%S); mkdir $$backup_dir; \ - cd $(FROZEN_MPY_DIR); git status --ignored -u all -s . | awk ' {print $$2}' \ - | xargs --no-run-if-empty cp --parents -t ../$$backup_dir; \ - rmdir ../$$backup_dir 2>/dev/null || true; \ - git clean -d -f .; \ - fi - - if [ -n "$(FROZEN_DIR)" ]; then \ - backup_dir=$(FROZEN_DIR).$$(date +%Y%m%dT%H%M%S); mkdir $$backup_dir; \ - cd $(FROZEN_DIR); git status --ignored -u all -s . | awk ' {print $$2}' \ - | xargs --no-run-if-empty cp --parents -t ../$$backup_dir; \ - rmdir ../$$backup_dir 2>/dev/null || true; \ - git clean -d -f .; \ - fi -.PHONY: clean-frozen - print-cfg: $(ECHO) "PY_SRC = $(PY_SRC)" $(ECHO) "BUILD = $(BUILD)" diff --git a/py/py.mk b/py/py.mk index 8e1e23554f..122dea225a 100644 --- a/py/py.mk +++ b/py/py.mk @@ -227,16 +227,6 @@ ifneq ($(FROZEN_MANIFEST),) PY_O += $(BUILD)/$(BUILD)/frozen_content.o endif -# object file for frozen files -ifneq ($(FROZEN_DIR),) -PY_O += $(BUILD)/$(BUILD)/frozen.o -endif - -# object file for frozen bytecode (frozen .mpy files) -ifneq ($(FROZEN_MPY_DIR),) -PY_O += $(BUILD)/$(BUILD)/frozen_mpy.o -endif - # Sources that may contain qstrings SRC_QSTR_IGNORE = py/nlr% SRC_QSTR += $(SRC_MOD) $(filter-out $(SRC_QSTR_IGNORE),$(PY_CORE_O_BASENAME:.o=.c)) $(PY_EXTMOD_O_BASENAME:.o=.c) From f853e3e106b151ec2819df729fd68815dce693fb Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 8 Dec 2021 16:47:33 +1100 Subject: [PATCH 261/335] tools/makemanifest.py: Merge make-frozen.py. Takes the functionality from tools/make-frozen.py, adds support for multiple frozen directories, and moves it to tools/makemanifest.py. Signed-off-by: Jim Mussared --- tools/make-frozen.py | 85 ------------------------------------------- tools/makemanifest.py | 74 +++++++++++++++++++++++++++++++++---- 2 files changed, 66 insertions(+), 93 deletions(-) delete mode 100755 tools/make-frozen.py diff --git a/tools/make-frozen.py b/tools/make-frozen.py deleted file mode 100755 index bc35d38342..0000000000 --- a/tools/make-frozen.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python -# -# Create frozen modules structure for MicroPython. -# -# Usage: -# -# Have a directory with modules to be frozen (only modules, not packages -# supported so far): -# -# frozen/foo.py -# frozen/bar.py -# -# Run script, passing path to the directory above: -# -# ./make-frozen.py frozen > frozen.c -# -# Include frozen.c in your build, having defined MICROPY_MODULE_FROZEN_STR in -# config. -# -from __future__ import print_function -import sys -import os - - -def module_name(f): - return f - - -modules = [] - -if len(sys.argv) > 1: - root = sys.argv[1].rstrip("/") - root_len = len(root) - - for dirpath, dirnames, filenames in os.walk(root): - for f in filenames: - fullpath = dirpath + "/" + f - st = os.stat(fullpath) - modules.append((fullpath[root_len + 1 :], st)) - -print("#include ") -print("const char mp_frozen_str_names[] = {") -for f, st in modules: - m = module_name(f) - print('"%s\\0"' % m) -print('"\\0"};') - -print("const uint32_t mp_frozen_str_sizes[] = {") - -for f, st in modules: - print("%d," % st.st_size) - -print("0};") - -print("const char mp_frozen_str_content[] = {") -for f, st in modules: - data = open(sys.argv[1] + "/" + f, "rb").read() - - # We need to properly escape the script data to create a C string. - # When C parses hex characters of the form \x00 it keeps parsing the hex - # data until it encounters a non-hex character. Thus one must create - # strings of the form "data\x01" "abc" to properly encode this kind of - # data. We could just encode all characters as hex digits but it's nice - # to be able to read the resulting C code as ASCII when possible. - - data = bytearray(data) # so Python2 extracts each byte as an integer - esc_dict = {ord("\n"): "\\n", ord("\r"): "\\r", ord('"'): '\\"', ord("\\"): "\\\\"} - chrs = ['"'] - break_str = False - for c in data: - try: - chrs.append(esc_dict[c]) - except KeyError: - if 32 <= c <= 126: - if break_str: - chrs.append('" "') - break_str = False - chrs.append(chr(c)) - else: - chrs.append("\\x%02x" % c) - break_str = True - chrs.append('\\0"') - print("".join(chrs)) - -print('"\\0"};') diff --git a/tools/makemanifest.py b/tools/makemanifest.py index fc608ed449..e37ae74cfd 100644 --- a/tools/makemanifest.py +++ b/tools/makemanifest.py @@ -201,8 +201,6 @@ def freeze_internal(kind, path, script, opt): if not os.path.isdir(path): raise FreezeError("freeze path must be a directory: {}".format(path)) if script is None and kind == KIND_AS_STR: - if any(f[0] == KIND_AS_STR for f in manifest_list): - raise FreezeError("can only freeze one str directory") manifest_list.append((KIND_AS_STR, path, script, opt)) elif script is None or isinstance(script, str) and script.find(".") == -1: # Recursively search `path` for files to freeze, optionally restricted @@ -235,6 +233,70 @@ def freeze_internal(kind, path, script, opt): manifest_list.append((kind, path, script, opt)) +def generate_frozen_str_content(paths): + def module_name(f): + return f + + modules = [] + output = [] + + for path in paths: + root = path.rstrip("/") + root_len = len(root) + + for dirpath, dirnames, filenames in os.walk(root): + for f in filenames: + fullpath = dirpath + "/" + f + st = os.stat(fullpath) + modules.append((path, fullpath[root_len + 1 :], st)) + + output.append("#include \n") + output.append("const char mp_frozen_str_names[] = {\n") + for _path, f, st in modules: + m = module_name(f) + output.append('"%s\\0"\n' % m) + output.append('"\\0"};\n') + + output.append("const uint32_t mp_frozen_str_sizes[] = {\n") + + for _path, f, st in modules: + output.append("%d," % st.st_size) + + output.append("0};\n") + + output.append("const char mp_frozen_str_content[] = {\n") + for path, f, st in modules: + data = open(path + "/" + f, "rb").read() + + # We need to properly escape the script data to create a C string. + # When C parses hex characters of the form \x00 it keeps parsing the hex + # data until it encounters a non-hex character. Thus one must create + # strings of the form "data\x01" "abc" to properly encode this kind of + # data. We could just encode all characters as hex digits but it's nice + # to be able to read the resulting C code as ASCII when possible. + + data = bytearray(data) # so Python2 extracts each byte as an integer + esc_dict = {ord("\n"): "\\n", ord("\r"): "\\r", ord('"'): '\\"', ord("\\"): "\\\\"} + output.append('"') + break_str = False + for c in data: + try: + output.append(esc_dict[c]) + except KeyError: + if 32 <= c <= 126: + if break_str: + output.append('" "') + break_str = False + output.append(chr(c)) + else: + output.append("\\x%02x" % c) + break_str = True + output.append('\\0"\n') + + output.append('"\\0"};\n') + return "".join(output) + + def main(): # Parse arguments import argparse @@ -264,7 +326,6 @@ def main(): sys.exit(1) # Get paths to tools - MAKE_FROZEN = VARS["MPY_DIR"] + "/tools/make-frozen.py" MPY_CROSS = VARS["MPY_DIR"] + "/mpy-cross/mpy-cross" if sys.platform == "win32": MPY_CROSS += ".exe" @@ -327,10 +388,7 @@ def main(): return # Freeze paths as strings - res, output_str = system([sys.executable, MAKE_FROZEN] + str_paths) - if res != 0: - print("error freezing strings {}: {}".format(str_paths, output_str)) - sys.exit(1) + output_str = generate_frozen_str_content(str_paths) # Freeze .mpy files if mpy_files: @@ -365,7 +423,7 @@ def main(): mkdir(args.output) with open(args.output, "wb") as f: f.write(b"//\n// Content for MICROPY_MODULE_FROZEN_STR\n//\n") - f.write(output_str) + f.write(output_str.encode()) f.write(b"//\n// Content for MICROPY_MODULE_FROZEN_MPY\n//\n") f.write(output_mpy) From e0bf4611c3a8b23b3c52e6a7804aac341ac3a87d Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 11 Dec 2021 22:40:21 +1100 Subject: [PATCH 262/335] py: Only search frozen modules when '.frozen' is found in sys.path. This changes makemanifest.py & mpy-tool.py to merge string and mpy names into the same list (now mp_frozen_names). The various paths for loading a frozen module (mp_find_frozen_module) and checking existence of a frozen module (mp_frozen_stat) use a common function that searches this list. In addition, the frozen lookup will now only take place if the path starts with ".frozen", which needs to be added to sys.path. This fixes issues #1804, #2322, #3509, #6419. Signed-off-by: Jim Mussared --- py/builtinhelp.c | 17 ++--- py/builtinimport.c | 48 +++++++----- py/frozenmod.c | 165 ++++++++++++++++++---------------------- py/frozenmod.h | 4 +- py/qstrdefs.h | 4 + shared/runtime/pyexec.c | 5 +- tools/makemanifest.py | 45 ++++++----- tools/mpy-tool.py | 6 +- 8 files changed, 143 insertions(+), 151 deletions(-) diff --git a/py/builtinhelp.c b/py/builtinhelp.c index 13735635e3..84d69caf35 100644 --- a/py/builtinhelp.c +++ b/py/builtinhelp.c @@ -67,10 +67,10 @@ STATIC void mp_help_add_from_map(mp_obj_t list, const mp_map_t *map) { #if MICROPY_MODULE_FROZEN STATIC void mp_help_add_from_names(mp_obj_t list, const char *name) { while (*name) { - size_t l = strlen(name); + size_t len = strlen(name); // name should end in '.py' and we strip it off - mp_obj_list_append(list, mp_obj_new_str(name, l - 3)); - name += l + 1; + mp_obj_list_append(list, mp_obj_new_str(name, len - 3)); + name += len + 1; } } #endif @@ -80,14 +80,9 @@ STATIC void mp_help_print_modules(void) { mp_help_add_from_map(list, &mp_builtin_module_map); - #if MICROPY_MODULE_FROZEN_STR - extern const char mp_frozen_str_names[]; - mp_help_add_from_names(list, mp_frozen_str_names); - #endif - - #if MICROPY_MODULE_FROZEN_MPY - extern const char mp_frozen_mpy_names[]; - mp_help_add_from_names(list, mp_frozen_mpy_names); + #if MICROPY_MODULE_FROZEN + extern const char mp_frozen_names[]; + mp_help_add_from_names(list, mp_frozen_names); #endif // sort the list so it's printed in alphabetical order diff --git a/py/builtinimport.c b/py/builtinimport.c index 755ce779a7..3e336633d9 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -50,6 +50,9 @@ // Must be a string of one byte. #define PATH_SEP_CHAR "/" +// Virtual sys.path entry that maps to the frozen modules. +#define MP_FROZEN_PATH_PREFIX ".frozen/" + bool mp_obj_is_package(mp_obj_t module) { mp_obj_t dest[2]; mp_load_method_maybe(module, MP_QSTR___path__, dest); @@ -62,9 +65,10 @@ bool mp_obj_is_package(mp_obj_t module) { // will return whether the path is a file, directory, or doesn't exist. STATIC mp_import_stat_t stat_path_or_frozen(const char *path) { #if MICROPY_MODULE_FROZEN - mp_import_stat_t st = mp_frozen_stat(path); - if (st != MP_IMPORT_STAT_NO_EXIST) { - return st; + // Only try and load as a frozen module if it starts with .frozen/. + const int frozen_path_prefix_len = strlen(MP_FROZEN_PATH_PREFIX); + if (strncmp(path, MP_FROZEN_PATH_PREFIX, frozen_path_prefix_len) == 0) { + return mp_find_frozen_module(path + frozen_path_prefix_len, NULL, NULL); } #endif return mp_import_stat(path); @@ -193,32 +197,36 @@ STATIC void do_execute_raw_code(mp_obj_t module_obj, mp_raw_code_t *raw_code, co STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { #if MICROPY_MODULE_FROZEN || MICROPY_ENABLE_COMPILER || (MICROPY_PERSISTENT_CODE_LOAD && MICROPY_HAS_FILE_READER) - char *file_str = vstr_null_terminated_str(file); + const char *file_str = vstr_null_terminated_str(file); #endif // If we support frozen modules (either as str or mpy) then try to find the // requested filename in the list of frozen module filenames. #if MICROPY_MODULE_FROZEN void *modref; - int frozen_type = mp_find_frozen_module(file_str, file->len, &modref); + int frozen_type; + const int frozen_path_prefix_len = strlen(MP_FROZEN_PATH_PREFIX); + if (strncmp(file_str, MP_FROZEN_PATH_PREFIX, frozen_path_prefix_len) == 0) { + mp_find_frozen_module(file_str + frozen_path_prefix_len, &frozen_type, &modref); - // If we support frozen str modules and the compiler is enabled, and we - // found the filename in the list of frozen files, then load and execute it. - #if MICROPY_MODULE_FROZEN_STR - if (frozen_type == MP_FROZEN_STR) { - do_load_from_lexer(module_obj, modref); - return; - } - #endif + // If we support frozen str modules and the compiler is enabled, and we + // found the filename in the list of frozen files, then load and execute it. + #if MICROPY_MODULE_FROZEN_STR + if (frozen_type == MP_FROZEN_STR) { + do_load_from_lexer(module_obj, modref); + return; + } + #endif - // If we support frozen mpy modules and we found a corresponding file (and - // its data) in the list of frozen files, execute it. - #if MICROPY_MODULE_FROZEN_MPY - if (frozen_type == MP_FROZEN_MPY) { - do_execute_raw_code(module_obj, modref, file_str); - return; + // If we support frozen mpy modules and we found a corresponding file (and + // its data) in the list of frozen files, execute it. + #if MICROPY_MODULE_FROZEN_MPY + if (frozen_type == MP_FROZEN_MPY) { + do_execute_raw_code(module_obj, modref, file_str + frozen_path_prefix_len); + return; + } + #endif } - #endif #endif // MICROPY_MODULE_FROZEN diff --git a/py/frozenmod.c b/py/frozenmod.c index a250c02151..6cb68d1ec0 100644 --- a/py/frozenmod.c +++ b/py/frozenmod.c @@ -5,6 +5,7 @@ * * Copyright (c) 2015 Paul Sokolovsky * Copyright (c) 2016 Damien P. George + * Copyright (c) 2021 Jim Mussared * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,6 +32,13 @@ #include "py/lexer.h" #include "py/frozenmod.h" +#if MICROPY_MODULE_FROZEN + +// Null-separated frozen file names. All string-type entries are listed first, +// followed by mpy-type entries. Use mp_frozen_str_sizes to determine how +// many string entries. +extern const char mp_frozen_names[]; + #if MICROPY_MODULE_FROZEN_STR #ifndef MICROPY_MODULE_FROZEN_LEXER @@ -39,118 +47,89 @@ mp_lexer_t *MICROPY_MODULE_FROZEN_LEXER(qstr src_name, const char *str, mp_uint_t len, mp_uint_t free_len); #endif -extern const char mp_frozen_str_names[]; +// Size in bytes of each string entry, followed by a zero (terminator). extern const uint32_t mp_frozen_str_sizes[]; +// Null-separated string content. extern const char mp_frozen_str_content[]; - -// On input, *len contains size of name, on output - size of content -const char *mp_find_frozen_str(const char *str, size_t *len) { - const char *name = mp_frozen_str_names; - - size_t offset = 0; - for (int i = 0; *name != 0; i++) { - size_t l = strlen(name); - if (l == *len && !memcmp(str, name, l)) { - *len = mp_frozen_str_sizes[i]; - return mp_frozen_str_content + offset; - } - name += l + 1; - offset += mp_frozen_str_sizes[i] + 1; - } - return NULL; -} - -STATIC mp_lexer_t *mp_lexer_frozen_str(const char *str, size_t len) { - size_t name_len = len; - const char *content = mp_find_frozen_str(str, &len); - - if (content == NULL) { - return NULL; - } - - qstr source = qstr_from_strn(str, name_len); - mp_lexer_t *lex = MICROPY_MODULE_FROZEN_LEXER(source, content, len, 0); - return lex; -} - -#endif +#endif // MICROPY_MODULE_FROZEN_STR #if MICROPY_MODULE_FROZEN_MPY #include "py/emitglue.h" -extern const char mp_frozen_mpy_names[]; extern const mp_raw_code_t *const mp_frozen_mpy_content[]; -STATIC const mp_raw_code_t *mp_find_frozen_mpy(const char *str, size_t len) { - const char *name = mp_frozen_mpy_names; - for (size_t i = 0; *name != 0; i++) { - size_t l = strlen(name); - if (l == len && !memcmp(str, name, l)) { - return mp_frozen_mpy_content[i]; - } - name += l + 1; - } - return NULL; -} +#endif // MICROPY_MODULE_FROZEN_MPY -#endif - -#if MICROPY_MODULE_FROZEN - -STATIC mp_import_stat_t mp_frozen_stat_helper(const char *name, const char *str) { +// Search for "str" as a frozen entry, returning the stat result +// (no-exist/file/dir), as well as the type (none/str/mpy) and data. +// frozen_type can be NULL if its value isn't needed (and then data is assumed to be NULL). +mp_import_stat_t mp_find_frozen_module(const char *str, int *frozen_type, void **data) { size_t len = strlen(str); + const char *name = mp_frozen_names; + + if (frozen_type != NULL) { + *frozen_type = MP_FROZEN_NONE; + } + + // Count the number of str lengths we have to find how many str entries. + size_t num_str = 0; + #if MICROPY_MODULE_FROZEN_STR && MICROPY_MODULE_FROZEN_MPY + for (const uint32_t *s = mp_frozen_str_sizes; *s != 0; ++s) { + ++num_str; + } + #endif + + for (size_t i = 0; *name != 0; i++) { + size_t entry_len = strlen(name); + if (entry_len >= len && memcmp(str, name, len) == 0) { + // Query is a prefix of the current entry. + if (entry_len == len) { + // Exact match --> file. + + if (frozen_type != NULL) { + #if MICROPY_MODULE_FROZEN_STR + if (i < num_str) { + *frozen_type = MP_FROZEN_STR; + // Use the size table to figure out where this index starts. + size_t offset = 0; + for (size_t j = 0; j < i; ++j) { + offset += mp_frozen_str_sizes[j] + 1; + } + size_t content_len = mp_frozen_str_sizes[i]; + const char *content = &mp_frozen_str_content[offset]; + + // Note: str & len have been updated by find_frozen_entry to strip + // the ".frozen/" prefix (to avoid this being a distinct qstr to + // the original path QSTR in frozen_content.c). + qstr source = qstr_from_strn(str, len); + mp_lexer_t *lex = MICROPY_MODULE_FROZEN_LEXER(source, content, content_len, 0); + *data = lex; + } + #endif + + #if MICROPY_MODULE_FROZEN_MPY + if (i >= num_str) { + *frozen_type = MP_FROZEN_MPY; + // Load the corresponding index as a raw_code, taking + // into account any string entries to offset by. + *data = (void *)mp_frozen_mpy_content[i - num_str]; + } + #endif + } - for (int i = 0; *name != 0; i++) { - size_t l = strlen(name); - if (l >= len && !memcmp(str, name, len)) { - if (name[len] == 0) { return MP_IMPORT_STAT_FILE; } else if (name[len] == '/') { + // Matches up to directory separator, this is a valid + // directory path. return MP_IMPORT_STAT_DIR; } } - name += l + 1; + // Skip null separator. + name += entry_len + 1; } - return MP_IMPORT_STAT_NO_EXIST; -} - -mp_import_stat_t mp_frozen_stat(const char *str) { - mp_import_stat_t stat; - - #if MICROPY_MODULE_FROZEN_STR - stat = mp_frozen_stat_helper(mp_frozen_str_names, str); - if (stat != MP_IMPORT_STAT_NO_EXIST) { - return stat; - } - #endif - - #if MICROPY_MODULE_FROZEN_MPY - stat = mp_frozen_stat_helper(mp_frozen_mpy_names, str); - if (stat != MP_IMPORT_STAT_NO_EXIST) { - return stat; - } - #endif return MP_IMPORT_STAT_NO_EXIST; } -int mp_find_frozen_module(const char *str, size_t len, void **data) { - #if MICROPY_MODULE_FROZEN_STR - mp_lexer_t *lex = mp_lexer_frozen_str(str, len); - if (lex != NULL) { - *data = lex; - return MP_FROZEN_STR; - } - #endif - #if MICROPY_MODULE_FROZEN_MPY - const mp_raw_code_t *rc = mp_find_frozen_mpy(str, len); - if (rc != NULL) { - *data = (void *)rc; - return MP_FROZEN_MPY; - } - #endif - return MP_FROZEN_NONE; -} - -#endif +#endif // MICROPY_MODULE_FROZEN diff --git a/py/frozenmod.h b/py/frozenmod.h index 8a477d028e..be735e85bd 100644 --- a/py/frozenmod.h +++ b/py/frozenmod.h @@ -35,8 +35,6 @@ enum { MP_FROZEN_MPY, }; -int mp_find_frozen_module(const char *str, size_t len, void **data); -const char *mp_find_frozen_str(const char *str, size_t *len); -mp_import_stat_t mp_frozen_stat(const char *str); +mp_import_stat_t mp_find_frozen_module(const char *str, int *frozen_type, void **data); #endif // MICROPY_INCLUDED_PY_FROZENMOD_H diff --git a/py/qstrdefs.h b/py/qstrdefs.h index 5b4e0dc48e..405813941b 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -60,6 +60,10 @@ Q() Q() Q(utf-8) +#if MICROPY_MODULE_FROZEN +Q(.frozen) +#endif + #if MICROPY_ENABLE_PYSTACK Q(pystack exhausted) #endif diff --git a/shared/runtime/pyexec.c b/shared/runtime/pyexec.c index 006ec096f7..2dceb647c3 100644 --- a/shared/runtime/pyexec.c +++ b/shared/runtime/pyexec.c @@ -674,7 +674,7 @@ int pyexec_file(const char *filename) { int pyexec_file_if_exists(const char *filename) { #if MICROPY_MODULE_FROZEN - if (mp_frozen_stat(filename) == MP_IMPORT_STAT_FILE) { + if (mp_find_frozen_module(filename, NULL, NULL) == MP_IMPORT_STAT_FILE) { return pyexec_frozen_module(filename); } #endif @@ -687,7 +687,8 @@ int pyexec_file_if_exists(const char *filename) { #if MICROPY_MODULE_FROZEN int pyexec_frozen_module(const char *name) { void *frozen_data; - int frozen_type = mp_find_frozen_module(name, strlen(name), &frozen_data); + int frozen_type; + mp_find_frozen_module(name, &frozen_type, &frozen_data); switch (frozen_type) { #if MICROPY_MODULE_FROZEN_STR diff --git a/tools/makemanifest.py b/tools/makemanifest.py index e37ae74cfd..8cdc3eb774 100644 --- a/tools/makemanifest.py +++ b/tools/makemanifest.py @@ -233,12 +233,17 @@ def freeze_internal(kind, path, script, opt): manifest_list.append((kind, path, script, opt)) +# Formerly make-frozen.py. +# This generates: +# - MP_FROZEN_STR_NAMES macro +# - mp_frozen_str_sizes +# - mp_frozen_str_content def generate_frozen_str_content(paths): def module_name(f): return f modules = [] - output = [] + output = [b"#include \n"] for path in paths: root = path.rstrip("/") @@ -250,21 +255,19 @@ def generate_frozen_str_content(paths): st = os.stat(fullpath) modules.append((path, fullpath[root_len + 1 :], st)) - output.append("#include \n") - output.append("const char mp_frozen_str_names[] = {\n") + output.append(b"#define MP_FROZEN_STR_NAMES \\\n") for _path, f, st in modules: m = module_name(f) - output.append('"%s\\0"\n' % m) - output.append('"\\0"};\n') + output.append(b'"%s\\0" \\\n' % m.encode()) + output.append(b"\n") - output.append("const uint32_t mp_frozen_str_sizes[] = {\n") + output.append(b"const uint32_t mp_frozen_str_sizes[] = { ") for _path, f, st in modules: - output.append("%d," % st.st_size) + output.append(b"%d, " % st.st_size) + output.append(b"0 };\n") - output.append("0};\n") - - output.append("const char mp_frozen_str_content[] = {\n") + output.append(b"const char mp_frozen_str_content[] = {\n") for path, f, st in modules: data = open(path + "/" + f, "rb").read() @@ -276,8 +279,8 @@ def generate_frozen_str_content(paths): # to be able to read the resulting C code as ASCII when possible. data = bytearray(data) # so Python2 extracts each byte as an integer - esc_dict = {ord("\n"): "\\n", ord("\r"): "\\r", ord('"'): '\\"', ord("\\"): "\\\\"} - output.append('"') + esc_dict = {ord("\n"): b"\\n", ord("\r"): b"\\r", ord('"'): b'\\"', ord("\\"): b"\\\\"} + output.append(b'"') break_str = False for c in data: try: @@ -285,16 +288,16 @@ def generate_frozen_str_content(paths): except KeyError: if 32 <= c <= 126: if break_str: - output.append('" "') + output.append(b'" "') break_str = False - output.append(chr(c)) + output.append(chr(c).encode()) else: - output.append("\\x%02x" % c) + output.append(b"\\x%02x" % c) break_str = True - output.append('\\0"\n') + output.append(b'\\0"\n') - output.append('"\\0"};\n') - return "".join(output) + output.append(b'"\\0"\n};\n\n') + return b"".join(output) def main(): @@ -414,8 +417,8 @@ def main(): b"const qstr_pool_t mp_qstr_frozen_const_pool = {\n" b" (qstr_pool_t*)&mp_qstr_const_pool, MP_QSTRnumber_of, 0, 0\n" b"};\n" - b'const char mp_frozen_mpy_names[1] = {"\\0"};\n' - b"const mp_raw_code_t *const mp_frozen_mpy_content[1] = {NULL};\n" + b'const char mp_frozen_names[] = { MP_FROZEN_STR_NAMES "\\0"};\n' + b"const mp_raw_code_t *const mp_frozen_mpy_content[] = {NULL};\n" ) # Generate output @@ -423,7 +426,7 @@ def main(): mkdir(args.output) with open(args.output, "wb") as f: f.write(b"//\n// Content for MICROPY_MODULE_FROZEN_STR\n//\n") - f.write(output_str.encode()) + f.write(output_str) f.write(b"//\n// Content for MICROPY_MODULE_FROZEN_MPY\n//\n") f.write(output_mpy) diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 6868ed5d4e..aa0272111c 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -886,7 +886,11 @@ def freeze_mpy(base_qstrs, raw_codes): rc.freeze(rc.source_file.str.replace("/", "_")[:-3] + "_") print() - print("const char mp_frozen_mpy_names[] = {") + print("const char mp_frozen_names[] = {") + print("#ifdef MP_FROZEN_STR_NAMES") + # makemanifest.py might also include some frozen string content. + print("MP_FROZEN_STR_NAMES") + print("#endif") for rc in raw_codes: module_name = rc.source_file.str print('"%s\\0"' % module_name) From d6d4a5819b4b2f5f58dcc5776c284b6f633c94aa Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 11 Dec 2021 23:01:58 +1100 Subject: [PATCH 263/335] py/mkrules.cmake: Set frozen preprocessor defs early. This ensures MICROPY_QSTR_EXTRA_POOL and MICROPY_MODULE_FROZEN_MPY are set if necessary before the CFLAGS are extracted for QSTR generation. Signed-off-by: Jim Mussared --- py/mkrules.cmake | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/py/mkrules.cmake b/py/mkrules.cmake index 9d08017931..cb5fdabf6b 100644 --- a/py/mkrules.cmake +++ b/py/mkrules.cmake @@ -10,6 +10,15 @@ set(MICROPY_QSTRDEFS_COLLECTED "${MICROPY_GENHDR_DIR}/qstrdefs.collected.h") set(MICROPY_QSTRDEFS_PREPROCESSED "${MICROPY_GENHDR_DIR}/qstrdefs.preprocessed.h") set(MICROPY_QSTRDEFS_GENERATED "${MICROPY_GENHDR_DIR}/qstrdefs.generated.h") +# Need to do this before extracting MICROPY_CPP_DEF below. Rest of frozen +# manifest handling is at the end of this file. +if(MICROPY_FROZEN_MANIFEST) + target_compile_definitions(${MICROPY_TARGET} PUBLIC + MICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool + MICROPY_MODULE_FROZEN_MPY=\(1\) + ) +endif() + # Provide defaults for preprocessor flags if not already defined if(NOT MICROPY_CPP_FLAGS) get_target_property(MICROPY_CPP_INC ${MICROPY_TARGET} INCLUDE_DIRECTORIES) @@ -120,10 +129,7 @@ if(MICROPY_FROZEN_MANIFEST) ${MICROPY_FROZEN_CONTENT} ) - target_compile_definitions(${MICROPY_TARGET} PUBLIC - MICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool - MICROPY_MODULE_FROZEN_MPY=\(1\) - ) + # Note: target_compile_definitions already added earlier. if(NOT MICROPY_LIB_DIR) set(MICROPY_LIB_DIR ${MICROPY_DIR}/../micropython-lib) From 86ce4426079b1b368881c22f46d80045e2f720b0 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 11 Dec 2021 23:04:01 +1100 Subject: [PATCH 264/335] ports: Add '.frozen' as the first entry in sys.path. Frozen modules will be searched preferentially, but gives the user the ability to override this behavior. This matches the previous behavior where "" was implicitly the frozen search path, but the frozen list was checked before the filesystem. Signed-off-by: Jim Mussared --- ports/esp32/main.c | 3 +++ ports/esp8266/main.c | 3 +++ ports/mimxrt/main.c | 3 +++ ports/nrf/main.c | 3 +++ ports/rp2/main.c | 3 +++ ports/stm32/main.c | 3 +++ ports/unix/main.c | 15 ++++++--------- ports/unix/mpconfigport.h | 3 +++ ports/unix/variants/minimal/mpconfigvariant.h | 3 +++ shared/upytesthelper/upytesthelper.c | 3 +++ 10 files changed, 33 insertions(+), 9 deletions(-) diff --git a/ports/esp32/main.c b/ports/esp32/main.c index 4920180b23..e95930ed07 100644 --- a/ports/esp32/main.c +++ b/ports/esp32/main.c @@ -141,6 +141,9 @@ soft_reset: gc_init(mp_task_heap, mp_task_heap + mp_task_heap_size); mp_init(); mp_obj_list_init(mp_sys_path, 0); + #if MICROPY_MODULE_FROZEN + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); + #endif mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); mp_obj_list_init(mp_sys_argv, 0); diff --git a/ports/esp8266/main.c b/ports/esp8266/main.c index 404188346c..14863a35b0 100644 --- a/ports/esp8266/main.c +++ b/ports/esp8266/main.c @@ -53,6 +53,9 @@ STATIC void mp_reset(void) { gc_init(heap, heap + sizeof(heap)); mp_init(); mp_obj_list_init(mp_sys_path, 0); + #if MICROPY_MODULE_FROZEN + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); + #endif mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_)); diff --git a/ports/mimxrt/main.c b/ports/mimxrt/main.c index 4d603913fd..28ee30d990 100644 --- a/ports/mimxrt/main.c +++ b/ports/mimxrt/main.c @@ -76,6 +76,9 @@ int main(void) { mp_init(); mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0); + #if MICROPY_MODULE_FROZEN + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); + #endif mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); #if MICROPY_PY_NETWORK diff --git a/ports/nrf/main.c b/ports/nrf/main.c index 3768b8f404..fc67bd657d 100644 --- a/ports/nrf/main.c +++ b/ports/nrf/main.c @@ -130,6 +130,9 @@ soft_reset: mp_init(); mp_obj_list_init(mp_sys_path, 0); + #if MICROPY_MODULE_FROZEN + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); + #endif mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) mp_obj_list_init(mp_sys_argv, 0); diff --git a/ports/rp2/main.c b/ports/rp2/main.c index 793444c9a9..6a5bb8867d 100644 --- a/ports/rp2/main.c +++ b/ports/rp2/main.c @@ -101,6 +101,9 @@ int main(int argc, char **argv) { // Initialise MicroPython runtime. mp_init(); mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0); + #if MICROPY_MODULE_FROZEN + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); + #endif mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 7a7f80467b..51459682fd 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -495,6 +495,9 @@ soft_reset: // MicroPython init mp_init(); mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0); + #if MICROPY_MODULE_FROZEN + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); + #endif mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); diff --git a/ports/unix/main.c b/ports/unix/main.c index 031bdd75d1..cecb806283 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -495,13 +495,9 @@ MP_NOINLINE int main_(int argc, char **argv) { char *home = getenv("HOME"); char *path = getenv("MICROPYPATH"); if (path == NULL) { - #ifdef MICROPY_PY_SYS_PATH_DEFAULT path = MICROPY_PY_SYS_PATH_DEFAULT; - #else - path = "~/.micropython/lib:/usr/lib/micropython"; - #endif } - size_t path_num = 1; // [0] is for current dir (or base dir of the script) + size_t path_num = 2; // [0] is frozen, [1] is for current dir (or base dir of the script) if (*path == PATHLIST_SEP_CHAR) { path_num++; } @@ -514,10 +510,11 @@ MP_NOINLINE int main_(int argc, char **argv) { mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), path_num); mp_obj_t *path_items; mp_obj_list_get(mp_sys_path, &path_num, &path_items); - path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR_); + path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen); + path_items[1] = MP_OBJ_NEW_QSTR(MP_QSTR_); { char *p = path; - for (mp_uint_t i = 1; i < path_num; i++) { + for (mp_uint_t i = 2; i < path_num; i++) { char *p1 = strchr(p, PATHLIST_SEP_CHAR); if (p1 == NULL) { p1 = p + strlen(p); @@ -658,9 +655,9 @@ MP_NOINLINE int main_(int argc, char **argv) { break; } - // Set base dir of the script as first entry in sys.path + // Set base dir of the script as second entry in sys.path. char *p = strrchr(basedir, '/'); - path_items[0] = mp_obj_new_str_via_qstr(basedir, p - basedir); + path_items[1] = mp_obj_new_str_via_qstr(basedir, p - basedir); free(pathbuf); set_sys_argv(argv, argc, a); diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index 93d790ac36..68d4d8d33f 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -123,6 +123,9 @@ #define MICROPY_PY_SYS_PLATFORM "linux" #endif #endif +#ifndef MICROPY_PY_SYS_PATH_DEFAULT +#define MICROPY_PY_SYS_PATH_DEFAULT "~/.micropython/lib:/usr/lib/micropython" +#endif #define MICROPY_PY_SYS_MAXSIZE (1) #define MICROPY_PY_SYS_STDFILES (1) #define MICROPY_PY_SYS_EXC_INFO (1) diff --git a/ports/unix/variants/minimal/mpconfigvariant.h b/ports/unix/variants/minimal/mpconfigvariant.h index 973febd572..4766b8e895 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.h +++ b/ports/unix/variants/minimal/mpconfigvariant.h @@ -88,6 +88,9 @@ #define MICROPY_PY_SYS (1) #define MICROPY_PY_SYS_EXIT (0) #define MICROPY_PY_SYS_PLATFORM "linux" +#ifndef MICROPY_PY_SYS_PATH_DEFAULT +#define MICROPY_PY_SYS_PATH_DEFAULT "~/.micropython/lib:/usr/lib/micropython" +#endif #define MICROPY_PY_SYS_MAXSIZE (0) #define MICROPY_PY_SYS_STDFILES (0) #define MICROPY_PY_CMATH (0) diff --git a/shared/upytesthelper/upytesthelper.c b/shared/upytesthelper/upytesthelper.c index 326172be65..ce60732424 100644 --- a/shared/upytesthelper/upytesthelper.c +++ b/shared/upytesthelper/upytesthelper.c @@ -94,6 +94,9 @@ void upytest_execute_test(const char *src) { gc_init(heap_start, heap_end); mp_init(); mp_obj_list_init(mp_sys_path, 0); + #if MICROPY_MODULE_FROZEN + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); + #endif mp_obj_list_init(mp_sys_argv, 0); nlr_buf_t nlr; From 86394f70fcd7b9fa66ec952711e5d64557d81a1e Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 11 Dec 2021 23:39:40 +1100 Subject: [PATCH 265/335] docs/library/sys.rst: Add note about '.frozen' as an entry in sys.path. Signed-off-by: Jim Mussared --- docs/library/sys.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/library/sys.rst b/docs/library/sys.rst index 80ac1ab84c..d36394c88c 100644 --- a/docs/library/sys.rst +++ b/docs/library/sys.rst @@ -115,6 +115,14 @@ Constants A mutable list of directories to search for imported modules. + .. admonition:: Difference to CPython + :class: attention + + On MicroPython, an entry with the value ``".frozen"`` will indicate that import + should search :term:`frozen modules ` at that point in the search. + If no frozen module is found then search will *not* look for a directory called + ``.frozen``, instead it will continue with the next entry in ``sys.path``. + .. data:: platform The platform that MicroPython is running on. For OS/RTOS ports, this is From de43b500bdff465539d89c5004d9e8cb3849eab1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 17 Dec 2021 23:35:32 +1100 Subject: [PATCH 266/335] py/runtime: Allow initialising sys.path/argv with defaults. If MICROPY_PY_SYS_PATH_ARGV_DEFAULTS is enabled (which it is by default) then sys.path and sys.argv will be initialised and populated with default values. This keeps all bare-metal ports aligned. Signed-off-by: Damien George --- docs/develop/porting.rst | 2 -- mpy-cross/main.c | 2 -- ports/cc3200/mptask.c | 3 --- ports/esp32/main.c | 6 ------ ports/esp8266/main.c | 6 ------ ports/javascript/main.c | 4 ---- ports/mimxrt/main.c | 6 ------ ports/nrf/main.c | 8 -------- ports/rp2/main.c | 6 ------ ports/samd/main.c | 3 --- ports/stm32/main.c | 6 ------ ports/teensy/main.c | 3 --- ports/unix/mpconfigport.h | 1 + ports/windows/mpconfigport.h | 1 + ports/zephyr/main.c | 3 --- py/mpconfig.h | 5 +++++ py/mpstate.h | 3 ++- py/runtime.c | 9 +++++++++ 18 files changed, 18 insertions(+), 59 deletions(-) diff --git a/docs/develop/porting.rst b/docs/develop/porting.rst index 549227d762..ae0cfd8b06 100644 --- a/docs/develop/porting.rst +++ b/docs/develop/porting.rst @@ -53,8 +53,6 @@ The basic MicroPython firmware is implemented in the main port file, e.g ``main. mp_stack_ctrl_init(); gc_init(heap, heap + sizeof(heap)); mp_init(); - mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0); - mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); // Start a normal REPL; will exit when ctrl-D is entered on a blank line. pyexec_friendly_repl(); diff --git a/mpy-cross/main.c b/mpy-cross/main.c index c677929c33..7218921b31 100644 --- a/mpy-cross/main.c +++ b/mpy-cross/main.c @@ -192,8 +192,6 @@ MP_NOINLINE int main_(int argc, char **argv) { #ifdef _WIN32 set_fmode_binary(); #endif - mp_obj_list_init(mp_sys_path, 0); - mp_obj_list_init(mp_sys_argv, 0); #if MICROPY_EMIT_NATIVE // Set default emitter options diff --git a/ports/cc3200/mptask.c b/ports/cc3200/mptask.c index 599211bdfb..81f00e5384 100644 --- a/ports/cc3200/mptask.c +++ b/ports/cc3200/mptask.c @@ -139,9 +139,6 @@ soft_reset: // MicroPython init mp_init(); - mp_obj_list_init(mp_sys_path, 0); - mp_obj_list_init(mp_sys_argv, 0); - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) // execute all basic initializations mp_irq_init0(); diff --git a/ports/esp32/main.c b/ports/esp32/main.c index e95930ed07..c9b033d626 100644 --- a/ports/esp32/main.c +++ b/ports/esp32/main.c @@ -140,13 +140,7 @@ soft_reset: mp_stack_set_limit(MP_TASK_STACK_SIZE - MP_TASK_STACK_LIMIT_MARGIN); gc_init(mp_task_heap, mp_task_heap + mp_task_heap_size); mp_init(); - mp_obj_list_init(mp_sys_path, 0); - #if MICROPY_MODULE_FROZEN - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); - #endif - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); - mp_obj_list_init(mp_sys_argv, 0); readline_init0(); // initialise peripherals diff --git a/ports/esp8266/main.c b/ports/esp8266/main.c index 14863a35b0..5d7debced0 100644 --- a/ports/esp8266/main.c +++ b/ports/esp8266/main.c @@ -52,14 +52,8 @@ STATIC void mp_reset(void) { mp_hal_init(); gc_init(heap, heap + sizeof(heap)); mp_init(); - mp_obj_list_init(mp_sys_path, 0); - #if MICROPY_MODULE_FROZEN - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); - #endif - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_)); - mp_obj_list_init(mp_sys_argv, 0); #if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA extern void esp_native_code_init(void); esp_native_code_init(); diff --git a/ports/javascript/main.c b/ports/javascript/main.c index 7a04b8eea3..04a853f66c 100644 --- a/ports/javascript/main.c +++ b/ports/javascript/main.c @@ -91,10 +91,6 @@ void mp_js_init(int heap_size) { #endif mp_init(); - - mp_obj_list_init(mp_sys_path, 0); - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); - mp_obj_list_init(mp_sys_argv, 0); } void mp_js_init_repl() { diff --git a/ports/mimxrt/main.c b/ports/mimxrt/main.c index 28ee30d990..a6a0d2e196 100644 --- a/ports/mimxrt/main.c +++ b/ports/mimxrt/main.c @@ -75,12 +75,6 @@ int main(void) { gc_init(&_gc_heap_start, &_gc_heap_end); mp_init(); - mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0); - #if MICROPY_MODULE_FROZEN - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); - #endif - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); - mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); #if MICROPY_PY_NETWORK mod_network_init(); #endif diff --git a/ports/nrf/main.c b/ports/nrf/main.c index fc67bd657d..2ec16194cb 100644 --- a/ports/nrf/main.c +++ b/ports/nrf/main.c @@ -129,16 +129,8 @@ soft_reset: gc_init(&_heap_start, &_heap_end); mp_init(); - mp_obj_list_init(mp_sys_path, 0); - #if MICROPY_MODULE_FROZEN - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); - #endif - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) - mp_obj_list_init(mp_sys_argv, 0); - readline_init0(); - #if MICROPY_PY_MACHINE_HW_SPI spi_init0(); #endif diff --git a/ports/rp2/main.c b/ports/rp2/main.c index 6a5bb8867d..84f23af23c 100644 --- a/ports/rp2/main.c +++ b/ports/rp2/main.c @@ -100,13 +100,7 @@ int main(int argc, char **argv) { // Initialise MicroPython runtime. mp_init(); - mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0); - #if MICROPY_MODULE_FROZEN - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); - #endif - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); - mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); // Initialise sub-systems. readline_init0(); diff --git a/ports/samd/main.c b/ports/samd/main.c index a08e66fda0..63fe4013a4 100644 --- a/ports/samd/main.c +++ b/ports/samd/main.c @@ -41,9 +41,6 @@ void samd_main(void) { for (;;) { gc_init(&_sheap, &_eheap); mp_init(); - mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0); - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); - mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); // Execute _boot.py to set up the filesystem. pyexec_frozen_module("_boot.py"); diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 51459682fd..431fa20dee 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -494,12 +494,6 @@ soft_reset: // MicroPython init mp_init(); - mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0); - #if MICROPY_MODULE_FROZEN - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); - #endif - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) - mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); // Initialise low-level sub-systems. Here we need to very basic things like // zeroing out memory and resetting any of the sub-systems. Following this diff --git a/ports/teensy/main.c b/ports/teensy/main.c index 6ebdcde21c..37a04c74f8 100644 --- a/ports/teensy/main.c +++ b/ports/teensy/main.c @@ -269,9 +269,6 @@ soft_reset: // MicroPython init mp_init(); - mp_obj_list_init(mp_sys_path, 0); - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) - mp_obj_list_init(mp_sys_argv, 0); readline_init0(); diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index 68d4d8d33f..a995ac52cc 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -110,6 +110,7 @@ #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) #define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) #define MICROPY_PY_BUILTINS_SLICE_INDICES (1) +#define MICROPY_PY_SYS_PATH_ARGV_DEFAULTS (0) #define MICROPY_PY_SYS_EXIT (1) #define MICROPY_PY_SYS_ATEXIT (1) #if MICROPY_PY_SYS_SETTRACE diff --git a/ports/windows/mpconfigport.h b/ports/windows/mpconfigport.h index 69193cb6af..30d8e09e6d 100644 --- a/ports/windows/mpconfigport.h +++ b/ports/windows/mpconfigport.h @@ -85,6 +85,7 @@ #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) #define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) +#define MICROPY_PY_SYS_PATH_ARGV_DEFAULTS (0) #define MICROPY_PY_SYS_EXIT (1) #define MICROPY_PY_SYS_ATEXIT (1) #define MICROPY_PY_SYS_PLATFORM "win32" diff --git a/ports/zephyr/main.c b/ports/zephyr/main.c index 63190bd5ed..f972768340 100644 --- a/ports/zephyr/main.c +++ b/ports/zephyr/main.c @@ -139,9 +139,6 @@ soft_reset: gc_init(heap, heap + sizeof(heap)); #endif mp_init(); - mp_obj_list_init(mp_sys_path, 0); - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) - mp_obj_list_init(mp_sys_argv, 0); #ifdef CONFIG_USB usb_enable(NULL); diff --git a/py/mpconfig.h b/py/mpconfig.h index 86e3e0f349..f0d11961d3 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1306,6 +1306,11 @@ typedef double mp_float_t; #define MICROPY_PY_SYS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif +// Whether to initialise "sys.path" and "sys.argv" to their defaults in mp_init() +#ifndef MICROPY_PY_SYS_PATH_ARGV_DEFAULTS +#define MICROPY_PY_SYS_PATH_ARGV_DEFAULTS (1) +#endif + // Whether to provide "sys.maxsize" constant #ifndef MICROPY_PY_SYS_MAXSIZE #define MICROPY_PY_SYS_MAXSIZE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) diff --git a/py/mpstate.h b/py/mpstate.h index 69360738c2..69fee06546 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -153,7 +153,8 @@ typedef struct _mp_state_vm_t { // dictionary for the __main__ module mp_obj_dict_t dict_main; - // these two lists must be initialised per port, after the call to mp_init + // If MICROPY_PY_SYS_PATH_ARGV_DEFAULTS is not enabled then these two lists + // must be initialised after the call to mp_init. mp_obj_list_t mp_sys_path_obj; mp_obj_list_t mp_sys_argv_obj; diff --git a/py/runtime.c b/py/runtime.c index 0120b70d74..7607ffb191 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -122,6 +122,15 @@ void mp_init(void) { MP_STATE_VM(vfs_mount_table) = NULL; #endif + #if MICROPY_PY_SYS_PATH_ARGV_DEFAULTS + mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0); + #if MICROPY_MODULE_FROZEN + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); + #endif + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) + mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); + #endif + #if MICROPY_PY_SYS_ATEXIT MP_STATE_VM(sys_exitfunc) = mp_const_none; #endif From fe9ffff9c0374684f9e89292099d11d957ef9a3e Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 19 Dec 2021 08:55:40 +1100 Subject: [PATCH 267/335] py/mpstate.h: Only include sys.path/argv objects in state when enabled. The mp_sys_path_obj and mp_sys_argv_obj objects are only used by the runtime and accessible from Python if MICROPY_PY_SYS is enabled. So exclude them from the runtime state if this option is disabled. Signed-off-by: Damien George --- py/mpconfig.h | 2 +- py/mpstate.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/py/mpconfig.h b/py/mpconfig.h index f0d11961d3..d93100bb83 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1308,7 +1308,7 @@ typedef double mp_float_t; // Whether to initialise "sys.path" and "sys.argv" to their defaults in mp_init() #ifndef MICROPY_PY_SYS_PATH_ARGV_DEFAULTS -#define MICROPY_PY_SYS_PATH_ARGV_DEFAULTS (1) +#define MICROPY_PY_SYS_PATH_ARGV_DEFAULTS (MICROPY_PY_SYS) #endif // Whether to provide "sys.maxsize" constant diff --git a/py/mpstate.h b/py/mpstate.h index 69fee06546..8ece151663 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -153,10 +153,12 @@ typedef struct _mp_state_vm_t { // dictionary for the __main__ module mp_obj_dict_t dict_main; + #if MICROPY_PY_SYS // If MICROPY_PY_SYS_PATH_ARGV_DEFAULTS is not enabled then these two lists // must be initialised after the call to mp_init. mp_obj_list_t mp_sys_path_obj; mp_obj_list_t mp_sys_argv_obj; + #endif // dictionary for overridden builtins #if MICROPY_CAN_OVERRIDE_BUILTINS From f9e5b0d93d0cd0eb65f23cff3ca7e827a96bd83c Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 18 Dec 2021 19:11:47 +0200 Subject: [PATCH 268/335] stm32/factoryreset: Init vfs flags before calling pyb_flash_init_vfs. The vfs flags could have any random value from stack. This bug was introduced back in 7723dac3371ccf081c2490b33b69492dc42818bd --- ports/stm32/factoryreset.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/stm32/factoryreset.c b/ports/stm32/factoryreset.c index 999056e726..10eb3a17a7 100644 --- a/ports/stm32/factoryreset.c +++ b/ports/stm32/factoryreset.c @@ -109,6 +109,7 @@ MP_WEAK int factory_reset_create_filesystem(void) { uint32_t start_tick = HAL_GetTick(); fs_user_mount_t vfs; + vfs.blockdev.flags = 0; pyb_flash_init_vfs(&vfs); uint8_t working_buf[FF_MAX_SS]; FRESULT res = f_mkfs(&vfs.fatfs, FM_FAT, 0, working_buf, sizeof(working_buf)); From 1dc532019b9d1bb6326856849975653d66258b24 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 18 Dec 2021 19:32:06 +0200 Subject: [PATCH 269/335] stm32/qspi: Fix typo in address comment. --- ports/stm32/qspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/stm32/qspi.c b/ports/stm32/qspi.c index b82d3d81c0..5ead66f4e4 100644 --- a/ports/stm32/qspi.c +++ b/ports/stm32/qspi.c @@ -318,7 +318,7 @@ STATIC void qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr, ; QUADSPI->ABR = 0; // alternate byte: disable continuous read mode - QUADSPI->AR = addr; // addres to read from + QUADSPI->AR = addr; // address to read from // Read in the data 4 bytes at a time if dest is aligned if (((uintptr_t)dest & 3) == 0) { From bedd9c5463b5eabcf586f08e9067e10d0aa3e458 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 18 Dec 2021 22:18:33 +0200 Subject: [PATCH 270/335] stm32/boards/make-pins.py: Generate empty ADC table if needed. If ADCx pins are hidden, print an empty table to prevent linker errors. --- ports/stm32/boards/make-pins.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/ports/stm32/boards/make-pins.py b/ports/stm32/boards/make-pins.py index b11f438aae..14c9e91097 100755 --- a/ports/stm32/boards/make-pins.py +++ b/ports/stm32/boards/make-pins.py @@ -426,16 +426,19 @@ class Pins(object): adc_pins[pin.adc_channel] = pin if adc_pins: table_size = max(adc_pins) + 1 - self.adc_table_size[adc_num] = table_size - print("") - print("const pin_obj_t * const pin_adc{:d}[{:d}] = {{".format(adc_num, table_size)) - for channel in range(table_size): - if channel in adc_pins: - obj = "&pin_{:s}_obj".format(adc_pins[channel].cpu_pin_name()) - else: - obj = "NULL" - print(" [{:d}] = {},".format(channel, obj)) - print("};") + else: + # If ADCx pins are hidden, print an empty table to prevent linker errors. + table_size = 0 + self.adc_table_size[adc_num] = table_size + print("") + print("const pin_obj_t * const pin_adc{:d}[{:d}] = {{".format(adc_num, table_size)) + for channel in range(table_size): + if channel in adc_pins: + obj = "&pin_{:s}_obj".format(adc_pins[channel].cpu_pin_name()) + else: + obj = "NULL" + print(" [{:d}] = {},".format(channel, obj)) + print("};") def print_header(self, hdr_filename, obj_decls): with open(hdr_filename, "wt") as hdr_file: From f2b5c99fde53796247921bfd016224b5edf7f8a6 Mon Sep 17 00:00:00 2001 From: Matt Trentini Date: Thu, 16 Dec 2021 21:52:05 +1100 Subject: [PATCH 271/335] stm32/boards/OLIMEX_H407: Fix typo in OLIMEX H407 board.json. Appears incorrectly as E407 in the download manager. --- ports/stm32/boards/OLIMEX_H407/board.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/stm32/boards/OLIMEX_H407/board.json b/ports/stm32/boards/OLIMEX_H407/board.json index d4e0fda98c..c074950ab3 100644 --- a/ports/stm32/boards/OLIMEX_H407/board.json +++ b/ports/stm32/boards/OLIMEX_H407/board.json @@ -6,7 +6,7 @@ "features": [], "images": [], "mcu": "stm32f4", - "product": "E407", + "product": "H407", "thumbnail": "", "url": "", "vendor": "OLIMEX" From 05bea70979232629e059a7453fb7965545113d9f Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 20 Dec 2021 12:27:06 +1100 Subject: [PATCH 272/335] esp8266/etshal.h: Remove unneeded function declarations. These removed ones are either unused by MicroPython or provided by osapi.h in the SDK. In particular ets_delay_us() has different signatures for different versions of the SDK, so best to let it provide the declaration. Fixes issue #8095. Signed-off-by: Damien George --- ports/esp8266/etshal.h | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/ports/esp8266/etshal.h b/ports/esp8266/etshal.h index f7b34b8356..7d0855a2ae 100644 --- a/ports/esp8266/etshal.h +++ b/ports/esp8266/etshal.h @@ -6,22 +6,10 @@ // see http://esp8266-re.foogod.com/wiki/Random_Number_Generator #define WDEV_HWRNG ((volatile uint32_t *)0x3ff20e44) -void ets_delay_us(uint16_t us); -void ets_intr_lock(void); -void ets_intr_unlock(void); void ets_isr_mask(uint32_t mask); void ets_isr_unmask(uint32_t mask); -void ets_isr_attach(int irq_no, void (*handler)(void *), void *arg); -void ets_install_putc1(); -void uart_div_modify(uint8_t uart, uint32_t divisor); -void ets_set_idle_cb(void (*handler)(void *), void *arg); -void ets_timer_arm_new(os_timer_t *tim, uint32_t millis, bool repeat, bool is_milli_timer); -void ets_timer_setfn(os_timer_t *tim, ETSTimerFunc callback, void *cb_data); -void ets_timer_disarm(os_timer_t *tim); - -extern void ets_wdt_disable(void); -extern void wdt_feed(void); +void ets_wdt_disable(void); // Opaque structure #ifndef MD5_CTX @@ -32,12 +20,6 @@ void MD5Init(MD5_CTX *context); void MD5Update(MD5_CTX *context, const void *data, unsigned int len); void MD5Final(unsigned char digest[16], MD5_CTX *context); -// These prototypes are for recent SDKs with "malloc tracking" -void *pvPortMalloc(size_t sz, const char *fname, unsigned line); -void *pvPortZalloc(size_t sz, const char *fname, unsigned line); -void *pvPortRealloc(void *p, unsigned sz, const char *fname, unsigned line); -void vPortFree(void *p, const char *fname, unsigned line); - uint32_t SPIRead(uint32_t offset, void *buf, uint32_t len); uint32_t SPIWrite(uint32_t offset, const void *buf, uint32_t len); uint32_t SPIEraseSector(int sector); From 2c139bbf4e5724ab253b5b034ce925e04267a9c4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 30 Nov 2021 00:31:46 +1100 Subject: [PATCH 273/335] py/mpz: Fix bugs with bitwise of -0 by ensuring all 0's are positive. This commit makes sure that the value zero is always encoded in an mpz_t as neg=0 and len=0 (previously it was just len=0). This invariant is needed for some of the bitwise operations that operate on negative numbers, because they cannot handle -0. For example (-((1<<100)-(1<<100)))|1 was being computed as -65535, instead of 1. Fixes issue #8042. Signed-off-by: Damien George --- py/mpz.c | 19 ++++++++------- py/mpz.h | 3 ++- tests/basics/int_big_zeroone.py | 41 +++++++++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/py/mpz.c b/py/mpz.c index 75e1fb1fdb..b61997e2fd 100644 --- a/py/mpz.c +++ b/py/mpz.c @@ -713,6 +713,7 @@ void mpz_set(mpz_t *dest, const mpz_t *src) { void mpz_set_from_int(mpz_t *z, mp_int_t val) { if (val == 0) { + z->neg = 0; z->len = 0; return; } @@ -899,10 +900,6 @@ bool mpz_is_even(const mpz_t *z) { #endif int mpz_cmp(const mpz_t *z1, const mpz_t *z2) { - // to catch comparison of -0 with +0 - if (z1->len == 0 && z2->len == 0) { - return 0; - } int cmp = (int)z2->neg - (int)z1->neg; if (cmp != 0) { return cmp; @@ -1052,7 +1049,9 @@ void mpz_neg_inpl(mpz_t *dest, const mpz_t *z) { if (dest != z) { mpz_set(dest, z); } - dest->neg = 1 - dest->neg; + if (dest->len) { + dest->neg = 1 - dest->neg; + } } /* computes dest = ~z (= -z - 1) @@ -1148,7 +1147,7 @@ void mpz_add_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) { dest->len = mpn_sub(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len); } - dest->neg = lhs->neg; + dest->neg = lhs->neg & !!dest->len; } /* computes dest = lhs - rhs @@ -1172,7 +1171,9 @@ void mpz_sub_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) { dest->len = mpn_sub(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len); } - if (neg) { + if (dest->len == 0) { + dest->neg = 0; + } else if (neg) { dest->neg = 1 - lhs->neg; } else { dest->neg = lhs->neg; @@ -1484,14 +1485,16 @@ void mpz_divmod_inpl(mpz_t *dest_quo, mpz_t *dest_rem, const mpz_t *lhs, const m mpz_need_dig(dest_quo, lhs->len + 1); // +1 necessary? memset(dest_quo->dig, 0, (lhs->len + 1) * sizeof(mpz_dig_t)); + dest_quo->neg = 0; dest_quo->len = 0; mpz_need_dig(dest_rem, lhs->len + 1); // +1 necessary? mpz_set(dest_rem, lhs); mpn_div(dest_rem->dig, &dest_rem->len, rhs->dig, rhs->len, dest_quo->dig, &dest_quo->len); + dest_rem->neg &= !!dest_rem->len; // check signs and do Python style modulo if (lhs->neg != rhs->neg) { - dest_quo->neg = 1; + dest_quo->neg = !!dest_quo->len; if (!mpz_is_zero(dest_rem)) { mpz_t mpzone; mpz_init_from_int(&mpzone, -1); diff --git a/py/mpz.h b/py/mpz.h index 425587ee9b..d27f572404 100644 --- a/py/mpz.h +++ b/py/mpz.h @@ -91,6 +91,7 @@ typedef int8_t mpz_dbl_dig_signed_t; #define MPZ_NUM_DIG_FOR_LL ((sizeof(long long) * 8 + MPZ_DIG_SIZE - 1) / MPZ_DIG_SIZE) typedef struct _mpz_t { + // Zero has neg=0, len=0. Negative zero is not allowed. size_t neg : 1; size_t fixed_dig : 1; size_t alloc : (8 * sizeof(size_t) - 2); @@ -119,7 +120,7 @@ static inline bool mpz_is_zero(const mpz_t *z) { return z->len == 0; } static inline bool mpz_is_neg(const mpz_t *z) { - return z->len != 0 && z->neg != 0; + return z->neg != 0; } int mpz_cmp(const mpz_t *lhs, const mpz_t *rhs); diff --git a/tests/basics/int_big_zeroone.py b/tests/basics/int_big_zeroone.py index 7e0b7a720e..81381526b9 100644 --- a/tests/basics/int_big_zeroone.py +++ b/tests/basics/int_big_zeroone.py @@ -1,4 +1,4 @@ -# test [0,-0,1,-1] edge cases of bignum +# test [0,1,-1] edge cases of bignum long_zero = (2**64) >> 65 long_neg_zero = -long_zero @@ -13,7 +13,7 @@ print([~c for c in cases]) print([c >> 1 for c in cases]) print([c << 1 for c in cases]) -# comparison of 0/-0/+0 +# comparison of 0 print(long_zero == 0) print(long_neg_zero == 0) print(long_one - 1 == 0) @@ -26,3 +26,40 @@ print(long_neg_zero < 1) print(long_neg_zero < -1) print(long_neg_zero > 1) print(long_neg_zero > -1) + +# generate zeros that involve negative numbers +large = 1 << 70 +large_plus_one = large + 1 +zeros = ( + large - large, + -large + large, + large + -large, + -(large - large), + large - large_plus_one + 1, + -large & (large - large), + -large ^ -large, + -large * (large - large), + (large - large) // -large, + -large // -large_plus_one, + -(large + large) % large, + (large + large) % -large, + -(large + large) % -large, +) +print(zeros) + +# compute arithmetic operations that may have problems with -0 +# (this checks that -0 is never generated in the zeros tuple) +cases = (0, 1, -1) + zeros +for lhs in cases: + print("-{} = {}".format(lhs, -lhs)) + print("~{} = {}".format(lhs, ~lhs)) + print("{} >> 1 = {}".format(lhs, lhs >> 1)) + print("{} << 1 = {}".format(lhs, lhs << 1)) + for rhs in cases: + print("{} == {} = {}".format(lhs, rhs, lhs == rhs)) + print("{} + {} = {}".format(lhs, rhs, lhs + rhs)) + print("{} - {} = {}".format(lhs, rhs, lhs - rhs)) + print("{} * {} = {}".format(lhs, rhs, lhs * rhs)) + print("{} | {} = {}".format(lhs, rhs, lhs | rhs)) + print("{} & {} = {}".format(lhs, rhs, lhs & rhs)) + print("{} ^ {} = {}".format(lhs, rhs, lhs ^ rhs)) From c768704cfdcb6dcafc0c972c6818fe4dd5b39034 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 21 Dec 2021 18:00:11 +1100 Subject: [PATCH 274/335] tests/basics/int_big_cmp.py: Add more tests for big-int comparison. To improve coverage of mpz_cmp and mpn_cmp. Signed-off-by: Damien George --- tests/basics/int_big_cmp.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/basics/int_big_cmp.py b/tests/basics/int_big_cmp.py index 7cb7412bdf..d7394d3bc8 100644 --- a/tests/basics/int_big_cmp.py +++ b/tests/basics/int_big_cmp.py @@ -1,10 +1,13 @@ # test bignum comparisons i = 1 << 65 +cases = (0, 1, -1, i, -i, i + 1, -(i + 1)) -print(i == 0) -print(i != 0) -print(i < 0) -print(i > 0) -print(i <= 0) -print(i >= 0) +for lhs in cases: + for rhs in cases: + print("{} == {} = {}".format(lhs, rhs, lhs == rhs)) + print("{} != {} = {}".format(lhs, rhs, lhs != rhs)) + print("{} < {} = {}".format(lhs, rhs, lhs < rhs)) + print("{} > {} = {}".format(lhs, rhs, lhs > rhs)) + print("{} <= {} = {}".format(lhs, rhs, lhs <= rhs)) + print("{} >= {} = {}".format(lhs, rhs, lhs >= rhs)) From 4189c64869bfe9054df7126ef33b80d718f08038 Mon Sep 17 00:00:00 2001 From: IhorNehrutsa Date: Sun, 5 Dec 2021 04:01:24 +0200 Subject: [PATCH 275/335] esp32/modnetwork: Synchronize WiFi AUTH_xxx constants with IDF values. --- ports/esp32/modnetwork.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ports/esp32/modnetwork.c b/ports/esp32/modnetwork.c index 51aaa59e87..a16c67eeb9 100644 --- a/ports/esp32/modnetwork.c +++ b/ports/esp32/modnetwork.c @@ -212,6 +212,13 @@ STATIC mp_obj_t esp_phy_mode(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_phy_mode_obj, 0, 1, esp_phy_mode); +#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(4, 3, 0) +#define TEST_WIFI_AUTH_MAX 9 +#else +#define TEST_WIFI_AUTH_MAX 8 +#endif +_Static_assert(WIFI_AUTH_MAX == TEST_WIFI_AUTH_MAX, "Synchronize WIFI_AUTH_XXX constants with the ESP-IDF. Look at esp-idf/components/esp_wifi/include/esp_wifi_types.h"); + STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) }, { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&esp_initialize_obj) }, @@ -242,9 +249,10 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_AUTH_WPA2_PSK), MP_ROM_INT(WIFI_AUTH_WPA2_PSK) }, { MP_ROM_QSTR(MP_QSTR_AUTH_WPA_WPA2_PSK), MP_ROM_INT(WIFI_AUTH_WPA_WPA2_PSK) }, { MP_ROM_QSTR(MP_QSTR_AUTH_WPA2_ENTERPRISE), MP_ROM_INT(WIFI_AUTH_WPA2_ENTERPRISE) }, - #if 0 // TODO: Remove this #if/#endif when lastest ISP IDF will be used { MP_ROM_QSTR(MP_QSTR_AUTH_WPA3_PSK), MP_ROM_INT(WIFI_AUTH_WPA3_PSK) }, { MP_ROM_QSTR(MP_QSTR_AUTH_WPA2_WPA3_PSK), MP_ROM_INT(WIFI_AUTH_WPA2_WPA3_PSK) }, + #if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(4, 3, 0) + { MP_ROM_QSTR(MP_QSTR_AUTH_WAPI_PSK), MP_ROM_INT(WIFI_AUTH_WAPI_PSK) }, #endif { MP_ROM_QSTR(MP_QSTR_AUTH_MAX), MP_ROM_INT(WIFI_AUTH_MAX) }, #endif From 09fe80d0912b2418fb704cf8e80db1712fb7523f Mon Sep 17 00:00:00 2001 From: IhorNehrutsa Date: Sun, 12 Dec 2021 14:16:53 +0200 Subject: [PATCH 276/335] esp32/machine_pwm: Keep duty constant when changing frequency. Save and restore the same duty cycle when the frequency (or frequency resolution) is changed. This allows a smooth frequency change. Also update the esp32 PWM quickref to be clearer. --- docs/esp32/quickref.rst | 14 +++++---- ports/esp32/machine_pwm.c | 61 +++++++++++++++++++-------------------- 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index 41c2fd6c65..e74d3d81f8 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -224,14 +224,18 @@ Use the :ref:`machine.PWM ` class:: from machine import Pin, PWM pwm0 = PWM(Pin(0)) # create PWM object from a pin - pwm0.freq() # get current frequency (default 5kHz) + freq = pwm0.freq() # get current frequency (default 5kHz) pwm0.freq(1000) # set PWM frequency from 1Hz to 40MHz - pwm0.duty() # get current duty cycle, range 0-1023 (default 512, 50%) + + duty = pwm0.duty() # get current duty cycle, range 0-1023 (default 512, 50%) pwm0.duty(256) # set duty cycle from 0 to 1023 as a ratio duty/1023, (now 25%) + + duty_u16 = pwm0.duty_u16() # get current duty cycle, range 0-65535 pwm0.duty_u16(2**16*3//4) # set duty cycle from 0 to 65535 as a ratio duty_u16/65535, (now 75%) - pwm0.duty_u16() # get current duty cycle, range 0-65535 + + duty_ns = pwm0.duty_ns() # get current pulse width in ns pwm0.duty_ns(250_000) # set pulse width in nanoseconds from 0 to 1_000_000_000/freq, (now 25%) - pwm0.duty_ns() # get current pulse width in ns + pwm0.deinit() # turn off PWM on the pin pwm2 = PWM(Pin(2), freq=20000, duty=512) # create and configure in one go @@ -246,7 +250,7 @@ Number of groups (speed modes) 2 1 Number of timers per group 4 4 4 Number of channels per group 8 8 6 ----------------------------------------------------- -------- -------- -------- -Different of PWM frequencies (groups * timers) 8 4 4 +Different PWM frequencies (groups * timers) 8 4 4 Total PWM channels (Pins, duties) (groups * channels) 16 8 6 ===================================================== ======== ======== ======== diff --git a/ports/esp32/machine_pwm.c b/ports/esp32/machine_pwm.c index 1cf3bc033a..43d44249dc 100644 --- a/ports/esp32/machine_pwm.c +++ b/ports/esp32/machine_pwm.c @@ -85,17 +85,17 @@ STATIC ledc_timer_config_t timers[PWM_TIMER_MAX]; // duty_u16() and duty_ns() use 16-bit resolution or less // Possible highest resolution in device -#if CONFIG_IDF_TARGET_ESP32 -#define HIGHEST_PWM_RES (LEDC_TIMER_16_BIT) // 20 bit in fact, but 16 bit is used +#if (LEDC_TIMER_BIT_MAX - 1) < LEDC_TIMER_16_BIT +#define HIGHEST_PWM_RES (LEDC_TIMER_BIT_MAX - 1) #else -#define HIGHEST_PWM_RES (LEDC_TIMER_14_BIT) +#define HIGHEST_PWM_RES (LEDC_TIMER_16_BIT) // 20 bit for ESP32, but 16 bit is used #endif // Duty resolution of user interface in `duty_u16()` and `duty_u16` parameter in constructor/initializer #define UI_RES_16_BIT (16) // Maximum duty value on highest user interface resolution #define UI_MAX_DUTY ((1 << UI_RES_16_BIT) - 1) // How much to shift from the HIGHEST_PWM_RES duty resolution to the user interface duty resolution UI_RES_16_BIT -#define UI_RES_SHIFT (16 - HIGHEST_PWM_RES) // 0 for ESP32, 2 for S2, S3, C3 +#define UI_RES_SHIFT (UI_RES_16_BIT - HIGHEST_PWM_RES) // 0 for ESP32, 2 for S2, S3, C3 // If the PWM frequency is less than EMPIRIC_FREQ, then LEDC_REF_CLK_HZ(1 MHz) source is used, else LEDC_APB_CLK_HZ(80 MHz) source is used #define EMPIRIC_FREQ (10) // Hz @@ -205,24 +205,19 @@ STATIC void configure_channel(machine_pwm_obj_t *self) { } STATIC void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_config_t *timer) { - // Even if the timer frequency is already set, - // the set_duty_x() is required to reconfigure the channel duty anyway if (freq != timer->freq_hz) { - PWM_DBG("set_freq(%d)", freq) - // Find the highest bit resolution for the requested frequency unsigned int i = LEDC_APB_CLK_HZ; // 80 MHz if (freq < EMPIRIC_FREQ) { i = LEDC_REF_CLK_HZ; // 1 MHz } - #if 1 + #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) // original code i /= freq; #else // See https://github.com/espressif/esp-idf/issues/7722 - unsigned int divider = i / freq; // truncated - // int divider = (i + freq / 2) / freq; // rounded + int divider = (i + freq / 2) / freq; // rounded if (divider == 0) { divider = 1; } @@ -245,6 +240,7 @@ STATIC void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_conf } // Configure the new resolution and frequency + unsigned int save_duty_resolution = timer->duty_resolution; timer->duty_resolution = res; timer->freq_hz = freq; timer->clk_cfg = LEDC_USE_APB_CLK; @@ -256,7 +252,6 @@ STATIC void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_conf esp_err_t err = ledc_timer_config(timer); if (err != ESP_OK) { if (err == ESP_FAIL) { - PWM_DBG(" (timer timer->speed_mode %d, timer->timer_num %d, timer->clk_cfg %d, timer->freq_hz %d, timer->duty_resolution %d) ", timer->speed_mode, timer->timer_num, timer->clk_cfg, timer->freq_hz, timer->duty_resolution); mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("unreachable frequency %d"), freq); } else { check_esp_err(err); @@ -266,15 +261,17 @@ STATIC void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_conf if (self->mode == LEDC_LOW_SPEED_MODE) { check_esp_err(ledc_timer_rst(self->mode, self->timer)); } - } - // Save the same duty cycle when frequency or channel are changed - if (self->duty_x == HIGHEST_PWM_RES) { - set_duty_u16(self, self->duty_u16); - } else if (self->duty_x == PWRES) { - set_duty_u10(self, self->duty_u10); - } else if (self->duty_x == -HIGHEST_PWM_RES) { - set_duty_ns(self, self->duty_ns); + // Save the same duty cycle when frequency is changed + if (save_duty_resolution != timer->duty_resolution) { + if (self->duty_x == HIGHEST_PWM_RES) { + set_duty_u16(self, self->duty_u16); + } else if (self->duty_x == PWRES) { + set_duty_u10(self, self->duty_u10); + } else if (self->duty_x == -HIGHEST_PWM_RES) { + set_duty_ns(self, self->duty_ns); + } + } } } @@ -287,14 +284,12 @@ STATIC int ns_to_duty(machine_pwm_obj_t *self, int ns) { } else if (duty > UI_MAX_DUTY) { duty = UI_MAX_DUTY; } - // PWM_DBG(" ns_to_duty(UI_MAX_DUTY=%d freq_hz=%d duty=%d=%f <- ns=%d) ", UI_MAX_DUTY, timer.freq_hz, duty, (float)ns * UI_MAX_DUTY * timer.freq_hz / 1000000000.0, ns); return duty; } STATIC int duty_to_ns(machine_pwm_obj_t *self, int duty) { ledc_timer_config_t timer = timers[TIMER_IDX(self->mode, self->timer)]; int64_t ns = ((int64_t)duty * 1000000000LL + (int64_t)timer.freq_hz * UI_MAX_DUTY / 2) / ((int64_t)timer.freq_hz * UI_MAX_DUTY); - // PWM_DBG(" duty_to_ns(UI_MAX_DUTY=%d freq_hz=%d duty=%d -> ns=%f=%d) ", UI_MAX_DUTY, timer.freq_hz, duty, (float)duty * 1000000000.0 / ((float)timer.freq_hz * UI_MAX_DUTY), ns); return ns; } @@ -316,23 +311,27 @@ STATIC void set_duty_u16(machine_pwm_obj_t *self, int duty) { if ((duty < 0) || (duty > UI_MAX_DUTY)) { mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("duty_u16 must be from 0 to %d"), UI_MAX_DUTY); } - duty >>= HIGHEST_PWM_RES + UI_RES_SHIFT - timers[TIMER_IDX(self->mode, self->timer)].duty_resolution; - int max_duty = (1 << timers[TIMER_IDX(self->mode, self->timer)].duty_resolution) - 1; - if (duty < 0) { - duty = 0; - } else if (duty > max_duty) { - duty = max_duty; + ledc_timer_config_t timer = timers[TIMER_IDX(self->mode, self->timer)]; + int channel_duty = duty >> (HIGHEST_PWM_RES + UI_RES_SHIFT - timer.duty_resolution); + int max_duty = (1 << timer.duty_resolution) - 1; + if (channel_duty < 0) { + channel_duty = 0; + } else if (channel_duty > max_duty) { + channel_duty = max_duty; } - check_esp_err(ledc_set_duty(self->mode, self->channel, duty)); + check_esp_err(ledc_set_duty(self->mode, self->channel, channel_duty)); check_esp_err(ledc_update_duty(self->mode, self->channel)); /* // Bug: Sometimes duty is not set right now. + // Not a bug. It's a feature. The duty is applied at the beginning of the next signal period. + // Bug: It has been experimentally established that the duty is setted during 2 signal periods, but 1 period is expected. // See https://github.com/espressif/esp-idf/issues/7288 if (duty != get_duty_u16(self)) { - ets_delay_us(100); + PWM_DBG("set_duty_u16(%u), get_duty_u16():%u, channel_duty:%d, duty_resolution:%d, freq_hz:%d", duty, get_duty_u16(self), channel_duty, timer.duty_resolution, timer.freq_hz); + ets_delay_us(2 * 1000000 / timer.freq_hz); if (duty != get_duty_u16(self)) { - PWM_DBG(" (set_duty_u16(%u) get_duty_u16()=%u duty_resolution=%d) ", duty, get_duty_u16(self), timers[TIMER_IDX(self->mode, self->timer)].duty_resolution); + PWM_DBG("set_duty_u16(%u), get_duty_u16():%u, channel_duty:%d, duty_resolution:%d, freq_hz:%d", duty, get_duty_u16(self), channel_duty, timer.duty_resolution, timer.freq_hz); } } */ From 599b61c08687ca077e3b0e115d5b76affcc673ca Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 11 Nov 2021 23:36:27 +1100 Subject: [PATCH 277/335] esp32/machine_bitstream: Replace bit-bang code with RMT-based driver. This aims to solve glitching issues on long neopixel strips. Signed-off-by: Jim Mussared --- ports/esp32/esp32_rmt.c | 6 ++ ports/esp32/machine_bitstream.c | 144 ++++++++++++++++++++++---------- ports/esp32/modesp32.h | 3 + 3 files changed, 107 insertions(+), 46 deletions(-) diff --git a/ports/esp32/esp32_rmt.c b/ports/esp32/esp32_rmt.c index 37ecef3248..1a7e77b9d2 100644 --- a/ports/esp32/esp32_rmt.c +++ b/ports/esp32/esp32_rmt.c @@ -29,6 +29,8 @@ #include "mphalport.h" #include "driver/rmt.h" +#include "modesp32.h" + // This exposes the ESP32's RMT module to MicroPython. RMT is provided by the Espressif ESP-IDF: // // https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/rmt.html @@ -73,6 +75,10 @@ STATIC mp_obj_t esp32_rmt_make_new(const mp_obj_type_t *type, size_t n_args, siz mp_uint_t idle_level = args[3].u_bool; mp_obj_t tx_carrier_obj = args[4].u_obj; + if (channel_id == MICROPY_HW_ESP32_RMT_CHANNEL_BITSTREAM) { + mp_raise_ValueError(MP_ERROR_TEXT("reserved channel id")); + } + if (clock_div < 1 || clock_div > 255) { mp_raise_ValueError(MP_ERROR_TEXT("clock_div must be between 1 and 255")); } diff --git a/ports/esp32/machine_bitstream.c b/ports/esp32/machine_bitstream.c index 9d2bb57246..9854b83434 100644 --- a/ports/esp32/machine_bitstream.c +++ b/ports/esp32/machine_bitstream.c @@ -24,63 +24,115 @@ * THE SOFTWARE. */ -// This is a translation of the cycle counter implementation in ports/stm32/machine_bitstream.c. - #include "py/mpconfig.h" #include "py/mphal.h" #if MICROPY_PY_MACHINE_BITSTREAM -#define NS_TICKS_OVERHEAD (6) +#include "driver/rmt.h" -void IRAM_ATTR machine_bitstream_high_low(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const uint8_t *buf, size_t len) { - uint32_t pin_mask, gpio_reg_set, gpio_reg_clear; - #if !CONFIG_IDF_TARGET_ESP32C3 - if (pin >= 32) { - pin_mask = 1 << (pin - 32); - gpio_reg_set = GPIO_OUT1_W1TS_REG; - gpio_reg_clear = GPIO_OUT1_W1TC_REG; - } else +#include "modesp32.h" + +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 1, 0) +// This convenience macro was not available in earlier IDF versions. +#define RMT_DEFAULT_CONFIG_TX(gpio, channel_id) \ + { \ + .rmt_mode = RMT_MODE_TX, \ + .channel = channel_id, \ + .clk_div = 80, \ + .gpio_num = gpio, \ + .mem_block_num = 1, \ + .tx_config = { \ + .loop_en = false, \ + .carrier_freq_hz = 38000, \ + .carrier_duty_percent = 33, \ + .carrier_level = RMT_CARRIER_LEVEL_HIGH, \ + .carrier_en = false, \ + .idle_level = RMT_IDLE_LEVEL_LOW, \ + .idle_output_en = true, \ + } \ + } +#endif + +// Logical 0 and 1 values (encoded as a rmt_item32_t). +// The duration fields will be set later. +STATIC rmt_item32_t bitstream_high_low_0 = {{{ 0, 1, 0, 0 }}}; +STATIC rmt_item32_t bitstream_high_low_1 = {{{ 0, 1, 0, 0 }}}; + +// See https://github.com/espressif/esp-idf/blob/master/examples/common_components/led_strip/led_strip_rmt_ws2812.c +// This is called automatically by the IDF during rmt_write_sample in order to +// convert the byte stream to rmt_item32_t's. +STATIC void IRAM_ATTR bitstream_high_low_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size, size_t wanted_num, size_t *translated_size, size_t *item_num) { + if (src == NULL || dest == NULL) { + *translated_size = 0; + *item_num = 0; + return; + } + + size_t size = 0; + size_t num = 0; + uint8_t *psrc = (uint8_t *)src; + rmt_item32_t *pdest = dest; + while (size < src_size && num < wanted_num) { + for (int i = 0; i < 8; i++) { + // MSB first + if (*psrc & (1 << (7 - i))) { + pdest->val = bitstream_high_low_1.val; + } else { + pdest->val = bitstream_high_low_0.val; + } + num++; + pdest++; + } + size++; + psrc++; + } + + *translated_size = size; + *item_num = num; +} + +// Use the reserved RMT channel to stream high/low data on the specified pin. +void machine_bitstream_high_low(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const uint8_t *buf, size_t len) { + rmt_config_t config = RMT_DEFAULT_CONFIG_TX(pin, MICROPY_HW_ESP32_RMT_CHANNEL_BITSTREAM); + + // Use 40MHz clock (although 2MHz would probably be sufficient). + config.clk_div = 2; + + // Install the driver on this channel & pin. + check_esp_err(rmt_config(&config)); + check_esp_err(rmt_driver_install(config.channel, 0, 0)); + + // Get the tick rate in kHz (this will likely be 40000). + uint32_t counter_clk_khz = 0; + #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 1, 0) + uint8_t div_cnt; + check_esp_err(rmt_get_clk_div(config.channel, &div_cnt)); + counter_clk_khz = APB_CLK_FREQ / div_cnt; + #else + check_esp_err(rmt_get_counter_clock(config.channel, &counter_clk_khz)); #endif - { - pin_mask = 1 << pin; - gpio_reg_set = GPIO_OUT_W1TS_REG; - gpio_reg_clear = GPIO_OUT_W1TC_REG; - } - // Convert ns to cpu ticks [high_time_0, period_0, high_time_1, period_1]. - uint32_t fcpu_mhz = ets_get_cpu_frequency(); - for (size_t i = 0; i < 4; ++i) { - timing_ns[i] = fcpu_mhz * timing_ns[i] / 1000; - if (timing_ns[i] > NS_TICKS_OVERHEAD) { - timing_ns[i] -= NS_TICKS_OVERHEAD; - } - if (i % 2 == 1) { - // Convert low_time to period (i.e. add high_time). - timing_ns[i] += timing_ns[i - 1]; - } - } + counter_clk_khz /= 1000; - uint32_t irq_state = mp_hal_quiet_timing_enter(); + // Convert nanoseconds to pulse duration. + bitstream_high_low_0.duration0 = (counter_clk_khz * timing_ns[0]) / 1e6; + bitstream_high_low_0.duration1 = (counter_clk_khz * timing_ns[1]) / 1e6; + bitstream_high_low_1.duration0 = (counter_clk_khz * timing_ns[2]) / 1e6; + bitstream_high_low_1.duration1 = (counter_clk_khz * timing_ns[3]) / 1e6; - for (size_t i = 0; i < len; ++i) { - uint8_t b = buf[i]; - for (size_t j = 0; j < 8; ++j) { - GPIO_REG_WRITE(gpio_reg_set, pin_mask); - uint32_t start_ticks = mp_hal_ticks_cpu(); - uint32_t *t = &timing_ns[b >> 6 & 2]; - while (mp_hal_ticks_cpu() - start_ticks < t[0]) { - ; - } - GPIO_REG_WRITE(gpio_reg_clear, pin_mask); - b <<= 1; - while (mp_hal_ticks_cpu() - start_ticks < t[1]) { - ; - } - } - } + // Install the bits->highlow translator. + rmt_translator_init(config.channel, bitstream_high_low_rmt_adapter); - mp_hal_quiet_timing_exit(irq_state); + // Stream the byte data using the translator. + check_esp_err(rmt_write_sample(config.channel, buf, len, true)); + + // Wait 50% longer than we expect (if every bit takes the maximum time). + uint32_t timeout_ms = (3 * len / 2) * (1 + (8 * MAX(timing_ns[0] + timing_ns[1], timing_ns[2] + timing_ns[3])) / 1000); + check_esp_err(rmt_wait_tx_done(config.channel, pdMS_TO_TICKS(timeout_ms))); + + // Uninstall the driver. + check_esp_err(rmt_driver_uninstall(config.channel)); } #endif // MICROPY_PY_MACHINE_BITSTREAM diff --git a/ports/esp32/modesp32.h b/ports/esp32/modesp32.h index 18bd62ee41..86979f0b3e 100644 --- a/ports/esp32/modesp32.h +++ b/ports/esp32/modesp32.h @@ -31,4 +31,7 @@ extern const mp_obj_type_t esp32_partition_type; extern const mp_obj_type_t esp32_rmt_type; extern const mp_obj_type_t esp32_ulp_type; +// Reserve the last channel for machine.bitstream. +#define MICROPY_HW_ESP32_RMT_CHANNEL_BITSTREAM (RMT_CHANNEL_MAX - 1) + #endif // MICROPY_INCLUDED_ESP32_MODESP32_H From 7566d107d5acc82a45df0dd5c5803bf5d2564043 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 3 Oct 2021 00:06:40 -0600 Subject: [PATCH 278/335] tools/mpremote: Add mkdir and rmdir to RemoteFS. This allows the remote MicroPython instance to create and delete directories from the mounted host filesystem in addition to the already existing functionality of reading, creating, and modifying files. Signed-off-by: Michael Bentley --- tools/mpremote/mpremote/pyboardextended.py | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tools/mpremote/mpremote/pyboardextended.py b/tools/mpremote/mpremote/pyboardextended.py index 70e3748ec8..41f360e5fd 100644 --- a/tools/mpremote/mpremote/pyboardextended.py +++ b/tools/mpremote/mpremote/pyboardextended.py @@ -21,6 +21,8 @@ fs_hook_cmds = { "CMD_SEEK": 8, "CMD_REMOVE": 9, "CMD_RENAME": 10, + "CMD_MKDIR": 11, + "CMD_RMDIR": 12, } fs_hook_code = """\ @@ -265,6 +267,24 @@ class RemoteFS: if res < 0: raise OSError(-res) + def mkdir(self, path): + c = self.cmd + c.begin(CMD_MKDIR) + c.wr_str(self.path + path) + res = c.rd_s32() + c.end() + if res < 0: + raise OSError(-res) + + def rmdir(self, path): + c = self.cmd + c.begin(CMD_RMDIR) + c.wr_str(self.path + path) + res = c.rd_s32() + c.end() + if res < 0: + raise OSError(-res) + def stat(self, path): c = self.cmd c.begin(CMD_STAT) @@ -501,6 +521,28 @@ class PyboardCommand: ret = -abs(er.errno) self.wr_s32(ret) + def do_mkdir(self): + path = self.root + self.rd_str() + # self.log_cmd(f"mkdir {path}") + try: + self.path_check(path) + os.mkdir(path) + ret = 0 + except OSError as er: + ret = -abs(er.errno) + self.wr_s32(ret) + + def do_rmdir(self): + path = self.root + self.rd_str() + # self.log_cmd(f"rmdir {path}") + try: + self.path_check(path) + os.rmdir(path) + ret = 0 + except OSError as er: + ret = -abs(er.errno) + self.wr_s32(ret) + cmd_table = { fs_hook_cmds["CMD_STAT"]: do_stat, fs_hook_cmds["CMD_ILISTDIR_START"]: do_ilistdir_start, @@ -512,6 +554,8 @@ class PyboardCommand: fs_hook_cmds["CMD_SEEK"]: do_seek, fs_hook_cmds["CMD_REMOVE"]: do_remove, fs_hook_cmds["CMD_RENAME"]: do_rename, + fs_hook_cmds["CMD_MKDIR"]: do_mkdir, + fs_hook_cmds["CMD_RMDIR"]: do_rmdir, } From 74e995dfd26c7c9304392b2073ec4558173b699c Mon Sep 17 00:00:00 2001 From: Sergei Silnov Date: Sun, 5 Sep 2021 14:11:35 +0200 Subject: [PATCH 279/335] tools/mpremote: Add help command. Fixes issue #7480 --- tools/mpremote/README.md | 6 +- tools/mpremote/mpremote/main.py | 126 ++++++++++++++++++++++---------- 2 files changed, 94 insertions(+), 38 deletions(-) diff --git a/tools/mpremote/README.md b/tools/mpremote/README.md index a6aaa1755d..c294b20811 100644 --- a/tools/mpremote/README.md +++ b/tools/mpremote/README.md @@ -27,6 +27,7 @@ The full list of supported commands are: --capture --inject-code --inject-file + mpremote help -- print list of commands and exit Multiple commands can be specified and they will be run sequentially. Connection and disconnection will be done automatically at the start and end of the execution @@ -50,7 +51,10 @@ Any user configuration, including user-defined shortcuts, can be placed in commands = { "c33": "connect id:334D335C3138", "bl": "bootloader", - "double x=4": "eval x*2", + "double x=4": { + "command": "eval x*2", + "help": "multiply by two" + } } Examples: diff --git a/tools/mpremote/mpremote/main.py b/tools/mpremote/mpremote/main.py index 6e2df5179d..5655bffbf3 100644 --- a/tools/mpremote/mpremote/main.py +++ b/tools/mpremote/mpremote/main.py @@ -18,6 +18,9 @@ MicroPython device over a serial connection. Commands supported are: """ import os, sys +from collections.abc import Mapping +from textwrap import dedent + import serial.tools.list_ports from . import pyboardextended as pyboard @@ -25,21 +28,42 @@ from .console import Console, ConsolePosix _PROG = "mpremote" +_COMMANDS = { + "connect": ( + False, + False, + 1, + """\ + connect to given device + device may be: list, auto, id:x, port:x + or any valid device name/path""", + ), + "disconnect": (False, False, 0, "disconnect current device"), + "mount": (True, False, 1, "mount local directory on device"), + "repl": ( + False, + True, + 0, + """\ + enter REPL + options: + --capture + --inject-code + --inject-file """, + ), + "eval": (True, True, 1, "evaluate and print the string"), + "exec": (True, True, 1, "execute the string"), + "run": (True, True, 1, "run the given local script"), + "fs": (True, True, 1, "execute filesystem commands on the device"), + "help": (False, False, 0, "print help and exit"), +} + _BUILTIN_COMMAND_EXPANSIONS = { # Device connection shortcuts. - "devs": "connect list", - "a0": "connect /dev/ttyACM0", - "a1": "connect /dev/ttyACM1", - "a2": "connect /dev/ttyACM2", - "a3": "connect /dev/ttyACM3", - "u0": "connect /dev/ttyUSB0", - "u1": "connect /dev/ttyUSB1", - "u2": "connect /dev/ttyUSB2", - "u3": "connect /dev/ttyUSB3", - "c0": "connect COM0", - "c1": "connect COM1", - "c2": "connect COM2", - "c3": "connect COM3", + "devs": { + "command": "connect list", + "help": "list available serial ports", + }, # Filesystem shortcuts. "cat": "fs cat", "ls": "fs ls", @@ -52,22 +76,35 @@ _BUILTIN_COMMAND_EXPANSIONS = { "import uos\nprint('mount \\tsize \\tused \\tavail \\tuse%')\nfor _m in [''] + uos.listdir('/'):\n _s = uos.stat('/' + _m)\n if not _s[0] & 1 << 14: continue\n _s = uos.statvfs(_m)\n if _s[0]:\n _size = _s[0] * _s[2]; _free = _s[0] * _s[3]; print(_m, _size, _size - _free, _free, int(100 * (_size - _free) / _size), sep='\\t')", ], # Other shortcuts. - "reset t_ms=100": [ - "exec", - "--no-follow", - "import utime, umachine; utime.sleep_ms(t_ms); umachine.reset()", - ], - "bootloader t_ms=100": [ - "exec", - "--no-follow", - "import utime, umachine; utime.sleep_ms(t_ms); umachine.bootloader()", - ], + "reset t_ms=100": { + "command": [ + "exec", + "--no-follow", + "import utime, umachine; utime.sleep_ms(t_ms); umachine.reset()", + ], + "help": "reset the device after delay", + }, + "bootloader t_ms=100": { + "command": [ + "exec", + "--no-follow", + "import utime, umachine; utime.sleep_ms(t_ms); umachine.bootloader()", + ], + "help": "make the device enter its bootloader", + }, "setrtc": [ "exec", "import machine; machine.RTC().datetime((2020, 1, 1, 0, 10, 0, 0, 0))", ], } +for port_num in range(4): + for prefix, port in [("a", "/dev/ttyACM"), ("u", "/dev/ttyUSB"), ("c", "COM")]: + _BUILTIN_COMMAND_EXPANSIONS["{}{}".format(prefix, port_num)] = { + "command": "connect {}{}".format(port, port_num), + "help": 'connect to serial port "{}{}"'.format(port, port_num), + } + def load_user_config(): # Create empty config object. @@ -111,9 +148,14 @@ def prepare_command_expansions(config): args = () else: args = tuple(c.split("=") for c in cmd[1:]) + + help_message = "" + if isinstance(sub, Mapping): + help_message = sub.get("help", "") + sub = sub["command"] if isinstance(sub, str): sub = sub.split() - _command_expansions[cmd[0]] = (args, sub) + _command_expansions[cmd[0]] = (args, sub, help_message) def do_command_expansion(args): @@ -126,7 +168,7 @@ def do_command_expansion(args): pre = [] while args and args[0] in _command_expansions: cmd = args.pop(0) - exp_args, exp_sub = _command_expansions[cmd] + exp_args, exp_sub, _ = _command_expansions[cmd] for exp_arg in exp_args: exp_arg_name = exp_arg[0] if args and "=" not in args[0]: @@ -365,6 +407,24 @@ def execbuffer(pyb, buf, follow): return ret_val +def print_help(): + def print_commands_help(cmds, help_idx): + max_command_len = max(len(cmd) for cmd in cmds.keys()) + for cmd in sorted(cmds.keys()): + help_message_lines = dedent(cmds[cmd][help_idx]).split("\n") + help_message = help_message_lines[0] + for line in help_message_lines[1:]: + help_message = "{}\n{}{}".format(help_message, " " * (max_command_len + 4), line) + print(" ", cmd, " " * (max_command_len - len(cmd) + 2), help_message, sep="") + + print(_PROG, "-- MicroPython remote control") + print("\nList of commands:") + print_commands_help(_COMMANDS, 3) + + print("\nList of shortcuts:") + print_commands_help(_command_expansions, 2) + + def main(): config = load_user_config() prepare_command_expansions(config) @@ -376,20 +436,9 @@ def main(): try: while args: do_command_expansion(args) - - cmds = { - "connect": (False, False, 1), - "disconnect": (False, False, 0), - "mount": (True, False, 1), - "repl": (False, True, 0), - "eval": (True, True, 1), - "exec": (True, True, 1), - "run": (True, True, 1), - "fs": (True, True, 1), - } cmd = args.pop(0) try: - need_raw_repl, is_action, num_args_min = cmds[cmd] + need_raw_repl, is_action, num_args_min, _ = _COMMANDS[cmd] except KeyError: print(f"{_PROG}: '{cmd}' is not a command") return 1 @@ -405,6 +454,9 @@ def main(): if pyb is None: did_action = True continue + elif cmd == "help": + print_help() + sys.exit(0) if pyb is None: pyb = do_connect(["auto"]) From 028776d97b284d2fda053dd7daa4c72591f0115e Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 29 Dec 2021 23:35:24 +1100 Subject: [PATCH 280/335] tools/mpremote: Add link to mpremote docs URL in help message. Signed-off-by: Damien George --- tools/mpremote/mpremote/main.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/mpremote/mpremote/main.py b/tools/mpremote/mpremote/main.py index 5655bffbf3..99e7bcd9bc 100644 --- a/tools/mpremote/mpremote/main.py +++ b/tools/mpremote/mpremote/main.py @@ -418,6 +418,8 @@ def print_help(): print(" ", cmd, " " * (max_command_len - len(cmd) + 2), help_message, sep="") print(_PROG, "-- MicroPython remote control") + print("See https://docs.micropython.org/en/latest/reference/mpremote.html") + print("\nList of commands:") print_commands_help(_COMMANDS, 3) From aac5a97d08f9f28b7c3f170d007be0b538349937 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 21 Dec 2021 23:07:00 +1100 Subject: [PATCH 281/335] ports: Move '.frozen' to second entry in sys.path. In commit 86ce4426079b1b368881c22f46d80045e2f720b0 the '.frozen' entry was added at the start of sys.path, to allow control over when frozen modules are searched during import, and retain existing behaviour whereby frozen was searched before the filesystem. But Python semantics of sys.path require sys.path[0] to be the directory of the currently executing script, or ''. This commit moves the '.frozen' entry to second place in sys.path, so sys.path[0] retains its correct value (described above). Signed-off-by: Damien George --- ports/unix/main.c | 11 +++++------ ports/unix/mpconfigport.h | 2 +- ports/unix/variants/minimal/mpconfigvariant.h | 2 +- ports/windows/mpconfigport.h | 2 +- py/runtime.c | 2 +- tests/basics/sys_path.py | 16 ++++++++++++++++ tests/run-tests.py | 2 +- 7 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 tests/basics/sys_path.py diff --git a/ports/unix/main.c b/ports/unix/main.c index cecb806283..b2790791af 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -497,7 +497,7 @@ MP_NOINLINE int main_(int argc, char **argv) { if (path == NULL) { path = MICROPY_PY_SYS_PATH_DEFAULT; } - size_t path_num = 2; // [0] is frozen, [1] is for current dir (or base dir of the script) + size_t path_num = 1; // [0] is for current dir (or base dir of the script) if (*path == PATHLIST_SEP_CHAR) { path_num++; } @@ -510,11 +510,10 @@ MP_NOINLINE int main_(int argc, char **argv) { mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), path_num); mp_obj_t *path_items; mp_obj_list_get(mp_sys_path, &path_num, &path_items); - path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen); - path_items[1] = MP_OBJ_NEW_QSTR(MP_QSTR_); + path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR_); { char *p = path; - for (mp_uint_t i = 2; i < path_num; i++) { + for (mp_uint_t i = 1; i < path_num; i++) { char *p1 = strchr(p, PATHLIST_SEP_CHAR); if (p1 == NULL) { p1 = p + strlen(p); @@ -655,9 +654,9 @@ MP_NOINLINE int main_(int argc, char **argv) { break; } - // Set base dir of the script as second entry in sys.path. + // Set base dir of the script as first entry in sys.path. char *p = strrchr(basedir, '/'); - path_items[1] = mp_obj_new_str_via_qstr(basedir, p - basedir); + path_items[0] = mp_obj_new_str_via_qstr(basedir, p - basedir); free(pathbuf); set_sys_argv(argv, argc, a); diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index a995ac52cc..658cb680f1 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -125,7 +125,7 @@ #endif #endif #ifndef MICROPY_PY_SYS_PATH_DEFAULT -#define MICROPY_PY_SYS_PATH_DEFAULT "~/.micropython/lib:/usr/lib/micropython" +#define MICROPY_PY_SYS_PATH_DEFAULT ".frozen:~/.micropython/lib:/usr/lib/micropython" #endif #define MICROPY_PY_SYS_MAXSIZE (1) #define MICROPY_PY_SYS_STDFILES (1) diff --git a/ports/unix/variants/minimal/mpconfigvariant.h b/ports/unix/variants/minimal/mpconfigvariant.h index 4766b8e895..e0db3756ca 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.h +++ b/ports/unix/variants/minimal/mpconfigvariant.h @@ -89,7 +89,7 @@ #define MICROPY_PY_SYS_EXIT (0) #define MICROPY_PY_SYS_PLATFORM "linux" #ifndef MICROPY_PY_SYS_PATH_DEFAULT -#define MICROPY_PY_SYS_PATH_DEFAULT "~/.micropython/lib:/usr/lib/micropython" +#define MICROPY_PY_SYS_PATH_DEFAULT ".frozen:~/.micropython/lib:/usr/lib/micropython" #endif #define MICROPY_PY_SYS_MAXSIZE (0) #define MICROPY_PY_SYS_STDFILES (0) diff --git a/ports/windows/mpconfigport.h b/ports/windows/mpconfigport.h index 30d8e09e6d..f22af9b7fc 100644 --- a/ports/windows/mpconfigport.h +++ b/ports/windows/mpconfigport.h @@ -90,7 +90,7 @@ #define MICROPY_PY_SYS_ATEXIT (1) #define MICROPY_PY_SYS_PLATFORM "win32" #ifndef MICROPY_PY_SYS_PATH_DEFAULT -#define MICROPY_PY_SYS_PATH_DEFAULT "~/.micropython/lib" +#define MICROPY_PY_SYS_PATH_DEFAULT ".frozen;~/.micropython/lib" #endif #define MICROPY_PY_SYS_MAXSIZE (1) #define MICROPY_PY_SYS_STDFILES (1) diff --git a/py/runtime.c b/py/runtime.c index 7607ffb191..8c93f539e0 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -124,10 +124,10 @@ void mp_init(void) { #if MICROPY_PY_SYS_PATH_ARGV_DEFAULTS mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0); + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) #if MICROPY_MODULE_FROZEN mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); #endif - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); #endif diff --git a/tests/basics/sys_path.py b/tests/basics/sys_path.py new file mode 100644 index 0000000000..6456e24019 --- /dev/null +++ b/tests/basics/sys_path.py @@ -0,0 +1,16 @@ +# test sys.path + +try: + import usys as sys +except ImportError: + import sys + +# check that this script was executed from a file of the same name +if "__file__" not in globals() or "sys_path.py" not in __file__: + print("SKIP") + raise SystemExit + +# test that sys.path[0] is the directory containing this script +with open(sys.path[0] + "/sys_path.py") as f: + for _ in range(4): + print(f.readline()) diff --git a/tests/run-tests.py b/tests/run-tests.py index a8a31c0ae5..6f3c09d1da 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -852,7 +852,7 @@ the last matching regex is used: if not args.keep_path: # clear search path to make sure tests use only builtin modules and those in extmod - os.environ["MICROPYPATH"] = os.pathsep + base_path("../extmod") + os.environ["MICROPYPATH"] = ".frozen" + os.pathsep + base_path("../extmod") try: os.makedirs(args.result_dir, exist_ok=True) From 959e6f7da91a8b751084c33a6ed0db807f72b0b9 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 21 Dec 2021 23:16:51 +1100 Subject: [PATCH 282/335] tools/upip.py: Skip '.frozen' entry in sys.path for install path. Signed-off-by: Damien George --- tools/upip.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/upip.py b/tools/upip.py index a6d4c93ae3..9fb8726420 100644 --- a/tools/upip.py +++ b/tools/upip.py @@ -262,6 +262,8 @@ def get_install_path(): if install_path is None: # sys.path[0] is current module's path install_path = sys.path[1] + if install_path == ".frozen": + install_path = sys.path[2] install_path = expandhome(install_path) return install_path @@ -281,11 +283,11 @@ upip - Simple PyPI package manager for MicroPython Usage: micropython -m upip install [-p ] ... | -r import upip; upip.install(package_or_list, []) -If is not given, packages will be installed into sys.path[1] -(can be set from MICROPYPATH environment variable, if current system -supports that).""" +If isn't given, packages will be installed to sys.path[1], or +sys.path[2] if the former is .frozen (path can be set from MICROPYPATH +environment variable if supported).""" ) - print("Current value of sys.path[1]:", sys.path[1]) + print("Default install path:", get_install_path()) print( """\ From 8af9dbbde1fca07371aa13a8276c8e764edac28c Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 29 Dec 2021 23:38:16 +0200 Subject: [PATCH 283/335] stm32/network_wiznet5k: Fix build error with wiznet5k and lwip enabled. Commit 4dba04a50fea01f6f8fec83d64f958f8d14e285a refactored the network code but the combination of MICROPY_PY_WIZNET5K=5500 and MICROPY_PY_LWIP=1 broke. --- ports/stm32/mpconfigport.h | 4 ++++ ports/stm32/mpnetworkport.c | 4 ++++ ports/stm32/network_wiznet5k.c | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 6639b92413..b1a38713dc 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -253,7 +253,11 @@ extern const struct _mp_obj_type_t mp_network_cyw43_type; #endif #if MICROPY_PY_WIZNET5K +#if MICROPY_PY_LWIP +extern const struct _mp_obj_type_t mod_network_nic_type_wiznet5k; +#else extern const struct _mod_network_nic_type_t mod_network_nic_type_wiznet5k; +#endif #define MICROPY_HW_NIC_WIZNET5K { MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) }, #else #define MICROPY_HW_NIC_WIZNET5K diff --git a/ports/stm32/mpnetworkport.c b/ports/stm32/mpnetworkport.c index a5ee15bc67..c879c50055 100644 --- a/ports/stm32/mpnetworkport.c +++ b/ports/stm32/mpnetworkport.c @@ -48,6 +48,10 @@ // Poll lwIP every 128ms #define LWIP_TICK(tick) (((tick) & ~(SYSTICK_DISPATCH_NUM_SLOTS - 1) & 0x7f) == 0) +#if MICROPY_PY_WIZNET5K +void wiznet5k_poll(void); +#endif + u32_t sys_now(void) { return mp_hal_ticks_ms(); } diff --git a/ports/stm32/network_wiznet5k.c b/ports/stm32/network_wiznet5k.c index b6f1498eff..a529191557 100644 --- a/ports/stm32/network_wiznet5k.c +++ b/ports/stm32/network_wiznet5k.c @@ -269,7 +269,7 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size mp_hal_pin_obj_t rst = pin_find(args[2]); // Access the existing object, if it has been constructed with the same hardware interface - if (wiznet5k_obj.base.type == &mod_network_nic_type_wiznet5k) { + if (wiznet5k_obj.base.type == (mp_obj_type_t *)&mod_network_nic_type_wiznet5k) { if (!(wiznet5k_obj.spi == spi && wiznet5k_obj.cs == cs && wiznet5k_obj.rst == rst && wiznet5k_obj.netif.flags != 0)) { wiznet5k_deinit(); @@ -277,7 +277,7 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size } // Init the wiznet5k object - wiznet5k_obj.base.type = &mod_network_nic_type_wiznet5k; + wiznet5k_obj.base.type = (mp_obj_type_t *)&mod_network_nic_type_wiznet5k; wiznet5k_obj.cris_state = 0; wiznet5k_obj.spi = spi; wiznet5k_obj.cs = cs; From a29c70c9b40b9f6cab9789805e445683418580f0 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 23 Dec 2021 17:09:05 +1100 Subject: [PATCH 284/335] esp8266: Allow building a board to any dest directory. Signed-off-by: Damien George --- ports/esp8266/boards/esp8266_common.ld | 4 ++-- tools/autobuild/build-esp8266-latest.sh | 13 ++++--------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/ports/esp8266/boards/esp8266_common.ld b/ports/esp8266/boards/esp8266_common.ld index f40ff1e5fc..ae1509faee 100644 --- a/ports/esp8266/boards/esp8266_common.ld +++ b/ports/esp8266/boards/esp8266_common.ld @@ -144,7 +144,7 @@ SECTIONS *shared/timeutils/*.o*(.literal*, .text*) *drivers/bus/*.o(.literal* .text*) - build-*/main.o(.literal* .text*) + */main.o(.literal* .text*) *fatfs_port.o(.literal* .text*) *gccollect.o(.literal* .text*) *gchelper.o(.literal* .text*) @@ -182,7 +182,7 @@ SECTIONS */frozen.o(.rodata.mp_frozen_content) /* frozen modules */ /* for -mforce-l32 */ - build-*/*.o(.rodata*) + */*.o(.rodata*) _irom0_text_end = ABSOLUTE(.); } >irom0_0_seg :irom0_0_phdr diff --git a/tools/autobuild/build-esp8266-latest.sh b/tools/autobuild/build-esp8266-latest.sh index fe79587fd1..72c6ee9886 100755 --- a/tools/autobuild/build-esp8266-latest.sh +++ b/tools/autobuild/build-esp8266-latest.sh @@ -13,9 +13,7 @@ function do_build() { shift shift echo "building $descr $board" - #build_dir=/tmp/esp8266-build-$board - build_dir=build-$board # until esp8266.ld is fixed - rm -rf $build_dir # be sure we don't have anything leftover from a previous build + build_dir=/tmp/esp8266-build-$board $MICROPY_AUTOBUILD_MAKE $@ BOARD=$board BUILD=$build_dir || exit 1 mv $build_dir/firmware-combined.bin $dest_dir/$descr$fw_tag.bin mv $build_dir/firmware.elf $dest_dir/$descr$fw_tag.elf @@ -29,19 +27,16 @@ function do_build_ota() { shift shift echo "building $descr $board" - #build_dir=/tmp/esp8266-build-$board - build_dir=build-$board # until esp8266.ld is fixed - rm -rf $build_dir # be sure we don't have anything leftover from a previous build + build_dir=/tmp/esp8266-build-$board $MICROPY_AUTOBUILD_MAKE $@ BOARD=$board BUILD=$build_dir || exit 1 cat $yaota8266/yaota8266.bin $build_dir/firmware-ota.bin > $dest_dir/$descr$fw_tag.bin - cwd=$(pwd) pushd $yaota8266/ota-client - $PYTHON3 ota_client.py sign $cwd/$build_dir/firmware-ota.bin + $PYTHON3 ota_client.py sign $build_dir/firmware-ota.bin popd mv $build_dir/firmware-ota.bin.ota $dest_dir/$descr$fw_tag.ota mv $build_dir/firmware.elf $dest_dir/$descr$fw_tag.elf mv $build_dir/firmware.map $dest_dir/$descr$fw_tag.map - #rm -rf $build_dir + rm -rf $build_dir } # check/get parameters From bfe9eba48440eaf0a56bfa2e19a10bc8ba8def5a Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 23 Dec 2021 17:41:28 +1100 Subject: [PATCH 285/335] tools/autobuild: Build esp8266 OTA image with GENERIC_1M board. Because the GENERIC board won't fit in the flash defined by esp8266_ota.ld. Signed-off-by: Damien George --- tools/autobuild/build-esp8266-latest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/autobuild/build-esp8266-latest.sh b/tools/autobuild/build-esp8266-latest.sh index 72c6ee9886..1972e85fcd 100755 --- a/tools/autobuild/build-esp8266-latest.sh +++ b/tools/autobuild/build-esp8266-latest.sh @@ -58,4 +58,4 @@ fi do_build esp8266 GENERIC do_build esp8266-512k GENERIC_512K do_build esp8266-1m GENERIC_1M -do_build_ota esp8266-ota GENERIC ota +do_build_ota esp8266-ota GENERIC_1M ota From 05ed19e73e26c4db3ec8637c3acf2a43be8c285a Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 25 Nov 2021 12:16:29 +1100 Subject: [PATCH 286/335] windows: Add support for build variants to windows port. Following the unix port. Support for building variants with msvc was done by @stinos. --- ports/windows/Makefile | 24 ++++++++++-- ports/windows/README.md | 20 ++++++++++ ports/windows/micropython.vcxproj | 2 + ports/windows/mpconfigport.h | 19 ++++++++-- ports/windows/mpconfigport.mk | 7 +--- ports/windows/msvc/common.props | 9 +++++ ports/windows/msvc/paths.props | 9 +++-- ports/windows/variants/dev/manifest.py | 1 + ports/windows/variants/dev/mpconfigvariant.h | 37 +++++++++++++++++++ ports/windows/variants/dev/mpconfigvariant.mk | 5 +++ .../variants/dev/mpconfigvariant.props | 5 +++ ports/windows/variants/manifest.py | 0 .../variants/standard/mpconfigvariant.h | 28 ++++++++++++++ .../variants/standard/mpconfigvariant.mk | 3 ++ .../variants/standard/mpconfigvariant.props | 5 +++ 15 files changed, 160 insertions(+), 14 deletions(-) create mode 100644 ports/windows/variants/dev/manifest.py create mode 100644 ports/windows/variants/dev/mpconfigvariant.h create mode 100644 ports/windows/variants/dev/mpconfigvariant.mk create mode 100644 ports/windows/variants/dev/mpconfigvariant.props create mode 100644 ports/windows/variants/manifest.py create mode 100644 ports/windows/variants/standard/mpconfigvariant.h create mode 100644 ports/windows/variants/standard/mpconfigvariant.mk create mode 100644 ports/windows/variants/standard/mpconfigvariant.props diff --git a/ports/windows/Makefile b/ports/windows/Makefile index cb2ebc22f7..b1d2d35c9a 100644 --- a/ports/windows/Makefile +++ b/ports/windows/Makefile @@ -1,11 +1,27 @@ +# Select the variant to build for. +VARIANT ?= standard + +# If the build directory is not given, make it reflect the variant name. +BUILD ?= build-$(VARIANT) + +VARIANT_DIR ?= variants/$(VARIANT) +ifeq ($(wildcard $(VARIANT_DIR)/.),) +$(error Invalid VARIANT specified: $(VARIANT_DIR)) +endif + include ../../py/mkenv.mk -include mpconfigport.mk +include $(VARIANT_DIR)/mpconfigvariant.mk -# define main target -PROG = micropython +FROZEN_MANIFEST ?= variants/manifest.py + +# Define main target +# This should be configured by the mpconfigvariant.mk +PROG ?= micropython # qstr definitions (must come before including py.mk) QSTR_DEFS = ../unix/qstrdefsport.h +QSTR_GLOBAL_DEPENDENCIES = $(VARIANT_DIR)/mpconfigvariant.h # include py core make definitions include $(TOP)/py/py.mk @@ -13,6 +29,7 @@ include $(TOP)/py/py.mk INC += -I. INC += -I$(TOP) INC += -I$(BUILD) +INC += -I$(VARIANT_DIR) # compiler settings CFLAGS = $(INC) -Wall -Wpointer-arith -Wdouble-promotion -Werror -std=gnu99 -DUNIX -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) @@ -41,7 +58,8 @@ SRC_C = \ init.c \ sleep.c \ fmode.c \ - $(SRC_MOD) + $(SRC_MOD) \ + $(wildcard $(VARIANT_DIR)/*.c) OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) diff --git a/ports/windows/README.md b/ports/windows/README.md index 55e23de7bf..713ea82b87 100644 --- a/ports/windows/README.md +++ b/ports/windows/README.md @@ -71,6 +71,26 @@ To build from the command line: msbuild ../../mpy-cross/mpy-cross.vcxproj msbuild micropython.vcxproj +__Variants__ + +The msvc port supports variants (like the unix and windows mingw ports) and the one which gets built is +controlled by the `PyVariant` msbuild property. It defaults to `standard`. +The other variants can be built like: + + msbuild micropython.vcxproj /p:PyVariant=dev + +Or by adding a file [Directory.build.props](https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build#directorybuildprops-and-directorybuildtargets) in this directory or a parent directory: + +```xml + + + dev + + +``` + +See [paths.props](msvc/paths.props) for other related variables like build and variant directories. + __Stack usage__ The msvc compiler is quite stack-hungry which might result in a "maximum recursion depth exceeded" diff --git a/ports/windows/micropython.vcxproj b/ports/windows/micropython.vcxproj index 1beca9e508..6817d6ed13 100644 --- a/ports/windows/micropython.vcxproj +++ b/ports/windows/micropython.vcxproj @@ -64,6 +64,7 @@ msvc/user.props + $(PyProg) @@ -95,6 +96,7 @@ + diff --git a/ports/windows/mpconfigport.h b/ports/windows/mpconfigport.h index f22af9b7fc..96405bc5d2 100644 --- a/ports/windows/mpconfigport.h +++ b/ports/windows/mpconfigport.h @@ -26,6 +26,9 @@ // options to control how MicroPython is built +// Variant-specific definitions. +#include "mpconfigvariant.h" + // By default use MicroPython version of readline #ifndef MICROPY_USE_READLINE #define MICROPY_USE_READLINE (1) @@ -54,9 +57,13 @@ #define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_HELPER_LEXER_UNIX (1) #define MICROPY_ENABLE_SOURCE_LINE (1) +#ifndef MICROPY_FLOAT_IMPL #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE) +#endif #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) +#ifndef MICROPY_STREAMS_NON_BLOCK #define MICROPY_STREAMS_NON_BLOCK (1) +#endif #define MICROPY_STREAMS_POSIX_API (1) #define MICROPY_OPT_COMPUTED_GOTO (0) #define MICROPY_MODULE_WEAK_LINKS (1) @@ -77,8 +84,12 @@ #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) #define MICROPY_PY_BUILTINS_INPUT (1) #define MICROPY_PY_BUILTINS_POW3 (1) +#ifndef MICROPY_PY_BUILTINS_HELP #define MICROPY_PY_BUILTINS_HELP (1) +#endif +#ifndef MICROPY_PY_BUILTINS_HELP_MODULES #define MICROPY_PY_BUILTINS_HELP_MODULES (1) +#endif #define MICROPY_PY_BUILTINS_ROUND_INT (1) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define MICROPY_PY_ALL_SPECIAL_METHODS (1) @@ -97,16 +108,18 @@ #define MICROPY_PY_SYS_EXC_INFO (1) #define MICROPY_PY_COLLECTIONS_DEQUE (1) #define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) +#ifndef MICROPY_PY_MATH_SPECIAL_FUNCTIONS #define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1) -#define MICROPY_PY_MATH_ISCLOSE (1) +#endif +#define MICROPY_PY_MATH_ISCLOSE (MICROPY_PY_MATH_SPECIAL_FUNCTIONS) #define MICROPY_PY_CMATH (1) #define MICROPY_PY_IO_IOBASE (1) #define MICROPY_PY_IO_FILEIO (1) #define MICROPY_PY_GC_COLLECT_RETVAL (1) -#define MICROPY_MODULE_FROZEN_STR (0) - +#ifndef MICROPY_STACKLESS #define MICROPY_STACKLESS (0) #define MICROPY_STACKLESS_STRICT (0) +#endif #define MICROPY_PY_UTIME (1) #define MICROPY_PY_UTIME_MP_HAL (1) diff --git a/ports/windows/mpconfigport.mk b/ports/windows/mpconfigport.mk index a2c618f143..3b7cf2100d 100644 --- a/ports/windows/mpconfigport.mk +++ b/ports/windows/mpconfigport.mk @@ -1,12 +1,9 @@ # Enable/disable modules and 3rd-party libs to be included in interpreter # Build 32-bit binaries on a 64-bit host -MICROPY_FORCE_32BIT = 0 +MICROPY_FORCE_32BIT ?= 0 # This variable can take the following values: # 0 - no readline, just simple stdin input # 1 - use MicroPython version of readline -MICROPY_USE_READLINE = 1 - -# ffi module requires libffi (libffi-dev Debian package) -MICROPY_PY_FFI = 0 +MICROPY_USE_READLINE ?= 1 diff --git a/ports/windows/msvc/common.props b/ports/windows/msvc/common.props index fcad5aeb6b..ab9b055def 100644 --- a/ports/windows/msvc/common.props +++ b/ports/windows/msvc/common.props @@ -1,7 +1,15 @@  + + + standard + build-$(PyVariant) + + @@ -31,6 +39,7 @@ $(PyTargetDir)%(FileName)%(Extension) + @@ -25,11 +27,12 @@ $([System.IO.Path]::GetFullPath(`$(MSBuildThisFileDirectory)..\..\..`))\ $(PyBaseDir)ports\windows\ - $(PyWinDir)build\ + $(PyWinDir)$(PyBuild)\ + $(PyWinDir)variants\$(PyVariant)\ $(PyWinDir) - $(PyIncDirs);$(PyBaseDir);$(PyWinDir);$(PyBuildDir);$(PyWinDir)msvc + $(PyIncDirs);$(PyBaseDir);$(PyWinDir);$(PyBuildDir);$(PyWinDir)msvc;$(PyVariantDir) + + + + + $(PlatformToolset.Replace('v', '')) + True + + @@ -57,6 +63,7 @@ using(var outFile = System.IO.File.CreateText(OutputFile)) { + False $([System.String]::new('%(FullPath)').Replace('$(PyBaseDir)', '$(DestDir)qstr\')) @@ -71,13 +78,21 @@ using(var outFile = System.IO.File.CreateText(OutputFile)) { + $(PyClTool) /nologo /I@(PyIncDirs, ' /I') /D@(PreProcDefs, ' /D') @(QstrDependencies->AnyHaveMetadataValue('Changed', 'True')) @(PyQstrSourceFiles->AnyHaveMetadataValue('Changed', 'True')) + + + $(PyPreProcCommand) /Fi%(OutFile) /P %(Identity) + %(OutFile) + + + + + + - - From 38054a57f3f405ace0d8854d58ad3b430703db3d Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 17 Jan 2022 09:39:38 +1100 Subject: [PATCH 334/335] tools/mpremote: Bump version to 0.1.0. Signed-off-by: Damien George --- tools/mpremote/setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mpremote/setup.cfg b/tools/mpremote/setup.cfg index 261369384f..bb2d0da52e 100644 --- a/tools/mpremote/setup.cfg +++ b/tools/mpremote/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = mpremote -version = 0.0.6 +version = 0.1.0 author = Damien George author_email = damien@micropython.org description = Tool for interacting remotely with MicroPython From da4b38e7562dfa451917f9d7f344a7f26de8c7bd Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 17 Jan 2022 09:50:31 +1100 Subject: [PATCH 335/335] all: Bump version to 1.18. Signed-off-by: Damien George --- docs/conf.py | 2 +- py/mpconfig.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index b35d03ba0e..741f8b3439 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -74,7 +74,7 @@ copyright = '- The MicroPython Documentation is Copyright © 2014-2022, Damien P # # We don't follow "The short X.Y version" vs "The full version, including alpha/beta/rc tags" # breakdown, so use the same version identifier for both to avoid confusion. -version = release = '1.17' +version = release = '1.18' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/py/mpconfig.h b/py/mpconfig.h index 597881d6fe..c1a0bfc046 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -28,7 +28,7 @@ // Current version of MicroPython #define MICROPY_VERSION_MAJOR 1 -#define MICROPY_VERSION_MINOR 17 +#define MICROPY_VERSION_MINOR 18 #define MICROPY_VERSION_MICRO 0 // Combined version as a 32-bit number for convenience