aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2015-09-17 13:38:08 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2015-09-17 13:38:08 +0000
commitdfc15ba56d3529d12d5d2806dfe1280250438649 (patch)
tree8b017350650c5bc7651a114ffee4080bdd65c09e /os/hal/ports
parent8a84310d9db0ccdfafe6e83babb2a264634dec5c (diff)
downloadChibiOS-dfc15ba56d3529d12d5d2806dfe1280250438649.tar.gz
ChibiOS-dfc15ba56d3529d12d5d2806dfe1280250438649.tar.bz2
ChibiOS-dfc15ba56d3529d12d5d2806dfe1280250438649.zip
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
Diffstat (limited to 'os/hal/ports')
-rw-r--r--os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.c889
-rw-r--r--os/hal/ports/STM32/LLD/SDMMCv1/sdc_lld.h266
-rw-r--r--os/hal/ports/STM32/STM32F7xx/platform.mk6
-rw-r--r--os/hal/ports/STM32/STM32F7xx/stm32_rcc.h49
-rw-r--r--os/hal/ports/STM32/STM32F7xx/stm32_registry.h12
5 files changed, 1171 insertions, 51 deletions
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 <string.h>
+
+#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