Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

SD card and FreeRTOS

Posted by owaisfazal on September 11, 2014

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;
    }

SD card and FreeRTOS

Posted by davedoors on September 11, 2014

So there are ASF functions and nothing to do with FreeRTOS? Have you tried the ASF documentation?


SD card and FreeRTOS

Posted by owaisfazal on September 11, 2014

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.


SD card and FreeRTOS

Posted by owaisfazal on September 11, 2014

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


SD card and FreeRTOS

Posted by woops_ on September 11, 2014

Help? http://www.freertos.org/FreeRTOSSupportForumArchive/June2014/freertosFreeRTOSFATSLSDCardinitializationissuec35711ecj.html


SD card and FreeRTOS

Posted by owaisfazal on September 11, 2014

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.


[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner