Skip to content

Added peripheral support for Daisy Seed stm32H750 board #10198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions locale/circuitpython.pot
Original file line number Diff line number Diff line change
Expand Up @@ -1369,6 +1369,11 @@ msgstr ""
msgid "MITM security not supported"
msgstr ""

#: ports/stm/common-hal/sdioio/SDCard.c
#, c-format
msgid "MMC/SDIO Clock Error %x"
msgstr ""

#: shared-bindings/is31fl3741/IS31FL3741.c
msgid "Mapping must be a tuple"
msgstr ""
Expand Down
7 changes: 7 additions & 0 deletions ports/stm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,13 @@ ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32F765xx STM32F767xx STM32F769xx
SRC_STM32 += $(HAL_DIR)/Src/stm32$(MCU_SERIES_LOWER)xx_hal_uart_ex.c
endif

ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32H750xx))
C_DEFS += -DHAL_SDRAM_MODULE_ENABLED
SRC_STM32 += st_driver/stm32$(MCU_SERIES_LOWER)xx_hal_driver/Src/stm32h7xx_hal_sdram.c
SRC_STM32 += st_driver/stm32$(MCU_SERIES_LOWER)xx_hal_driver/Src/stm32h7xx_ll_fmc.c
SRC_C += peripherals/sdram.c
endif

SRC_STM32 += boards/system_stm32$(MCU_SERIES_LOWER)xx.c

SRC_C += \
Expand Down
53 changes: 52 additions & 1 deletion ports/stm/boards/daisy_seed_with_sdram/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,58 @@
// SPDX-FileCopyrightText: Copyright (c) 2024 snkYmkrct
//
// SPDX-License-Identifier: MIT
#include STM32_HAL_H

#include "supervisor/board.h"
#include "supervisor/stm.h"
#include "sdram.h"

// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.

/** SDRAM banks configuration. */
static const struct stm32_sdram_bank_config bank_config[] = {
{ .init = {
.SDBank = FMC_SDRAM_BANK1,
.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9,
.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13,
.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32,
.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4,
.CASLatency = FMC_SDRAM_CAS_LATENCY_3,
.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE,
.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2,
.ReadBurst = FMC_SDRAM_RBURST_ENABLE,
.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0
},
.timing = {
.LoadToActiveDelay = 2,
.ExitSelfRefreshDelay = 8,
.SelfRefreshTime = 5,
.RowCycleDelay = 6,
.WriteRecoveryTime = 3,
.RPDelay = 2,
.RCDDelay = 2
}}
};

/* SDRAM configuration. */
static const struct stm32_sdram_config config = {
.sdram = FMC_SDRAM_DEVICE,
.power_up_delay = 100,
.num_auto_refresh = 8,
.mode_register = SDRAM_MODEREG_BURST_LENGTH_4 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_3 |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE,
/* Set the device refresh rate based on the RM0433 STM reference manual
refresh_rate = [(SDRAM self refresh time / number of rows) x SDRAM CLK] – 20
= [(64ms/8192) * 100MHz] - 20 = 781.25 - 20
*/
.refresh_rate = (64 * 100000 / 8192 - 20),
.banks = bank_config,
.banks_len = 1,
};

void board_init(void) {
sdram_init(&config);
// sdram_test(true);
stm_add_sdram_to_heap();
}
7 changes: 7 additions & 0 deletions ports/stm/boards/daisy_seed_with_sdram/mpconfigboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,10 @@

// for RNG not audio
#define CPY_CLK_USB_USES_AUDIOPLL (1)

// SDRAM and MPU region

#define CIRCUITPY_HW_SDRAM_SIZE (64 * 1024 * 1024) // 64 MByte

#define CPY_SDRAM_REGION MPU_REGION_NUMBER10
#define CPY_SDRAM_REGION_SIZE MPU_REGION_SIZE_64MB
4 changes: 4 additions & 0 deletions ports/stm/boards/daisy_seed_with_sdram/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ MCU_PACKAGE = UFBGA176

LD_COMMON = boards/common_tcm.ld
LD_FILE = boards/STM32H750.ld

CIRCUITPY_SDIOIO = 1
CIRCUITPY_PWMIO = 1
CIRCUITPY_AUDIOPWMIO = 1
48 changes: 48 additions & 0 deletions ports/stm/boards/daisy_seed_with_sdram/pins.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,56 @@

#include "shared-bindings/board/__init__.h"

// See pinout on Daisy Seed product page
// https://electro-smith.com/products/daisy-seed?variant=45234245108004
static const mp_rom_map_elem_t board_module_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PC07)},
{MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_PG03)},
{MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB12)},
{MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PC11)},
{MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PC10)},
{MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PC09)},
{MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PC08)},
{MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PD02)},
{MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PC12)},
{MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PG10)},
{MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PG11)},
{MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB04)},
{MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PB05)},
{MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PB08)},
{MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PB09)},
{MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB06)},
{MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB07)},

{MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PC00)},
{MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PC00)},
{MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PA03)},
{MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA03)},
{MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PB01)},
{MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB01)},
{MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_PA07)},
{MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA07)},
{MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_PA06)},
{MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA06)},
{MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_PC01)},
{MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PC01)},
{MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_PC04)},
{MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PC04)},
{MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_PA05)},
{MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PA05)},
{MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_PA04)},
{MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA04)},
{MP_ROM_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_PA01)},
{MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PA01)},
{MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_PA00)},
{MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA00)},
{MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_PD11)},
{MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_PG09)},
{MP_ROM_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_PA02)},
{MP_ROM_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_PA02)},
{MP_ROM_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_PB14)},
{MP_ROM_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_PB15)},

};

MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
3 changes: 2 additions & 1 deletion ports/stm/common-hal/audiopwmio/PWMAudioOut.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,6 @@ void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t *self)
tim_handle.Instance->CR1 &= ~TIM_CR1_CEN;
stm_peripherals_timer_free(tim_handle.Instance);

active_audio = NULL;
self->stopping = false;
self->paused = false;

Expand All @@ -352,6 +351,8 @@ void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t *self)
set_pin(1, GPIO_PIN_RESET);
}

active_audio = NULL;

// Cannot free buffers here because we may be called from
// the interrupt handler, and the heap is not reentrant.
}
Expand Down
49 changes: 45 additions & 4 deletions ports/stm/common-hal/sdioio/SDCard.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,11 @@ void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self,
uint8_t num_data, const mcu_pin_obj_t **data, uint32_t frequency) {

int periph_index = check_pins(self, clock, command, num_data, data);
#ifdef STM32H750xx
SDMMC_TypeDef *SDMMCx = mcu_sdio_banks[periph_index - 1];
#else
SDIO_TypeDef *SDIOx = mcu_sdio_banks[periph_index - 1];
#endif

GPIO_InitTypeDef GPIO_InitStruct = {0};

Expand All @@ -128,6 +132,25 @@ void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self,
GPIO_InitStruct.Pin = pin_mask(clock->number);
HAL_GPIO_Init(pin_port(clock->port), &GPIO_InitStruct);

#ifdef STM32H750xx
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SDMMC;
PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
mp_raise_ValueError_varg(MP_ERROR_TEXT("MMC/SDIO Clock Error %x"));
}
__HAL_RCC_SDMMC1_CLK_ENABLE();

self->handle.Init.ClockDiv = SDMMC_NSPEED_CLK_DIV;
self->handle.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
self->handle.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
self->handle.Init.BusWide = SDMMC_BUS_WIDE_1B;
// For the SDMMC controller Hardware Flow Control needs to be enabled
// at the default speed of 25MHz, in order to avoid FIFO underrun (TX mode)
// and overrun (RX mode) errors.
self->handle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE;
self->handle.Instance = SDMMCx;
#else
__HAL_RCC_SDIO_CLK_ENABLE();

self->handle.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV;
Expand All @@ -137,6 +160,7 @@ void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self,
self->handle.Init.BusWide = SDIO_BUS_WIDE_1B;
self->handle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
self->handle.Instance = SDIOx;
#endif

HAL_StatusTypeDef r = HAL_SD_Init(&self->handle);
if (r != HAL_OK) {
Expand All @@ -150,9 +174,14 @@ void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self,
}

self->num_data = 1;
#ifdef STM32H750xx
uint32_t bus_wide_opt = SDMMC_BUS_WIDE_4B;
#else
uint32_t bus_wide_opt = SDIO_BUS_WIDE_4B;
#endif
if (num_data == 4) {
if ((r = HAL_SD_ConfigWideBusOperation(&self->handle, SDIO_BUS_WIDE_4B)) == HAL_SD_ERROR_NONE) {
self->handle.Init.BusWide = SDIO_BUS_WIDE_4B;
if ((r = HAL_SD_ConfigWideBusOperation(&self->handle, bus_wide_opt)) == HAL_SD_ERROR_NONE) {
self->handle.Init.BusWide = bus_wide_opt;
self->num_data = 4;
} else {
}
Expand Down Expand Up @@ -216,7 +245,13 @@ int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t sta
wait_write_complete(self);
self->state_programming = true;
common_hal_mcu_disable_interrupts();
HAL_StatusTypeDef r = HAL_SD_WriteBlocks(&self->handle, bufinfo->buf, start_block, bufinfo->len / 512, 1000);
#ifdef STM32H750xx
// longer timeouts needed because code executing from QSPI is slower
uint32_t time_out = SDMMC_DATATIMEOUT;
#else
uint32_t time_out = 1000;
#endif
HAL_StatusTypeDef r = HAL_SD_WriteBlocks(&self->handle, bufinfo->buf, start_block, bufinfo->len / 512, time_out);
common_hal_mcu_enable_interrupts();
if (r != HAL_OK) {
return -EIO;
Expand All @@ -229,7 +264,13 @@ int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t star
check_whole_block(bufinfo);
wait_write_complete(self);
common_hal_mcu_disable_interrupts();
HAL_StatusTypeDef r = HAL_SD_ReadBlocks(&self->handle, bufinfo->buf, start_block, bufinfo->len / 512, 1000);
#ifdef STM32H750xx
// longer timeouts needed because code executing from QSPI is slower
uint32_t time_out = SDMMC_DATATIMEOUT;
#else
uint32_t time_out = 1000;
#endif
HAL_StatusTypeDef r = HAL_SD_ReadBlocks(&self->handle, bufinfo->buf, start_block, bufinfo->len / 512, time_out);
common_hal_mcu_enable_interrupts();
if (r != HAL_OK) {
return -EIO;
Expand Down
2 changes: 1 addition & 1 deletion ports/stm/peripherals/periph.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ typedef struct {
// Timer Peripheral

typedef struct {
uint8_t tim_index : 4;
uint8_t tim_index : 5;
uint8_t altfn_index : 4;
uint8_t channel_index : 4;
const mcu_pin_obj_t *pin;
Expand Down
Loading