From 42cbb58543acec490647d4736f6b4783e2d81f9c Mon Sep 17 00:00:00 2001 From: scgbckbone Date: Wed, 22 Apr 2026 11:34:01 +0200 Subject: [PATCH 1/2] CC patch --- drivers/dht/dht.c | 3 + extmod/modhashlib.c | 10 ++-- extmod/vfs_fat.c | 3 + lib/oofatfs/ffconf.h | 2 + ports/stm32/Makefile | 3 + ports/stm32/adc.h | 2 +- ports/stm32/dma.c | 48 ++++++++++++++- ports/stm32/flash.c | 17 ++++++ ports/stm32/help.c | 60 +------------------ ports/stm32/machine_adc.c | 2 + ports/stm32/main.c | 2 + ports/stm32/mpconfigboard_common.h | 10 ++++ ports/stm32/mpconfigport.h | 2 +- ports/stm32/sdcard.c | 40 ++++++++++++- ports/stm32/uart.c | 21 +++++-- ports/stm32/uart.h | 2 + ports/stm32/usb.c | 18 +++++- ports/stm32/usbd_hid_interface.c | 3 +- .../stm32/usbdev/class/src/usbd_cdc_msc_hid.c | 3 + ports/stm32/usbdev/class/src/usbd_msc_bot.c | 2 +- ports/stm32/usbdev/class/src/usbd_msc_scsi.c | 8 +-- ports/unix/mpconfigport.h | 4 ++ tests/extmod/hashlib_final.py | 8 --- tests/extmod/hashlib_sha256.py | 18 +++--- 24 files changed, 190 insertions(+), 101 deletions(-) diff --git a/drivers/dht/dht.c b/drivers/dht/dht.c index e6b71542dabc9..45cc7824e6d63 100644 --- a/drivers/dht/dht.c +++ b/drivers/dht/dht.c @@ -1,3 +1,4 @@ +#ifdef MICROPY_HW_ENABLE_DHT /* * This file is part of the MicroPython project, http://micropython.org/ * @@ -97,3 +98,5 @@ static mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) { MP_DEFINE_CONST_FUN_OBJ_2(dht_readinto_obj, dht_readinto); #endif // MICROPY_PY_MACHINE_PULSE + +#endif // MICROPY_HW_ENABLE_DHT diff --git a/extmod/modhashlib.c b/extmod/modhashlib.c index 4754e44463019..6e4921eb4e1fd 100644 --- a/extmod/modhashlib.c +++ b/extmod/modhashlib.c @@ -105,10 +105,11 @@ static mp_obj_t hashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { static mp_obj_t hashlib_sha256_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); hashlib_ensure_not_final(self); - self->final = true; vstr_t vstr; vstr_init_len(&vstr, 32); - mbedtls_sha256_finish_ret((mbedtls_sha256_context *)&self->state, (unsigned char *)vstr.buf); + mbedtls_sha256_context tmp_ctx; + memcpy(&tmp_ctx, &self->state, sizeof(tmp_ctx)); + mbedtls_sha256_finish_ret(&tmp_ctx, (unsigned char *)vstr.buf); return mp_obj_new_bytes_from_vstr(&vstr); } @@ -139,10 +140,11 @@ static mp_obj_t hashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { static mp_obj_t hashlib_sha256_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); hashlib_ensure_not_final(self); - self->final = true; vstr_t vstr; vstr_init_len(&vstr, SHA256_BLOCK_SIZE); - sha256_final((CRYAL_SHA256_CTX *)self->state, (byte *)vstr.buf); + CRYAL_SHA256_CTX tmp_ctx; + memcpy(&tmp_ctx, self->state, sizeof(tmp_ctx)); + sha256_final(&tmp_ctx, (byte *)vstr.buf); return mp_obj_new_bytes_from_vstr(&vstr); } #endif diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index e832992f46f4e..3a0c4cda4734b 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -394,6 +394,9 @@ static mp_obj_t vfs_fat_mount(mp_obj_t self_in, mp_obj_t readonly, mp_obj_t mkfs if (res == FR_NO_FILESYSTEM && mp_obj_is_true(mkfs)) { uint8_t working_buf[FF_MAX_SS]; res = f_mkfs(&self->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf)); + if (res == FR_MKFS_ABORTED) { // Probably doesn't support FAT16 + res = f_mkfs(&self->fatfs, FM_FAT32, 0, working_buf, sizeof(working_buf)); + } } if (res != FR_OK) { mp_raise_OSError(fresult_to_errno_table[res]); diff --git a/lib/oofatfs/ffconf.h b/lib/oofatfs/ffconf.h index 4a8015668f4d0..89d53e69b1f67 100644 --- a/lib/oofatfs/ffconf.h +++ b/lib/oofatfs/ffconf.h @@ -73,7 +73,9 @@ /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ +#ifndef FF_USE_FASTSEEK #define FF_USE_FASTSEEK 0 +#endif /* This option switches fast seek function. (0:Disable or 1:Enable) */ diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 4c9366b8bdcdd..daf5f262b596d 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -388,6 +388,9 @@ HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\ ll_sdmmc.c \ ll_fmc.c \ ) +ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),h7 l4)) +HAL_SRC_C += $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_hal_sd_ex.c +endif ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),h5)) # HAL H5-1.0.0 has a bug with uninitialised variable in HAL_SD_ConfigWideBusOperation. $(BUILD)/$(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_hal_sd.o: CFLAGS += -Wno-error=maybe-uninitialized diff --git a/ports/stm32/adc.h b/ports/stm32/adc.h index 96947c3266fb7..8e33ee817ee20 100644 --- a/ports/stm32/adc.h +++ b/ports/stm32/adc.h @@ -34,7 +34,7 @@ extern const mp_obj_type_t pyb_adc_all_type; void adc_config(ADC_TypeDef *adc, uint32_t bits); uint32_t adc_config_and_read_u16(ADC_TypeDef *adc, uint32_t channel, uint32_t sample_time); -#if defined(ADC_CHANNEL_VBAT) +#if defined(ADC_CHANNEL_VBAT) && MICROPY_HW_ENABLE_ADC static inline void adc_deselect_vbat(ADC_TypeDef *adc, uint32_t channel) { (void)adc; diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c index 346b6b6f70ff4..b405a82857b0f 100644 --- a/ports/stm32/dma.c +++ b/ports/stm32/dma.c @@ -487,6 +487,48 @@ static const uint8_t dma_irqn[NSTREAM] = { 0 }; +#elif defined(STM32L4) && defined(DMAMUX1) + +// newer L4+ series parts have a DMAMUX unit +#define NCONTROLLERS (2) +#define NSTREAMS_PER_CONTROLLER (7) +#define NSTREAM (NCONTROLLERS * NSTREAMS_PER_CONTROLLER) + +#define DMA_SUB_INSTANCE_AS_UINT8(dma_request) (dma_request) + +#define DMA1_ENABLE_MASK (0x007f) // Bits in dma_enable_mask corresponding to DMA1 +#define DMA2_ENABLE_MASK (0x3f80) // Bits in dma_enable_mask corresponding to DMA2 + +// DMA1 streams +const dma_descr_t dma_SPI_1_RX = { DMA1_Channel1, DMA_REQUEST_SPI1_RX, dma_id_0, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_1_TX = { DMA1_Channel2, DMA_REQUEST_SPI1_TX, dma_id_1, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_2_RX = { DMA1_Channel3, DMA_REQUEST_SPI2_RX, dma_id_2, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_2_TX = { DMA1_Channel4, DMA_REQUEST_SPI2_TX, dma_id_3, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_I2C_2_RX = { DMA1_Channel5, DMA_REQUEST_I2C2_RX, dma_id_4, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_I2C_2_TX = { DMA1_Channel6, DMA_REQUEST_I2C2_TX, dma_id_5, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_I2C_1_RX = { DMA1_Channel5, DMA_REQUEST_I2C1_RX, dma_id_4, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_I2C_1_TX = { DMA1_Channel6, DMA_REQUEST_I2C1_TX, dma_id_5, &dma_init_struct_spi_i2c }; + +static const uint8_t dma_irqn[NSTREAM] = { + DMA1_Channel1_IRQn, + DMA1_Channel2_IRQn, + DMA1_Channel3_IRQn, + DMA1_Channel4_IRQn, + DMA1_Channel5_IRQn, + DMA1_Channel6_IRQn, + DMA1_Channel7_IRQn, + DMA2_Channel1_IRQn, + DMA2_Channel2_IRQn, + DMA2_Channel3_IRQn, + DMA2_Channel4_IRQn, + DMA2_Channel5_IRQn, + DMA2_Channel6_IRQn, + DMA2_Channel7_IRQn, +}; + +// chip has some special DMA between SDMMC and system +#undef ENABLE_SDIO + #elif defined(STM32L4) #define NCONTROLLERS (2) @@ -1704,7 +1746,11 @@ static void dma_idle_handler(uint32_t tick) { } #endif -#if defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) +#if defined(STM32L4) && defined(DMAMUX1) + +// not required on L4+? + +#elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) void dma_nohal_init(const dma_descr_t *descr, uint32_t config) { DMA_Channel_TypeDef *dma = descr->instance; diff --git a/ports/stm32/flash.c b/ports/stm32/flash.c index fcf46049c0abd..4408b6849ebbd 100644 --- a/ports/stm32/flash.c +++ b/ports/stm32/flash.c @@ -134,6 +134,23 @@ static const flash_layout_t flash_layout[] = { }; #endif +#elif defined(STM32L4S5xx) + +// as defined stm32lib/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h +// - operating in single-bank mode (DBANK=0), total 2M; 8k pages +// Use the homogeneous form: the get_bank() / get_page() code path below +// (for L4 with SYSCFG_MEMRMP_FB_MODE) references FLASH_LAYOUT_START_ADDR +// and FLASH_LAYOUT_SECTOR_SIZE, so the layout must be expressed as macros. +// Alternative (non-homogeneous array) approach kept here for reference: +// #define FLASH_LAYOUT_IS_HOMOGENEOUS (0) +// static const flash_layout_t flash_layout[] = { +// { (uint32_t)FLASH_BASE, 0x2000, (2<<20)/0x2000 }, +// }; +#define FLASH_LAYOUT_IS_HOMOGENEOUS (1) +#define FLASH_LAYOUT_START_ADDR (FLASH_BASE) +#define FLASH_LAYOUT_SECTOR_SIZE (0x2000) +#define FLASH_LAYOUT_NUM_SECTORS ((2 << 20) / 0x2000) + #elif defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) #define FLASH_LAYOUT_IS_HOMOGENEOUS (1) diff --git a/ports/stm32/help.c b/ports/stm32/help.c index 4d4f89caeae76..3b0397660a949 100644 --- a/ports/stm32/help.c +++ b/ports/stm32/help.c @@ -26,62 +26,4 @@ #include "py/builtin.h" -const char stm32_help_text[] = - "Welcome to MicroPython!\n" - "\n" - "For online docs please visit http://docs.micropython.org/\n" - "\n" - "Quick overview of commands for the board:\n" - #if MICROPY_PY_PYB_LEGACY - " pyb.info() -- print some general information\n" - " pyb.delay(n) -- wait for n milliseconds\n" - " pyb.millis() -- get number of milliseconds since hard reset\n" - #endif - #if MICROPY_HW_HAS_SWITCH - " pyb.Switch() -- create a switch object\n" - " Switch methods: (), callback(f)\n" - #endif - " pyb.LED(n) -- create an LED object for LED n (n=1,2,3,4)\n" - " LED methods: on(), off(), toggle(), intensity()\n" - " pyb.Pin(pin) -- get a pin, eg pyb.Pin('X1')\n" - " pyb.Pin(pin, m, [p]) -- get a pin and configure it for IO mode m, pull mode p\n" - " Pin methods: init(..), value([v]), high(), low()\n" - " pyb.ExtInt(pin, m, p, callback) -- create an external interrupt object\n" - #if MICROPY_HW_ENABLE_ADC - " pyb.ADC(pin) -- make an analog object from a pin\n" - " ADC methods: read(), read_timed(buf, freq)\n" - #endif - #if MICROPY_HW_ENABLE_DAC - " pyb.DAC(port) -- make a DAC object\n" - " DAC methods: triangle(freq), write(n), write_timed(buf, freq)\n" - #endif - #if MICROPY_HW_ENABLE_RTC - " pyb.RTC() -- make an RTC object; methods: datetime([val])\n" - #endif - #if MICROPY_HW_ENABLE_RNG - " pyb.rng() -- get a 30-bit hardware random number\n" - #endif - #if MICROPY_HW_ENABLE_SERVO - " pyb.Servo(n) -- create Servo object for servo n (n=1,2,3,4)\n" - " Servo methods: calibration(..), angle([x, [t]]), speed([x, [t]])\n" - #endif - #if MICROPY_HW_HAS_MMA7660 - " pyb.Accel() -- create an Accelerometer object\n" - " Accelerometer methods: x(), y(), z(), tilt(), filtered_xyz()\n" - #endif - "\n" - "Pins are numbered X1-X12, X17-X22, Y1-Y12, or by their MCU name\n" - "Pin IO modes are: pyb.Pin.IN, pyb.Pin.OUT, pyb.Pin.OPEN_DRAIN\n" - "Pin pull modes are: None, pyb.Pin.PULL_UP, pyb.Pin.PULL_DOWN\n" - "Additional serial bus objects: pyb.I2C(n), pyb.SPI(n), pyb.UART(n)\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" - "For a list of available modules, type help('modules')\n" -; +const char stm32_help_text[] = ""; diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c index a6e960911bd69..8b4c12b4db6ac 100644 --- a/ports/stm32/machine_adc.c +++ b/ports/stm32/machine_adc.c @@ -40,6 +40,8 @@ #define ADCx_COMMON ADC_COMMON_REGISTER(0) #elif defined(STM32F7) #define ADCx_COMMON ADC123_COMMON +#elif defined(STM32L4S5xx) +#define ADCx_COMMON ADC1_COMMON #elif defined(STM32L4) #define ADCx_COMMON __LL_ADC_COMMON_INSTANCE(0) #endif diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 17111c6df983e..f6eefa3f634c1 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -356,9 +356,11 @@ void stm32_main(uint32_t reset_mode) { SCB->CCR |= SCB_CCR_STKALIGN_Msk; #endif + #if 0 // Hook for a board to run code at start up, for example check if a // bootloader should be entered instead of the main application. MICROPY_BOARD_STARTUP(); + #endif // Enable caches and prefetch buffers diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h index 30314a38a59ff..e723a13675092 100644 --- a/ports/stm32/mpconfigboard_common.h +++ b/ports/stm32/mpconfigboard_common.h @@ -803,6 +803,16 @@ void mp_usbd_ll_init(void); #define MICROPY_HW_USES_BOOTLOADER (MICROPY_HW_VTOR != 0x08000000) +// Expose the CSD and CID values from the card inserted, via pyb.SDCard.ident() function +#ifndef MICROPY_HW_ENABLE_CARD_IDENT +#define MICROPY_HW_ENABLE_CARD_IDENT (0) +#endif + +// drivers/dht ... a specific enviro sensor of some sort +#ifndef MICROPY_HW_ENABLE_DHT +#define MICROPY_HW_ENABLE_DHT (1) +#endif + #ifndef MICROPY_HW_ETH_DMA_ATTRIBUTE #define MICROPY_HW_ETH_DMA_ATTRIBUTE __attribute__((aligned(16384))); #endif diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 19d4ef8ae0ff5..0481732e74105 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -130,7 +130,7 @@ #endif #endif #define MICROPY_PY_MACHINE_CAN_INCLUDEFILE "ports/stm32/machine_can.c" -#define MICROPY_PY_MACHINE_DHT_READINTO (1) +#define MICROPY_PY_MACHINE_DHT_READINTO (MICROPY_HW_ENABLE_DHT) #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new #define MICROPY_PY_MACHINE_I2C (MICROPY_HW_ENABLE_HW_I2C) diff --git a/ports/stm32/sdcard.c b/ports/stm32/sdcard.c index 3e755bf9f2602..e1063123e55db 100644 --- a/ports/stm32/sdcard.c +++ b/ports/stm32/sdcard.c @@ -107,6 +107,10 @@ #if defined(STM32H5) || defined(STM32H7) || defined(STM32N6) #define SDIO_TRANSFER_CLK_DIV SDMMC_HSPEED_CLK_DIV #define SDIO_USE_GPDMA 0 +#elif defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) +// L4+ family: SDMMC has internal DMA, no external DMA controller needed +#define SDIO_USE_GPDMA 0 +#define SDIO_TRANSFER_CLK_DIV SDMMC_TRANSFER_CLK_DIV #else #define SDIO_TRANSFER_CLK_DIV SDMMC_TRANSFER_CLK_DIV #define SDIO_USE_GPDMA 1 @@ -270,7 +274,7 @@ static HAL_StatusTypeDef sdmmc_init_sd(void) { // SD device interface configuration sdmmc_handle.sd.Instance = SDIO; sdmmc_handle.sd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; - #if !defined(STM32H5) && !defined(STM32H7) && !defined(STM32N6) + #if !defined(STM32H5) && !defined(STM32H7) && !defined(STM32N6) && !defined(STM32L4S5xx) sdmmc_handle.sd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; #endif sdmmc_handle.sd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_ENABLE; @@ -794,6 +798,35 @@ static mp_obj_t sd_info(mp_obj_t self) { } static MP_DEFINE_CONST_FUN_OBJ_1(sd_info_obj, sd_info); +#if MICROPY_HW_ENABLE_CARD_IDENT +static mp_obj_t sd_card_ident(mp_obj_t self) { + if (!(pyb_sdmmc_flags & PYB_SDMMC_FLAG_ACTIVE)) { + mp_raise_ValueError(MP_ERROR_TEXT("no card")); + } + + uint32_t *CSD; + uint32_t *CID; + + #if MICROPY_HW_ENABLE_MMCARD + if (pyb_sdmmc_flags & PYB_SDMMC_FLAG_MMC) { + CSD = sdmmc_handle.mmc.CSD; + CID = sdmmc_handle.mmc.CID; + } else + #endif + { + CSD = sdmmc_handle.sd.CSD; + CID = sdmmc_handle.sd.CID; + } + + mp_obj_t tuple[2] = { + mp_obj_new_bytes((const uint8_t *)CSD, 16), + mp_obj_new_bytes((const uint8_t *)CID, 16), + }; + return mp_obj_new_tuple(2, tuple); +} +static MP_DEFINE_CONST_FUN_OBJ_1(sd_ident_obj, sd_card_ident); +#endif + // now obsolete, kept for backwards compatibility static mp_obj_t sd_read(mp_obj_t self, mp_obj_t block_num) { uint8_t *dest = m_new(uint8_t, SDCARD_BLOCK_SIZE); @@ -875,6 +908,9 @@ static const mp_rom_map_elem_t pyb_sdcard_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_present), MP_ROM_PTR(&sd_present_obj) }, { MP_ROM_QSTR(MP_QSTR_power), MP_ROM_PTR(&sd_power_obj) }, { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&sd_info_obj) }, + #if MICROPY_HW_ENABLE_CARD_IDENT + { MP_ROM_QSTR(MP_QSTR_ident), MP_ROM_PTR(&sd_ident_obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&sd_read_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&sd_write_obj) }, // block device protocol @@ -910,9 +946,7 @@ void sdcard_init_vfs(fs_user_mount_t *vfs, int part) { vfs->base.type = &mp_fat_vfs_type; vfs->blockdev.flags |= MP_BLOCKDEV_FLAG_NATIVE | MP_BLOCKDEV_FLAG_HAVE_IOCTL; vfs->fatfs.drv = vfs; - #if MICROPY_FATFS_MULTI_PARTITION vfs->fatfs.part = part; - #endif vfs->blockdev.readblocks[0] = MP_OBJ_FROM_PTR(&pyb_sdcard_readblocks_obj); vfs->blockdev.readblocks[1] = MP_OBJ_FROM_PTR(&pyb_sdcard_obj); vfs->blockdev.readblocks[2] = MP_OBJ_FROM_PTR(sdcard_read_blocks); // native version diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c index 0235078b61a60..6b8713053ad15 100644 --- a/ports/stm32/uart.c +++ b/ports/stm32/uart.c @@ -41,7 +41,7 @@ #if defined(STM32F4) || defined(STM32L1) #define UART_RXNE_IS_SET(uart) ((uart)->SR & USART_SR_RXNE) #else -#if defined(STM32G0) || defined(STM32H7) || defined(STM32WL) +#if defined(STM32G0) || defined(STM32H7) || defined(STM32WL) || (defined(STM32L4) && defined(USART_ISR_RXNE_RXFNE)) #define USART_ISR_RXNE USART_ISR_RXNE_RXFNE #endif #define UART_RXNE_IS_SET(uart) ((uart)->ISR & USART_ISR_RXNE) @@ -106,6 +106,17 @@ #define USART_CR2_IE_ALL (USART_CR2_IE_BASE) #define USART_CR3_IE_ALL (USART_CR3_IE_BASE) +#elif defined(STM32L4) && defined(USART_CR1_FIFOEN) +// L4+ series has a FIFO +#define USART_CR1_IE_ALL (USART_CR1_IE_BASE | USART_CR1_EOBIE | USART_CR1_RTOIE | USART_CR1_CMIE) +#define USART_CR2_IE_ALL (USART_CR2_IE_BASE) +#define USART_CR3_IE_ALL (USART_CR3_IE_BASE) + +#undef USART_CR1_TXEIE +#define USART_CR1_TXEIE USART_CR1_TXEIE_TXFNFIE +#undef USART_CR1_RXNEIE +#define USART_CR1_RXNEIE USART_CR1_RXNEIE_RXFNEIE + #elif defined(STM32L4) || defined(STM32WB) || defined(STM32WL) #define USART_CR1_IE_ALL (USART_CR1_IE_BASE | USART_CR1_EOBIE | USART_CR1_RTOIE | USART_CR1_CMIE) #define USART_CR2_IE_ALL (USART_CR2_IE_BASE) @@ -1062,14 +1073,14 @@ uint32_t uart_get_baudrate(machine_uart_obj_t *self) { #if defined(LPUART1) if (self->uart_id == PYB_LPUART_1) { return LL_LPUART_GetBaudRate(self->uartx, uart_get_source_freq(self) - #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL) + #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL) || (defined(STM32L4) && defined(USART_PRESC_PRESCALER)) , self->uartx->PRESC #endif ); } #endif return LL_USART_GetBaudRate(self->uartx, uart_get_source_freq(self), - #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL) + #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL) || (defined(STM32L4) && defined(USART_PRESC_PRESCALER)) self->uartx->PRESC, #endif LL_USART_OVERSAMPLING_16); @@ -1079,7 +1090,7 @@ void uart_set_baudrate(machine_uart_obj_t *self, uint32_t baudrate) { #if defined(LPUART1) if (self->uart_id == PYB_LPUART_1) { LL_LPUART_SetBaudRate(self->uartx, uart_get_source_freq(self), - #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL) + #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL) || (defined(STM32L4) && defined(USART_PRESC_PRESCALER)) LL_LPUART_PRESCALER_DIV1, #endif baudrate); @@ -1087,7 +1098,7 @@ void uart_set_baudrate(machine_uart_obj_t *self, uint32_t baudrate) { } #endif LL_USART_SetBaudRate(self->uartx, uart_get_source_freq(self), - #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL) + #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL) || (defined(STM32L4) && defined(USART_PRESC_PRESCALER)) LL_USART_PRESCALER_DIV1, #endif LL_USART_OVERSAMPLING_16, baudrate); diff --git a/ports/stm32/uart.h b/ports/stm32/uart.h index 448140f1778ce..093a9bf011cb1 100644 --- a/ports/stm32/uart.h +++ b/ports/stm32/uart.h @@ -110,6 +110,8 @@ static inline bool uart_tx_avail(machine_uart_obj_t *self) { return self->uartx->SR & USART_SR_TXE; #elif defined(STM32G0) || defined(STM32H7) || defined(STM32WL) return self->uartx->ISR & USART_ISR_TXE_TXFNF; + #elif defined(UART_FLAG_TXFNF) + return self->uartx->ISR & UART_FLAG_TXFNF; // TXFIFO not full #else return self->uartx->ISR & USART_ISR_TXE; #endif diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index c17d049124fbc..08261821a55ff 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -289,7 +289,9 @@ bool pyb_usb_dev_init(int dev_id, uint16_t vid, uint16_t pid, uint8_t mode, size return false; } - #if MICROPY_HW_USB_MSC + #if defined(MICROPY_HW_CUSTOM_USB_MSC) + MICROPY_HW_CUSTOM_USB_MSC(msc_n, &usb_dev->usbd_cdc_msc_hid_state); + #elif MICROPY_HW_USB_MSC // Configure the MSC interface const void *msc_unit_default[1]; if (msc_n == 0) { @@ -481,6 +483,9 @@ 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 + if (!usb_device.enabled) { + 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]; @@ -488,7 +493,8 @@ static mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t * return MP_OBJ_NEW_QSTR(m->qst); } } - return mp_const_none; + // some mode we don't understand + return MP_OBJ_NEW_QSTR(MP_QSTR_USB_space_enabled); #endif } @@ -546,7 +552,9 @@ static mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t * // Get MSC logical units size_t msc_n = 0; const void *msc_unit[USBD_MSC_MAX_LUN]; - #if MICROPY_HW_USB_MSC + #if defined(MICROPY_HW_CUSTOM_USB_MSC) + // config not supported for now + #elif MICROPY_HW_USB_MSC if (mode & USBD_MODE_IFACE_MSC) { mp_obj_t *items; mp_obj_get_array(args[ARG_msc].u_obj, &msc_n, &items); @@ -1058,6 +1066,10 @@ static mp_uint_t pyb_usb_hid_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_ pyb_usb_hid_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t ret; if (request == MP_STREAM_POLL) { + if (!self->usb_dev->usbd_hid_itf.base.usbd) { + // not enumerated for first time yet, structures not initialized + return 0; + } uintptr_t flags = arg; ret = 0; if ((flags & MP_STREAM_POLL_RD) && usbd_hid_rx_num(&self->usb_dev->usbd_hid_itf) > 0) { diff --git a/ports/stm32/usbd_hid_interface.c b/ports/stm32/usbd_hid_interface.c index b11d59cbbf714..bc66b741cd194 100644 --- a/ports/stm32/usbd_hid_interface.c +++ b/ports/stm32/usbd_hid_interface.c @@ -49,12 +49,13 @@ int8_t usbd_hid_receive(usbd_hid_state_t *hid_in, size_t len) { int usbd_hid_rx(usbd_hid_itf_t *hid, size_t len, uint8_t *buf, uint32_t timeout_ms) { // Wait for an incoming report uint32_t t0 = mp_hal_ticks_ms(); - while (hid->report_in_len == USBD_HID_REPORT_INVALID) { + while (hid->report_in_len == USBD_HID_REPORT_INVALID || !hid->base.usbd) { if (mp_hal_ticks_ms() - t0 >= timeout_ms || query_irq() == IRQ_STATE_DISABLED) { return -MP_ETIMEDOUT; } mp_event_wait_ms(1); } + assert(hid->base.usbd); // Copy bytes from report to user buffer int n = MIN(len, hid->report_in_len); diff --git a/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c index e541c32134372..81e691b49491b 100644 --- a/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c +++ b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c @@ -1240,6 +1240,7 @@ uint8_t USBD_CDC_ReceivePacket(usbd_cdc_state_t *cdc, uint8_t *buf) { // prepare OUT endpoint for reception uint8_t USBD_HID_ReceivePacket(usbd_hid_state_t *hid, uint8_t *buf) { // Suspend or Resume USB Out process + if (!hid || !hid->usbd || !hid->usbd->pdev) return USBD_FAIL; #if !USBD_SUPPORT_HS_MODE if (hid->usbd->pdev->dev_speed == USBD_SPEED_HIGH) { @@ -1257,10 +1258,12 @@ uint8_t USBD_HID_ReceivePacket(usbd_hid_state_t *hid, uint8_t *buf) { } int USBD_HID_CanSendReport(usbd_hid_state_t *hid) { + if (!hid || !hid->usbd || !hid->usbd->pdev) return 0; return hid->usbd->pdev->dev_state == USBD_STATE_CONFIGURED && hid->state == HID_IDLE; } uint8_t USBD_HID_SendReport(usbd_hid_state_t *hid, uint8_t *report, uint16_t len) { + if (!hid || !hid->usbd || !hid->usbd->pdev) return USBD_FAIL; if (hid->usbd->pdev->dev_state == USBD_STATE_CONFIGURED) { if (hid->state == HID_IDLE) { hid->state = HID_BUSY; diff --git a/ports/stm32/usbdev/class/src/usbd_msc_bot.c b/ports/stm32/usbdev/class/src/usbd_msc_bot.c index 5bda0f8653c40..2f82145c4c44c 100644 --- a/ports/stm32/usbdev/class/src/usbd_msc_bot.c +++ b/ports/stm32/usbdev/class/src/usbd_msc_bot.c @@ -240,7 +240,7 @@ static void MSC_BOT_CBW_Decode (USBD_HandleTypeDef *pdev) if ((USBD_LL_GetRxDataSize (pdev ,MSC_OUT_EP) != USBD_BOT_CBW_LENGTH) || (hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE)|| - (hmsc->cbw.bLUN > 1) || + (hmsc->cbw.bLUN >= USBD_MSC_MAX_LUN) || (hmsc->cbw.bCBLength < 1) || (hmsc->cbw.bCBLength > 16)) { diff --git a/ports/stm32/usbdev/class/src/usbd_msc_scsi.c b/ports/stm32/usbdev/class/src/usbd_msc_scsi.c index 78c8c5af19916..241a2afe397b8 100644 --- a/ports/stm32/usbdev/class/src/usbd_msc_scsi.c +++ b/ports/stm32/usbdev/class/src/usbd_msc_scsi.c @@ -511,7 +511,6 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *para return -1; /* error */ } - hmsc->bot_state = USBD_BOT_DATA_IN; hmsc->scsi_blk_len *= hmsc->scsi_blk_size[lun]; /* cases 4,5 : Hi <> Dn */ @@ -523,6 +522,8 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *para INVALID_CDB); return -1; } + + hmsc->bot_state = USBD_BOT_DATA_IN; } hmsc->bot_data_length = MSC_MEDIA_PACKET; @@ -732,10 +733,9 @@ static int8_t SCSI_ProcessRead (USBD_HandleTypeDef *pdev, uint8_t lun) static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef *pdev, uint8_t lun) { - uint32_t len; USBD_MSC_BOT_HandleTypeDef *hmsc = &((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->MSC_BOT_ClassData; - len = MIN(hmsc->scsi_blk_len , MSC_MEDIA_PACKET); + uint32_t len = MIN(hmsc->scsi_blk_len, MSC_MEDIA_PACKET); if(hmsc->bdev_ops->Write(lun , hmsc->bot_data, @@ -762,7 +762,7 @@ static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef *pdev, uint8_t lun) } else { - /* Prapare EP to Receive next packet */ + /* Prepare EP to Receive next packet */ USBD_LL_PrepareReceive (pdev, MSC_OUT_EP, hmsc->bot_data, diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index 44e840209328e..2eeafb34ddca7 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -106,10 +106,14 @@ typedef long mp_off_t; // Enable the VFS, and enable the posix "filesystem". #define MICROPY_ENABLE_FINALISER (1) +#ifndef MICROPY_VFS #define MICROPY_VFS (1) +#endif #define MICROPY_READER_VFS (1) #define MICROPY_HELPER_LEXER_UNIX (1) +#ifndef MICROPY_VFS_POSIX #define MICROPY_VFS_POSIX (1) +#endif #define MICROPY_READER_POSIX (1) #if MICROPY_PY_FFI || MICROPY_BLUETOOTH_BTSTACK #define MICROPY_TRACKED_ALLOC (1) diff --git a/tests/extmod/hashlib_final.py b/tests/extmod/hashlib_final.py index c8fdac92346c5..7aeb96ea01813 100644 --- a/tests/extmod/hashlib_final.py +++ b/tests/extmod/hashlib_final.py @@ -10,16 +10,8 @@ if not algo: continue - # Running .digest() several times in row is not supported. h = algo(b"123") h.digest() - try: - h.digest() - print("fail") - except ValueError: - # Expected path, don't print anything so test output is the - # same even if the algorithm is not implemented on the port. - pass # Partial digests are not supported. h = algo(b"123") diff --git a/tests/extmod/hashlib_sha256.py b/tests/extmod/hashlib_sha256.py index ffa0922a1cf49..1684df47eb5a9 100644 --- a/tests/extmod/hashlib_sha256.py +++ b/tests/extmod/hashlib_sha256.py @@ -22,13 +22,11 @@ # 56 bytes is a boundary case in the algorithm print(hashlib.sha256(b"\xff" * 56).digest()) -# TODO: running .digest() several times in row is not supported() -# h = hashlib.sha256(b'123') -# print(h.digest()) -# print(h.digest()) - -# TODO: partial digests are not supported -# h = hashlib.sha256(b'123') -# print(h.digest()) -# h.update(b'456') -# print(h.digest()) +h = hashlib.sha256(b'123') +print(h.digest()) +print(h.digest()) + +h = hashlib.sha256(b'123') +print(h.digest()) +h.update(b'456') +print(h.digest()) From 06309b211a8553c305bafd59e91022e512b91870 Mon Sep 17 00:00:00 2001 From: scgbckbone Date: Sun, 26 Apr 2026 20:12:18 +0200 Subject: [PATCH 2/2] fix --- ports/stm32/flash.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/ports/stm32/flash.c b/ports/stm32/flash.c index 4408b6849ebbd..9a644dc6fe39d 100644 --- a/ports/stm32/flash.c +++ b/ports/stm32/flash.c @@ -136,20 +136,23 @@ static const flash_layout_t flash_layout[] = { #elif defined(STM32L4S5xx) -// as defined stm32lib/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h -// - operating in single-bank mode (DBANK=0), total 2M; 8k pages -// Use the homogeneous form: the get_bank() / get_page() code path below -// (for L4 with SYSCFG_MEMRMP_FB_MODE) references FLASH_LAYOUT_START_ADDR -// and FLASH_LAYOUT_SECTOR_SIZE, so the layout must be expressed as macros. -// Alternative (non-homogeneous array) approach kept here for reference: -// #define FLASH_LAYOUT_IS_HOMOGENEOUS (0) -// static const flash_layout_t flash_layout[] = { -// { (uint32_t)FLASH_BASE, 0x2000, (2<<20)/0x2000 }, -// }; +// STM32L4S5xx: 2 MB total, dual-bank (DBANK=1) with 4 KB pages. +// Verified at runtime via FLASH->OPTR bit 22 (DBANK) = 1 on Q1/Mk4. +// In dual-bank mode the HAL macros agree: +// FLASH_BANK_SIZE = FLASH_SIZE >> 1 = 1 MB +// FLASH_PAGE_SIZE = 0x1000 (per stm32l4xx_hal_flash.h) +// The flash_get_sector_info() / get_bank() / get_page() math (selected by +// the STM32L4 + SYSCFG_MEMRMP_FB_MODE branch below) then produces correct +// physical addresses for both banks. +// +// NOTE: an earlier revision of this case used 0x2000 sectors (single-bank +// DBANK=0 assumption). That made get_page() return half the page index it +// should, so the flash_bdev cache committed to the wrong physical sector +// and settings did not survive reboot. #define FLASH_LAYOUT_IS_HOMOGENEOUS (1) #define FLASH_LAYOUT_START_ADDR (FLASH_BASE) -#define FLASH_LAYOUT_SECTOR_SIZE (0x2000) -#define FLASH_LAYOUT_NUM_SECTORS ((2 << 20) / 0x2000) +#define FLASH_LAYOUT_SECTOR_SIZE (0x1000) +#define FLASH_LAYOUT_NUM_SECTORS ((2 << 20) / 0x1000) #elif defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)