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
This commit is contained in:
Giovanni Di Sirio 2015-09-17 13:38:08 +00:00
parent 8a84310d9d
commit dfc15ba56d
13 changed files with 1221 additions and 95 deletions

View File

@ -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
/**

View File

@ -663,7 +663,7 @@ int main(void) {
* configuration.
*/
sdStart(&SD1, NULL);
// sdcStart(&SDCD1, NULL);
sdcStart(&SDCD1, NULL);
/*
* Activates the card insertion monitor.

View File

@ -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.

View File

@ -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.

View File

@ -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 */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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

View File

@ -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
*

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.