From dfc15ba56d3529d12d5d2806dfe1280250438649 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 17 Sep 2015 13:38:08 +0000 Subject: [PATCH] SDC on SDMMCv1 peripheral for STM32F7, not tested. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8304 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- .../halconf.h | 2 +- .../main.c | 2 +- .../mcuconf.h | 15 +- demos/STM32/RT-STM32F746G-DISCOVERY/mcuconf.h | 15 +- os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.c | 889 ++++++++++++++++++ os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.h | 266 ++++++ os/hal/ports/STM32/STM32F7xx/platform.mk | 6 +- os/hal/ports/STM32/STM32F7xx/stm32_rcc.h | 49 +- os/hal/ports/STM32/STM32F7xx/stm32_registry.h | 12 +- testhal/STM32/STM32F7xx/GPT-ADC/mcuconf.h | 15 +- testhal/STM32/STM32F7xx/PWM-ICU/mcuconf.h | 15 +- testhal/STM32/STM32F7xx/SPI/mcuconf.h | 15 +- testhal/STM32/STM32F7xx/USB_CDC/mcuconf.h | 15 +- 13 files changed, 1221 insertions(+), 95 deletions(-) create mode 100644 os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.c create mode 100644 os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.h diff --git a/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/halconf.h b/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/halconf.h index 36a7ef467..d14d03c01 100644 --- a/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/halconf.h +++ b/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/halconf.h @@ -132,7 +132,7 @@ * @brief Enables the SDC subsystem. */ #if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) -#define HAL_USE_SDC FALSE +#define HAL_USE_SDC TRUE #endif /** diff --git a/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/main.c b/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/main.c index 093329ec8..f7e4851c8 100644 --- a/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/main.c +++ b/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/main.c @@ -663,7 +663,7 @@ int main(void) { * configuration. */ sdStart(&SD1, NULL); -// sdcStart(&SDCD1, NULL); + sdcStart(&SDCD1, NULL); /* * Activates the card insertion monitor. diff --git a/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/mcuconf.h b/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/mcuconf.h index 5eae8dff9..0ecab7cda 100644 --- a/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/mcuconf.h +++ b/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/mcuconf.h @@ -252,13 +252,14 @@ /* * SDC driver system settings. */ -#define STM32_SDC_SDIO_DMA_PRIORITY 3 -#define STM32_SDC_SDIO_IRQ_PRIORITY 9 -#define STM32_SDC_WRITE_TIMEOUT_MS 250 -#define STM32_SDC_READ_TIMEOUT_MS 25 -#define STM32_SDC_CLOCK_ACTIVATION_DELAY 10 -#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE -#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SDC_USE_SDMMC1 TRUE +#define STM32_SDC_SDMMC_UNALIGNED_SUPPORT TRUE +#define STM32_SDC_SDMMC_WRITE_TIMEOUT 250 +#define STM32_SDC_SDMMC_READ_TIMEOUT 25 +#define STM32_SDC_SDMMC_CLOCK_DELAY 10 +#define STM32_SDC_SDMMC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SDC_SDMMC1_DMA_PRIORITY 3 +#define STM32_SDC_SDMMC1_IRQ_PRIORITY 9 /* * SERIAL driver system settings. diff --git a/demos/STM32/RT-STM32F746G-DISCOVERY/mcuconf.h b/demos/STM32/RT-STM32F746G-DISCOVERY/mcuconf.h index e9b5b8ab7..0be888597 100644 --- a/demos/STM32/RT-STM32F746G-DISCOVERY/mcuconf.h +++ b/demos/STM32/RT-STM32F746G-DISCOVERY/mcuconf.h @@ -252,13 +252,14 @@ /* * SDC driver system settings. */ -#define STM32_SDC_SDIO_DMA_PRIORITY 3 -#define STM32_SDC_SDIO_IRQ_PRIORITY 9 -#define STM32_SDC_WRITE_TIMEOUT_MS 250 -#define STM32_SDC_READ_TIMEOUT_MS 25 -#define STM32_SDC_CLOCK_ACTIVATION_DELAY 10 -#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE -#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SDC_USE_SDMMC1 FALSE +#define STM32_SDC_SDMMC_UNALIGNED_SUPPORT TRUE +#define STM32_SDC_SDMMC_WRITE_TIMEOUT 250 +#define STM32_SDC_SDMMC_READ_TIMEOUT 25 +#define STM32_SDC_SDMMC_CLOCK_DELAY 10 +#define STM32_SDC_SDMMC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SDC_SDMMC1_DMA_PRIORITY 3 +#define STM32_SDC_SDMMC1_IRQ_PRIORITY 9 /* * SERIAL driver system settings. diff --git a/os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.c b/os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.c new file mode 100644 index 000000000..768258303 --- /dev/null +++ b/os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.c @@ -0,0 +1,889 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file STM32/SDMMCv1/sdc_lld.c + * @brief STM32 SDC subsystem low level driver source. + * + * @addtogroup SDC + * @{ + */ + +#include + +#include "hal.h" + +#if HAL_USE_SDC || defined(__DOXYGEN__) + +#if !defined(STM32_SDMMCCLK) +#error "STM32_SDMMCCLK not defined" +#endif + +#if STM32_SDMMCCLK > 48000000 +#error "STM32_SDMMCCLK exceeding 48MHz" +#endif + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define SDMMC_ICR_ALL_FLAGS \ + (SDMMC_ICR_CCRCFAILC | SDMMC_ICR_DCRCFAILC | \ + SDMMC_ICR_CTIMEOUTC | SDMMC_ICR_DTIMEOUTC | \ + SDMMC_ICR_TXUNDERRC | SDMMC_ICR_RXOVERRC | \ + SDMMC_ICR_CMDRENDC | SDMMC_ICR_CMDSENTC | \ + SDMMC_ICR_DATAENDC | SDMMC_ICR_DBCKENDC | \ + SDMMC_ICR_SDIOITC) + +#define SDMMC_STA_ERROR_MASK \ + (SDMMC_STA_CCRCFAIL | SDMMC_STA_DCRCFAIL | \ + SDMMC_STA_CTIMEOUT | SDMMC_STA_DTIMEOUT | \ + SDMMC_STA_TXUNDERR | SDMMC_STA_RXOVERR) + +#define SDMMC_CLKDIV_HS (2 - 2) +#define SDMMC_CLKDIV_LS (120 - 2) + +#define SDMMC_WRITE_TIMEOUT \ + (((STM32_SDMMCCLK / (SDMMC_CLKDIV_HS + 2)) / 1000) * \ + STM32_SDC_SDMMC_WRITE_TIMEOUT) +#define SDMMC_READ_TIMEOUT \ + (((STM32_SDMMCCLK / (SDMMC_CLKDIV_HS + 2)) / 1000) * \ + STM32_SDC_SDMMC_READ_TIMEOUT) + +#define DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SDC_SDMMC1_DMA_STREAM, \ + STM32_SDC_SDMMC1_DMA_CHN) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief SDCD1 driver identifier.*/ +SDCDriver SDCD1; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +#if STM32_SDC_SDMMC_UNALIGNED_SUPPORT +/** + * @brief Buffer for temporary storage during unaligned transfers. + */ +static union { + uint32_t alignment; + uint8_t buf[MMCSD_BLOCK_SIZE]; +} u; +#endif /* STM32_SDC_SDMMC_UNALIGNED_SUPPORT */ + + +/** + * @brief SDIO default configuration. + */ +static const SDCConfig sdc_default_cfg = { + NULL, + SDC_MODE_4BIT +}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Prepares to handle read transaction. + * @details Designed for read special registers from card. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[out] buf pointer to the read buffer + * @param[in] bytes number of bytes to read + * + * @return The operation status. + * @retval HAL_SUCCESS operation succeeded. + * @retval HAL_FAILED operation failed. + * + * @notapi + */ +static bool sdc_lld_prepare_read_bytes(SDCDriver *sdcp, + uint8_t *buf, uint32_t bytes) { + osalDbgCheck(bytes < 0x1000000); + + sdcp->sdmmc->DTIMER = SDMMC_READ_TIMEOUT; + + /* Checks for errors and waits for the card to be ready for reading.*/ + if (_sdc_wait_for_transfer_state(sdcp)) + return HAL_FAILED; + + /* Prepares the DMA channel for writing.*/ + dmaStreamSetMemory0(sdcp->dma, buf); + dmaStreamSetTransactionSize(sdcp->dma, bytes / sizeof (uint32_t)); + dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M); + dmaStreamEnable(sdcp->dma); + + /* Setting up data transfer.*/ + sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS; + sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE | + SDMMC_MASK_DTIMEOUTIE | + SDMMC_MASK_RXOVERRIE | + SDMMC_MASK_DATAENDIE; + sdcp->sdmmc->DLEN = bytes; + + /* Transaction starts just after DTEN bit setting.*/ + sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DTDIR | + SDMMC_DCTRL_DTMODE | /* multibyte data transfer */ + SDMMC_DCTRL_DMAEN | + SDMMC_DCTRL_DTEN; + + return HAL_SUCCESS; +} + +/** + * @brief Prepares card to handle read transaction. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to read + * @param[in] n number of blocks to read + * @param[in] resp pointer to the response buffer + * + * @return The operation status. + * @retval HAL_SUCCESS operation succeeded. + * @retval HAL_FAILED operation failed. + * + * @notapi + */ +static bool sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk, + uint32_t n, uint32_t *resp) { + + /* Driver handles data in 512 bytes blocks (just like HC cards). But if we + have not HC card than we must convert address from blocks to bytes.*/ + if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY)) + startblk *= MMCSD_BLOCK_SIZE; + + if (n > 1) { + /* Send read multiple blocks command to card.*/ + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_MULTIPLE_BLOCK, + startblk, resp) || MMCSD_R1_ERROR(resp[0])) + return HAL_FAILED; + } + else{ + /* Send read single block command.*/ + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_SINGLE_BLOCK, + startblk, resp) || MMCSD_R1_ERROR(resp[0])) + return HAL_FAILED; + } + + return HAL_SUCCESS; +} + +/** + * @brief Prepares card to handle write transaction. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to read + * @param[in] n number of blocks to write + * @param[in] resp pointer to the response buffer + * + * @return The operation status. + * @retval HAL_SUCCESS operation succeeded. + * @retval HAL_FAILED operation failed. + * + * @notapi + */ +static bool sdc_lld_prepare_write(SDCDriver *sdcp, uint32_t startblk, + uint32_t n, uint32_t *resp) { + + /* Driver handles data in 512 bytes blocks (just like HC cards). But if we + have not HC card than we must convert address from blocks to bytes.*/ + if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY)) + startblk *= MMCSD_BLOCK_SIZE; + + if (n > 1) { + /* Write multiple blocks command.*/ + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK, + startblk, resp) || MMCSD_R1_ERROR(resp[0])) + return HAL_FAILED; + } + else{ + /* Write single block command.*/ + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_BLOCK, + startblk, resp) || MMCSD_R1_ERROR(resp[0])) + return HAL_FAILED; + } + + return HAL_SUCCESS; +} + +/** + * @brief Wait end of data transaction and performs finalizations. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] n number of blocks in transaction + * @param[in] resp pointer to the response buffer + * + * @return The operation status. + * @retval HAL_SUCCESS operation succeeded. + * @retval HAL_FAILED operation failed. + */ +static bool sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n, + uint32_t *resp) { + + /* Note the mask is checked before going to sleep because the interrupt + may have occurred before reaching the critical zone.*/ + osalSysLock(); + if (sdcp->sdmmc->MASK != 0) + osalThreadSuspendS(&sdcp->thread); + if ((sdcp->sdmmc->STA & SDMMC_STA_DATAEND) == 0) { + osalSysUnlock(); + return HAL_FAILED; + } + + /* Wait until DMA channel enabled to be sure that all data transferred.*/ + while (sdcp->dma->stream->CR & STM32_DMA_CR_EN) + ; + + /* DMA event flags must be manually cleared.*/ + dmaStreamClearInterrupt(sdcp->dma); + + sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS; + sdcp->sdmmc->DCTRL = 0; + osalSysUnlock(); + + /* Finalize transaction.*/ + if (n > 1) + return sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp); + + return HAL_SUCCESS; +} + +/** + * @brief Gets SDC errors. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] sta value of the STA register + * + * @notapi + */ +static void sdc_lld_collect_errors(SDCDriver *sdcp, uint32_t sta) { + uint32_t errors = SDC_NO_ERROR; + + if (sta & SDMMC_STA_CCRCFAIL) + errors |= SDC_CMD_CRC_ERROR; + if (sta & SDMMC_STA_DCRCFAIL) + errors |= SDC_DATA_CRC_ERROR; + if (sta & SDMMC_STA_CTIMEOUT) + errors |= SDC_COMMAND_TIMEOUT; + if (sta & SDMMC_STA_DTIMEOUT) + errors |= SDC_DATA_TIMEOUT; + if (sta & SDMMC_STA_TXUNDERR) + errors |= SDC_TX_UNDERRUN; + if (sta & SDMMC_STA_RXOVERR) + errors |= SDC_RX_OVERRUN; +/* if (sta & SDMMC_STA_STBITERR) + errors |= SDC_STARTBIT_ERROR;*/ + + sdcp->errors |= errors; +} + +/** + * @brief Performs clean transaction stopping in case of errors. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] n number of blocks in transaction + * @param[in] resp pointer to the response buffer + * + * @notapi + */ +static void sdc_lld_error_cleanup(SDCDriver *sdcp, + uint32_t n, + uint32_t *resp) { + uint32_t sta = sdcp->sdmmc->STA; + + dmaStreamClearInterrupt(sdcp->dma); + dmaStreamDisable(sdcp->dma); + sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS; + sdcp->sdmmc->MASK = 0; + sdcp->sdmmc->DCTRL = 0; + sdc_lld_collect_errors(sdcp, sta); + + if (n > 1) + sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp); +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if !defined(STM32_SDMMC1_HANDLER) +#error "STM32_SDMMC1_HANDLER not defined" +#endif + +/** + * @brief SDIO IRQ handler. + * @details It just wakes transaction thread. All error handling performs in + * that thread. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_SDMMC1_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + osalSysLockFromISR(); + + /* Disables the source but the status flags are not reset because the + read/write functions needs to check them.*/ + SDMMC1->MASK = 0; + + osalThreadResumeI(&SDCD1.thread, MSG_OK); + + osalSysUnlockFromISR(); + + OSAL_IRQ_EPILOGUE(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level SDC driver initialization. + * + * @notapi + */ +void sdc_lld_init(void) { + + sdcObjectInit(&SDCD1); + SDCD1.thread = NULL; + SDCD1.dma = STM32_DMA_STREAM(STM32_SDC_SDMMC1_DMA_STREAM); + SDCD1.sdmmc = SDMMC1; +} + +/** + * @brief Configures and activates the SDC peripheral. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @notapi + */ +void sdc_lld_start(SDCDriver *sdcp) { + + /* Checking configuration, using a default if NULL has been passed.*/ + if (sdcp->config == NULL) { + sdcp->config = &sdc_default_cfg; + } + + sdcp->dmamode = STM32_DMA_CR_CHSEL(DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SDC_SDMMC1_DMA_PRIORITY) | + STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | + STM32_DMA_CR_MINC; + +#if 1 + sdcp->dmamode |= STM32_DMA_CR_PFCTRL | + STM32_DMA_CR_PBURST_INCR4 | + STM32_DMA_CR_MBURST_INCR4; +#endif + + if (sdcp->state == BLK_STOP) { + /* Note, the DMA must be enabled before the IRQs.*/ + bool b; + b = dmaStreamAllocate(sdcp->dma, STM32_SDC_SDMMC1_IRQ_PRIORITY, NULL, NULL); + osalDbgAssert(!b, "stream already allocated"); + dmaStreamSetPeripheral(sdcp->dma, &sdcp->sdmmc->FIFO); +#if 1 + dmaStreamSetFIFO(sdcp->dma, STM32_DMA_FCR_DMDIS | STM32_DMA_FCR_FTH_FULL); +#endif + nvicEnableVector(STM32_SDMMC1_NUMBER, STM32_SDC_SDMMC1_IRQ_PRIORITY); + rccEnableSDMMC1(FALSE); + } + + /* Configuration, card clock is initially stopped.*/ + sdcp->sdmmc->POWER = 0; + sdcp->sdmmc->CLKCR = 0; + sdcp->sdmmc->DCTRL = 0; + sdcp->sdmmc->DTIMER = 0; +} + +/** + * @brief Deactivates the SDC peripheral. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @notapi + */ +void sdc_lld_stop(SDCDriver *sdcp) { + + if (sdcp->state != BLK_STOP) { + + /* SDIO deactivation.*/ + sdcp->sdmmc->POWER = 0; + sdcp->sdmmc->CLKCR = 0; + sdcp->sdmmc->DCTRL = 0; + sdcp->sdmmc->DTIMER = 0; + + /* Clock deactivation.*/ + nvicDisableVector(STM32_SDMMC1_NUMBER); + dmaStreamRelease(sdcp->dma); + rccDisableSDMMC1(FALSE); + } +} + +/** + * @brief Starts the SDIO clock and sets it to init mode (400kHz or less). + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @notapi + */ +void sdc_lld_start_clk(SDCDriver *sdcp) { + + /* Initial clock setting: 400kHz, 1bit mode.*/ + sdcp->sdmmc->CLKCR = SDMMC_CLKDIV_LS; + sdcp->sdmmc->POWER |= SDMMC_POWER_PWRCTRL_0 | SDMMC_POWER_PWRCTRL_1; + sdcp->sdmmc->CLKCR |= SDMMC_CLKCR_CLKEN; + + /* Clock activation delay.*/ + osalThreadSleep(OSAL_MS2ST(STM32_SDC_SDMMC_CLOCK_DELAY)); +} + +/** + * @brief Sets the SDIO clock to data mode (25MHz or less). + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] clk the clock mode + * + * @notapi + */ +void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk) { +#if 0 + if (SDC_CLK_50MHz == clk) { + sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) | + SDMMC_CLKDIV_HS | SDMMC_CLKCR_BYPASS; + } + else + sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) | SDMMC_CLKDIV_HS; +#else + (void)clk; + + sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) | SDMMC_CLKDIV_HS; +#endif +} + +/** + * @brief Stops the SDIO clock. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @notapi + */ +void sdc_lld_stop_clk(SDCDriver *sdcp) { + + sdcp->sdmmc->CLKCR = 0; + sdcp->sdmmc->POWER = 0; +} + +/** + * @brief Switches the bus to 4 bits mode. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] mode bus mode + * + * @notapi + */ +void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) { + uint32_t clk = sdcp->sdmmc->CLKCR & ~SDMMC_CLKCR_WIDBUS; + + switch (mode) { + case SDC_MODE_1BIT: + sdcp->sdmmc->CLKCR = clk; + break; + case SDC_MODE_4BIT: + sdcp->sdmmc->CLKCR = clk | SDMMC_CLKCR_WIDBUS_0; + break; + case SDC_MODE_8BIT: + sdcp->sdmmc->CLKCR = clk | SDMMC_CLKCR_WIDBUS_1; + break; + } +} + +/** + * @brief Sends an SDIO command with no response expected. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] cmd card command + * @param[in] arg command argument + * + * @notapi + */ +void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) { + + sdcp->sdmmc->ARG = arg; + sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_CPSMEN; + while ((sdcp->sdmmc->STA & SDMMC_STA_CMDSENT) == 0) + ; + sdcp->sdmmc->ICR = SDMMC_ICR_CMDSENTC; +} + +/** + * @brief Sends an SDIO command with a short response expected. + * @note The CRC is not verified. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] cmd card command + * @param[in] arg command argument + * @param[out] resp pointer to the response buffer (one word) + * + * @return The operation status. + * @retval HAL_SUCCESS operation succeeded. + * @retval HAL_FAILED operation failed. + * + * @notapi + */ +bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, + uint32_t *resp) { + uint32_t sta; + + sdcp->sdmmc->ARG = arg; + sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN; + while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT | + SDMMC_STA_CCRCFAIL)) == 0) + ; + sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT | + SDMMC_STA_CCRCFAIL); + if ((sta & (SDMMC_STA_CTIMEOUT)) != 0) { + sdc_lld_collect_errors(sdcp, sta); + return HAL_FAILED; + } + *resp = sdcp->sdmmc->RESP1; + return HAL_SUCCESS; +} + +/** + * @brief Sends an SDIO command with a short response expected and CRC. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] cmd card command + * @param[in] arg command argument + * @param[out] resp pointer to the response buffer (one word) + * + * @return The operation status. + * @retval HAL_SUCCESS operation succeeded. + * @retval HAL_FAILED operation failed. + * + * @notapi + */ +bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, + uint32_t *resp) { + uint32_t sta; + + sdcp->sdmmc->ARG = arg; + sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN; + while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT | + SDMMC_STA_CCRCFAIL)) == 0) + ; + sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT | SDMMC_STA_CCRCFAIL); + if ((sta & (SDMMC_STA_CTIMEOUT | SDMMC_STA_CCRCFAIL)) != 0) { + sdc_lld_collect_errors(sdcp, sta); + return HAL_FAILED; + } + *resp = sdcp->sdmmc->RESP1; + return HAL_SUCCESS; +} + +/** + * @brief Sends an SDIO command with a long response expected and CRC. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] cmd card command + * @param[in] arg command argument + * @param[out] resp pointer to the response buffer (four words) + * + * @return The operation status. + * @retval HAL_SUCCESS operation succeeded. + * @retval HAL_FAILED operation failed. + * + * @notapi + */ +bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, + uint32_t *resp) { + uint32_t sta; + + (void)sdcp; + + sdcp->sdmmc->ARG = arg; + sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_WAITRESP_1 | + SDMMC_CMD_CPSMEN; + while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT | + SDMMC_STA_CCRCFAIL)) == 0) + ; + sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT | + SDMMC_STA_CCRCFAIL); + if ((sta & (SDMMC_STA_ERROR_MASK)) != 0) { + sdc_lld_collect_errors(sdcp, sta); + return HAL_FAILED; + } + /* Save bytes in reverse order because MSB in response comes first.*/ + *resp++ = sdcp->sdmmc->RESP4; + *resp++ = sdcp->sdmmc->RESP3; + *resp++ = sdcp->sdmmc->RESP2; + *resp = sdcp->sdmmc->RESP1; + return HAL_SUCCESS; +} + +/** + * @brief Reads special registers using data bus. + * @details Needs only during card detection procedure. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[out] buf pointer to the read buffer + * @param[in] bytes number of bytes to read + * @param[in] cmd card command + * @param[in] arg argument for command + * + * @return The operation status. + * @retval HAL_SUCCESS operation succeeded. + * @retval HAL_FAILED operation failed. + * + * @notapi + */ +bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes, + uint8_t cmd, uint32_t arg) { + uint32_t resp[1]; + + if(sdc_lld_prepare_read_bytes(sdcp, buf, bytes)) + goto error; + + if (sdc_lld_send_cmd_short_crc(sdcp, cmd, arg, resp) + || MMCSD_R1_ERROR(resp[0])) + goto error; + + if (sdc_lld_wait_transaction_end(sdcp, 1, resp)) + goto error; + + return HAL_SUCCESS; + +error: + sdc_lld_error_cleanup(sdcp, 1, resp); + return HAL_FAILED; +} + +/** + * @brief Reads one or more blocks. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to read + * @param[out] buf pointer to the read buffer + * @param[in] blocks number of blocks to read + * + * @return The operation status. + * @retval HAL_SUCCESS operation succeeded. + * @retval HAL_FAILED operation failed. + * + * @notapi + */ +bool sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk, + uint8_t *buf, uint32_t blocks) { + uint32_t resp[1]; + + osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE); + + sdcp->sdmmc->DTIMER = SDMMC_READ_TIMEOUT; + + /* Checks for errors and waits for the card to be ready for reading.*/ + if (_sdc_wait_for_transfer_state(sdcp)) + return HAL_FAILED; + + /* Prepares the DMA channel for writing.*/ + dmaStreamSetMemory0(sdcp->dma, buf); + dmaStreamSetTransactionSize(sdcp->dma, + (blocks * MMCSD_BLOCK_SIZE) / sizeof (uint32_t)); + dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M); + dmaStreamEnable(sdcp->dma); + + /* Setting up data transfer.*/ + sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS; + sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE | + SDMMC_MASK_DTIMEOUTIE | + SDMMC_MASK_RXOVERRIE | + SDMMC_MASK_DATAENDIE; + sdcp->sdmmc->DLEN = blocks * MMCSD_BLOCK_SIZE; + + /* Transaction starts just after DTEN bit setting.*/ + sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DTDIR | + SDMMC_DCTRL_DBLOCKSIZE_3 | + SDMMC_DCTRL_DBLOCKSIZE_0 | + SDMMC_DCTRL_DMAEN | + SDMMC_DCTRL_DTEN; + + if (sdc_lld_prepare_read(sdcp, startblk, blocks, resp) == TRUE) + goto error; + + if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == TRUE) + goto error; + + return HAL_SUCCESS; + +error: + sdc_lld_error_cleanup(sdcp, blocks, resp); + return HAL_FAILED; +} + +/** + * @brief Writes one or more blocks. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to write + * @param[out] buf pointer to the write buffer + * @param[in] n number of blocks to write + * + * @return The operation status. + * @retval HAL_SUCCESS operation succeeded. + * @retval HAL_FAILED operation failed. + * + * @notapi + */ +bool sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk, + const uint8_t *buf, uint32_t blocks) { + uint32_t resp[1]; + + osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE); + + sdcp->sdmmc->DTIMER = SDMMC_WRITE_TIMEOUT; + + /* Checks for errors and waits for the card to be ready for writing.*/ + if (_sdc_wait_for_transfer_state(sdcp)) + return HAL_FAILED; + + /* Prepares the DMA channel for writing.*/ + dmaStreamSetMemory0(sdcp->dma, buf); + dmaStreamSetTransactionSize(sdcp->dma, + (blocks * MMCSD_BLOCK_SIZE) / sizeof (uint32_t)); + dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_M2P); + dmaStreamEnable(sdcp->dma); + + /* Setting up data transfer.*/ + sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS; + sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE | + SDMMC_MASK_DTIMEOUTIE | + SDMMC_MASK_TXUNDERRIE | + SDMMC_MASK_DATAENDIE; + sdcp->sdmmc->DLEN = blocks * MMCSD_BLOCK_SIZE; + + /* Talk to card what we want from it.*/ + if (sdc_lld_prepare_write(sdcp, startblk, blocks, resp) == TRUE) + goto error; + + /* Transaction starts just after DTEN bit setting.*/ + sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DBLOCKSIZE_3 | + SDMMC_DCTRL_DBLOCKSIZE_0 | + SDMMC_DCTRL_DMAEN | + SDMMC_DCTRL_DTEN; + + if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == TRUE) + goto error; + + return HAL_SUCCESS; + +error: + sdc_lld_error_cleanup(sdcp, blocks, resp); + return HAL_FAILED; +} + +/** + * @brief Reads one or more blocks. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to read + * @param[out] buf pointer to the read buffer + * @param[in] blocks number of blocks to read + * + * @return The operation status. + * @retval HAL_SUCCESS operation succeeded. + * @retval HAL_FAILED operation failed. + * + * @notapi + */ +bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, + uint8_t *buf, uint32_t blocks) { + +#if STM32_SDC_SDMMC_UNALIGNED_SUPPORT + if (((unsigned)buf & 3) != 0) { + uint32_t i; + for (i = 0; i < blocks; i++) { + if (sdc_lld_read_aligned(sdcp, startblk, u.buf, 1)) + return HAL_FAILED; + memcpy(buf, u.buf, MMCSD_BLOCK_SIZE); + buf += MMCSD_BLOCK_SIZE; + startblk++; + } + return HAL_SUCCESS; + } +#endif /* STM32_SDC_SDMMC_UNALIGNED_SUPPORT */ + return sdc_lld_read_aligned(sdcp, startblk, buf, blocks); +} + +/** + * @brief Writes one or more blocks. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to write + * @param[out] buf pointer to the write buffer + * @param[in] blocks number of blocks to write + * + * @return The operation status. + * @retval HAL_SUCCESS operation succeeded. + * @retval HAL_FAILED operation failed. + * + * @notapi + */ +bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, + const uint8_t *buf, uint32_t blocks) { + +#if STM32_SDC_SDMMC_UNALIGNED_SUPPORT + if (((unsigned)buf & 3) != 0) { + uint32_t i; + for (i = 0; i < blocks; i++) { + memcpy(u.buf, buf, MMCSD_BLOCK_SIZE); + buf += MMCSD_BLOCK_SIZE; + if (sdc_lld_write_aligned(sdcp, startblk, u.buf, 1)) + return HAL_FAILED; + startblk++; + } + return HAL_SUCCESS; + } +#endif /* STM32_SDC_SDMMC_UNALIGNED_SUPPORT */ + return sdc_lld_write_aligned(sdcp, startblk, buf, blocks); +} + +/** + * @brief Waits for card idle condition. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @return The operation status. + * @retval HAL_SUCCESS the operation succeeded. + * @retval HAL_FAILED the operation failed. + * + * @api + */ +bool sdc_lld_sync(SDCDriver *sdcp) { + + /* TODO: Implement.*/ + (void)sdcp; + return HAL_SUCCESS; +} + +#endif /* HAL_USE_SDC */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.h b/os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.h new file mode 100644 index 000000000..66a423362 --- /dev/null +++ b/os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.h @@ -0,0 +1,266 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file STM32/SDMMCv1/sdc_lld.h + * @brief STM32 SDC subsystem low level driver header. + * + * @addtogroup SDC + * @{ + */ + +#ifndef _SDC_LLD_H_ +#define _SDC_LLD_H_ + +#if HAL_USE_SDC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Support for unaligned transfers. + * @note Unaligned transfers are much slower. + */ +#if !defined(STM32_SDC_SDMMC_UNALIGNED_SUPPORT) || defined(__DOXYGEN__) +#define STM32_SDC_SDMMC_UNALIGNED_SUPPORT TRUE +#endif + +/** + * @brief Write timeout in milliseconds. + */ +#if !defined(STM32_SDC_SDMMC_WRITE_TIMEOUT) || defined(__DOXYGEN__) +#define STM32_SDC_SDMMC_WRITE_TIMEOUT 250 +#endif + +/** + * @brief Read timeout in milliseconds. + */ +#if !defined(STM32_SDC_SDMMC_READ_TIMEOUT) || defined(__DOXYGEN__) +#define STM32_SDC_SDMMC_READ_TIMEOUT 25 +#endif + +/** + * @brief Card clock activation delay in milliseconds. + */ +#if !defined(STM32_SDC_SDMMC_CLOCK_DELAY) || defined(__DOXYGEN__) +#define STM32_SDC_SDMMC_CLOCK_DELAY 10 +#endif + +/** + * @brief SDMMC1 DMA priority (0..3|lowest..highest). + */ +#if !defined(STM32_SDC_SDMMC1_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SDC_SDMMC1_DMA_PRIORITY 3 +#endif + +/** + * @brief SDMMC1 interrupt priority level setting. + */ +#if !defined(STM32_SDC_SDMMC1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SDC_SDMMC1_IRQ_PRIORITY 9 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if STM32_SDC_USE_SDMMC1 && !STM32_HAS_SDMMC1 +#error "SDMMC1 not present in the selected device" +#endif + +#if !STM32_SDC_USE_SDMMC1 +#error "SDC driver activated but no SDMMC peripheral assigned" +#endif + +#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SDC_SDMMC1_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SDIO" +#endif + +#if !STM32_DMA_IS_VALID_PRIORITY(STM32_SDC_SDMMC1_DMA_PRIORITY) +#error "Invalid DMA priority assigned to SDIO" +#endif + +/* Check on the presence of the DMA streams settings in mcuconf.h.*/ +#if !defined(STM32_SDC_SDMMC1_DMA_STREAM) +#error "SDMMC1 DMA streams not defined" +#endif + +/* Check on the validity of the assigned DMA channels.*/ +#if !STM32_DMA_IS_VALID_ID(STM32_SDC_SDMMC1_DMA_STREAM, STM32_SDC_SDMMC1_DMA_MSK) +#error "invalid DMA stream associated to SDMMC1" +#endif + +#if !defined(STM32_DMA_REQUIRED) +#define STM32_DMA_REQUIRED +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of card flags. + */ +typedef uint32_t sdcmode_t; + +/** + * @brief SDC Driver condition flags type. + */ +typedef uint32_t sdcflags_t; + +/** + * @brief Type of a structure representing an SDC driver. + */ +typedef struct SDCDriver SDCDriver; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /** + * @brief Working area for memory consuming operations. + * @note Buffer must be word aligned and big enough to store 512 bytes. + * @note It is mandatory for detecting MMC cards bigger than 2GB else it + * can be @p NULL. SD cards do NOT need it. + * @note Memory pointed by this buffer is only used by @p sdcConnect(), + * afterward it can be reused for other purposes. + */ + uint8_t *scratchpad; + /** + * @brief Bus width. + */ + sdcbusmode_t bus_width; + /* End of the mandatory fields.*/ +} SDCConfig; + +/** + * @brief @p SDCDriver specific methods. + */ +#define _sdc_driver_methods \ + _mmcsd_block_device_methods + +/** + * @extends MMCSDBlockDeviceVMT + * + * @brief @p SDCDriver virtual methods table. + */ +struct SDCDriverVMT { + _sdc_driver_methods +}; + +/** + * @brief Structure representing an SDC driver. + */ +struct SDCDriver { + /** + * @brief Virtual Methods Table. + */ + const struct SDCDriverVMT *vmt; + _mmcsd_block_device_data + /** + * @brief Current configuration data. + */ + const SDCConfig *config; + /** + * @brief Various flags regarding the mounted card. + */ + sdcmode_t cardmode; + /** + * @brief Errors flags. + */ + sdcflags_t errors; + /** + * @brief Card RCA. + */ + uint32_t rca; + /* End of the mandatory fields.*/ + /** + * @brief Thread waiting for I/O completion IRQ. + */ + thread_reference_t thread; + /** + * @brief DMA mode bit mask. + */ + uint32_t dmamode; + /** + * @brief Transmit DMA channel. + */ + const stm32_dma_stream_t *dma; + /** + * @brief Pointer to the SDMMC registers block. + * @note Needed for debugging aid. + */ + SDMMC_TypeDef *sdmmc; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern SDCDriver SDCD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void sdc_lld_init(void); + void sdc_lld_start(SDCDriver *sdcp); + void sdc_lld_stop(SDCDriver *sdcp); + void sdc_lld_start_clk(SDCDriver *sdcp); + void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk); + void sdc_lld_stop_clk(SDCDriver *sdcp); + void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode); + void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg); + bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, + uint32_t *resp); + bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, + uint32_t *resp); + bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, + uint32_t *resp); + bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes, + uint8_t cmd, uint32_t argument); + bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, + uint8_t *buf, uint32_t blocks); + bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, + const uint8_t *buf, uint32_t blocks); + bool sdc_lld_sync(SDCDriver *sdcp); + bool sdc_lld_is_card_inserted(SDCDriver *sdcp); + bool sdc_lld_is_write_protected(SDCDriver *sdcp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_SDC */ + +#endif /* _SDC_LLD_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F7xx/platform.mk b/os/hal/ports/STM32/STM32F7xx/platform.mk index 4161dab50..1be54100f 100644 --- a/os/hal/ports/STM32/STM32F7xx/platform.mk +++ b/os/hal/ports/STM32/STM32F7xx/platform.mk @@ -38,7 +38,7 @@ ifneq ($(findstring HAL_USE_I2S TRUE,$(HALCONF)),) PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/i2s_lld.c endif ifneq ($(findstring HAL_USE_SDC TRUE,$(HALCONF)),) -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDIOv1/sdc_lld.c +PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.c endif ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),) PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c @@ -72,7 +72,7 @@ PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \ $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv1/mac_lld.c \ $(CHIBIOS)/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c \ $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/rtc_lld.c \ - $(CHIBIOS)/os/hal/ports/STM32/LLD/SDIOv1/sdc_lld.c \ + $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.c \ $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/i2s_lld.c \ $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c \ $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/gpt_lld.c \ @@ -96,7 +96,7 @@ PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \ $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv1 \ $(CHIBIOS)/os/hal/ports/STM32/LLD/OTGv1 \ $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2 \ - $(CHIBIOS)/os/hal/ports/STM32/LLD/SDIOv1 \ + $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1 \ $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2 \ $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1 \ $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2 diff --git a/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h b/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h index 49e9c63f1..ee504200a 100644 --- a/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h +++ b/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h @@ -531,7 +531,6 @@ */ /** * @brief Enables the ETH peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -543,7 +542,6 @@ /** * @brief Disables the ETH peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -740,36 +738,33 @@ /** @} */ /** - * @name SDIO peripheral specific RCC operations + * @name SDMMC peripheral specific RCC operations * @{ */ /** - * @brief Enables the SDIO peripheral clock. - * @note The @p lp parameter is ignored in this family. + * @brief Enables the SDMMC1 peripheral clock. * * @param[in] lp low power enable flag * * @api */ -#define rccEnableSDIO(lp) rccEnableAPB2(RCC_APB2ENR_SDIOEN, lp) +#define rccEnableSDMMC1(lp) rccEnableAPB2(RCC_APB2ENR_SDMMC1EN, lp) /** - * @brief Disables the SDIO peripheral clock. - * @note The @p lp parameter is ignored in this family. + * @brief Disables the SDMMC1 peripheral clock. * * @param[in] lp low power enable flag * * @api */ -#define rccDisableSDIO(lp) rccDisableAPB2(RCC_APB2ENR_SDIOEN, lp) +#define rccDisableSDMMC1(lp) rccDisableAPB2(RCC_APB2ENR_SDMMC1EN, lp) /** - * @brief Resets the SDIO peripheral. - * @note Not supported in this family, does nothing. + * @brief Resets the SDMMC1 peripheral. * * @api */ -#define rccResetSDIO() rccResetAPB2(RCC_APB2RSTR_SDIORST) +#define rccResetSDMMC1() rccResetAPB2(RCC_APB2RSTR_SDMMC1RST) /** @} */ /** @@ -933,7 +928,6 @@ */ /** * @brief Enables the TIM1 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -943,7 +937,6 @@ /** * @brief Disables the TIM1 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1035,7 +1028,6 @@ /** * @brief Enables the TIM5 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1045,7 +1037,6 @@ /** * @brief Disables the TIM5 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1062,7 +1053,6 @@ /** * @brief Enables the TIM6 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1072,7 +1062,6 @@ /** * @brief Disables the TIM6 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1089,7 +1078,6 @@ /** * @brief Enables the TIM7 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1099,7 +1087,6 @@ /** * @brief Disables the TIM7 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1116,7 +1103,6 @@ /** * @brief Enables the TIM8 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1126,7 +1112,6 @@ /** * @brief Disables the TIM8 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1143,7 +1128,6 @@ /** * @brief Enables the TIM9peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1153,7 +1137,6 @@ /** * @brief Disables the TIM9 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1170,7 +1153,6 @@ /** * @brief Enables the TIM10 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1180,7 +1162,6 @@ /** * @brief Disables the TIM10 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1197,7 +1178,6 @@ /** * @brief Enables the TIM11 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1207,7 +1187,6 @@ /** * @brief Disables the TIM11 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1224,7 +1203,6 @@ /** * @brief Enables the TIM12 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1234,7 +1212,6 @@ /** * @brief Disables the TIM12 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1251,7 +1228,6 @@ /** * @brief Enables the TIM13 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1261,7 +1237,6 @@ /** * @brief Disables the TIM13 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1278,7 +1253,6 @@ /** * @brief Enables the TIM14 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1288,7 +1262,6 @@ /** * @brief Disables the TIM14 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1385,7 +1358,6 @@ /** * @brief Enables the UART4 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1395,7 +1367,6 @@ /** * @brief Disables the UART4 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1412,7 +1383,6 @@ /** * @brief Enables the UART5 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1422,7 +1392,6 @@ /** * @brief Disables the UART5 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1464,7 +1433,6 @@ /** * @brief Enables the UART7 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1474,7 +1442,6 @@ /** * @brief Disables the UART7 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1491,7 +1458,6 @@ /** * @brief Enables the UART8 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * @@ -1501,7 +1467,6 @@ /** * @brief Disables the UART8 peripheral clock. - * @note The @p lp parameter is ignored in this family. * * @param[in] lp low power enable flag * diff --git a/os/hal/ports/STM32/STM32F7xx/stm32_registry.h b/os/hal/ports/STM32/STM32F7xx/stm32_registry.h index ff317028c..ed4e185b6 100644 --- a/os/hal/ports/STM32/STM32F7xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32F7xx/stm32_registry.h @@ -222,13 +222,13 @@ #define STM32_RTC_NUM_ALARMS 2 #define STM32_RTC_HAS_INTERRUPTS FALSE -/* SDIO attributes.*/ -#define STM32_HAS_SDIO TRUE -#define STM32_SDIO_HANDLER Vector104 -#define STM32_SDIO_NUMBER 49 -#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ +/* SDMMC attributes.*/ +#define STM32_HAS_SDMMC1 TRUE +#define STM32_SDMMC1_HANDLER Vector104 +#define STM32_SDMMC1_NUMBER 49 +#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ STM32_DMA_STREAM_ID_MSK(2, 6)) -#define STM32_SDC_SDIO_DMA_CHN 0x04004000 +#define STM32_SDC_SDMMC1_DMA_CHN 0x04004000 /* SPI attributes.*/ #define STM32_HAS_SPI1 TRUE diff --git a/testhal/STM32/STM32F7xx/GPT-ADC/mcuconf.h b/testhal/STM32/STM32F7xx/GPT-ADC/mcuconf.h index dad6a515f..70c6129b9 100644 --- a/testhal/STM32/STM32F7xx/GPT-ADC/mcuconf.h +++ b/testhal/STM32/STM32F7xx/GPT-ADC/mcuconf.h @@ -252,13 +252,14 @@ /* * SDC driver system settings. */ -#define STM32_SDC_SDIO_DMA_PRIORITY 3 -#define STM32_SDC_SDIO_IRQ_PRIORITY 9 -#define STM32_SDC_WRITE_TIMEOUT_MS 250 -#define STM32_SDC_READ_TIMEOUT_MS 25 -#define STM32_SDC_CLOCK_ACTIVATION_DELAY 10 -#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE -#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SDC_USE_SDMMC1 FALSE +#define STM32_SDC_SDMMC_UNALIGNED_SUPPORT TRUE +#define STM32_SDC_SDMMC_WRITE_TIMEOUT 250 +#define STM32_SDC_SDMMC_READ_TIMEOUT 25 +#define STM32_SDC_SDMMC_CLOCK_DELAY 10 +#define STM32_SDC_SDMMC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SDC_SDMMC1_DMA_PRIORITY 3 +#define STM32_SDC_SDMMC1_IRQ_PRIORITY 9 /* * SERIAL driver system settings. diff --git a/testhal/STM32/STM32F7xx/PWM-ICU/mcuconf.h b/testhal/STM32/STM32F7xx/PWM-ICU/mcuconf.h index 5678eaca6..26d0b4a67 100644 --- a/testhal/STM32/STM32F7xx/PWM-ICU/mcuconf.h +++ b/testhal/STM32/STM32F7xx/PWM-ICU/mcuconf.h @@ -252,13 +252,14 @@ /* * SDC driver system settings. */ -#define STM32_SDC_SDIO_DMA_PRIORITY 3 -#define STM32_SDC_SDIO_IRQ_PRIORITY 9 -#define STM32_SDC_WRITE_TIMEOUT_MS 250 -#define STM32_SDC_READ_TIMEOUT_MS 25 -#define STM32_SDC_CLOCK_ACTIVATION_DELAY 10 -#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE -#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SDC_USE_SDMMC1 FALSE +#define STM32_SDC_SDMMC_UNALIGNED_SUPPORT TRUE +#define STM32_SDC_SDMMC_WRITE_TIMEOUT 250 +#define STM32_SDC_SDMMC_READ_TIMEOUT 25 +#define STM32_SDC_SDMMC_CLOCK_DELAY 10 +#define STM32_SDC_SDMMC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SDC_SDMMC1_DMA_PRIORITY 3 +#define STM32_SDC_SDMMC1_IRQ_PRIORITY 9 /* * SERIAL driver system settings. diff --git a/testhal/STM32/STM32F7xx/SPI/mcuconf.h b/testhal/STM32/STM32F7xx/SPI/mcuconf.h index 9a7ac538a..add76b7b4 100644 --- a/testhal/STM32/STM32F7xx/SPI/mcuconf.h +++ b/testhal/STM32/STM32F7xx/SPI/mcuconf.h @@ -252,13 +252,14 @@ /* * SDC driver system settings. */ -#define STM32_SDC_SDIO_DMA_PRIORITY 3 -#define STM32_SDC_SDIO_IRQ_PRIORITY 9 -#define STM32_SDC_WRITE_TIMEOUT_MS 250 -#define STM32_SDC_READ_TIMEOUT_MS 25 -#define STM32_SDC_CLOCK_ACTIVATION_DELAY 10 -#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE -#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SDC_USE_SDMMC1 FALSE +#define STM32_SDC_SDMMC_UNALIGNED_SUPPORT TRUE +#define STM32_SDC_SDMMC_WRITE_TIMEOUT 250 +#define STM32_SDC_SDMMC_READ_TIMEOUT 25 +#define STM32_SDC_SDMMC_CLOCK_DELAY 10 +#define STM32_SDC_SDMMC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SDC_SDMMC1_DMA_PRIORITY 3 +#define STM32_SDC_SDMMC1_IRQ_PRIORITY 9 /* * SERIAL driver system settings. diff --git a/testhal/STM32/STM32F7xx/USB_CDC/mcuconf.h b/testhal/STM32/STM32F7xx/USB_CDC/mcuconf.h index 5eae8dff9..9ff367c02 100644 --- a/testhal/STM32/STM32F7xx/USB_CDC/mcuconf.h +++ b/testhal/STM32/STM32F7xx/USB_CDC/mcuconf.h @@ -252,13 +252,14 @@ /* * SDC driver system settings. */ -#define STM32_SDC_SDIO_DMA_PRIORITY 3 -#define STM32_SDC_SDIO_IRQ_PRIORITY 9 -#define STM32_SDC_WRITE_TIMEOUT_MS 250 -#define STM32_SDC_READ_TIMEOUT_MS 25 -#define STM32_SDC_CLOCK_ACTIVATION_DELAY 10 -#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE -#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SDC_USE_SDMMC1 FALSE +#define STM32_SDC_SDMMC_UNALIGNED_SUPPORT TRUE +#define STM32_SDC_SDMMC_WRITE_TIMEOUT 250 +#define STM32_SDC_SDMMC_READ_TIMEOUT 25 +#define STM32_SDC_SDMMC_CLOCK_DELAY 10 +#define STM32_SDC_SDMMC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SDC_SDMMC1_DMA_PRIORITY 3 +#define STM32_SDC_SDMMC1_IRQ_PRIORITY 9 /* * SERIAL driver system settings.