mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-16 04:45:24 +03:00
Add PG for 4Bit SDIO, fix whitespaces.
This commit is contained in:
parent
aa8d6b3676
commit
cdb4c1ef44
5 changed files with 399 additions and 352 deletions
|
@ -269,17 +269,17 @@ void SDIO_DMA_ST6_IRQHandler(dmaChannelDescriptor_t *dma);
|
|||
*/
|
||||
bool SD_IsDetected(void)
|
||||
{
|
||||
__IO uint8_t status = SD_PRESENT;
|
||||
__IO uint8_t status = SD_PRESENT;
|
||||
|
||||
/*!< Check GPIO to detect SD */
|
||||
#ifdef SDCARD_DETECT_PIN
|
||||
const IO_t sd_det = IOGetByTag(IO_TAG(SDCARD_DETECT_PIN));
|
||||
if (IORead(sd_det) != 0)
|
||||
{
|
||||
status = SD_NOT_PRESENT;
|
||||
}
|
||||
#endif
|
||||
return status;
|
||||
/*!< Check GPIO to detect SD */
|
||||
#ifdef SDCARD_DETECT_PIN
|
||||
const IO_t sd_det = IOGetByTag(IO_TAG(SDCARD_DETECT_PIN));
|
||||
if (IORead(sd_det) != 0)
|
||||
{
|
||||
status = SD_NOT_PRESENT;
|
||||
}
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -341,8 +341,11 @@ static SD_Error_t SD_CmdResponse(uint8_t SD_CMD, int8_t ResponseType)
|
|||
uint32_t TimeOut;
|
||||
uint32_t Flag;
|
||||
|
||||
if(ResponseType == -1) Flag = SDIO_STA_CMDSENT;
|
||||
else Flag = SDIO_STA_CCRCFAIL | SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT;
|
||||
if(ResponseType == -1) {
|
||||
Flag = SDIO_STA_CMDSENT;
|
||||
} else {
|
||||
Flag = SDIO_STA_CCRCFAIL | SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT;
|
||||
}
|
||||
|
||||
TimeOut = SD_SOFTWARE_COMMAND_TIMEOUT;
|
||||
do
|
||||
|
@ -354,20 +357,34 @@ static SD_Error_t SD_CmdResponse(uint8_t SD_CMD, int8_t ResponseType)
|
|||
|
||||
if(ResponseType <= 0)
|
||||
{
|
||||
if(TimeOut == 0) return SD_CMD_RSP_TIMEOUT;
|
||||
else return SD_OK;
|
||||
if(TimeOut == 0) {
|
||||
return SD_CMD_RSP_TIMEOUT;
|
||||
} else {
|
||||
return SD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if((SDIO->STA & SDIO_STA_CTIMEOUT) != 0) return SD_CMD_RSP_TIMEOUT;
|
||||
if((SDIO->STA & SDIO_STA_CTIMEOUT) != 0) {
|
||||
return SD_CMD_RSP_TIMEOUT;
|
||||
}
|
||||
if(ResponseType == 3)
|
||||
{
|
||||
if(TimeOut == 0) return SD_CMD_RSP_TIMEOUT; // Card is not V2.0 compliant or card does not support the set voltage range
|
||||
else return SD_OK; // Card is SD V2.0 compliant
|
||||
if(TimeOut == 0) {
|
||||
return SD_CMD_RSP_TIMEOUT; // Card is not V2.0 compliant or card does not support the set voltage range
|
||||
} else {
|
||||
return SD_OK; // Card is SD V2.0 compliant
|
||||
}
|
||||
}
|
||||
|
||||
if((SDIO->STA & SDIO_STA_CCRCFAIL) != 0) return SD_CMD_CRC_FAIL;
|
||||
if(ResponseType == 2) return SD_OK;
|
||||
if((uint8_t)SDIO->RESPCMD != SD_CMD) return SD_ILLEGAL_CMD; // Check if response is of desired command
|
||||
if((SDIO->STA & SDIO_STA_CCRCFAIL) != 0) {
|
||||
return SD_CMD_CRC_FAIL;
|
||||
}
|
||||
if(ResponseType == 2) {
|
||||
return SD_OK;
|
||||
}
|
||||
if((uint8_t)SDIO->RESPCMD != SD_CMD) {
|
||||
return SD_ILLEGAL_CMD; // Check if response is of desired command
|
||||
}
|
||||
|
||||
Response_R1 = SDIO->RESP1; // We have received response, retrieve it for analysis
|
||||
|
||||
|
@ -381,9 +398,15 @@ static SD_Error_t SD_CmdResponse(uint8_t SD_CMD, int8_t ResponseType)
|
|||
{
|
||||
SD_CardRCA = Response_R1;
|
||||
}
|
||||
if((Response_R1 & SD_R6_GENERAL_UNKNOWN_ERROR) == SD_R6_GENERAL_UNKNOWN_ERROR) return SD_GENERAL_UNKNOWN_ERROR;
|
||||
if((Response_R1 & SD_R6_ILLEGAL_CMD) == SD_R6_ILLEGAL_CMD) return SD_ILLEGAL_CMD;
|
||||
if((Response_R1 & SD_R6_COM_CRC_FAILED) == SD_R6_COM_CRC_FAILED) return SD_COM_CRC_FAILED;
|
||||
if((Response_R1 & SD_R6_GENERAL_UNKNOWN_ERROR) == SD_R6_GENERAL_UNKNOWN_ERROR) {
|
||||
return SD_GENERAL_UNKNOWN_ERROR;
|
||||
}
|
||||
if((Response_R1 & SD_R6_ILLEGAL_CMD) == SD_R6_ILLEGAL_CMD) {
|
||||
return SD_ILLEGAL_CMD;
|
||||
}
|
||||
if((Response_R1 & SD_R6_COM_CRC_FAILED) == SD_R6_COM_CRC_FAILED) {
|
||||
return SD_COM_CRC_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return SD_OK;
|
||||
|
@ -446,26 +469,26 @@ static void SD_GetResponse(uint32_t* pResponse)
|
|||
static void SD_DMA_Complete(DMA_Stream_TypeDef* pDMA_Stream)
|
||||
{
|
||||
if (SD_Handle.RXCplt) {
|
||||
if (SD_Handle.Operation == ((SDIO_DIR_RX << 1) | SD_MULTIPLE_BLOCK)) {
|
||||
/* Send stop command in multiblock write */
|
||||
SD_TransmitCommand((SD_CMD_STOP_TRANSMISSION | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
if (SD_Handle.Operation == ((SDIO_DIR_RX << 1) | SD_MULTIPLE_BLOCK)) {
|
||||
/* Send stop command in multiblock write */
|
||||
SD_TransmitCommand((SD_CMD_STOP_TRANSMISSION | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
|
||||
/* Disable the DMA transfer for transmit request by setting the DMAEN bit
|
||||
in the SD DCTRL register */
|
||||
SDIO->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
|
||||
/* Disable the DMA transfer for transmit request by setting the DMAEN bit
|
||||
in the SD DCTRL register */
|
||||
SDIO->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
|
||||
|
||||
/* Clear all the static flags */
|
||||
SDIO->ICR = SDIO_ICR_STATIC_FLAGS;
|
||||
/* Clear all the static flags */
|
||||
SDIO->ICR = SDIO_ICR_STATIC_FLAGS;
|
||||
|
||||
/* Clear flag */
|
||||
SD_Handle.RXCplt = 0;
|
||||
/* Clear flag */
|
||||
SD_Handle.RXCplt = 0;
|
||||
|
||||
/* Disable the stream */
|
||||
pDMA_Stream->CR &= ~DMA_SxCR_EN;
|
||||
/* Disable the stream */
|
||||
pDMA_Stream->CR &= ~DMA_SxCR_EN;
|
||||
} else {
|
||||
/* Enable Dataend IE */
|
||||
SDIO->MASK |= SDIO_MASK_DATAENDIE;
|
||||
/* Enable Dataend IE */
|
||||
SDIO->MASK |= SDIO_MASK_DATAENDIE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -536,7 +559,7 @@ static SD_Error_t SD_InitializeCard(void)
|
|||
*/
|
||||
static void SD_StartBlockTransfert(uint32_t* pBuffer, uint32_t BlockSize, uint32_t NumberOfBlocks, uint8_t dir)
|
||||
{
|
||||
DMA_Stream_TypeDef *pDMA = dma_stream;
|
||||
DMA_Stream_TypeDef *pDMA = dma_stream;
|
||||
|
||||
SDIO->DCTRL = 0; // Initialize data control register
|
||||
SD_Handle.TransferComplete = 0; // Initialize handle flags
|
||||
|
@ -551,31 +574,31 @@ static void SD_StartBlockTransfert(uint32_t* pBuffer, uint32_t BlockSize, uint32
|
|||
SDIO->MASK |= (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | // Enable transfer interrupts
|
||||
SDIO_MASK_TXUNDERRIE);
|
||||
}
|
||||
if (dir == SDIO_DIR_TX) {
|
||||
SDIO->DCTRL |= SDIO_DCTRL_DMAEN; // Enable SDIO DMA transfer
|
||||
}
|
||||
if (dir == SDIO_DIR_TX) {
|
||||
SDIO->DCTRL |= SDIO_DCTRL_DMAEN; // Enable SDIO DMA transfer
|
||||
}
|
||||
pDMA->CR &= ~DMA_SxCR_EN; // Disable the Peripheral
|
||||
while (pDMA->CR & DMA_SxCR_EN);
|
||||
pDMA->NDTR = (uint32_t) (BlockSize * NumberOfBlocks) / 4; // Configure DMA Stream data length
|
||||
pDMA->M0AR = (uint32_t) pBuffer; // Configure DMA Stream memory address
|
||||
if (dir == SDIO_DIR_RX) {
|
||||
pDMA->CR &= ~(0x01U << 6U); // Sets peripheral to memory
|
||||
} else {
|
||||
pDMA->CR |= DMA_MEMORY_TO_PERIPH; // Sets memory to peripheral
|
||||
}
|
||||
if (dma_stream == DMA2_Stream3) {
|
||||
DMA2->LIFCR = DMA_LIFCR_CTEIF3 | DMA_LIFCR_CDMEIF3 |
|
||||
DMA_LIFCR_CFEIF3 | DMA_LIFCR_CHTIF3 | DMA_LIFCR_CTCIF3; // Clear the transfer error flag
|
||||
if (dir == SDIO_DIR_RX) {
|
||||
pDMA->CR &= ~(0x01U << 6U); // Sets peripheral to memory
|
||||
} else {
|
||||
DMA2->HIFCR = DMA_HIFCR_CTEIF6 | DMA_HIFCR_CDMEIF6 |
|
||||
DMA_HIFCR_CFEIF6 | DMA_HIFCR_CHTIF6 | DMA_HIFCR_CTCIF6; // Clear the transfer error flag
|
||||
pDMA->CR |= DMA_MEMORY_TO_PERIPH; // Sets memory to peripheral
|
||||
}
|
||||
if (dma_stream == DMA2_Stream3) {
|
||||
DMA2->LIFCR = DMA_LIFCR_CTEIF3 | DMA_LIFCR_CDMEIF3 |
|
||||
DMA_LIFCR_CFEIF3 | DMA_LIFCR_CHTIF3 | DMA_LIFCR_CTCIF3; // Clear the transfer error flag
|
||||
} else {
|
||||
DMA2->HIFCR = DMA_HIFCR_CTEIF6 | DMA_HIFCR_CDMEIF6 |
|
||||
DMA_HIFCR_CFEIF6 | DMA_HIFCR_CHTIF6 | DMA_HIFCR_CTCIF6; // Clear the transfer error flag
|
||||
}
|
||||
pDMA->CR |= DMA_SxCR_TCIE | DMA_SxCR_HTIE | DMA_SxCR_TEIE | DMA_SxCR_DMEIE; // Enable all interrupts
|
||||
pDMA->FCR |= DMA_SxFCR_FEIE;
|
||||
pDMA->CR |= DMA_SxCR_EN; // Enable the Peripheral
|
||||
if (dir == SDIO_DIR_RX) {
|
||||
SDIO->DCTRL |= SDIO_DCTRL_DMAEN; // Enable SDIO DMA transfer
|
||||
}
|
||||
if (dir == SDIO_DIR_RX) {
|
||||
SDIO->DCTRL |= SDIO_DCTRL_DMAEN; // Enable SDIO DMA transfer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -608,7 +631,7 @@ SD_Error_t SD_ReadBlocks_DMA(uint64_t ReadAddress, uint32_t *buffer, uint32_t Bl
|
|||
SD_StartBlockTransfert(buffer, BlockSize, NumberOfBlocks, SDIO_DIR_RX);
|
||||
|
||||
// Configure the SD DPSM (Data Path State Machine)
|
||||
SD_DataTransferInit(BlockSize * NumberOfBlocks, SD_DATABLOCK_SIZE_512B, true);
|
||||
SD_DataTransferInit(BlockSize * NumberOfBlocks, SD_DATABLOCK_SIZE_512B, true);
|
||||
|
||||
// Set Block Size for Card
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_SET_BLOCKLEN | SD_CMD_RESPONSE_SHORT), BlockSize, 1);
|
||||
|
@ -618,14 +641,14 @@ SD_Error_t SD_ReadBlocks_DMA(uint64_t ReadAddress, uint32_t *buffer, uint32_t Bl
|
|||
uint8_t retries = 10;
|
||||
CmdIndex = (NumberOfBlocks > 1) ? SD_CMD_READ_MULT_BLOCK : SD_CMD_READ_SINGLE_BLOCK;
|
||||
do {
|
||||
ErrorState = SD_TransmitCommand((CmdIndex | SD_CMD_RESPONSE_SHORT), (uint32_t)ReadAddress, 1);
|
||||
if (ErrorState != SD_OK && retries--) {
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
ErrorState = SD_TransmitCommand((CmdIndex | SD_CMD_RESPONSE_SHORT), (uint32_t)ReadAddress, 1);
|
||||
if (ErrorState != SD_OK && retries--) {
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
} while (ErrorState != SD_OK && retries);
|
||||
|
||||
if (ErrorState != SD_OK) {
|
||||
SD_Handle.RXCplt = 0;
|
||||
SD_Handle.RXCplt = 0;
|
||||
}
|
||||
|
||||
// Update the SD transfer error in SD handle
|
||||
|
@ -669,21 +692,21 @@ SD_Error_t SD_WriteBlocks_DMA(uint64_t WriteAddress, uint32_t *buffer, uint32_t
|
|||
// Set Block Size for Card
|
||||
uint8_t retries = 10;
|
||||
do {
|
||||
ErrorState = SD_TransmitCommand((CmdIndex | SD_CMD_RESPONSE_SHORT), (uint32_t)WriteAddress, 1);
|
||||
if (ErrorState != SD_OK && retries--) {
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
ErrorState = SD_TransmitCommand((CmdIndex | SD_CMD_RESPONSE_SHORT), (uint32_t)WriteAddress, 1);
|
||||
if (ErrorState != SD_OK && retries--) {
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
} while(ErrorState != SD_OK && retries);
|
||||
|
||||
if (ErrorState != SD_OK) {
|
||||
SD_Handle.TXCplt = 0;
|
||||
return ErrorState;
|
||||
SD_Handle.TXCplt = 0;
|
||||
return ErrorState;
|
||||
}
|
||||
|
||||
SD_StartBlockTransfert(buffer, BlockSize, NumberOfBlocks, SDIO_DIR_TX);
|
||||
|
||||
// Configure the SD DPSM (Data Path State Machine)
|
||||
SD_DataTransferInit(BlockSize * NumberOfBlocks, SD_DATABLOCK_SIZE_512B, false);
|
||||
SD_DataTransferInit(BlockSize * NumberOfBlocks, SD_DATABLOCK_SIZE_512B, false);
|
||||
|
||||
SD_Handle.TransferError = ErrorState;
|
||||
|
||||
|
@ -691,13 +714,13 @@ SD_Error_t SD_WriteBlocks_DMA(uint64_t WriteAddress, uint32_t *buffer, uint32_t
|
|||
}
|
||||
|
||||
SD_Error_t SD_CheckWrite(void) {
|
||||
if (SD_Handle.TXCplt != 0) return SD_BUSY;
|
||||
return SD_OK;
|
||||
if (SD_Handle.TXCplt != 0) return SD_BUSY;
|
||||
return SD_OK;
|
||||
}
|
||||
|
||||
SD_Error_t SD_CheckRead(void) {
|
||||
if (SD_Handle.RXCplt != 0) return SD_BUSY;
|
||||
return SD_OK;
|
||||
if (SD_Handle.RXCplt != 0) return SD_BUSY;
|
||||
return SD_OK;
|
||||
}
|
||||
|
||||
/** -----------------------------------------------------------------------------------------------------------------*/
|
||||
|
@ -1074,7 +1097,7 @@ static SD_Error_t SD_WideBusOperationConfig(uint32_t WideMode)
|
|||
if((SDIO->RESP1 & SD_CARD_LOCKED) != SD_CARD_LOCKED)
|
||||
{
|
||||
// Get SCR Register
|
||||
ErrorState = SD_FindSCR(SCR);
|
||||
ErrorState = SD_FindSCR(SCR);
|
||||
if(ErrorState == SD_OK)
|
||||
{
|
||||
Temp = (WideMode == SD_BUS_WIDE_4B) ? SD_WIDE_BUS_SUPPORT : SD_SINGLE_BUS_SUPPORT;
|
||||
|
@ -1083,7 +1106,7 @@ static SD_Error_t SD_WideBusOperationConfig(uint32_t WideMode)
|
|||
if((SCR[1] & Temp) != SD_ALLZERO)
|
||||
{
|
||||
// Send CMD55 APP_CMD with argument as card's RCA.
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), SD_CardRCA, 1);
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), SD_CardRCA, 1);
|
||||
if(ErrorState == SD_OK)
|
||||
{
|
||||
Temp = (WideMode == SD_BUS_WIDE_4B) ? 2 : 0;
|
||||
|
@ -1111,13 +1134,13 @@ static SD_Error_t SD_WideBusOperationConfig(uint32_t WideMode)
|
|||
if(ErrorState == SD_OK)
|
||||
{
|
||||
// Configure the SDIO peripheral, we need this delay for some reason...
|
||||
while ((READ_REG(SDIO->CLKCR) & 0x800) != WideMode) {
|
||||
MODIFY_REG(SDIO->CLKCR, CLKCR_CLEAR_MASK, (uint32_t) WideMode);
|
||||
}
|
||||
while ((READ_REG(SDIO->CLKCR) & 0x800) != WideMode) {
|
||||
MODIFY_REG(SDIO->CLKCR, CLKCR_CLEAR_MASK, (uint32_t) WideMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ErrorState = SD_UNSUPPORTED_FEATURE;
|
||||
ErrorState = SD_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1573,21 +1596,21 @@ void SD_Initialize_LL(DMA_Stream_TypeDef *dma)
|
|||
//Configure Pins
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN;
|
||||
|
||||
uint8_t is4BitWidth = sdioConfig()->use4BitWidth;
|
||||
|
||||
const IO_t d0 = IOGetByTag(IO_TAG(PC8));
|
||||
#ifndef USE_SDIO_1BIT
|
||||
const IO_t d1 = IOGetByTag(IO_TAG(PC9));
|
||||
const IO_t d2 = IOGetByTag(IO_TAG(PC10));
|
||||
const IO_t d3 = IOGetByTag(IO_TAG(PC11));
|
||||
#endif
|
||||
const IO_t clk = IOGetByTag(IO_TAG(PC12));
|
||||
const IO_t cmd = IOGetByTag(IO_TAG(PD2));
|
||||
|
||||
IOInit(d0, OWNER_SDCARD, 0);
|
||||
#ifndef USE_SDIO_1BIT
|
||||
IOInit(d1, OWNER_SDCARD, 0);
|
||||
IOInit(d2, OWNER_SDCARD, 0);
|
||||
IOInit(d3, OWNER_SDCARD, 0);
|
||||
#endif
|
||||
if (is4BitWidth) {
|
||||
IOInit(d1, OWNER_SDCARD, 0);
|
||||
IOInit(d2, OWNER_SDCARD, 0);
|
||||
IOInit(d3, OWNER_SDCARD, 0);
|
||||
}
|
||||
IOInit(clk, OWNER_SDCARD, 0);
|
||||
IOInit(cmd, OWNER_SDCARD, 0);
|
||||
|
||||
|
@ -1596,11 +1619,11 @@ void SD_Initialize_LL(DMA_Stream_TypeDef *dma)
|
|||
#define SDIO_CLK IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_100MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL)
|
||||
|
||||
IOConfigGPIOAF(d0, SDIO_DATA, GPIO_AF_SDIO);
|
||||
#ifndef USE_SDIO_1BIT
|
||||
IOConfigGPIOAF(d1, SDIO_DATA, GPIO_AF_SDIO);
|
||||
IOConfigGPIOAF(d2, SDIO_DATA, GPIO_AF_SDIO);
|
||||
IOConfigGPIOAF(d3, SDIO_DATA, GPIO_AF_SDIO);
|
||||
#endif
|
||||
if (is4BitWidth) {
|
||||
IOConfigGPIOAF(d1, SDIO_DATA, GPIO_AF_SDIO);
|
||||
IOConfigGPIOAF(d2, SDIO_DATA, GPIO_AF_SDIO);
|
||||
IOConfigGPIOAF(d3, SDIO_DATA, GPIO_AF_SDIO);
|
||||
}
|
||||
IOConfigGPIOAF(clk, SDIO_CLK, GPIO_AF_SDIO);
|
||||
IOConfigGPIOAF(cmd, SDIO_CMD, GPIO_AF_SDIO);
|
||||
|
||||
|
@ -1615,31 +1638,31 @@ void SD_Initialize_LL(DMA_Stream_TypeDef *dma)
|
|||
dma_stream = dma;
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
|
||||
if ((uint32_t)dma_stream == (uint32_t)DMA2_Stream3) {
|
||||
// Initialize DMA2 channel 3
|
||||
DMA2_Stream3->CR = 0; // Reset DMA Stream control register
|
||||
DMA2_Stream3->PAR = (uint32_t)&SDIO->FIFO;
|
||||
DMA2->LIFCR = IFCR_CLEAR_MASK_STREAM3; // Clear all interrupt flags
|
||||
DMA2_Stream3->CR = (DMA_CHANNEL_4 | DMA_SxCR_PFCTRL | // Prepare the DMA Stream configuration
|
||||
DMA_MINC_ENABLE | DMA_PDATAALIGN_WORD | // And write to DMA Stream CR register
|
||||
DMA_MDATAALIGN_WORD | DMA_PRIORITY_VERY_HIGH |
|
||||
DMA_MBURST_INC4 | DMA_PBURST_INC4 |
|
||||
DMA_MEMORY_TO_PERIPH);
|
||||
DMA2_Stream3->FCR = (DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); // Configuration FIFO control register
|
||||
dmaInit(dmaGetIdentifier(DMA2_Stream3), OWNER_SDCARD, 0);
|
||||
dmaSetHandler(dmaGetIdentifier(DMA2_Stream3), SDIO_DMA_ST3_IRQHandler, 1, 0);
|
||||
// Initialize DMA2 channel 3
|
||||
DMA2_Stream3->CR = 0; // Reset DMA Stream control register
|
||||
DMA2_Stream3->PAR = (uint32_t)&SDIO->FIFO;
|
||||
DMA2->LIFCR = IFCR_CLEAR_MASK_STREAM3; // Clear all interrupt flags
|
||||
DMA2_Stream3->CR = (DMA_CHANNEL_4 | DMA_SxCR_PFCTRL | // Prepare the DMA Stream configuration
|
||||
DMA_MINC_ENABLE | DMA_PDATAALIGN_WORD | // And write to DMA Stream CR register
|
||||
DMA_MDATAALIGN_WORD | DMA_PRIORITY_VERY_HIGH |
|
||||
DMA_MBURST_INC4 | DMA_PBURST_INC4 |
|
||||
DMA_MEMORY_TO_PERIPH);
|
||||
DMA2_Stream3->FCR = (DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); // Configuration FIFO control register
|
||||
dmaInit(dmaGetIdentifier(DMA2_Stream3), OWNER_SDCARD, 0);
|
||||
dmaSetHandler(dmaGetIdentifier(DMA2_Stream3), SDIO_DMA_ST3_IRQHandler, 1, 0);
|
||||
} else {
|
||||
// Initialize DMA2 channel 6
|
||||
DMA2_Stream6->CR = 0; // Reset DMA Stream control register
|
||||
DMA2_Stream6->PAR = (uint32_t)&SDIO->FIFO;
|
||||
DMA2->HIFCR = IFCR_CLEAR_MASK_STREAM6; // Clear all interrupt flags
|
||||
DMA2_Stream6->CR = (DMA_CHANNEL_4 | DMA_SxCR_PFCTRL | // Prepare the DMA Stream configuration
|
||||
DMA_MINC_ENABLE | DMA_PDATAALIGN_WORD | // And write to DMA Stream CR register
|
||||
DMA_MDATAALIGN_WORD | DMA_PRIORITY_VERY_HIGH |
|
||||
DMA_MBURST_INC4 | DMA_PBURST_INC4 |
|
||||
DMA_MEMORY_TO_PERIPH);
|
||||
DMA2_Stream6->FCR = (DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); // Configuration FIFO control register
|
||||
dmaInit(dmaGetIdentifier(DMA2_Stream6), OWNER_SDCARD, 0);
|
||||
dmaSetHandler(dmaGetIdentifier(DMA2_Stream6), SDIO_DMA_ST6_IRQHandler, 1, 0);
|
||||
// Initialize DMA2 channel 6
|
||||
DMA2_Stream6->CR = 0; // Reset DMA Stream control register
|
||||
DMA2_Stream6->PAR = (uint32_t)&SDIO->FIFO;
|
||||
DMA2->HIFCR = IFCR_CLEAR_MASK_STREAM6; // Clear all interrupt flags
|
||||
DMA2_Stream6->CR = (DMA_CHANNEL_4 | DMA_SxCR_PFCTRL | // Prepare the DMA Stream configuration
|
||||
DMA_MINC_ENABLE | DMA_PDATAALIGN_WORD | // And write to DMA Stream CR register
|
||||
DMA_MDATAALIGN_WORD | DMA_PRIORITY_VERY_HIGH |
|
||||
DMA_MBURST_INC4 | DMA_PBURST_INC4 |
|
||||
DMA_MEMORY_TO_PERIPH);
|
||||
DMA2_Stream6->FCR = (DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); // Configuration FIFO control register
|
||||
dmaInit(dmaGetIdentifier(DMA2_Stream6), OWNER_SDCARD, 0);
|
||||
dmaSetHandler(dmaGetIdentifier(DMA2_Stream6), SDIO_DMA_ST6_IRQHandler, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1647,25 +1670,25 @@ void SD_Initialize_LL(DMA_Stream_TypeDef *dma)
|
|||
/** -----------------------------------------------------------------------------------------------------------------*/
|
||||
bool SD_GetState(void)
|
||||
{
|
||||
// Check SDCARD status
|
||||
if(SD_GetStatus() == SD_OK) return true;
|
||||
return false;
|
||||
// Check SDCARD status
|
||||
if(SD_GetStatus() == SD_OK) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** -----------------------------------------------------------------------------------------------------------------*/
|
||||
bool SD_Init(void)
|
||||
{
|
||||
SD_Error_t ErrorState;
|
||||
SD_Error_t ErrorState;
|
||||
|
||||
// Check if SD card is present
|
||||
if(SD_IsDetected() != SD_PRESENT)
|
||||
// Check if SD card is present
|
||||
if(SD_IsDetected() != SD_PRESENT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialize SDIO peripheral interface with default configuration for SD card initialization
|
||||
MODIFY_REG(SDIO->CLKCR, CLKCR_CLEAR_MASK, (uint32_t) SDIO_INIT_CLK_DIV);
|
||||
MODIFY_REG(SDIO->CLKCR, CLKCR_CLEAR_MASK, (uint32_t) SDIO_INIT_CLK_DIV);
|
||||
|
||||
if((ErrorState = SD_PowerON()) == SD_OK) // Identify card operating voltage
|
||||
{
|
||||
|
@ -1680,26 +1703,25 @@ bool SD_Init(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Configure SD Bus width
|
||||
if(ErrorState == SD_OK)
|
||||
{
|
||||
// Enable wide operation
|
||||
#ifdef USE_SDIO_1BIT
|
||||
ErrorState = SD_WideBusOperationConfig(SD_BUS_WIDE_1B);
|
||||
#else
|
||||
ErrorState = SD_WideBusOperationConfig(SD_BUS_WIDE_4B);
|
||||
#endif
|
||||
// Configure SD Bus width
|
||||
if(ErrorState == SD_OK)
|
||||
{
|
||||
// Enable wide operation
|
||||
if (sdioConfig()->use4BitWidth) {
|
||||
ErrorState = SD_WideBusOperationConfig(SD_BUS_WIDE_4B);
|
||||
} else {
|
||||
ErrorState = SD_WideBusOperationConfig(SD_BUS_WIDE_1B);
|
||||
}
|
||||
if (ErrorState == SD_OK && sdioConfig()->clockBypass) {
|
||||
if (SD_HighSpeed()) {
|
||||
SDIO->CLKCR |= SDIO_CLKCR_BYPASS;
|
||||
SDIO->CLKCR |= SDIO_CLKCR_NEGEDGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ErrorState == SD_OK && sdioConfig()->clockBypass) {
|
||||
if (SD_HighSpeed()) {
|
||||
SDIO->CLKCR |= SDIO_CLKCR_BYPASS;
|
||||
SDIO->CLKCR |= SDIO_CLKCR_NEGEDGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Configure the SDCARD device
|
||||
return ErrorState;
|
||||
// Configure the SDCARD device
|
||||
return ErrorState;
|
||||
}
|
||||
|
||||
/** -----------------------------------------------------------------------------------------------------------------*/
|
||||
|
@ -1707,44 +1729,44 @@ bool SD_Init(void)
|
|||
* @brief This function handles SD card interrupt request.
|
||||
*/
|
||||
void SDIO_IRQHandler(void) {
|
||||
// Check for SDIO interrupt flags
|
||||
if ((SDIO->STA & SDIO_STA_DATAEND) != 0) {
|
||||
SDIO->ICR = SDIO_ICR_DATAENDC;
|
||||
SDIO->ICR = SDIO_ICR_STATIC_FLAGS;
|
||||
SDIO->MASK &= ~(SDIO_MASK_DATAENDIE | SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \
|
||||
SDIO_MASK_TXUNDERRIE | SDIO_MASK_RXOVERRIE | SDIO_MASK_TXFIFOHEIE | SDIO_MASK_RXFIFOHFIE);
|
||||
// Check for SDIO interrupt flags
|
||||
if ((SDIO->STA & SDIO_STA_DATAEND) != 0) {
|
||||
SDIO->ICR = SDIO_ICR_DATAENDC;
|
||||
SDIO->ICR = SDIO_ICR_STATIC_FLAGS;
|
||||
SDIO->MASK &= ~(SDIO_MASK_DATAENDIE | SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \
|
||||
SDIO_MASK_TXUNDERRIE | SDIO_MASK_RXOVERRIE | SDIO_MASK_TXFIFOHEIE | SDIO_MASK_RXFIFOHFIE);
|
||||
|
||||
/* Currently doesn't implement multiple block write handling */
|
||||
if ((SD_Handle.Operation & 0x02) == (SDIO_DIR_TX << 1)) {
|
||||
/* Disable the stream */
|
||||
dma_stream->CR &= ~DMA_SxCR_EN;
|
||||
SDIO->DCTRL &= ~(SDIO_DCTRL_DMAEN);
|
||||
/* Transfer is complete */
|
||||
SD_Handle.TXCplt = 0;
|
||||
if ((SD_Handle.Operation & 0x01) == SD_MULTIPLE_BLOCK) {
|
||||
/* Send stop command in multiblock write */
|
||||
SD_TransmitCommand((SD_CMD_STOP_TRANSMISSION | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
}
|
||||
SD_Handle.TransferComplete = 1;
|
||||
SD_Handle.TransferError = SD_OK; // No transfer error
|
||||
}
|
||||
else if ((SDIO->STA & SDIO_STA_DCRCFAIL) != 0)
|
||||
SD_Handle.TransferError = SD_DATA_CRC_FAIL;
|
||||
else if ((SDIO->STA & SDIO_STA_DTIMEOUT) != 0)
|
||||
SD_Handle.TransferError = SD_DATA_TIMEOUT;
|
||||
else if ((SDIO->STA & SDIO_STA_RXOVERR) != 0)
|
||||
SD_Handle.TransferError = SD_RX_OVERRUN;
|
||||
else if ((SDIO->STA & SDIO_STA_TXUNDERR) != 0)
|
||||
SD_Handle.TransferError = SD_TX_UNDERRUN;
|
||||
/* Currently doesn't implement multiple block write handling */
|
||||
if ((SD_Handle.Operation & 0x02) == (SDIO_DIR_TX << 1)) {
|
||||
/* Disable the stream */
|
||||
dma_stream->CR &= ~DMA_SxCR_EN;
|
||||
SDIO->DCTRL &= ~(SDIO_DCTRL_DMAEN);
|
||||
/* Transfer is complete */
|
||||
SD_Handle.TXCplt = 0;
|
||||
if ((SD_Handle.Operation & 0x01) == SD_MULTIPLE_BLOCK) {
|
||||
/* Send stop command in multiblock write */
|
||||
SD_TransmitCommand((SD_CMD_STOP_TRANSMISSION | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
}
|
||||
SD_Handle.TransferComplete = 1;
|
||||
SD_Handle.TransferError = SD_OK; // No transfer error
|
||||
}
|
||||
else if ((SDIO->STA & SDIO_STA_DCRCFAIL) != 0)
|
||||
SD_Handle.TransferError = SD_DATA_CRC_FAIL;
|
||||
else if ((SDIO->STA & SDIO_STA_DTIMEOUT) != 0)
|
||||
SD_Handle.TransferError = SD_DATA_TIMEOUT;
|
||||
else if ((SDIO->STA & SDIO_STA_RXOVERR) != 0)
|
||||
SD_Handle.TransferError = SD_RX_OVERRUN;
|
||||
else if ((SDIO->STA & SDIO_STA_TXUNDERR) != 0)
|
||||
SD_Handle.TransferError = SD_TX_UNDERRUN;
|
||||
|
||||
SDIO->ICR = SDIO_ICR_STATIC_FLAGS;
|
||||
SDIO->ICR = SDIO_ICR_STATIC_FLAGS;
|
||||
|
||||
// Disable all SDIO peripheral interrupt sources
|
||||
SDIO->MASK &= ~(SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE
|
||||
| SDIO_MASK_DATAENDIE |
|
||||
SDIO_MASK_TXFIFOHEIE | SDIO_MASK_RXFIFOHFIE | SDIO_MASK_TXUNDERRIE |
|
||||
SDIO_MASK_RXOVERRIE);
|
||||
// Disable all SDIO peripheral interrupt sources
|
||||
SDIO->MASK &= ~(SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE
|
||||
| SDIO_MASK_DATAENDIE |
|
||||
SDIO_MASK_TXFIFOHEIE | SDIO_MASK_RXFIFOHFIE | SDIO_MASK_TXUNDERRIE |
|
||||
SDIO_MASK_RXOVERRIE);
|
||||
}
|
||||
|
||||
/** -----------------------------------------------------------------------------------------------------------------*/
|
||||
|
@ -1753,7 +1775,7 @@ void SDIO_IRQHandler(void) {
|
|||
*/
|
||||
void SDIO_DMA_ST3_IRQHandler(dmaChannelDescriptor_t *dma)
|
||||
{
|
||||
UNUSED(dma);
|
||||
UNUSED(dma);
|
||||
// Transfer Error Interrupt management
|
||||
if((DMA2->LISR & DMA_LISR_TEIF3) != 0)
|
||||
{
|
||||
|
@ -1835,7 +1857,7 @@ void SDIO_DMA_ST3_IRQHandler(dmaChannelDescriptor_t *dma)
|
|||
*/
|
||||
void SDIO_DMA_ST6_IRQHandler(dmaChannelDescriptor_t *dma)
|
||||
{
|
||||
UNUSED(dma);
|
||||
UNUSED(dma);
|
||||
// Transfer Error Interrupt management
|
||||
if((DMA2->HISR & DMA_HISR_TEIF6) != 0)
|
||||
{
|
||||
|
|
|
@ -264,17 +264,17 @@ void SDMMC_DMA_ST6_IRQHandler(dmaChannelDescriptor_t *dma);
|
|||
*/
|
||||
bool SD_IsDetected(void)
|
||||
{
|
||||
__IO uint8_t status = SD_PRESENT;
|
||||
__IO uint8_t status = SD_PRESENT;
|
||||
|
||||
/*!< Check GPIO to detect SD */
|
||||
#ifdef SDCARD_DETECT_PIN
|
||||
const IO_t sd_det = IOGetByTag(IO_TAG(SDCARD_DETECT_PIN));
|
||||
if (IORead(sd_det) != 0)
|
||||
{
|
||||
status = SD_NOT_PRESENT;
|
||||
}
|
||||
#endif
|
||||
return status;
|
||||
/*!< Check GPIO to detect SD */
|
||||
#ifdef SDCARD_DETECT_PIN
|
||||
const IO_t sd_det = IOGetByTag(IO_TAG(SDCARD_DETECT_PIN));
|
||||
if (IORead(sd_det) != 0)
|
||||
{
|
||||
status = SD_NOT_PRESENT;
|
||||
}
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -313,7 +313,7 @@ static SD_Error_t SD_TransmitCommand(uint32_t Command, uint32_t Argument, int8_t
|
|||
WRITE_REG(SDMMC1->ICR, SDMMC_ICR_STATIC_FLAGS); // Clear the Command Flags
|
||||
WRITE_REG(SDMMC1->ARG, (uint32_t)Argument); // Set the SDMMC1 Argument value
|
||||
WRITE_REG(SDMMC1->CMD, (uint32_t)(Command | SDMMC_CMD_CPSMEN)); // Set SDMMC1 command parameters
|
||||
if((Argument == 0) && (ResponseType == 0)) ResponseType = -1; // Go idle command
|
||||
if((Argument == 0) && (ResponseType == 0)) ResponseType = -1; // Go idle command
|
||||
ErrorState = SD_CmdResponse(Command & SDMMC_CMD_CMDINDEX, ResponseType);
|
||||
WRITE_REG(SDMMC1->ICR, SDMMC_ICR_STATIC_FLAGS); // Clear the Command Flags
|
||||
|
||||
|
@ -336,8 +336,11 @@ static SD_Error_t SD_CmdResponse(uint8_t SD_CMD, int8_t ResponseType)
|
|||
uint32_t TimeOut;
|
||||
uint32_t Flag;
|
||||
|
||||
if(ResponseType == -1) Flag = SDMMC_STA_CMDSENT;
|
||||
else Flag = SDMMC_STA_CCRCFAIL | SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT;
|
||||
if(ResponseType == -1) {
|
||||
Flag = SDMMC_STA_CMDSENT;
|
||||
} else {
|
||||
Flag = SDMMC_STA_CCRCFAIL | SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT;
|
||||
}
|
||||
|
||||
TimeOut = SD_SOFTWARE_COMMAND_TIMEOUT;
|
||||
do
|
||||
|
@ -349,20 +352,34 @@ static SD_Error_t SD_CmdResponse(uint8_t SD_CMD, int8_t ResponseType)
|
|||
|
||||
if(ResponseType <= 0)
|
||||
{
|
||||
if(TimeOut == 0) return SD_CMD_RSP_TIMEOUT;
|
||||
else return SD_OK;
|
||||
if(TimeOut == 0){
|
||||
return SD_CMD_RSP_TIMEOUT;
|
||||
} else {
|
||||
return SD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if((SDMMC1->STA & SDMMC_STA_CTIMEOUT) != 0) return SD_CMD_RSP_TIMEOUT;
|
||||
if((SDMMC1->STA & SDMMC_STA_CTIMEOUT) != 0) {
|
||||
return SD_CMD_RSP_TIMEOUT;
|
||||
}
|
||||
if(ResponseType == 3)
|
||||
{
|
||||
if(TimeOut == 0) return SD_CMD_RSP_TIMEOUT; // Card is not V2.0 compliant or card does not support the set voltage range
|
||||
else return SD_OK; // Card is SD V2.0 compliant
|
||||
if(TimeOut == 0) {
|
||||
return SD_CMD_RSP_TIMEOUT; // Card is not V2.0 compliant or card does not support the set voltage range
|
||||
} else {
|
||||
return SD_OK; // Card is SD V2.0 compliant
|
||||
}
|
||||
}
|
||||
|
||||
if((SDMMC1->STA & SDMMC_STA_CCRCFAIL) != 0) return SD_CMD_CRC_FAIL;
|
||||
if(ResponseType == 2) return SD_OK;
|
||||
if((uint8_t)SDMMC1->RESPCMD != SD_CMD) return SD_ILLEGAL_CMD; // Check if response is of desired command
|
||||
if((SDMMC1->STA & SDMMC_STA_CCRCFAIL) != 0) {
|
||||
return SD_CMD_CRC_FAIL;
|
||||
}
|
||||
if(ResponseType == 2) {
|
||||
return SD_OK;
|
||||
}
|
||||
if((uint8_t)SDMMC1->RESPCMD != SD_CMD) {
|
||||
return SD_ILLEGAL_CMD; // Check if response is of desired command
|
||||
}
|
||||
|
||||
Response_R1 = SDMMC1->RESP1; // We have received response, retrieve it for analysis
|
||||
|
||||
|
@ -376,9 +393,15 @@ static SD_Error_t SD_CmdResponse(uint8_t SD_CMD, int8_t ResponseType)
|
|||
{
|
||||
SD_CardRCA = Response_R1;
|
||||
}
|
||||
if((Response_R1 & SD_R6_GENERAL_UNKNOWN_ERROR) == SD_R6_GENERAL_UNKNOWN_ERROR) return SD_GENERAL_UNKNOWN_ERROR;
|
||||
if((Response_R1 & SD_R6_ILLEGAL_CMD) == SD_R6_ILLEGAL_CMD) return SD_ILLEGAL_CMD;
|
||||
if((Response_R1 & SD_R6_COM_CRC_FAILED) == SD_R6_COM_CRC_FAILED) return SD_COM_CRC_FAILED;
|
||||
if((Response_R1 & SD_R6_GENERAL_UNKNOWN_ERROR) == SD_R6_GENERAL_UNKNOWN_ERROR) {
|
||||
return SD_GENERAL_UNKNOWN_ERROR;
|
||||
}
|
||||
if((Response_R1 & SD_R6_ILLEGAL_CMD) == SD_R6_ILLEGAL_CMD) {
|
||||
return SD_ILLEGAL_CMD;
|
||||
}
|
||||
if((Response_R1 & SD_R6_COM_CRC_FAILED) == SD_R6_COM_CRC_FAILED) {
|
||||
return SD_COM_CRC_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return SD_OK;
|
||||
|
@ -441,26 +464,26 @@ static void SD_GetResponse(uint32_t* pResponse)
|
|||
static void SD_DMA_Complete(DMA_Stream_TypeDef* pDMA_Stream)
|
||||
{
|
||||
if (SD_Handle.RXCplt) {
|
||||
if (SD_Handle.Operation == ((SDMMC_DIR_RX << 1) | SD_MULTIPLE_BLOCK)) {
|
||||
/* Send stop command in multiblock write */
|
||||
SD_TransmitCommand((SD_CMD_STOP_TRANSMISSION | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
if (SD_Handle.Operation == ((SDMMC_DIR_RX << 1) | SD_MULTIPLE_BLOCK)) {
|
||||
/* Send stop command in multiblock write */
|
||||
SD_TransmitCommand((SD_CMD_STOP_TRANSMISSION | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
|
||||
/* Disable the DMA transfer for transmit request by setting the DMAEN bit
|
||||
in the SD DCTRL register */
|
||||
SDMMC1->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
|
||||
/* Disable the DMA transfer for transmit request by setting the DMAEN bit
|
||||
in the SD DCTRL register */
|
||||
SDMMC1->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
|
||||
|
||||
/* Clear all the static flags */
|
||||
SDMMC1->ICR = SDMMC_ICR_STATIC_FLAGS;
|
||||
/* Clear all the static flags */
|
||||
SDMMC1->ICR = SDMMC_ICR_STATIC_FLAGS;
|
||||
|
||||
/* Clear flag */
|
||||
SD_Handle.RXCplt = 0;
|
||||
/* Clear flag */
|
||||
SD_Handle.RXCplt = 0;
|
||||
|
||||
/* Disable the stream */
|
||||
pDMA_Stream->CR &= ~DMA_SxCR_EN;
|
||||
/* Disable the stream */
|
||||
pDMA_Stream->CR &= ~DMA_SxCR_EN;
|
||||
} else {
|
||||
/* Enable Dataend IE */
|
||||
SDMMC1->MASK |= SDMMC_MASK_DATAENDIE;
|
||||
/* Enable Dataend IE */
|
||||
SDMMC1->MASK |= SDMMC_MASK_DATAENDIE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,7 +554,7 @@ static SD_Error_t SD_InitializeCard(void)
|
|||
*/
|
||||
static void SD_StartBlockTransfert(uint32_t* pBuffer, uint32_t BlockSize, uint32_t NumberOfBlocks, uint8_t dir)
|
||||
{
|
||||
DMA_Stream_TypeDef *pDMA = dma_stream;
|
||||
DMA_Stream_TypeDef *pDMA = dma_stream;
|
||||
|
||||
SDMMC1->DCTRL = 0; // Initialize data control register
|
||||
SD_Handle.TransferComplete = 0; // Initialize handle flags
|
||||
|
@ -546,31 +569,31 @@ static void SD_StartBlockTransfert(uint32_t* pBuffer, uint32_t BlockSize, uint32
|
|||
SDMMC1->MASK |= (SDMMC_MASK_DCRCFAILIE | SDMMC_MASK_DTIMEOUTIE | // Enable transfer interrupts
|
||||
SDMMC_MASK_TXUNDERRIE);
|
||||
}
|
||||
if (dir == SDMMC_DIR_TX) {
|
||||
SDMMC1->DCTRL |= SDMMC_DCTRL_DMAEN; // Enable SDMMC1 DMA transfer
|
||||
}
|
||||
if (dir == SDMMC_DIR_TX) {
|
||||
SDMMC1->DCTRL |= SDMMC_DCTRL_DMAEN; // Enable SDMMC1 DMA transfer
|
||||
}
|
||||
pDMA->CR &= ~DMA_SxCR_EN; // Disable the Peripheral
|
||||
while (pDMA->CR & DMA_SxCR_EN);
|
||||
pDMA->NDTR = (uint32_t) (BlockSize * NumberOfBlocks) / 4; // Configure DMA Stream data length
|
||||
pDMA->M0AR = (uint32_t) pBuffer; // Configure DMA Stream memory address
|
||||
if (dir == SDMMC_DIR_RX) {
|
||||
pDMA->CR &= ~(0x01U << 6U); // Sets peripheral to memory
|
||||
} else {
|
||||
pDMA->CR |= DMA_MEMORY_TO_PERIPH; // Sets memory to peripheral
|
||||
}
|
||||
if (dma_stream == DMA2_Stream3) {
|
||||
DMA2->LIFCR = DMA_LIFCR_CTEIF3 | DMA_LIFCR_CDMEIF3 |
|
||||
DMA_LIFCR_CFEIF3 | DMA_LIFCR_CHTIF3 | DMA_LIFCR_CTCIF3; // Clear the transfer error flag
|
||||
if (dir == SDMMC_DIR_RX) {
|
||||
pDMA->CR &= ~(0x01U << 6U); // Sets peripheral to memory
|
||||
} else {
|
||||
DMA2->HIFCR = DMA_HIFCR_CTEIF6 | DMA_HIFCR_CDMEIF6 |
|
||||
DMA_HIFCR_CFEIF6 | DMA_HIFCR_CHTIF6 | DMA_HIFCR_CTCIF6; // Clear the transfer error flag
|
||||
pDMA->CR |= DMA_MEMORY_TO_PERIPH; // Sets memory to peripheral
|
||||
}
|
||||
if (dma_stream == DMA2_Stream3) {
|
||||
DMA2->LIFCR = DMA_LIFCR_CTEIF3 | DMA_LIFCR_CDMEIF3 |
|
||||
DMA_LIFCR_CFEIF3 | DMA_LIFCR_CHTIF3 | DMA_LIFCR_CTCIF3; // Clear the transfer error flag
|
||||
} else {
|
||||
DMA2->HIFCR = DMA_HIFCR_CTEIF6 | DMA_HIFCR_CDMEIF6 |
|
||||
DMA_HIFCR_CFEIF6 | DMA_HIFCR_CHTIF6 | DMA_HIFCR_CTCIF6; // Clear the transfer error flag
|
||||
}
|
||||
pDMA->CR |= DMA_SxCR_TCIE | DMA_SxCR_HTIE | DMA_SxCR_TEIE | DMA_SxCR_DMEIE; // Enable all interrupts
|
||||
pDMA->FCR |= DMA_SxFCR_FEIE;
|
||||
pDMA->CR |= DMA_SxCR_EN; // Enable the Peripheral
|
||||
if (dir == SDMMC_DIR_RX) {
|
||||
SDMMC1->DCTRL |= SDMMC_DCTRL_DMAEN; // Enable SDMMC1 DMA transfer
|
||||
}
|
||||
if (dir == SDMMC_DIR_RX) {
|
||||
SDMMC1->DCTRL |= SDMMC_DCTRL_DMAEN; // Enable SDMMC1 DMA transfer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -603,7 +626,7 @@ SD_Error_t SD_ReadBlocks_DMA(uint64_t ReadAddress, uint32_t *buffer, uint32_t Bl
|
|||
SD_StartBlockTransfert(buffer, BlockSize, NumberOfBlocks, SDMMC_DIR_RX);
|
||||
|
||||
// Configure the SD DPSM (Data Path State Machine)
|
||||
SD_DataTransferInit(BlockSize * NumberOfBlocks, SD_DATABLOCK_SIZE_512B, true);
|
||||
SD_DataTransferInit(BlockSize * NumberOfBlocks, SD_DATABLOCK_SIZE_512B, true);
|
||||
|
||||
// Set Block Size for Card
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_SET_BLOCKLEN | SD_CMD_RESPONSE_SHORT), BlockSize, 1);
|
||||
|
@ -613,14 +636,14 @@ SD_Error_t SD_ReadBlocks_DMA(uint64_t ReadAddress, uint32_t *buffer, uint32_t Bl
|
|||
uint8_t retries = 10;
|
||||
CmdIndex = (NumberOfBlocks > 1) ? SD_CMD_READ_MULT_BLOCK : SD_CMD_READ_SINGLE_BLOCK;
|
||||
do {
|
||||
ErrorState = SD_TransmitCommand((CmdIndex | SD_CMD_RESPONSE_SHORT), (uint32_t)ReadAddress, 1);
|
||||
if (ErrorState != SD_OK && retries--) {
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
ErrorState = SD_TransmitCommand((CmdIndex | SD_CMD_RESPONSE_SHORT), (uint32_t)ReadAddress, 1);
|
||||
if (ErrorState != SD_OK && retries--) {
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
} while (ErrorState != SD_OK && retries);
|
||||
|
||||
if (ErrorState != SD_OK) {
|
||||
SD_Handle.RXCplt = 0;
|
||||
SD_Handle.RXCplt = 0;
|
||||
}
|
||||
|
||||
// Update the SD transfer error in SD handle
|
||||
|
@ -664,21 +687,21 @@ SD_Error_t SD_WriteBlocks_DMA(uint64_t WriteAddress, uint32_t *buffer, uint32_t
|
|||
// Set Block Size for Card
|
||||
uint8_t retries = 10;
|
||||
do {
|
||||
ErrorState = SD_TransmitCommand((CmdIndex | SD_CMD_RESPONSE_SHORT), (uint32_t)WriteAddress, 1);
|
||||
if (ErrorState != SD_OK && retries--) {
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
ErrorState = SD_TransmitCommand((CmdIndex | SD_CMD_RESPONSE_SHORT), (uint32_t)WriteAddress, 1);
|
||||
if (ErrorState != SD_OK && retries--) {
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
} while(ErrorState != SD_OK && retries);
|
||||
|
||||
if (ErrorState != SD_OK) {
|
||||
SD_Handle.TXCplt = 0;
|
||||
return ErrorState;
|
||||
SD_Handle.TXCplt = 0;
|
||||
return ErrorState;
|
||||
}
|
||||
|
||||
SD_StartBlockTransfert(buffer, BlockSize, NumberOfBlocks, SDMMC_DIR_TX);
|
||||
|
||||
// Configure the SD DPSM (Data Path State Machine)
|
||||
SD_DataTransferInit(BlockSize * NumberOfBlocks, SD_DATABLOCK_SIZE_512B, false);
|
||||
SD_DataTransferInit(BlockSize * NumberOfBlocks, SD_DATABLOCK_SIZE_512B, false);
|
||||
|
||||
SD_Handle.TransferError = ErrorState;
|
||||
|
||||
|
@ -686,13 +709,13 @@ SD_Error_t SD_WriteBlocks_DMA(uint64_t WriteAddress, uint32_t *buffer, uint32_t
|
|||
}
|
||||
|
||||
SD_Error_t SD_CheckWrite(void) {
|
||||
if (SD_Handle.TXCplt != 0) return SD_BUSY;
|
||||
return SD_OK;
|
||||
if (SD_Handle.TXCplt != 0) return SD_BUSY;
|
||||
return SD_OK;
|
||||
}
|
||||
|
||||
SD_Error_t SD_CheckRead(void) {
|
||||
if (SD_Handle.RXCplt != 0) return SD_BUSY;
|
||||
return SD_OK;
|
||||
if (SD_Handle.RXCplt != 0) return SD_BUSY;
|
||||
return SD_OK;
|
||||
}
|
||||
|
||||
/** -----------------------------------------------------------------------------------------------------------------*/
|
||||
|
@ -1069,7 +1092,7 @@ static SD_Error_t SD_WideBusOperationConfig(uint32_t WideMode)
|
|||
if((SDMMC1->RESP1 & SD_CARD_LOCKED) != SD_CARD_LOCKED)
|
||||
{
|
||||
// Get SCR Register
|
||||
ErrorState = SD_FindSCR(SCR);
|
||||
ErrorState = SD_FindSCR(SCR);
|
||||
if(ErrorState == SD_OK)
|
||||
{
|
||||
Temp = (WideMode == SD_BUS_WIDE_4B) ? SD_WIDE_BUS_SUPPORT : SD_SINGLE_BUS_SUPPORT;
|
||||
|
@ -1078,7 +1101,7 @@ static SD_Error_t SD_WideBusOperationConfig(uint32_t WideMode)
|
|||
if((SCR[1] & Temp) != SD_ALLZERO)
|
||||
{
|
||||
// Send CMD55 APP_CMD with argument as card's RCA.
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), SD_CardRCA, 1);
|
||||
ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), SD_CardRCA, 1);
|
||||
if(ErrorState == SD_OK)
|
||||
{
|
||||
Temp = (WideMode == SD_BUS_WIDE_4B) ? 2 : 0;
|
||||
|
@ -1106,13 +1129,13 @@ static SD_Error_t SD_WideBusOperationConfig(uint32_t WideMode)
|
|||
if(ErrorState == SD_OK)
|
||||
{
|
||||
// Configure the SDMMC1 peripheral, we need this delay for some reason...
|
||||
while ((READ_REG(SDMMC1->CLKCR) & 0x800) != WideMode) {
|
||||
MODIFY_REG(SDMMC1->CLKCR, CLKCR_CLEAR_MASK, (uint32_t) WideMode);
|
||||
}
|
||||
while ((READ_REG(SDMMC1->CLKCR) & 0x800) != WideMode) {
|
||||
MODIFY_REG(SDMMC1->CLKCR, CLKCR_CLEAR_MASK, (uint32_t) WideMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ErrorState = SD_UNSUPPORTED_FEATURE;
|
||||
ErrorState = SD_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1571,21 +1594,21 @@ void SD_Initialize_LL(DMA_Stream_TypeDef *dma)
|
|||
//Configure Pins
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN;
|
||||
|
||||
uint8_t is4BitWidth = sdioConfig()->use4BitWidth;
|
||||
|
||||
const IO_t d0 = IOGetByTag(IO_TAG(PC8));
|
||||
#ifndef USE_SDIO_1BIT
|
||||
const IO_t d1 = IOGetByTag(IO_TAG(PC9));
|
||||
const IO_t d2 = IOGetByTag(IO_TAG(PC10));
|
||||
const IO_t d3 = IOGetByTag(IO_TAG(PC11));
|
||||
#endif
|
||||
const IO_t clk = IOGetByTag(IO_TAG(PC12));
|
||||
const IO_t cmd = IOGetByTag(IO_TAG(PD2));
|
||||
|
||||
IOInit(d0, OWNER_SDCARD, 0);
|
||||
#ifndef USE_SDIO_1BIT
|
||||
IOInit(d1, OWNER_SDCARD, 0);
|
||||
IOInit(d2, OWNER_SDCARD, 0);
|
||||
IOInit(d3, OWNER_SDCARD, 0);
|
||||
#endif
|
||||
if (is4BitWidth) {
|
||||
IOInit(d1, OWNER_SDCARD, 0);
|
||||
IOInit(d2, OWNER_SDCARD, 0);
|
||||
IOInit(d3, OWNER_SDCARD, 0);
|
||||
}
|
||||
IOInit(clk, OWNER_SDCARD, 0);
|
||||
IOInit(cmd, OWNER_SDCARD, 0);
|
||||
|
||||
|
@ -1594,48 +1617,48 @@ void SD_Initialize_LL(DMA_Stream_TypeDef *dma)
|
|||
#define SDMMC_CLK IO_CONFIG(GPIO_MODE_AF_PP, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_NOPULL)
|
||||
|
||||
IOConfigGPIOAF(d0, SDMMC_DATA, GPIO_AF12_SDMMC1);
|
||||
#ifndef USE_SDIO_1BIT
|
||||
IOConfigGPIOAF(d1, SDMMC_DATA, GPIO_AF12_SDMMC1);
|
||||
IOConfigGPIOAF(d2, SDMMC_DATA, GPIO_AF12_SDMMC1);
|
||||
IOConfigGPIOAF(d3, SDMMC_DATA, GPIO_AF12_SDMMC1);
|
||||
#endif
|
||||
if(is4BitWidth) {
|
||||
IOConfigGPIOAF(d1, SDMMC_DATA, GPIO_AF12_SDMMC1);
|
||||
IOConfigGPIOAF(d2, SDMMC_DATA, GPIO_AF12_SDMMC1);
|
||||
IOConfigGPIOAF(d3, SDMMC_DATA, GPIO_AF12_SDMMC1);
|
||||
}
|
||||
IOConfigGPIOAF(clk, SDMMC_CLK, GPIO_AF12_SDMMC1);
|
||||
IOConfigGPIOAF(cmd, SDMMC_CMD, GPIO_AF12_SDMMC1);
|
||||
|
||||
uint32_t PriorityGroup = NVIC_GetPriorityGrouping();
|
||||
|
||||
// NVIC configuration for SDIO interrupts
|
||||
NVIC_SetPriority(SDMMC1_IRQn, NVIC_EncodePriority(PriorityGroup, 1, 0));
|
||||
NVIC_EnableIRQ(SDMMC1_IRQn);
|
||||
// NVIC configuration for SDIO interrupts
|
||||
NVIC_SetPriority(SDMMC1_IRQn, NVIC_EncodePriority(PriorityGroup, 1, 0));
|
||||
NVIC_EnableIRQ(SDMMC1_IRQn);
|
||||
|
||||
dma_stream = dma;
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
|
||||
if ((uint32_t)dma_stream == (uint32_t)DMA2_Stream3) {
|
||||
// Initialize DMA2 channel 3
|
||||
DMA2_Stream3->CR = 0; // Reset DMA Stream control register
|
||||
DMA2_Stream3->PAR = (uint32_t)&SDMMC1->FIFO;
|
||||
DMA2->LIFCR = IFCR_CLEAR_MASK_STREAM3; // Clear all interrupt flags
|
||||
DMA2_Stream3->CR = (DMA_CHANNEL_4 | DMA_SxCR_PFCTRL | // Prepare the DMA Stream configuration
|
||||
DMA_MINC_ENABLE | DMA_PDATAALIGN_WORD | // And write to DMA Stream CR register
|
||||
DMA_MDATAALIGN_WORD | DMA_PRIORITY_VERY_HIGH |
|
||||
DMA_MBURST_INC4 | DMA_PBURST_INC4 |
|
||||
DMA_MEMORY_TO_PERIPH);
|
||||
DMA2_Stream3->FCR = (DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); // Configuration FIFO control register
|
||||
dmaInit(dmaGetIdentifier(DMA2_Stream3), OWNER_SDCARD, 0);
|
||||
dmaSetHandler(dmaGetIdentifier(DMA2_Stream3), SDMMC_DMA_ST3_IRQHandler, 1, 0);
|
||||
// Initialize DMA2 channel 3
|
||||
DMA2_Stream3->CR = 0; // Reset DMA Stream control register
|
||||
DMA2_Stream3->PAR = (uint32_t)&SDMMC1->FIFO;
|
||||
DMA2->LIFCR = IFCR_CLEAR_MASK_STREAM3; // Clear all interrupt flags
|
||||
DMA2_Stream3->CR = (DMA_CHANNEL_4 | DMA_SxCR_PFCTRL | // Prepare the DMA Stream configuration
|
||||
DMA_MINC_ENABLE | DMA_PDATAALIGN_WORD | // And write to DMA Stream CR register
|
||||
DMA_MDATAALIGN_WORD | DMA_PRIORITY_VERY_HIGH |
|
||||
DMA_MBURST_INC4 | DMA_PBURST_INC4 |
|
||||
DMA_MEMORY_TO_PERIPH);
|
||||
DMA2_Stream3->FCR = (DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); // Configuration FIFO control register
|
||||
dmaInit(dmaGetIdentifier(DMA2_Stream3), OWNER_SDCARD, 0);
|
||||
dmaSetHandler(dmaGetIdentifier(DMA2_Stream3), SDMMC_DMA_ST3_IRQHandler, 1, 0);
|
||||
} else {
|
||||
// Initialize DMA2 channel 6
|
||||
DMA2_Stream6->CR = 0; // Reset DMA Stream control register
|
||||
DMA2_Stream6->PAR = (uint32_t)&SDMMC1->FIFO;
|
||||
DMA2->HIFCR = IFCR_CLEAR_MASK_STREAM6; // Clear all interrupt flags
|
||||
DMA2_Stream6->CR = (DMA_CHANNEL_4 | DMA_SxCR_PFCTRL | // Prepare the DMA Stream configuration
|
||||
DMA_MINC_ENABLE | DMA_PDATAALIGN_WORD | // And write to DMA Stream CR register
|
||||
DMA_MDATAALIGN_WORD | DMA_PRIORITY_VERY_HIGH |
|
||||
DMA_MBURST_INC4 | DMA_PBURST_INC4 |
|
||||
DMA_MEMORY_TO_PERIPH);
|
||||
DMA2_Stream6->FCR = (DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); // Configuration FIFO control register
|
||||
dmaInit(dmaGetIdentifier(DMA2_Stream6), OWNER_SDCARD, 0);
|
||||
dmaSetHandler(dmaGetIdentifier(DMA2_Stream6), SDMMC_DMA_ST6_IRQHandler, 1, 0);
|
||||
// Initialize DMA2 channel 6
|
||||
DMA2_Stream6->CR = 0; // Reset DMA Stream control register
|
||||
DMA2_Stream6->PAR = (uint32_t)&SDMMC1->FIFO;
|
||||
DMA2->HIFCR = IFCR_CLEAR_MASK_STREAM6; // Clear all interrupt flags
|
||||
DMA2_Stream6->CR = (DMA_CHANNEL_4 | DMA_SxCR_PFCTRL | // Prepare the DMA Stream configuration
|
||||
DMA_MINC_ENABLE | DMA_PDATAALIGN_WORD | // And write to DMA Stream CR register
|
||||
DMA_MDATAALIGN_WORD | DMA_PRIORITY_VERY_HIGH |
|
||||
DMA_MBURST_INC4 | DMA_PBURST_INC4 |
|
||||
DMA_MEMORY_TO_PERIPH);
|
||||
DMA2_Stream6->FCR = (DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); // Configuration FIFO control register
|
||||
dmaInit(dmaGetIdentifier(DMA2_Stream6), OWNER_SDCARD, 0);
|
||||
dmaSetHandler(dmaGetIdentifier(DMA2_Stream6), SDMMC_DMA_ST6_IRQHandler, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1643,25 +1666,25 @@ void SD_Initialize_LL(DMA_Stream_TypeDef *dma)
|
|||
/** -----------------------------------------------------------------------------------------------------------------*/
|
||||
bool SD_GetState(void)
|
||||
{
|
||||
// Check SDCARD status
|
||||
if(SD_GetStatus() == SD_OK) return true;
|
||||
return false;
|
||||
// Check SDCARD status
|
||||
if(SD_GetStatus() == SD_OK) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** -----------------------------------------------------------------------------------------------------------------*/
|
||||
bool SD_Init(void)
|
||||
{
|
||||
SD_Error_t ErrorState;
|
||||
SD_Error_t ErrorState;
|
||||
|
||||
// Check if SD card is present
|
||||
if(SD_IsDetected() != SD_PRESENT)
|
||||
// Check if SD card is present
|
||||
if(SD_IsDetected() != SD_PRESENT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialize SDMMC1 peripheral interface with default configuration for SD card initialization
|
||||
MODIFY_REG(SDMMC1->CLKCR, CLKCR_CLEAR_MASK, (uint32_t) SDMMC_INIT_CLK_DIV);
|
||||
MODIFY_REG(SDMMC1->CLKCR, CLKCR_CLEAR_MASK, (uint32_t) SDMMC_INIT_CLK_DIV);
|
||||
|
||||
if((ErrorState = SD_PowerON()) == SD_OK) // Identify card operating voltage
|
||||
{
|
||||
|
@ -1676,20 +1699,19 @@ bool SD_Init(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Configure SD Bus width
|
||||
if(ErrorState == SD_OK)
|
||||
{
|
||||
// Enable wide operation
|
||||
#ifdef USE_SDIO_1BIT
|
||||
ErrorState = SD_WideBusOperationConfig(SD_BUS_WIDE_1B);
|
||||
#else
|
||||
ErrorState = SD_WideBusOperationConfig(SD_BUS_WIDE_4B);
|
||||
#endif
|
||||
// Configure SD Bus width
|
||||
if(ErrorState == SD_OK)
|
||||
{
|
||||
// Enable wide operation
|
||||
if (sdioConfig()->use4BitWidth) {
|
||||
ErrorState = SD_WideBusOperationConfig(SD_BUS_WIDE_4B);
|
||||
} else {
|
||||
ErrorState = SD_WideBusOperationConfig(SD_BUS_WIDE_1B);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Configure the SDCARD device
|
||||
return ErrorState;
|
||||
// Configure the SDCARD device
|
||||
return ErrorState;
|
||||
}
|
||||
|
||||
/** -----------------------------------------------------------------------------------------------------------------*/
|
||||
|
@ -1697,44 +1719,44 @@ bool SD_Init(void)
|
|||
* @brief This function handles SD card interrupt request.
|
||||
*/
|
||||
void SDMMC1_IRQHandler(void) {
|
||||
// Check for SDMMC1 interrupt flags
|
||||
if ((SDMMC1->STA & SDMMC_STA_DATAEND) != 0) {
|
||||
SDMMC1->ICR = SDMMC_ICR_DATAENDC;
|
||||
SDMMC1->ICR = SDMMC_ICR_STATIC_FLAGS;
|
||||
SDMMC1->MASK &= ~(SDMMC_MASK_DATAENDIE | SDMMC_MASK_DCRCFAILIE | SDMMC_MASK_DTIMEOUTIE | \
|
||||
SDMMC_MASK_TXUNDERRIE | SDMMC_MASK_RXOVERRIE | SDMMC_MASK_TXFIFOHEIE | SDMMC_MASK_RXFIFOHFIE);
|
||||
// Check for SDMMC1 interrupt flags
|
||||
if ((SDMMC1->STA & SDMMC_STA_DATAEND) != 0) {
|
||||
SDMMC1->ICR = SDMMC_ICR_DATAENDC;
|
||||
SDMMC1->ICR = SDMMC_ICR_STATIC_FLAGS;
|
||||
SDMMC1->MASK &= ~(SDMMC_MASK_DATAENDIE | SDMMC_MASK_DCRCFAILIE | SDMMC_MASK_DTIMEOUTIE | \
|
||||
SDMMC_MASK_TXUNDERRIE | SDMMC_MASK_RXOVERRIE | SDMMC_MASK_TXFIFOHEIE | SDMMC_MASK_RXFIFOHFIE);
|
||||
|
||||
/* Currently doesn't implement multiple block write handling */
|
||||
if ((SD_Handle.Operation & 0x02) == (SDMMC_DIR_TX << 1)) {
|
||||
/* Disable the stream */
|
||||
dma_stream->CR &= ~DMA_SxCR_EN;
|
||||
SDMMC1->DCTRL &= ~(SDMMC_DCTRL_DMAEN);
|
||||
/* Transfer is complete */
|
||||
SD_Handle.TXCplt = 0;
|
||||
if ((SD_Handle.Operation & 0x01) == SD_MULTIPLE_BLOCK) {
|
||||
/* Send stop command in multiblock write */
|
||||
SD_TransmitCommand((SD_CMD_STOP_TRANSMISSION | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
}
|
||||
SD_Handle.TransferComplete = 1;
|
||||
SD_Handle.TransferError = SD_OK; // No transfer error
|
||||
}
|
||||
else if ((SDMMC1->STA & SDMMC_STA_DCRCFAIL) != 0)
|
||||
SD_Handle.TransferError = SD_DATA_CRC_FAIL;
|
||||
else if ((SDMMC1->STA & SDMMC_STA_DTIMEOUT) != 0)
|
||||
SD_Handle.TransferError = SD_DATA_TIMEOUT;
|
||||
else if ((SDMMC1->STA & SDMMC_STA_RXOVERR) != 0)
|
||||
SD_Handle.TransferError = SD_RX_OVERRUN;
|
||||
else if ((SDMMC1->STA & SDMMC_STA_TXUNDERR) != 0)
|
||||
SD_Handle.TransferError = SD_TX_UNDERRUN;
|
||||
/* Currently doesn't implement multiple block write handling */
|
||||
if ((SD_Handle.Operation & 0x02) == (SDMMC_DIR_TX << 1)) {
|
||||
/* Disable the stream */
|
||||
dma_stream->CR &= ~DMA_SxCR_EN;
|
||||
SDMMC1->DCTRL &= ~(SDMMC_DCTRL_DMAEN);
|
||||
/* Transfer is complete */
|
||||
SD_Handle.TXCplt = 0;
|
||||
if ((SD_Handle.Operation & 0x01) == SD_MULTIPLE_BLOCK) {
|
||||
/* Send stop command in multiblock write */
|
||||
SD_TransmitCommand((SD_CMD_STOP_TRANSMISSION | SD_CMD_RESPONSE_SHORT), 0, 1);
|
||||
}
|
||||
}
|
||||
SD_Handle.TransferComplete = 1;
|
||||
SD_Handle.TransferError = SD_OK; // No transfer error
|
||||
}
|
||||
else if ((SDMMC1->STA & SDMMC_STA_DCRCFAIL) != 0)
|
||||
SD_Handle.TransferError = SD_DATA_CRC_FAIL;
|
||||
else if ((SDMMC1->STA & SDMMC_STA_DTIMEOUT) != 0)
|
||||
SD_Handle.TransferError = SD_DATA_TIMEOUT;
|
||||
else if ((SDMMC1->STA & SDMMC_STA_RXOVERR) != 0)
|
||||
SD_Handle.TransferError = SD_RX_OVERRUN;
|
||||
else if ((SDMMC1->STA & SDMMC_STA_TXUNDERR) != 0)
|
||||
SD_Handle.TransferError = SD_TX_UNDERRUN;
|
||||
|
||||
SDMMC1->ICR = SDMMC_ICR_STATIC_FLAGS;
|
||||
SDMMC1->ICR = SDMMC_ICR_STATIC_FLAGS;
|
||||
|
||||
// Disable all SDMMC1 peripheral interrupt sources
|
||||
SDMMC1->MASK &= ~(SDMMC_MASK_DCRCFAILIE | SDMMC_MASK_DTIMEOUTIE
|
||||
| SDMMC_MASK_DATAENDIE |
|
||||
SDMMC_MASK_TXFIFOHEIE | SDMMC_MASK_RXFIFOHFIE | SDMMC_MASK_TXUNDERRIE |
|
||||
SDMMC_MASK_RXOVERRIE);
|
||||
// Disable all SDMMC1 peripheral interrupt sources
|
||||
SDMMC1->MASK &= ~(SDMMC_MASK_DCRCFAILIE | SDMMC_MASK_DTIMEOUTIE
|
||||
| SDMMC_MASK_DATAENDIE |
|
||||
SDMMC_MASK_TXFIFOHEIE | SDMMC_MASK_RXFIFOHFIE | SDMMC_MASK_TXUNDERRIE |
|
||||
SDMMC_MASK_RXOVERRIE);
|
||||
}
|
||||
|
||||
/** -----------------------------------------------------------------------------------------------------------------*/
|
||||
|
@ -1743,7 +1765,7 @@ void SDMMC1_IRQHandler(void) {
|
|||
*/
|
||||
void SDMMC_DMA_ST3_IRQHandler(dmaChannelDescriptor_t *dma)
|
||||
{
|
||||
UNUSED(dma);
|
||||
UNUSED(dma);
|
||||
// Transfer Error Interrupt management
|
||||
if((DMA2->LISR & DMA_LISR_TEIF3) != 0)
|
||||
{
|
||||
|
@ -1825,7 +1847,7 @@ void SDMMC_DMA_ST3_IRQHandler(dmaChannelDescriptor_t *dma)
|
|||
*/
|
||||
void SDMMC_DMA_ST6_IRQHandler(dmaChannelDescriptor_t *dma)
|
||||
{
|
||||
UNUSED(dma);
|
||||
UNUSED(dma);
|
||||
// Transfer Error Interrupt management
|
||||
if((DMA2->HISR & DMA_HISR_TEIF6) != 0)
|
||||
{
|
||||
|
|
|
@ -990,6 +990,7 @@ const clivalue_t valueTable[] = {
|
|||
#ifdef USE_SDCARD_SDIO
|
||||
{ "sdio_clk_bypass", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_SDIO_CONFIG, offsetof(sdioConfig_t, clockBypass) },
|
||||
{ "sdio_use_cache", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_SDIO_CONFIG, offsetof(sdioConfig_t, useCache) },
|
||||
{ "sdio_use_4bit_width", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_SDIO_CONFIG, offsetof(sdioConfig_t, use4BitWidth) },
|
||||
#endif
|
||||
|
||||
// PG_OSD_CONFIG
|
||||
|
|
|
@ -30,6 +30,7 @@ PG_REGISTER_WITH_RESET_TEMPLATE(sdioConfig_t, sdioConfig, PG_SDIO_CONFIG, 0);
|
|||
PG_RESET_TEMPLATE(sdioConfig_t, sdioConfig,
|
||||
.clockBypass = 0,
|
||||
.useCache = 0,
|
||||
.use4BitWidth = 1
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
typedef struct sdioConfig_s {
|
||||
uint8_t clockBypass;
|
||||
uint8_t useCache;
|
||||
uint8_t use4BitWidth;
|
||||
} sdioConfig_t;
|
||||
|
||||
PG_DECLARE(sdioConfig_t, sdioConfig);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue