stmhal/sdcard: Add support for SDMMC2 on F7 MCUs.
By default the SDIO (F4) or SDMMC1 (L4, F7) is used as the SD card peripheral, but if a board config defines MICROPY_HW_SDMMC2_CK and other pins then the SD card driver will use SDMMC2.
This commit is contained in:
parent
43defc9e98
commit
7876e54aa5
@ -186,6 +186,9 @@ const dma_descr_t dma_I2C_1_TX = { DMA1_Stream6, DMA_CHANNEL_1, DMA_MEMORY_TO_PE
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// DMA2 streams
|
// DMA2 streams
|
||||||
|
#if defined(MCU_SERIES_F7) && MICROPY_HW_HAS_SDCARD
|
||||||
|
const dma_descr_t dma_SDMMC_2_RX= { DMA2_Stream0, DMA_CHANNEL_11, DMA_PERIPH_TO_MEMORY, dma_id_8, &dma_init_struct_sdio };
|
||||||
|
#endif
|
||||||
const dma_descr_t dma_SPI_1_RX = { DMA2_Stream2, DMA_CHANNEL_3, DMA_PERIPH_TO_MEMORY, dma_id_10, &dma_init_struct_spi_i2c };
|
const dma_descr_t dma_SPI_1_RX = { DMA2_Stream2, DMA_CHANNEL_3, DMA_PERIPH_TO_MEMORY, dma_id_10, &dma_init_struct_spi_i2c };
|
||||||
const dma_descr_t dma_SPI_5_RX = { DMA2_Stream3, DMA_CHANNEL_2, DMA_PERIPH_TO_MEMORY, dma_id_11, &dma_init_struct_spi_i2c };
|
const dma_descr_t dma_SPI_5_RX = { DMA2_Stream3, DMA_CHANNEL_2, DMA_PERIPH_TO_MEMORY, dma_id_11, &dma_init_struct_spi_i2c };
|
||||||
#if defined(MICROPY_HW_HAS_SDCARD) && MICROPY_HW_HAS_SDCARD
|
#if defined(MICROPY_HW_HAS_SDCARD) && MICROPY_HW_HAS_SDCARD
|
||||||
@ -196,6 +199,9 @@ const dma_descr_t dma_SPI_5_TX = { DMA2_Stream4, DMA_CHANNEL_2, DMA_MEMORY_TO_PE
|
|||||||
const dma_descr_t dma_SPI_4_TX = { DMA2_Stream4, DMA_CHANNEL_5, DMA_MEMORY_TO_PERIPH, dma_id_12, &dma_init_struct_spi_i2c };
|
const dma_descr_t dma_SPI_4_TX = { DMA2_Stream4, DMA_CHANNEL_5, DMA_MEMORY_TO_PERIPH, dma_id_12, &dma_init_struct_spi_i2c };
|
||||||
const dma_descr_t dma_SPI_6_TX = { DMA2_Stream5, DMA_CHANNEL_1, DMA_MEMORY_TO_PERIPH, dma_id_13, &dma_init_struct_spi_i2c };
|
const dma_descr_t dma_SPI_6_TX = { DMA2_Stream5, DMA_CHANNEL_1, DMA_MEMORY_TO_PERIPH, dma_id_13, &dma_init_struct_spi_i2c };
|
||||||
const dma_descr_t dma_SPI_1_TX = { DMA2_Stream5, DMA_CHANNEL_3, DMA_MEMORY_TO_PERIPH, dma_id_13, &dma_init_struct_spi_i2c };
|
const dma_descr_t dma_SPI_1_TX = { DMA2_Stream5, DMA_CHANNEL_3, DMA_MEMORY_TO_PERIPH, dma_id_13, &dma_init_struct_spi_i2c };
|
||||||
|
#if defined(MCU_SERIES_F7) && MICROPY_HW_HAS_SDCARD
|
||||||
|
const dma_descr_t dma_SDMMC_2_TX= { DMA2_Stream5, DMA_CHANNEL_11, DMA_MEMORY_TO_PERIPH, dma_id_13, &dma_init_struct_sdio };
|
||||||
|
#endif
|
||||||
const dma_descr_t dma_SPI_6_RX = { DMA2_Stream6, DMA_CHANNEL_1, DMA_PERIPH_TO_MEMORY, dma_id_14, &dma_init_struct_spi_i2c };
|
const dma_descr_t dma_SPI_6_RX = { DMA2_Stream6, DMA_CHANNEL_1, DMA_PERIPH_TO_MEMORY, dma_id_14, &dma_init_struct_spi_i2c };
|
||||||
#if defined(MICROPY_HW_HAS_SDCARD) && MICROPY_HW_HAS_SDCARD
|
#if defined(MICROPY_HW_HAS_SDCARD) && MICROPY_HW_HAS_SDCARD
|
||||||
const dma_descr_t dma_SDIO_0_TX= { DMA2_Stream6, DMA_CHANNEL_4, DMA_MEMORY_TO_PERIPH, dma_id_14, &dma_init_struct_sdio };
|
const dma_descr_t dma_SDIO_0_TX= { DMA2_Stream6, DMA_CHANNEL_4, DMA_MEMORY_TO_PERIPH, dma_id_14, &dma_init_struct_sdio };
|
||||||
|
@ -45,6 +45,7 @@ extern const dma_descr_t dma_DAC_2_TX;
|
|||||||
extern const dma_descr_t dma_SPI_3_TX;
|
extern const dma_descr_t dma_SPI_3_TX;
|
||||||
extern const dma_descr_t dma_I2C_1_TX;
|
extern const dma_descr_t dma_I2C_1_TX;
|
||||||
extern const dma_descr_t dma_I2C_2_TX;
|
extern const dma_descr_t dma_I2C_2_TX;
|
||||||
|
extern const dma_descr_t dma_SDMMC_2_RX;
|
||||||
extern const dma_descr_t dma_SPI_1_RX;
|
extern const dma_descr_t dma_SPI_1_RX;
|
||||||
extern const dma_descr_t dma_SPI_5_RX;
|
extern const dma_descr_t dma_SPI_5_RX;
|
||||||
extern const dma_descr_t dma_SDIO_0_RX;
|
extern const dma_descr_t dma_SDIO_0_RX;
|
||||||
@ -53,6 +54,7 @@ extern const dma_descr_t dma_SPI_5_TX;
|
|||||||
extern const dma_descr_t dma_SPI_4_TX;
|
extern const dma_descr_t dma_SPI_4_TX;
|
||||||
extern const dma_descr_t dma_SPI_6_TX;
|
extern const dma_descr_t dma_SPI_6_TX;
|
||||||
extern const dma_descr_t dma_SPI_1_TX;
|
extern const dma_descr_t dma_SPI_1_TX;
|
||||||
|
extern const dma_descr_t dma_SDMMC_2_TX;
|
||||||
extern const dma_descr_t dma_SPI_6_RX;
|
extern const dma_descr_t dma_SPI_6_RX;
|
||||||
extern const dma_descr_t dma_SDIO_0_TX;
|
extern const dma_descr_t dma_SDIO_0_TX;
|
||||||
|
|
||||||
|
@ -43,11 +43,29 @@
|
|||||||
|
|
||||||
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_L4)
|
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_L4)
|
||||||
|
|
||||||
|
// The F7 has 2 SDMMC units but at the moment we only support using one of them in
|
||||||
|
// a given build. If a boards config file defines MICROPY_HW_SDMMC2_CK then SDMMC2
|
||||||
|
// is used, otherwise SDMMC1 is used.
|
||||||
|
|
||||||
|
#if defined(MICROPY_HW_SDMMC2_CK)
|
||||||
|
#define SDIO SDMMC2
|
||||||
|
#define SDMMC_CLK_ENABLE() __HAL_RCC_SDMMC2_CLK_ENABLE()
|
||||||
|
#define SDMMC_CLK_DISABLE() __HAL_RCC_SDMMC2_CLK_DISABLE()
|
||||||
|
#define SDMMC_IRQn SDMMC2_IRQn
|
||||||
|
#define SDMMC_TX_DMA dma_SDMMC_2_TX
|
||||||
|
#define SDMMC_RX_DMA dma_SDMMC_2_RX
|
||||||
|
#else
|
||||||
|
#define SDIO SDMMC1
|
||||||
|
#define SDMMC_CLK_ENABLE() __HAL_RCC_SDMMC1_CLK_ENABLE()
|
||||||
|
#define SDMMC_CLK_DISABLE() __HAL_RCC_SDMMC1_CLK_DISABLE()
|
||||||
|
#define SDMMC_IRQn SDMMC1_IRQn
|
||||||
|
#define SDMMC_TX_DMA dma_SDIO_0_TX
|
||||||
|
#define SDMMC_RX_DMA dma_SDIO_0_RX
|
||||||
|
#endif
|
||||||
|
|
||||||
// The F7 & L4 series calls the peripheral SDMMC rather than SDIO, so provide some
|
// The F7 & L4 series calls the peripheral SDMMC rather than SDIO, so provide some
|
||||||
// #defines for backwards compatability.
|
// #defines for backwards compatability.
|
||||||
|
|
||||||
#define SDIO SDMMC1
|
|
||||||
|
|
||||||
#define SDIO_CLOCK_EDGE_RISING SDMMC_CLOCK_EDGE_RISING
|
#define SDIO_CLOCK_EDGE_RISING SDMMC_CLOCK_EDGE_RISING
|
||||||
#define SDIO_CLOCK_EDGE_FALLING SDMMC_CLOCK_EDGE_FALLING
|
#define SDIO_CLOCK_EDGE_FALLING SDMMC_CLOCK_EDGE_FALLING
|
||||||
|
|
||||||
@ -66,6 +84,16 @@
|
|||||||
|
|
||||||
#define SDIO_TRANSFER_CLK_DIV SDMMC_TRANSFER_CLK_DIV
|
#define SDIO_TRANSFER_CLK_DIV SDMMC_TRANSFER_CLK_DIV
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// These are definitions for F4 MCUs so there is a common macro across all MCUs.
|
||||||
|
|
||||||
|
#define SDMMC_CLK_ENABLE() __SDIO_CLK_ENABLE()
|
||||||
|
#define SDMMC_CLK_DISABLE() __SDIO_CLK_DISABLE()
|
||||||
|
#define SDMMC_IRQn SDIO_IRQn
|
||||||
|
#define SDMMC_TX_DMA dma_SDIO_0_TX
|
||||||
|
#define SDMMC_RX_DMA dma_SDIO_0_RX
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: Since SDIO is fundamentally half-duplex, we really only need to
|
// TODO: Since SDIO is fundamentally half-duplex, we really only need to
|
||||||
@ -90,12 +118,23 @@ void sdcard_init(void) {
|
|||||||
// Note: the mp_hal_pin_config function will configure the GPIO in
|
// Note: the mp_hal_pin_config function will configure the GPIO in
|
||||||
// fast mode which can do up to 50MHz. This should be plenty for SDIO
|
// fast mode which can do up to 50MHz. This should be plenty for SDIO
|
||||||
// which clocks up to 25MHz maximum.
|
// which clocks up to 25MHz maximum.
|
||||||
|
#if defined(MICROPY_HW_SDMMC2_CK)
|
||||||
|
// Use SDMMC2 peripheral with pins provided by the board's config
|
||||||
|
mp_hal_pin_config_alt(&MICROPY_HW_SDMMC2_CK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_SDMMC, 2);
|
||||||
|
mp_hal_pin_config_alt(&MICROPY_HW_SDMMC2_CMD, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_SDMMC, 2);
|
||||||
|
mp_hal_pin_config_alt(&MICROPY_HW_SDMMC2_D0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_SDMMC, 2);
|
||||||
|
mp_hal_pin_config_alt(&MICROPY_HW_SDMMC2_D1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_SDMMC, 2);
|
||||||
|
mp_hal_pin_config_alt(&MICROPY_HW_SDMMC2_D2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_SDMMC, 2);
|
||||||
|
mp_hal_pin_config_alt(&MICROPY_HW_SDMMC2_D3, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_SDMMC, 2);
|
||||||
|
#else
|
||||||
|
// Default SDIO/SDMMC1 config
|
||||||
mp_hal_pin_config(&pin_C8, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
|
mp_hal_pin_config(&pin_C8, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
|
||||||
mp_hal_pin_config(&pin_C9, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
|
mp_hal_pin_config(&pin_C9, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
|
||||||
mp_hal_pin_config(&pin_C10, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
|
mp_hal_pin_config(&pin_C10, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
|
||||||
mp_hal_pin_config(&pin_C11, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
|
mp_hal_pin_config(&pin_C11, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
|
||||||
mp_hal_pin_config(&pin_C12, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
|
mp_hal_pin_config(&pin_C12, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
|
||||||
mp_hal_pin_config(&pin_D2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
|
mp_hal_pin_config(&pin_D2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
|
||||||
|
#endif
|
||||||
|
|
||||||
// configure the SD card detect pin
|
// configure the SD card detect pin
|
||||||
// we do this here so we can detect if the SD card is inserted before powering it on
|
// we do this here so we can detect if the SD card is inserted before powering it on
|
||||||
@ -104,18 +143,18 @@ void sdcard_init(void) {
|
|||||||
|
|
||||||
void HAL_SD_MspInit(SD_HandleTypeDef *hsd) {
|
void HAL_SD_MspInit(SD_HandleTypeDef *hsd) {
|
||||||
// enable SDIO clock
|
// enable SDIO clock
|
||||||
__SDIO_CLK_ENABLE();
|
SDMMC_CLK_ENABLE();
|
||||||
|
|
||||||
// NVIC configuration for SDIO interrupts
|
// NVIC configuration for SDIO interrupts
|
||||||
HAL_NVIC_SetPriority(SDIO_IRQn, IRQ_PRI_SDIO, IRQ_SUBPRI_SDIO);
|
HAL_NVIC_SetPriority(SDMMC_IRQn, IRQ_PRI_SDIO, IRQ_SUBPRI_SDIO);
|
||||||
HAL_NVIC_EnableIRQ(SDIO_IRQn);
|
HAL_NVIC_EnableIRQ(SDMMC_IRQn);
|
||||||
|
|
||||||
// GPIO have already been initialised by sdcard_init
|
// GPIO have already been initialised by sdcard_init
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) {
|
void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) {
|
||||||
HAL_NVIC_DisableIRQ(SDIO_IRQn);
|
HAL_NVIC_DisableIRQ(SDMMC_IRQn);
|
||||||
__SDIO_CLK_DISABLE();
|
SDMMC_CLK_DISABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sdcard_is_present(void) {
|
bool sdcard_is_present(void) {
|
||||||
@ -184,6 +223,14 @@ void SDIO_IRQHandler(void) {
|
|||||||
IRQ_EXIT(SDIO_IRQn);
|
IRQ_EXIT(SDIO_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MCU_SERIES_F7)
|
||||||
|
void SDMMC2_IRQHandler(void) {
|
||||||
|
IRQ_ENTER(SDMMC2_IRQn);
|
||||||
|
HAL_SD_IRQHandler(&sd_handle);
|
||||||
|
IRQ_EXIT(SDMMC2_IRQn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
|
mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
|
||||||
// check that SD card is initialised
|
// check that SD card is initialised
|
||||||
if (sd_handle.Instance == NULL) {
|
if (sd_handle.Instance == NULL) {
|
||||||
@ -214,7 +261,7 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo
|
|||||||
// we must disable USB irqs to prevent MSC contention with SD card
|
// we must disable USB irqs to prevent MSC contention with SD card
|
||||||
uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);
|
uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);
|
||||||
|
|
||||||
dma_init(&sd_rx_dma, &dma_SDIO_0_RX, &sd_handle);
|
dma_init(&sd_rx_dma, &SDMMC_RX_DMA, &sd_handle);
|
||||||
sd_handle.hdmarx = &sd_rx_dma;
|
sd_handle.hdmarx = &sd_rx_dma;
|
||||||
|
|
||||||
// make sure cache is flushed and invalidated so when DMA updates the RAM
|
// make sure cache is flushed and invalidated so when DMA updates the RAM
|
||||||
@ -227,7 +274,7 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo
|
|||||||
err = HAL_SD_CheckReadOperation(&sd_handle, 100000000);
|
err = HAL_SD_CheckReadOperation(&sd_handle, 100000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
dma_deinit(&dma_SDIO_0_RX);
|
dma_deinit(&SDMMC_RX_DMA);
|
||||||
sd_handle.hdmarx = NULL;
|
sd_handle.hdmarx = NULL;
|
||||||
|
|
||||||
restore_irq_pri(basepri);
|
restore_irq_pri(basepri);
|
||||||
@ -274,7 +321,7 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n
|
|||||||
// we must disable USB irqs to prevent MSC contention with SD card
|
// we must disable USB irqs to prevent MSC contention with SD card
|
||||||
uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);
|
uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);
|
||||||
|
|
||||||
dma_init(&sd_tx_dma, &dma_SDIO_0_TX, &sd_handle);
|
dma_init(&sd_tx_dma, &SDMMC_TX_DMA, &sd_handle);
|
||||||
sd_handle.hdmatx = &sd_tx_dma;
|
sd_handle.hdmatx = &sd_tx_dma;
|
||||||
|
|
||||||
// make sure cache is flushed to RAM so the DMA can read the correct data
|
// make sure cache is flushed to RAM so the DMA can read the correct data
|
||||||
@ -285,7 +332,7 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n
|
|||||||
// wait for DMA transfer to finish, with a large timeout
|
// wait for DMA transfer to finish, with a large timeout
|
||||||
err = HAL_SD_CheckWriteOperation(&sd_handle, 100000000);
|
err = HAL_SD_CheckWriteOperation(&sd_handle, 100000000);
|
||||||
}
|
}
|
||||||
dma_deinit(&dma_SDIO_0_TX);
|
dma_deinit(&SDMMC_TX_DMA);
|
||||||
sd_handle.hdmatx = NULL;
|
sd_handle.hdmatx = NULL;
|
||||||
|
|
||||||
restore_irq_pri(basepri);
|
restore_irq_pri(basepri);
|
||||||
|
@ -335,6 +335,12 @@ g_pfnVectors:
|
|||||||
.word I2C4_EV_IRQHandler /* I2C4 Event */
|
.word I2C4_EV_IRQHandler /* I2C4 Event */
|
||||||
.word I2C4_ER_IRQHandler /* I2C4 Error */
|
.word I2C4_ER_IRQHandler /* I2C4 Error */
|
||||||
.word SPDIF_RX_IRQHandler /* SPDIF_RX */
|
.word SPDIF_RX_IRQHandler /* SPDIF_RX */
|
||||||
|
.word DSIHOST_IRQHandler /* DSI host */
|
||||||
|
.word DFSDM1_FLT0_IRQHandler /* DFSDM1 filter 0 */
|
||||||
|
.word DFSDM1_FLT1_IRQHandler /* DFSDM1 filter 1 */
|
||||||
|
.word DFSDM1_FLT2_IRQHandler /* DFSDM1 filter 2 */
|
||||||
|
.word DFSDM1_FLT3_IRQHandler /* DFSDM1 filter 3 */
|
||||||
|
.word SDMMC2_IRQHandler /* SDMMC2 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -793,6 +799,24 @@ g_pfnVectors:
|
|||||||
|
|
||||||
.weak SPDIF_RX_IRQHandler
|
.weak SPDIF_RX_IRQHandler
|
||||||
.thumb_set SPDIF_RX_IRQHandler,Default_Handler
|
.thumb_set SPDIF_RX_IRQHandler,Default_Handler
|
||||||
|
|
||||||
|
.weak DSIHOST_IRQHandler
|
||||||
|
.thumb_set DSIHOST_IRQHandler,Default_Handler
|
||||||
|
|
||||||
|
.weak DFSDM1_FLT0_IRQHandler
|
||||||
|
.thumb_set DFSDM1_FLT0_IRQHandler,Default_Handler
|
||||||
|
|
||||||
|
.weak DFSDM1_FLT1_IRQHandler
|
||||||
|
.thumb_set DFSDM1_FLT1_IRQHandler,Default_Handler
|
||||||
|
|
||||||
|
.weak DFSDM1_FLT2_IRQHandler
|
||||||
|
.thumb_set DFSDM1_FLT2_IRQHandler,Default_Handler
|
||||||
|
|
||||||
|
.weak DFSDM1_FLT3_IRQHandler
|
||||||
|
.thumb_set DFSDM1_FLT3_IRQHandler,Default_Handler
|
||||||
|
|
||||||
|
.weak SDMMC2_IRQHandler
|
||||||
|
.thumb_set SDMMC2_IRQHandler,Default_Handler
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
Loading…
Reference in New Issue
Block a user