下面来介绍一下,emmc、sd的驱动实现。
一、vivado PL端设置
PL端 设置: 如果你是用sd卡、或者EMMC要在vivado zynq核上勾选 sd、emmc。
emmc和sd使用公用那几个IO.同一个时刻只能当做其中一个使用。
zynq有两个sd接口。也可以一个给sd卡,一个给EMMC使用。
下面的例子是修改官方例程。
二、ps端代码编写
SD 、emm初始化基本一样。这是裸机不需要文件系统。直接对sd卡/emmc进行读写
#ifdef __ICCARM__
#pragma data_alignment = 32
u8 DestinationAddress[10*1024];
#pragma data_alignment = 32
u8 SourceAddress[10*1024];
#else
u8 DestinationAddress[10*1024] __attribute__ ((aligned(32)));
u8 SourceAddress[10*1024]__attribute__ ((aligned(32)));
#endif
#define TEST 7/* Number of SD blocks to test */
#define NUM_BLOCKS 16/* Sector offset to test */
#define SECTOR_OFFSET 204800
XSdPs SD_InstancePtr;
bool SdCard_Init(void)
{
static XSdPs SdInstance;
XSdPs_Config *SdConfig;
int Status;
u32 BuffCnt;
/* * Since block size is 512 bytes. File Size is 512*BlockCount. */
u32 FileSize = (512*NUM_BLOCKS);
/* File Size is only up to 2MB */
u32 Sector = SECTOR_OFFSET;
for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++)
{
SourceAddress[BuffCnt] = 4;
//TEST + BuffCnt;
}
/* * Initialize the host controller */
SdConfig = XSdPs_LookupConfig(XPAR_XSDPS_1_DEVICE_ID);
if (NULL == SdConfig)
{
return XST_FAILURE;
}
Status = XSdPs_CfgInitialize(&SdInstance, SdConfig,SdConfig->BaseAddress);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
Status = XSdPs_CardInitialize(&SdInstance);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/* * Write data to SD/eMMC. */
if (!(SdInstance.HCS)) Sector *= XSDPS_BLK_SIZE_512_MASK;
Status = XSdPs_WritePolled(&SdInstance, Sector, NUM_BLOCKS, SourceAddress);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/* * Read data from SD/eMMC. */
if (!(SdInstance.HCS))
Sector *= XSDPS_BLK_SIZE_512_MASK;
Status = XSdPs_ReadPolled(&SdInstance, Sector, NUM_BLOCKS, DestinationAddress);
if (Status!=XST_SUCCESS)
{
return XST_FAILURE;
}
/* * Data verification */
for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++)
{
if(SourceAddress[BuffCnt] != DestinationAddress[BuffCnt])
{
Uart_Send("qwert",5);
return XST_FAILURE;
}
}
Uart_Send(DestinationAddress,FileSize); //输出从sd或者emmc的数观察对不对
}