gpt4 book ai didi

c - 从 vivado 2015.2 迁移到 2016.4 后初始化和使用 SD 卡不起作用

转载 作者:行者123 更新时间:2023-12-01 21:59:13 25 4
gpt4 key购买 nike

---------------- 编辑:附加说明---------------------------- --------------

我们只是尝试只迁移到 Vivado 2016.1。使用该版本,SD 卡可以使用新功能,即使它以某种方式破坏了音频编解码器。这很有趣,因为我们查看了从 2015.2 到 2016.4 的每个补丁说明,唯一提到的是他们为 sd 卡 I/O 添加了一个额外的数据类型,在下一个版本中将再次删除。

----------------结束编辑---------------------------- ----------------------------

我们刚刚将我们的机器人项目从vivado 2015.2 迁移到2016.4,升级后,当fpga (zynq 7020) ist 启动时,sd 镜像会闪烁,但不会执行处理器代码。经过一些调试后,我们发现,我们必须使用新的 FSBL 和 BSP 创建一个新的 SDK 项目,并将源文件包含在一个新的空应用程序中。在此之后,程序陷入了循环,因此我们不得不进一步调试。然后我们发现我们必须用我们的旧功能替换我们的实际 SD 卡功能(那些在 TRM UG585 中推荐的功能)。

新标清功能:

        void readBlock(unsigned char sd_id, unsigned int sector, unsigned int* buf){
unsigned int baseaddress = sd_id == 0 ? SD0_BASEADDRESS : SD1_BASEADDRESS; // Choose baseaddress based on the desired SD-slot
// START
TO_REG(baseaddress + SD_BLOCK_SIZE_REG_OFFSET) = SD_BLOCKCOUNT1_BLOCKSIZE512; // (1) Set Block Size Reg -> 512 Bytes, (2) Set Block Count Reg -> 1 Block
TO_REG(baseaddress + SD_ARGUMENT_REG_OFFSET) = sector; // (3) Set Argument Reg -> Readaddress
TO_REG(baseaddress + SD_TRANSFER_MODE_COMMAND_REG_OFFSET) = SD_SINGLEBLOCK_READ; // (4/5) Set Transfer Mode / Command Reg -> CMD17, Normal, Data Present, Enable Index-Check, Enable CRC-Check, Response length 48, Single Block, Read, Disable Auto CMD12, Disable Block Count, Disable DMA

while(!SD_CMD_COMPLETE_INTERRUPT(baseaddress)); // (6) Wait for Command Complete Interrupt
TO_REG(baseaddress + SD_INTERRUPT_STATUS_REG_OFFSET) = SD_INTERRUPT_STATUS_CMD_COMPLETE_MASK; // (7) Clear Command Complete Status
// (8) Get Response Data -> ignored, maybe checked for errors and retry
// (9) Write or Read -> Read

while(!SD_BUFFER_READ_RDY_INTERRUPT(baseaddress)); // (10-R) Wait for Buffer Read Ready Interrupt
TO_REG(baseaddress + SD_INTERRUPT_STATUS_REG_OFFSET) = SD_INTERRUPT_STATUS_BUFFER_READ_RDY_MASK; // (11-R) Clear Buffer Read Ready Status

for(unsigned char i = 0; i< 128; i++) // (12-R) Get Block Data
buf[i] = TO_REG(baseaddress + SD_BUFFER_DATA_PORT_REG_OFFSET);
// (13-R) More Blocks? -> No
// (14) Single/Multi/Infinite Block Transfer? -> Single

while(!SD_TRANSFER_COMPLETE_INTERRUPT(baseaddress)); // (15) Wait for Transfer Complete Interrupt
TO_REG(baseaddress + SD_INTERRUPT_STATUS_REG_OFFSET) = SD_INTERRUPT_STATUS_TRANSFER_COMPLETE_MASK; // (16) Clear Transfer Complete Status
// END
}

void writeBlock(unsigned char sd_id, unsigned int sector, unsigned int* buf){
unsigned int baseaddress = sd_id == 0 ? SD0_BASEADDRESS : SD1_BASEADDRESS; // Choose baseaddress based on the desired SD-slot
// START
TO_REG(baseaddress + SD_BLOCK_SIZE_REG_OFFSET) = SD_BLOCKCOUNT1_BLOCKSIZE512; // (1) Set Block Size Reg -> 512 Bytes, (2) Set Block Count Reg -> 1 Block
TO_REG(baseaddress + SD_ARGUMENT_REG_OFFSET) = sector; // (3) Set Argument Reg -> Readaddress
TO_REG(baseaddress + SD_TRANSFER_MODE_COMMAND_REG_OFFSET) = SD_SINGLEBLOCK_WRITE; // (4/5) Set Transfer Mode / Command Reg -> CMD24, Normal, Data Present, Enable Index-Check, Enable CRC-Check, Response length 48, Single Block, Write, Disable Auto CMD12, Disable Block Count, Disable DMA

while(!SD_CMD_COMPLETE_INTERRUPT(baseaddress)); // (6) Wait for Command Complete Interrupt
TO_REG(baseaddress + SD_INTERRUPT_STATUS_REG_OFFSET) = SD_INTERRUPT_STATUS_CMD_COMPLETE_MASK; // (7) Clear Command Complete

Status
// (8) Get Response Data -> ignored, maybe checked for errors and retry
// (9) Write or Read -> Write

while(!SD_BUFFER_WRITE_RDY_INTERRUPT(baseaddress)); // (10-W) Wait for Buffer Write Ready Interrupt
TO_REG(baseaddress + SD_INTERRUPT_STATUS_REG_OFFSET) = SD_INTERRUPT_STATUS_BUFFER_WRITE_RDY_MASK; // (11-W) Clear Buffer Write Ready Status

for(unsigned char i = 0; i< 128; i++) // (12-W) Set Block Data
TO_REG(baseaddress + SD_BUFFER_DATA_PORT_REG_OFFSET) = buf[i];
// (13-W) More Blocks? -> No
// (14) Single/Multi/Infinite Block Transfer? -> Single

while(!SD_TRANSFER_COMPLETE_INTERRUPT(baseaddress)); // (15) Wait for Transfer Complete Interrupt
TO_REG(baseaddress + SD_INTERRUPT_STATUS_REG_OFFSET) = SD_INTERRUPT_STATUS_TRANSFER_COMPLETE_MASK; // (16) Clear Transfer Complete Status
// END
}

旧 SD 功能:

DRESULT readBlock(unsigned char sd_id, unsigned long sector, unsigned char* buff){

unsigned int count = 1;

if(sd_id > 1) return RES_ERROR; //only id = 0 or id = 1 is valid

s32 Status;
DWORD LocSector = sector;

/* Convert LBA to byte address if needed */
if ((SdInstance[sd_id].HCS) == 0U) {
LocSector *= (DWORD)XSDPS_BLK_SIZE_512_MASK;
}

Status = XSdPs_ReadPolled(&SdInstance[sd_id], (u32)LocSector, count,(unsigned char *) buff);
if (Status != XST_SUCCESS) {
return RES_ERROR;
}

return RES_OK;
}


DRESULT writeBlock(unsigned char sd_id, unsigned long sector, unsigned char* buff){

unsigned int count = 1;
if(sd_id > 1) return RES_ERROR; //only id = 0 or id = 1 is valid

s32 Status;
DWORD LocSector = sector;

/* Convert LBA to byte address if needed */
if ((SdInstance[sd_id].HCS) == 0U) {
LocSector *= (DWORD)XSDPS_BLK_SIZE_512_MASK;
}

Status = XSdPs_WritePolled(&SdInstance[sd_id], (u32)LocSector, count,buff);
if (Status != XST_SUCCESS) {
return RES_ERROR;
}

return RES_OK;
}

这解决了处理器代码的一般问题,但我们仍然无法初始化或在 SD 卡上进行 IO 操作。此外,我们发现在初始化 SD 时,函数 getBusWidth (bsp) 在尝试调用 XSdPs_CmdTransfer() -> XSdPs_ReadReg() 时失败。当我们尝试使用我们的旧功能在 SD 卡上执行 IO 操作时,情况似乎也是如此。

SD 初始化函数:

unsigned char initSD(unsigned char sd_id){

if(sd_id > 1) return 0xFF; //only id = 0 or id = 1 is valid

DSTATUS s = 0;
s32 Status;
u8 SCR[8] = {0U};
u8 ReadBuff[64] = {0U};

XSdPs_Config *SdConfig = NULL;

/*
* Initialize the host controller
*/
SdConfig = &XSdPs_ConfigTable[sd_id];

Status = XSdPs_CfgInitialize(&SdInstance[sd_id], SdConfig, SdConfig->BaseAddress);
if (Status != XST_SUCCESS) {
s |= STA_NOINIT;
return s;
}

Status = XSdPs_SdCardInitialize(&SdInstance[sd_id]);
if (Status != XST_SUCCESS) {
s |= STA_NOINIT;
return s;
}

Status = XSdPs_Change_ClkFreq(&SdInstance[sd_id], SD_CLK_25_MHZ);
if (Status != XST_SUCCESS) {
s |= STA_NOINIT;
return s;
}

Status = XSdPs_Select_Card(&SdInstance[sd_id]);
if (Status != XST_SUCCESS) {
s |= STA_NOINIT;
return s;
}

Status = XSdPs_Get_BusWidth(&SdInstance[sd_id], SCR);
if (Status != XST_SUCCESS) {
s |= STA_NOINIT;
return s;
}

Status = XSdPs_Get_BusSpeed(&SdInstance[sd_id], ReadBuff);
if (Status != XST_SUCCESS) {
s |= STA_NOINIT;
return s;
}

if((ReadBuff[13] & HIGH_SPEED_SUPPORT) != 0U){
Status = XSdPs_Change_BusSpeed(&SdInstance[sd_id]);
if (Status != XST_SUCCESS) {
s |= STA_NOINIT;
return s;
}
}

Status = XSdPs_Pullup(&SdInstance[sd_id]);
if (Status != XST_SUCCESS) {
s |= STA_NOINIT;
return s;
}

if ((SCR[1] & WIDTH_4_BIT_SUPPORT) != 0U) {
Status = XSdPs_Change_BusWidth(&SdInstance[sd_id]);
if (Status != XST_SUCCESS) {
s |= STA_NOINIT;
return s;
}
}

Status = XSdPs_SetBlkSize(&SdInstance[sd_id], (u16)XSDPS_BLK_SIZE_512_MASK);
if (Status != XST_SUCCESS) {
s |= STA_NOINIT;
return s;
}

在对我们的问题进行了相当简短的描述之后 ;),现在是我的问题。你们中有没有人遇到过类似的问题并且知道解决方法或者可以指出我们可以找到解决方案的方向?

提前致谢:)。

删除0r

最佳答案

所以它之前有效,这意味着您的 SD 配置似乎是正确的。

您是否尝试过在 XSdPs_CardInitialize(...) 函数中构建,而不是您自定义的 initSD(...) 函数? XSdPs_CardInitialize(...) 位于 sdps 驱动程序的 xsdps.c 中。这个函数正在做更多的检查,还有一些不同顺序的事情,就像你在你的 initSD(...) 中一样。

那么试试这个:

unsigned char initSD(unsigned char sd_id){

if(sd_id > 1) return 0xFF; //only id = 0 or id = 1 is valid

DSTATUS s = 0;
s32 Status;

XSdPs_Config *SdConfig = NULL;

/*
* Initialize the host controller
*/
SdConfig = &XSdPs_ConfigTable[sd_id];

Status = XSdPs_CfgInitialize(&SdInstance[sd_id], SdConfig, SdConfig->BaseAddress);
if (Status != XST_SUCCESS) {
s |= STA_NOINIT;
return s;
}

Status = XSdPs_CardInitialize(&SdInstance[sd_id]);
if (Status != XST_SUCCESS) {
s |= STA_NOINIT;
return s;
}

return Status;
}

关于c - 从 vivado 2015.2 迁移到 2016.4 后初始化和使用 SD 卡不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42760968/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com