summaryrefslogtreecommitdiffstatshomepage
path: root/stmhal/sdcard.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2017-03-30 17:55:21 +1100
committerDamien George <damien.p.george@gmail.com>2017-03-30 17:55:21 +1100
commit7876e54aa5ebd0daca0fa4cd7b0faaa424b1d23d (patch)
treef662ac2d92b556b438506b29af648633624075ef /stmhal/sdcard.c
parent43defc9e98d27d370d1aa728c24ca48377ca6f66 (diff)
downloadmicropython-7876e54aa5ebd0daca0fa4cd7b0faaa424b1d23d.tar.gz
micropython-7876e54aa5ebd0daca0fa4cd7b0faaa424b1d23d.zip
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.
Diffstat (limited to 'stmhal/sdcard.c')
-rw-r--r--stmhal/sdcard.c69
1 files changed, 58 insertions, 11 deletions
diff --git a/stmhal/sdcard.c b/stmhal/sdcard.c
index 73206f4316..5abffa730b 100644
--- a/stmhal/sdcard.c
+++ b/stmhal/sdcard.c
@@ -43,11 +43,29 @@
#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
// #defines for backwards compatability.
-#define SDIO SDMMC1
-
#define SDIO_CLOCK_EDGE_RISING SDMMC_CLOCK_EDGE_RISING
#define SDIO_CLOCK_EDGE_FALLING SDMMC_CLOCK_EDGE_FALLING
@@ -66,6 +84,16 @@
#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
// 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
// fast mode which can do up to 50MHz. This should be plenty for SDIO
// 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_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_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_D2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
+ #endif
// configure the SD card detect pin
// 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) {
// enable SDIO clock
- __SDIO_CLK_ENABLE();
+ SDMMC_CLK_ENABLE();
// NVIC configuration for SDIO interrupts
- HAL_NVIC_SetPriority(SDIO_IRQn, IRQ_PRI_SDIO, IRQ_SUBPRI_SDIO);
- HAL_NVIC_EnableIRQ(SDIO_IRQn);
+ HAL_NVIC_SetPriority(SDMMC_IRQn, IRQ_PRI_SDIO, IRQ_SUBPRI_SDIO);
+ HAL_NVIC_EnableIRQ(SDMMC_IRQn);
// GPIO have already been initialised by sdcard_init
}
void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) {
- HAL_NVIC_DisableIRQ(SDIO_IRQn);
- __SDIO_CLK_DISABLE();
+ HAL_NVIC_DisableIRQ(SDMMC_IRQn);
+ SDMMC_CLK_DISABLE();
}
bool sdcard_is_present(void) {
@@ -184,6 +223,14 @@ void SDIO_IRQHandler(void) {
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) {
// check that SD card is initialised
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
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;
// 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);
}
- dma_deinit(&dma_SDIO_0_RX);
+ dma_deinit(&SDMMC_RX_DMA);
sd_handle.hdmarx = NULL;
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
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;
// 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
err = HAL_SD_CheckWriteOperation(&sd_handle, 100000000);
}
- dma_deinit(&dma_SDIO_0_TX);
+ dma_deinit(&SDMMC_TX_DMA);
sd_handle.hdmatx = NULL;
restore_irq_pri(basepri);