|
|
|
@ -14,15 +14,14 @@
|
|
|
|
|
* 2010-10-13 Wangmeng Added sep4020 support
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "sdcard.h"
|
|
|
|
|
//#include <dfs_config.h>
|
|
|
|
|
#include <rtthread.h>
|
|
|
|
|
|
|
|
|
|
volatile rt_int32_t RCA;
|
|
|
|
|
#include "sdcard.h"
|
|
|
|
|
|
|
|
|
|
#ifdef RT_USING_DFS
|
|
|
|
|
volatile rt_int32_t RCA;
|
|
|
|
|
|
|
|
|
|
/* RT-Thread Device Driver Interface */
|
|
|
|
|
#include <rtthread.h>
|
|
|
|
|
#include <dfs_fs.h>
|
|
|
|
|
|
|
|
|
|
/*GLOBAL SD DEVICE PONITER*/
|
|
|
|
@ -62,9 +61,11 @@ static void delay (U32 j)
|
|
|
|
|
U32 i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < j; i++)
|
|
|
|
|
{};
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
/* nothing */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Send the command to set the data transfer mode
|
|
|
|
|
* @param cmd:the command to sent
|
|
|
|
@ -81,22 +82,22 @@ static rt_err_t cmd_data(U16 cmd,U32 arg,U16 mode,U16 blk_len,U16 num,U16 mask)
|
|
|
|
|
U32 to = 10000;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
*(RP)SDC_CLOCK_CONTROL = 0Xff00; //配置SD时钟,512分频,关闭SD 时钟
|
|
|
|
|
*(RP)SDC_CLOCK_CONTROL = 0Xff04; //打开SD时钟,512分频,开启SD 时钟
|
|
|
|
|
*(RP)SDC_INTERRUPT_STATUS_MASK = mask; //中断状态屏蔽寄存器赋值
|
|
|
|
|
*(RP)SDC_CLOCK_CONTROL = 0Xff00;
|
|
|
|
|
*(RP)SDC_CLOCK_CONTROL = 0Xff04;
|
|
|
|
|
*(RP)SDC_INTERRUPT_STATUS_MASK = mask;
|
|
|
|
|
|
|
|
|
|
*(RP)SDC_TRANSFER_MODE = mode; //传输模式选择寄存器赋值
|
|
|
|
|
*(RP)SDC_TRANSFER_MODE = mode;
|
|
|
|
|
|
|
|
|
|
*(RP)SDC_BLOCK_SIZE = blk_len; //数据块长度寄存器赋值
|
|
|
|
|
*(RP)SDC_BLOCK_COUNT = num; //数据块数目寄存器赋值
|
|
|
|
|
*(RP)SDC_ARGUMENT = arg; //命令参数寄存器赋值
|
|
|
|
|
*(RP)SDC_COMMAND = cmd; //命令控制寄存器赋值
|
|
|
|
|
*(RP)SDC_BLOCK_SIZE = blk_len;
|
|
|
|
|
*(RP)SDC_BLOCK_COUNT = num;
|
|
|
|
|
*(RP)SDC_ARGUMENT = arg;
|
|
|
|
|
*(RP)SDC_COMMAND = cmd;
|
|
|
|
|
|
|
|
|
|
delay(10);
|
|
|
|
|
|
|
|
|
|
i = *(RP)SDC_INTERRUPT_STATUS & 0x1000;
|
|
|
|
|
|
|
|
|
|
while(i != 0x1000) //判断:是否命令发送完毕,并且收到响应
|
|
|
|
|
while (i != 0x1000)
|
|
|
|
|
{
|
|
|
|
|
i = *(RP)SDC_INTERRUPT_STATUS & 0x1000;
|
|
|
|
|
#ifdef USE_TIMEOUT
|
|
|
|
@ -110,11 +111,7 @@ static rt_err_t cmd_data(U16 cmd,U32 arg,U16 mode,U16 blk_len,U16 num,U16 mask)
|
|
|
|
|
}
|
|
|
|
|
delay(160);
|
|
|
|
|
|
|
|
|
|
#ifdef USE_TIMEOUT
|
|
|
|
|
//DBOUT("cmd_data TO is %d\n",to);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return *(RP)SDC_RESPONSE0; //返回命令反馈信息
|
|
|
|
|
return *(RP)SDC_RESPONSE0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static rt_err_t cmd_response(U16 Cmd, U32 Arg, U16 TransMode, U16 BlkLen, U16 Nob, U16 IntMask)
|
|
|
|
@ -124,23 +121,23 @@ static rt_err_t cmd_response(U16 Cmd,U32 Arg,U16 TransMode,U16 BlkLen,U16 Nob,U1
|
|
|
|
|
U32 to = 50000;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
*(RP)SDC_CLOCK_CONTROL=0Xff00; //配置SD时钟
|
|
|
|
|
*(RP)SDC_CLOCK_CONTROL = 0Xff00;
|
|
|
|
|
|
|
|
|
|
*(RP)SDC_CLOCK_CONTROL=0Xff04; //打开SD时钟
|
|
|
|
|
*(RP)SDC_CLOCK_CONTROL = 0Xff04;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*(RP)SDC_INTERRUPT_STATUS_MASK=IntMask; //中断状态屏蔽寄存器赋值
|
|
|
|
|
*(RP)SDC_TRANSFER_MODE=TransMode; //传输模式选择寄存器赋值
|
|
|
|
|
*(RP)SDC_BLOCK_SIZE=BlkLen; //数据块长度寄存器赋值
|
|
|
|
|
*(RP)SDC_BLOCK_COUNT=Nob; //数据块数目寄存器赋值
|
|
|
|
|
*(RP)SDC_ARGUMENT=Arg; //命令参数寄存器赋值
|
|
|
|
|
*(RP)SDC_COMMAND=Cmd; //命令控制寄存器赋值
|
|
|
|
|
*(RP)SDC_INTERRUPT_STATUS_MASK = IntMask;
|
|
|
|
|
*(RP)SDC_TRANSFER_MODE = TransMode;
|
|
|
|
|
*(RP)SDC_BLOCK_SIZE = BlkLen;
|
|
|
|
|
*(RP)SDC_BLOCK_COUNT = Nob;
|
|
|
|
|
*(RP)SDC_ARGUMENT = Arg;
|
|
|
|
|
*(RP)SDC_COMMAND = Cmd;
|
|
|
|
|
|
|
|
|
|
delay(10);
|
|
|
|
|
|
|
|
|
|
i = *(RP)SDC_INTERRUPT_STATUS & 0x1040;
|
|
|
|
|
|
|
|
|
|
while(i != 0x1040) //判断:命令发送完毕,并且收到响应,数据传输完毕。这三项是否已经都完成。
|
|
|
|
|
while (i != 0x1040)
|
|
|
|
|
{
|
|
|
|
|
i = *(RP)SDC_INTERRUPT_STATUS & 0x1040;
|
|
|
|
|
#ifdef USE_TIMEOUT
|
|
|
|
@ -156,8 +153,9 @@ static rt_err_t cmd_response(U16 Cmd,U32 Arg,U16 TransMode,U16 BlkLen,U16 Nob,U1
|
|
|
|
|
//DBOUT("cmd_response TO is %d\n",to);
|
|
|
|
|
delay(100);
|
|
|
|
|
|
|
|
|
|
return RT_EOK; //返回命令反馈信息
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static rt_err_t cmd_wait(U16 Cmd, U32 Arg, U16 IntMask)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
@ -165,19 +163,19 @@ static rt_err_t cmd_wait(U16 Cmd,U32 Arg,U16 IntMask )
|
|
|
|
|
U32 to = 200000;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
*(RP)SDC_CLOCK_CONTROL=0Xff00; //配置SD时钟
|
|
|
|
|
*(RP)SDC_CLOCK_CONTROL = 0Xff00;
|
|
|
|
|
|
|
|
|
|
*(RP)SDC_CLOCK_CONTROL=0Xff04; //打开SD时钟
|
|
|
|
|
*(RP)SDC_CLOCK_CONTROL = 0Xff04;
|
|
|
|
|
|
|
|
|
|
*(RP)SDC_COMMAND=Cmd; //命令控制寄存器赋值
|
|
|
|
|
*(RP)SDC_COMMAND = Cmd;
|
|
|
|
|
|
|
|
|
|
*(RP)SDC_INTERRUPT_STATUS_MASK=IntMask; //中断状态屏蔽寄存器赋值
|
|
|
|
|
*(RP)SDC_INTERRUPT_STATUS_MASK = IntMask;
|
|
|
|
|
|
|
|
|
|
*(RP)SDC_ARGUMENT=Arg; //命令参数寄存器赋值
|
|
|
|
|
*(RP)SDC_ARGUMENT = Arg;
|
|
|
|
|
|
|
|
|
|
i = *(RP)SDC_INTERRUPT_STATUS & 0x1000;
|
|
|
|
|
|
|
|
|
|
while(i != 0x1000) //判断:是否命令发送完毕,并且收到响应
|
|
|
|
|
while (i != 0x1000)
|
|
|
|
|
{
|
|
|
|
|
i = *(RP)SDC_INTERRUPT_STATUS & 0x1000;
|
|
|
|
|
#ifdef USE_TIMEOUT
|
|
|
|
@ -195,8 +193,9 @@ static rt_err_t cmd_wait(U16 Cmd,U32 Arg,U16 IntMask )
|
|
|
|
|
|
|
|
|
|
delay(10);
|
|
|
|
|
|
|
|
|
|
return RT_EOK; //返回命令反馈信息以及数值1
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This function will set a hook function, which will be invoked when a memory
|
|
|
|
|
* block is allocated from heap memory.
|
|
|
|
@ -211,16 +210,16 @@ static rt_err_t sd_init(void)
|
|
|
|
|
#endif
|
|
|
|
|
sd_pwr(1);
|
|
|
|
|
|
|
|
|
|
*(RP)SDC_SOFTWARE_RESET=0x0; //触发软复位,对其写0是进行reset
|
|
|
|
|
*(RP)SDC_SOFTWARE_RESET = 0x0;
|
|
|
|
|
delay(200);
|
|
|
|
|
*(RP)SDC_SOFTWARE_RESET=0x1; //不触发软复位
|
|
|
|
|
*(RP)SDC_SOFTWARE_RESET = 0x1;
|
|
|
|
|
delay(200);
|
|
|
|
|
|
|
|
|
|
cmd_wait(0x08,0x0,0xfff); //CMD0,命令发送使能
|
|
|
|
|
cmd_wait(0x08, 0x0, 0xfff);
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
err = cmd_wait(0x6ea,0x0,0xfff); //CMD55,以切换到ACMD命令
|
|
|
|
|
err = cmd_wait(0x6ea, 0x0, 0xfff);
|
|
|
|
|
|
|
|
|
|
#ifdef USE_TIMEOUT
|
|
|
|
|
if (err != RT_EOK)
|
|
|
|
@ -231,7 +230,7 @@ static rt_err_t sd_init(void)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
delay(3);
|
|
|
|
|
err = cmd_wait(0x52a,0x80ff8000,0xfff); //ACMD41,向SD控制器发送命令,等待SD控制器确认收到命令
|
|
|
|
|
err = cmd_wait(0x52a, 0x80ff8000, 0xfff);
|
|
|
|
|
if (err != RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
EOUT("cmd_wait err in %s\n", __FUNCTION__);
|
|
|
|
@ -246,16 +245,13 @@ static rt_err_t sd_init(void)
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
}while(*(RP)SDC_RESPONSE0<0X80008000);
|
|
|
|
|
}
|
|
|
|
|
while (*(RP)SDC_RESPONSE0 < 0X80008000);
|
|
|
|
|
|
|
|
|
|
#ifdef USE_TIMEOUT
|
|
|
|
|
//DBOUT("%s TO is %d\n",__FUNCTION__,to);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
cmd_data(0x49,0X0,0X0,0x0,0x0,0Xfff);//CMD2,发送CID
|
|
|
|
|
cmd_data(0x6a,0X0,0X0,0x0,0x0,0Xfff);//CMD3,询问卡片发出新的相关地址
|
|
|
|
|
cmd_data(0x49, 0X0, 0X0, 0x0, 0x0, 0Xfff);
|
|
|
|
|
cmd_data(0x6a, 0X0, 0X0, 0x0, 0x0, 0Xfff);
|
|
|
|
|
RCA = *(RP)SDC_RESPONSE0;
|
|
|
|
|
cmd_data(0xea,RCA,0X0,0x0,0x0,0Xfff);//CMD7,设置选择性的相关参数
|
|
|
|
|
cmd_data(0xea, RCA, 0X0, 0x0, 0x0, 0Xfff);
|
|
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
@ -276,7 +272,6 @@ static rt_err_t sd_readblock(rt_uint32_t address, rt_uint8_t* buf)
|
|
|
|
|
rt_uint32_t to = 10;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//rt_kprintf("in readblock:%x\n",address);
|
|
|
|
|
//Clear all the errors & interrups
|
|
|
|
|
*(RP)DMAC_INTINTERRCLR |= 0x1;
|
|
|
|
@ -409,21 +404,20 @@ static rt_uint8_t sd_writeblock(rt_uint32_t address, rt_uint8_t* buf)
|
|
|
|
|
*(RP)DMAC_INTTCCLEAR |= 0x1;
|
|
|
|
|
*(RP)DMAC_INTTCCLEAR &= ~0x1;
|
|
|
|
|
|
|
|
|
|
//***********************配置DMA2进行四位写*************************
|
|
|
|
|
*(RP)DMAC_C2SRCADDR = (U32)buf; //DMAC道2源地址赋为0x30200000
|
|
|
|
|
*(RP)DMAC_C2DESTADDR = SDC_WRITE_BUFER_ACCESS; //DMAC道2目的地址赋为发送FIFO的地址
|
|
|
|
|
*(RP)DMAC_C2CONTROL = 0x20149b; //传输尺寸0x080,源地址增加目的地址不增加,传输宽度32bit,传输的数目4
|
|
|
|
|
*(RP)DMAC_C2CONFIGURATION = 0x380b; //不屏蔽传输中断,屏蔽错误中断,通道使能,传输类型:存储器到外设
|
|
|
|
|
*(RP)DMAC_C2SRCADDR = (U32)buf;
|
|
|
|
|
*(RP)DMAC_C2DESTADDR = SDC_WRITE_BUFER_ACCESS;
|
|
|
|
|
*(RP)DMAC_C2CONTROL = 0x20149b;
|
|
|
|
|
*(RP)DMAC_C2CONFIGURATION = 0x380b;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err = cmd_wait(0x6ea,RCA,0xfff); //CMD55,以切换到ACMD命令
|
|
|
|
|
err = cmd_wait(0x6ea, RCA, 0xfff);
|
|
|
|
|
if (err != RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
rt_set_errno(err);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = cmd_wait(0xca,0x2,0xfff); //ACMD6,定义数据线宽度,48 位短反馈,无数据传输
|
|
|
|
|
err = cmd_wait(0xca, 0x2, 0xfff);
|
|
|
|
|
if (err != RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
rt_set_errno(err);
|
|
|
|
@ -439,7 +433,7 @@ static rt_uint8_t sd_writeblock(rt_uint32_t address, rt_uint8_t* buf)
|
|
|
|
|
|
|
|
|
|
complete = *(RP)SDC_INTERRUPT_STATUS;
|
|
|
|
|
|
|
|
|
|
if((complete |0xfffffffe) !=0xfffffffe) //响应超时错误
|
|
|
|
|
if ((complete | 0xfffffffe) != 0xfffffffe)
|
|
|
|
|
{
|
|
|
|
|
//printf("CRC ERROR");
|
|
|
|
|
complete = *(RP)SDC_INTERRUPT_STATUS;
|
|
|
|
@ -538,8 +532,16 @@ static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_
|
|
|
|
|
rt_uint8_t status;
|
|
|
|
|
rt_uint32_t index;
|
|
|
|
|
|
|
|
|
|
///*take the semaphore
|
|
|
|
|
struct dfs_partition *part = (struct dfs_partition *)dev->user_data;
|
|
|
|
|
struct dfs_partition *part;
|
|
|
|
|
|
|
|
|
|
if (dev == RT_NULL)
|
|
|
|
|
{
|
|
|
|
|
rt_set_errno(-DFS_STATUS_EINVAL);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
part = (struct dfs_partition *)dev->user_data;
|
|
|
|
|
// take the semaphore
|
|
|
|
|
rt_sem_take(part->lock, RT_WAITING_FOREVER);
|
|
|
|
|
while (retry--)
|
|
|
|
|
{
|
|
|
|
@ -586,8 +588,7 @@ static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buf
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
rt_uint8_t status;
|
|
|
|
|
|
|
|
|
|
struct dfs_partition *part = (struct dfs_partition *)dev->user_data;
|
|
|
|
|
struct dfs_partition *part;
|
|
|
|
|
|
|
|
|
|
if (dev == RT_NULL)
|
|
|
|
|
{
|
|
|
|
@ -595,6 +596,8 @@ static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buf
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
part = (struct dfs_partition *)dev->user_data;
|
|
|
|
|
|
|
|
|
|
rt_sem_take(part->lock, RT_WAITING_FOREVER);
|
|
|
|
|
|
|
|
|
|
if (((rt_uint32_t)buffer % 4 != 0) ||
|
|
|
|
@ -783,8 +786,6 @@ rt_err_t rt_hw_sdcard_init()
|
|
|
|
|
ptr_sddev = RT_NULL;
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|