UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Observer fdpousa
Observer
1,514 Views
Registered: ‎11-08-2017

How to write correctly a SD card for standalone application?

Hi all,

 

I have to implement some code in order to store some raw parameters in a SD Card, we are avoiding the xilffs. I am able to initialize the SD card correctly and now I want to implement the write function based on XSdPs_WritePolled() bsp provided function.

 

I have some questions related. What are the Arg and BlkCount parameters? What are they intended for? Where can I find some info in how to handle them?

 

I am basing on this example for read function:

 

XSdPs_ReadPolled(&sd0Inst, 1, 1, buf);

 

Why the argument is 1 and block counter is also 1?

 

Thanks in advance,

0 Kudos
2 Replies
Highlighted
Observer fdpousa
Observer
1,443 Views
Registered: ‎11-08-2017

Re: How to write correctly a SD card for standalone application?

Hi there,

 

Finally I was able to create a baremetal driver for Zynq based on Xilinx Standalone functions and in diskio files (in SDK v2016.4 there is not an example avaiable like other controllers). The driver can write or read in multiple blocks without problem. I attach you my code:

 

#include "xparameters.h"
#include "xsdps.h"

#include <stdio.h>

typedef unsigned char bool_t;

typedef enum xilSDResult
{
   XILSD_SUCCESS = 0,
   XILSD_NO_CARD,
   XILSD_WRITE_PROTECTION,
   XILSD_ERR_WRITING,
   XILSD_ERR_READING
} xilSDResult_t;

#define SD_DEVICE_ID    XPAR_XSDPS_0_DEVICE_ID
#define SD_BASEADDR     XPAR_PS7_SD_0_BASEADDR
#define SD_CLK_FREQ_HZ  XPAR_PS7_SD_0_SDIO_CLK_FREQ_HZ

#define CARD_INSERTED(a) ((a & XSDPS_PSR_CARD_INSRT_MASK) >> 16) ? TRUE : FALSE
#define WRITE_PROTECTED(a) ((a & XSDPS_PSR_WPS_PL_MASK) >> 18) ? TRUE :FALSE

static XSdPs gXilSdPsInst;

bool_t isCardInTheSocket(void);
bool_t isCardWriteProtected(void);
bool_t xilSdInit(void);
xilSDResult_t xilSdWrite(uint8_t* buff, uint32_t blkId, uint32_t numBlks);
xilSDResult_t xilSdRead(uint8_t* buff, uint32_t blkId, uint32_t numBlks);

int main(void)
{
   bool_t status;
   uint8_t write[3*512] = {0,0,0};
   uint8_t read[3*512] = {0,0,0};
   uint8_t read1[3*512] = {0,0,0};

   uint32_t i = 0;

   printf("XIL SD PS DRIVER TEST\n");

   for(i=0; i < (3*512); i++)
   {
      write[i] = 0xAA;
   }

   status = xilSdInit();

   printf("SD Controller init with status = %d \n", status);

   status = xilSdRead(read1, 3000, 3);

   printf("SD Reading with status = %d \n", status);

   printf("Read1 v1 = %d v2 = %d v3 =%d\n", read[0], read[1], read[511]);

   status = xilSdWrite(write, 3000, 3);

   printf("SD Writing with status = %d \n", status);

   printf("Write v1 = %d v2 = %d v3 =%d\n", write[1], write[512-1], write[3*512-1]);

   status = xilSdRead(read, 3000, 3);

   printf("SD Reading with status = %d \n", status);

   printf("Read v1 = %d v2 = %d v3 =%d\n", read[1], read[511], read[2*513]);

   return 0;
}

bool_t isCardInTheSocket(void)
{
   bool_t   ret;
   uint32_t statusReg;

   statusReg = XSdPs_GetPresentStatusReg(SD_BASEADDR);

   ret = CARD_INSERTED(statusReg);

   return ret;
}

bool_t isCardWriteProtected(void)
{
   bool_t   ret;
   uint32_t statusReg;

   statusReg = XSdPs_GetPresentStatusReg(SD_BASEADDR);

   ret = WRITE_PROTECTED(statusReg);

   return ret;
}

bool_t xilSdInit(void)
{
   bool_t ret = TRUE;

   uint32_t status;
   XSdPs *sdInstPtr = &gXilSdPsInst;
   XSdPs_Config *ConfigPtr;

   //Check if it is possible to write in card (card must be inserted)

   //Write enable can also be checked if it is routed on HW
   if(isCardInTheSocket() != TRUE)
   {
      printf("SD device is not inserted", NULL);
      return FALSE;
   }

   /*
    * If card can be written, controller is initialized
    */
   ConfigPtr = XSdPs_LookupConfig(SD_DEVICE_ID);
   if (ConfigPtr == NULL)
   {
      printf("SD device does not exist", NULL);
      ret = FALSE;
   }

   status = XSdPs_CfgInitialize(sdInstPtr, ConfigPtr, ConfigPtr->BaseAddress);
   if (status != XST_SUCCESS)
   {
      printf("SD controller could not be initialized", NULL);
      ret = FALSE;
   }

   status = XSdPs_CardInitialize(sdInstPtr);
   if(status != XST_SUCCESS)
   {
      printf("SD card could not be initialized", NULL);
      ret = FALSE;
   }

   return ret;

}

xilSDResult_t xilSdWrite(uint8_t* buff, uint32_t blkId, uint32_t numBlks)
{
   XSdPs *sdInstPtr = &gXilSdPsInst;
   uint32_t statusReg;
   xilSDResult_t ret;

   statusReg = XSdPs_WritePolled(sdInstPtr,blkId, numBlks, buff);
   if(statusReg != XST_SUCCESS)
   {
      printf("SD WRITING did not end correctly. Block = %d Blocks-count = %d", blkId, numBlks);
      ret = XILSD_ERR_WRITING;
   }

   return ret;
}

xilSDResult_t xilSdRead(uint8_t* buff, uint32_t blkId, uint32_t numBlks)
{
   XSdPs *sdInstPtr = &gXilSdPsInst;
   uint32_t statusReg;
   xilSDResult_t ret;

   statusReg = XSdPs_ReadPolled(sdInstPtr,blkId, numBlks, buff);
   if(statusReg != XST_SUCCESS)
   {
      printf("SD READING did not end correctly. Block = %d Blocks-count = %d", blkId, numBlks);
      ret = XILSD_ERR_READING;
   }

   return ret;
}

 

I hope this can be useful for future programmers,

 

Regards,

Tags (3)
Observer sidesantis01
Observer
99 Views
Registered: ‎01-18-2019

Re: How to write correctly a SD card for standalone application?

Great job with the driver!

Is there a way I can access a SD card to read an image with this? If not, do you have an idea how to get started with it?

I haven't found very good material when it comes to reading/writing to SD cards. This is definitely the best topic I've found so far. Do you have any resources that you used to help you write this code?

Thanks!

0 Kudos