Dear All,
I am using SDIO to store data on a SD card and I would like to get the SD card size/capacity [in GB] (which corresponds to CMD9 with SD protocol and SPI). In the example ''periph_SDIO'', there is:
SDIO_Read_Direct(LPC_SDMMC, 1, 0x1C, &val) and SDIO_Read_Direct(LPC_SDMMC, 1, 0x1D, &val)
Where do the 0x1C or 0x1D come from ?
I look into the file "simplified_SDIO_card_spec.pdf" but cannot make sense of it to answer the question above. I understand that the information should be in the FBR -> CIS register (right?).
Looking further in the "periph_SDIO" example, there is SDIO_Read_Direct(LPC_SDMMC, 1, 0x04, &val) (clear the interrupt). Again, I am not able to understand or to calculate the 0x04 address.
Could you explain or point to a good document in order to understand these addresses?
Thank you very much.
Hi Valeremar,
I checked the SDIO_Read_Direct function, it is using the CMD52 to access the according register.
From the CMD52 command description, we can get the CMD52 can access a signal register within the total 128K of register space in any I/O function, including the common I/O area (CIA).
As you know, CIS is included in the CIA register.
So, I think the 0X1D, 0X1C, 0X04 is not the address, it should be the SDIO register.
More details, you also can refer to the SDIO card spec:
http://ugweb.cs.ualberta.ca/~c274/resources/hardware/SDcards/SD_SDIO_specsv1.pdf
https://www.sdcard.org/developers/overview/sdio/sdio_spec/Simplified_SDIO_Card_Spec.pdf
Associated with these code to find the according SDIO register which is controlled by the CMD52:
int SDIO_Write_Direct(LPC_SDMMC_T *pSDMMC, uint32_t func, uint32_t addr, uint32_t data)
{
int ret;
ret = SDIO_Send_Command(pSDMMC, CMD52, (func << 28) | (addr << 9) | (data & 0xFF) | (1UL << 31));
if (ret) return ret;
/* Check response for errors */
if(sdioif->response[0] & 0xcb00){
/* COM_CRC_ERROR */
/* ILLEGAL_CRC_ERROR */
/* ERROR */
/* RFU FUNCTION_NUMBER */
/* OUT_OF_RANGE */
/* Response flag error */
return SDIO_ERR_READWRITE;
}
return data != (sdioif->response[0] & 0xFF);
}
uint32_t SDIO_Send_Command(LPC_SDMMC_T *pSDMMC, uint32_t cmd, uint32_t arg)
{
uint32_t ret, ival;
uint32_t imsk = pSDMMC->INTMASK;
ret = sdioif->wait_evt(pSDMMC, SDIO_START_COMMAND, (void *)(cmd & 0x3F));
ival = SDIO_CMD_INT_MSK & ~ret;
/* Set data interrupts for data commands */
if (cmd & SDIO_CMD_DATA) {
ival |= SDIO_DATA_INT_MSK;
imsk |= SDIO_DATA_INT_MSK;
}
Chip_SDIF_SetIntMask(pSDMMC, ival);
Chip_SDIF_SendCmd(pSDMMC, cmd, arg);
ret = sdioif->wait_evt(pSDMMC, SDIO_WAIT_COMMAND, 0);
if (!ret && (cmd & SDIO_CMD_RESP_R1)) {
Chip_SDIF_GetResponse(pSDMMC, &sdioif->response[0]);
}
Chip_SDIF_SetIntMask(pSDMMC, imsk);
return ret;
}
Wish it helps you!
Have a great day,
Kerry
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------