FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [September 2014 Threads]
Hello everyone,
I am a beginner in using SD cards. I am working with SAM4SD32C in Atmel Studio. So far I have managed to initialize the HSMCI interface and SD card is also initialized by sending the corresponding commands given in SD simplified specifications. Now i would like to test read and write operation for the SD card to make sure everything is working properly. After this my intention is to use the SD card as a storage device in FreeRTOS+FATSL. I have gone through the examples given in Atmel Studio and I have the following functions which are used to write and read to and from the SD card. I am stuck at this point as I am not sure what to give in the parameters of these functions to initiate a write or read operation. The functions are as follows, The read block and write block function calls the adtc command and the read block init and write block init send CMD13 to check the data ready status from the card. Please also suggest how I could integrate these function into FreeRTOS+FATSL to be able to use the SD card as a storage device with FreeRTOS.
Regards,
Owais
uint32_t sd_mmc_init_read_blocks(uint8_t slot, uint32_t start,
uint16_t nb_block)
{
uint32_t cmd, arg, resp;
// Wait for data ready status
if (!sd_mmc_cmd13())
{
printf("CMD13 data ready error\n\r");
return FAIL;
}
if (nb_block > 1)
{
cmd = SDMMC_CMD18_READ_MULTIPLE_BLOCK;
}
else
{
cmd = SDMMC_CMD17_READ_SINGLE_BLOCK;
}
/*
* SDSC Card (CCS=0) uses byte unit address,
* SDHC and SDXCCards(CCS=1)use blockunitaddress(512Bytes unit).
*/
arg = start;
if (!hsmci_adtc_start(cmd, arg, SD_MMC_BLOCK_SIZE, nb_block,1))
{
printf("adtc start error\n\r");
return FAIL;
}
// Check response
resp = hsmci_get_response();
if (resp & CARD_STATUS_ERR_RD_WR)
{
return FAIL;
}
sd_mmc_nb_block_remaining = nb_block;
sd_mmc_nb_block_to_tranfer = nb_block;
printf("Read blocks initialization done\n\r");
return OK;
}
uint32_t sd_mmc_start_read_blocks(void *dest, uint16_t
nb_block)
{
if (!(sd_mmc_nb_block_remaining >= nb_block))
{
printf("No. of blocks remaining is >= start read
block\n\r");
return FAIL;
}
if (!hsmci_start_read_blocks(dest, nb_block))
{
printf("Start read blocks failed\n\r");
sd_mmc_nb_block_remaining = 0;
return FAIL;
}
sd_mmc_nb_block_remaining -= nb_block;
return OK;
}
uint32_t sd_mmc_wait_end_of_read_blocks(int abort)
{
if (!hsmci_wait_end_of_read_blocks())
{
printf("HSMCI wait end of read blocks failed\n\r");
return FAIL;
}
if (abort)
{
sd_mmc_nb_block_remaining = 0;
}
else if (sd_mmc_nb_block_remaining)
{
return OK;
}
// All blocks are transfered then stop read operation
if (sd_mmc_nb_block_to_tranfer == 1)
{
// Single block transfer, then nothing to do
printf("All blocks transferred\n\r");
return OK;
}
if (!hsmci_adtc_stop(SDMMC_CMD12_STOP_TRANSMISSION, 0))
{
hsmci_adtc_stop(SDMMC_CMD12_STOP_TRANSMISSION, 0);
}
return OK;
}
uint32_t sd_mmc_init_write_blocks(uint8_t slot, uint32_t start,
uint16_t nb_block)
{
uint32_t cmd, arg, resp;
if (nb_block > 1)
{
cmd = SDMMC_CMD25_WRITE_MULTIPLE_BLOCK;
}
else
{
cmd = SDMMC_CMD24_WRITE_BLOCK;
}
/*
* SDSC Card (CCS=0) uses byte unit address,
* SDHC and SDXCCards(CCS=1)useblockunitaddress(512Bytes unit).
*/
arg = start;
if (!hsmci_adtc_start(cmd, arg, SD_MMC_BLOCK_SIZE, nb_block,1))
{
printf("adtc start error\n\r");
return FAIL;
}
// Check response
resp = hsmci_get_response();
if (resp & CARD_STATUS_ERR_RD_WR)
{
return FAIL;
}
sd_mmc_nb_block_remaining = nb_block;
sd_mmc_nb_block_to_tranfer = nb_block;
printf("Write blocks initialization done\n\r");
return OK;
}
uint32_t sd_mmc_start_write_blocks(const void *src, uint16_t
nb_block)
{
if(!(sd_mmc_nb_block_remaining >= nb_block))
{
printf("No. of blocks remaining is >= to start write
block\n\r");
return FAIL;
}
if (!hsmci_start_write_blocks(src, nb_block))
{
printf("Start write blocks failed\n\r");
sd_mmc_nb_block_remaining = 0;
return FAIL;
}
sd_mmc_nb_block_remaining -= nb_block;
return OK;
}
uint32_t sd_mmc_wait_end_of_write_blocks(int abort)
{
if (!hsmci_wait_end_of_write_blocks())
{
printf("HSMCI wait end of write blocks failed\n\r");
return FAIL;
}
if (abort)
{
sd_mmc_nb_block_remaining = 0;
}
else if (sd_mmc_nb_block_remaining)
{
return OK;
}
// All blocks are transfered then stop write operation
if (sd_mmc_nb_block_to_tranfer == 1)
{
// Single block transfer, then nothing to do
printf("All blocks written\n\r");
return OK;
}
// Note: SPI multiblock writes terminate using a special
// token, not a STOP_TRANSMISSION request.
if (!hsmci_adtc_stop(SDMMC_CMD12_STOP_TRANSMISSION, 0))
{
return FAIL;
}
else
{
printf("adtc stop command executed\n\r");
}
return OK;
}
uint32_t hsmci_adtc_start(uint32_t cmd, uint32_t arg, uint16_t
block_size, uint16_t nb_block, uint32_t access_block)
{
uint32_t cmdr;
#ifdef HSMCI_MR_PDCMODE
if (access_block)
{
// Enable PDC for HSMCI
HSMCI->HSMCI_MR |= HSMCI_MR_PDCMODE;
}
else
{
// Disable PDC for HSMCI
HSMCI->HSMCI_MR &= ~HSMCI_MR_PDCMODE;
}
#endif
// Enabling Read/Write Proof allows to stop the HSMCI Clock
// during read/write access if the internal FIFO is full.
// This will guarantee data integrity, not bandwidth.
HSMCI->HSMCI_MR |= HSMCI_MR_WRPROOF | HSMCI_MR_RDPROOF;
// Force byte transfer if needed
if (block_size & 0x3)
{
HSMCI->HSMCI_MR |= HSMCI_MR_FBYTE;
}
else
{
HSMCI->HSMCI_MR &= ~HSMCI_MR_FBYTE;
}
if (cmd & SDMMC_CMD_WRITE)
{
cmdr = HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRDIR_WRITE;
}
else
{
cmdr = HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRDIR_READ;
}
if (cmd & SDMMC_CMD_SDIO_BYTE)
{
cmdr |= HSMCI_CMDR_TRTYP_BYTE;
// Value 0 corresponds to a 512-byte transfer
HSMCI->HSMCI_BLKR = ((block_size % 512) <<HSMCI_BLKR_BCNT_Pos);
}
else
{
HSMCI->HSMCI_BLKR = (block_size << HSMCI_BLKR_BLKLEN_Pos) |
(nb_block << HSMCI_BLKR_BCNT_Pos);
if (cmd & SDMMC_CMD_SDIO_BLOCK)
{
cmdr |= HSMCI_CMDR_TRTYP_BLOCK;
}
else if (cmd & SDMMC_CMD_STREAM)
{
cmdr |= HSMCI_CMDR_TRTYP_STREAM;
}
else if (cmd & SDMMC_CMD_SINGLE_BLOCK)
{
cmdr |= HSMCI_CMDR_TRTYP_SINGLE;
}
else if (cmd & SDMMC_CMD_MULTI_BLOCK)
{
cmdr |= HSMCI_CMDR_TRTYP_MULTIPLE;
}
else
{
//Assert(FAIL); // Incorrect flags
printf("Incorrect flags in adtc command\n\r");
}
}
hsmci_transfert_pos = 0;
hsmci_block_size = block_size;
hsmci_nb_block = nb_block;
return hsmci_send_cmd_execute(cmdr, cmd, arg);
}
uint32_t hsmci_adtc_stop(uint32_t cmd, uint32_t arg)
{
return hsmci_send_cmd_execute(HSMCI_CMDR_TRCMD_STOP_DATA, cmd,
arg);
}
uint32_t sd_mmc_cmd13(void)
{
uint32_t nec_timeout;
/* Wait for data ready status.
* Nec timing: 0 to unlimited
* However a timeout is used.
* 200 000 * 8 cycles
*/
nec_timeout = 200000;
do
{
if (!hsmci_send_cmd(SDMMC_MCI_CMD13_SEND_STATUS, rca << 16))
{
return FAIL;
}
// Check busy flag
if (hsmci_get_response() & CARD_STATUS_READY_FOR_DATA)
{
break;
}
if (nec_timeout-- == 0)
{
printf("%s: CMD13 Busy timeout\n\r", __func__);
return FAIL;
}
} while (1);
return OK;
}
So there are ASF functions and nothing to do with FreeRTOS? Have you tried the ASF documentation?
I was very reluctant to post this right now since everything is related to ASF but this is where I have to start in order to use SD card with FreeRTOS+FATSL. I have searched a lot but in vain. ASF documentation explains the functions and their variables but not exactly how to read and write and I cannot find any application notes related to HSMCI. Please give me some references where I could get help in this regard.
Is there anyone who has implemented the FreeRTOS+FAT for an SD card before. If so please do share your experience. I am stuck at this point and cannot proceed.
Regrads,
Owais
Help? http://www.freertos.org/FreeRTOSSupportForumArchive/June2014/freertosFreeRTOSFATSLSDCardinitializationissuec35711ecj.html
Thanks woops_ I have seen this thread before. It seems as if it has gone idle since a while now. I wonder what is the progress now.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.