lindahnu 发表于 2022-8-23 11:10:38

SDIO HAL库疑问

1、执行读写操作时,对于标准卡的地址为什么要乘以512,高容量的卡就不用?

例如函数HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)

    if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
    {
      add *= 512U;
    }


2、函数HAL_StatusTypeDef HAL_SD_ConfigWideBusOperation(SD_HandleTypeDef *hsd, uint32_t WideMode)
调用SD_FindSCR为什么要配置块大小为8byte?

static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR)
{
SDIO_DataInitTypeDef config;
uint32_t errorstate;
uint32_t tickstart = HAL_GetTick();
uint32_t index = 0U;
uint32_t tempscr = {0U, 0U};
uint32_t *scr = pSCR;

/* Set Block Size To 8 Bytes */
errorstate = SDMMC_CmdBlockLength(hsd->Instance, 8U);
if(errorstate != HAL_SD_ERROR_NONE)
{
    return errorstate;
}

/* Send CMD55 APP_CMD with argument as card's RCA */
errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)((hsd->SdCard.RelCardAdd) << 16U));
if(errorstate != HAL_SD_ERROR_NONE)
{
    return errorstate;
}

config.DataTimeOut   = SDMMC_DATATIMEOUT;
config.DataLength    = 8U;
config.DataBlockSize = SDIO_DATABLOCK_SIZE_8B;
config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
config.TransferMode= SDIO_TRANSFER_MODE_BLOCK;
config.DPSM          = SDIO_DPSM_ENABLE;
(void)SDIO_ConfigData(hsd->Instance, &config);

/* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */
errorstate = SDMMC_CmdSendSCR(hsd->Instance);
if(errorstate != HAL_SD_ERROR_NONE)
{
    return errorstate;
}

while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT))
{
    if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXDAVL))
    {
      *(tempscr + index) = SDIO_ReadFIFO(hsd->Instance);
      index++;
    }
    else if(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXACT))
    {
      break;
    }

    if((HAL_GetTick() - tickstart) >=SDMMC_DATATIMEOUT)
    {
      return HAL_SD_ERROR_TIMEOUT;
    }
}

if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
{
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);

    return HAL_SD_ERROR_DATA_TIMEOUT;
}
else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
{
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);

    return HAL_SD_ERROR_DATA_CRC_FAIL;
}
else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
{
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);

    return HAL_SD_ERROR_RX_OVERRUN;
}
else
{
    /* No error flag set */
    /* Clear all the static flags */
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);

    *scr = (((tempscr & SDMMC_0TO7BITS) << 24)| ((tempscr & SDMMC_8TO15BITS) << 8) |\
            ((tempscr & SDMMC_16TO23BITS) >> 8) | ((tempscr & SDMMC_24TO31BITS) >> 24));
    scr++;
    *scr = (((tempscr & SDMMC_0TO7BITS) << 24)| ((tempscr & SDMMC_8TO15BITS) << 8) |\
            ((tempscr & SDMMC_16TO23BITS) >> 8) | ((tempscr & SDMMC_24TO31BITS) >> 24));

}

return HAL_SD_ERROR_NONE;
}





eric2013 发表于 2022-8-24 01:41:17

帮顶,这个得研究SDIO协议才行。

lindahnu 发表于 2022-8-24 10:32:28

eric2013 发表于 2022-8-24 01:41
帮顶,这个得研究SDIO协议才行。

看了协议,第一个问题知道怎么回事了,第二个问题就不知道了,还有一个函数HAL_SD_GetCardStatus是设置块长度为64byte,也不知道为什么

eric2013 发表于 2022-8-25 10:28:29

lindahnu 发表于 2022-8-24 10:32
看了协议,第一个问题知道怎么回事了,第二个问题就不知道了,还有一个函数HAL_SD_GetCardStatus是设置块 ...
还得继续研究,我平时没关心过这个,都是直接用,有问题再查查,懒了。

lindahnu 发表于 2022-9-6 11:16:33

由于SCR是64bit,所以要设置块长度为8byte,而SD状态为512bit,所以设置为64byte

lindahnu 发表于 2022-9-6 11:18:15

SCR为64bit,SD卡状态为512bit,所以要分别设置块长度为8byte和64byte
页: [1]
查看完整版本: SDIO HAL库疑问