readme.txt
来自「SdCard_V2.1TinyFatFs.rar是单片机实现SD卡功能的FAT文」· 文本 代码 · 共 270 行
TXT
270 行
USB download firmware readme file ---Kimi 03/02/2006
1, Endpoint information
EP0 --control pipe 64bytes
EPA --EP1 bulk out 512bytes
EPB --EP2 bulk in 512bytes
2, File description
CtrlReq.c: realize basic usb control transfer
Fw.c: realize basic bulk transfer
3, Fs7822.h file
define the global variables and functions, prevent multiple public definitions
4, Manual IN without SFI Mode of Ping-Pong FIFO
Manual OUT without SFI Mode of Ping-Pong FIFO
MCU pass FIFO to USB
inquire the EP1, EP2 USB interrupt
Support USB process USB Host request
EP1----EPA---Bulk Out
EP2----EPB---Bulk In
Manual in without SFI of Single Fifo
T5 SD card reader--V1.2--2006.08.28
低速下通过测试!
1.修改Vendor ID -> 0X5121
修改procduct id -> 0x4020,使得PC机的驱动支持。
2.每次复位后检测速度,若是低速接口,那么
EPAFIFOCS |= 0X22;
EPBFIFOCS |= 0X22;
bulk传输按照64字节的数据包收发!
3.修改了FullSpeedConfigDscr[]中的接口描述符
2006.09.07
BulkSetDmaIn中
while((EP2FIFOCS&bmFIFO0_FULL)&&(CmdTimer));
如果没有时间限制,写数据时会陷入死循环~!
去掉后,读数据会出错!
2006.09.08
USB1.1下写数据会出错,在SdWriteOneSector()中的
if(!ReadyForData)
{ CmdTimer=20;
while(CmdTimer);
continue;}
有data not ready错误,说明SD card没有准备好接收下一block数据,重试几次仍不能满足后,
返回错误。
2006.09.12
USB1.1下稳定工作。
2006.09.13
USB2.0下,系统经常停在BulkSetDmaIn()中的等待数据发送完成。
原因是,设备已经发出数据,主机收到且回复了ACK信号,但是设备没有正确识别到,就没有
清零FIFO_FULL位,伴随着超时错误的发生~!
2006.09.14
2006.09.20-V1.29
在SdReadCSD()中加入了
if(CardType == CARD_MMC) {
if(((SdRespBuf[1]&0x3f)>>2)==4) MmcProtol = 1; //判断是何种卡4.0 ?3.1?
else MmcProtol = 0;
}
用来判断是MMC 4.0的卡还是3.1的卡。
2006.09.20-V1.30
把描述符重新放入到dscr.h中,保持和原先文件的一致!
2006.10.19
在ScsiPrepareDiskInfo()中回复,0x00本地磁盘,用partitionmagic格式化为多分区结构
-扩展分区格式。
2006.10.25
在准备CSW和读第一个扇区前,
加入while(EPBFIFOCS&bmFIFO0_FULL);
等待FIFO为空~!不在 BulkSetDmaIn()的末尾判断,
防止了死机出现,问题得到了阶段性解决。
以前只是在准备CSW前判断FIFO是否为空,没有尝试在
读SD扇区前判断!思路不够开阔和思维不够周密。
2006.11.14
精简了代码,直接用DMA_FIFOA0,DMA_FIFOB0来操作,减少了中间环节。
另外,对SdReadOneSector(),SdReadNextSectorData()等函数,加上
#pragma OPTIMIZE(4)
降低优化级别,增加了稳定性。
2006.12.15
ReadSector()中连续实现了数据读取。pingpong IN Fifo
写数据采用single FIFO,写完跳出的模式。
20006.12.27
void BulkFreeBuffer()中的流程按照spec中121页去做,就好了。
先前的原因再分析~
bulkcmd.h中定义
#define WR_CONTINOUS //控制连续写
#define RD_CONTINOUS //控制连续读
第一次读数据,在ReadSector()中完成。
其余的在ReadNextSector()中连续完成。
第一次写数据,在WriteSector()中完成。
其余的在WriteNextSector()中连续完成。
这样,对原有的架构改动不大。
CSW仍然在UsbBulkIntHandler()中完成。
2006.12.28
BulkFreeBuffer()与SelectFifo()配对使用。
直接在WriteSector中调用BulkFreeBuffer()。
SectorCount--在ReadSector、writesector中调用。
writesector()中:
while(1) {
// while (((EPAFIFOCS & bmFIFO0_FULL)==0) && ((EPAFIFOCS & bmFIFO1_FULL)==0));
//等待一包数据的到来--无限等待可能会漏掉reset信号~~再分析之。
if(((EPAFIFOCS & bmFIFO0_FULL)) || ((EPAFIFOCS & bmFIFO1_FULL)))
2006.12.29
SPI 的4根信号线和MMC DATA4-DATA7复用,读写有冲突~!硬件要考虑隔离。
2007.01.02
重新增加了SectorStart ++;
一次读扇区错误时,还可以从当前扇区再次读。否则,会仍然从起始扇区读~!
另外,
STATUS ReadSector()
{
BYTE status;
SetBulkInFull();
status = SdReadSector();//
if(SectorCount > 0)
SectorCount --;//先读sector,再SectorCount --!!2007.01.02
return status;
}
2007.01.11
case STALL_IN_COMPLETED: //IN trasaction ends with stall后,进入此状态
if (IntEvent & bmEPAINT) // Keep receving out packets.
{ SelectOutFifo(); //SelectOutfifo()和BulkFreeBuffer配对使用!切记!
BulkFreeBuffer(); //Derek 07.01.11
}
写多个扇区中间出错时,进入STALL_IN_STALL状态,收到一包数据后,
仍然需要使能接收,直到结束,IN CSW.
SelectOutfifo()和BulkFreeBuffer配对使用!
*.c文件中,SelectOutfifo()出现7次,BulkFreeBuffer()出现21次。
toggle error和写保护处理时,都增加了SelectOutFifo()函数。
2007.01.18
由于卡的原因,在执行multi read命令,读到最后几个block时,会出现
OUT_OF_RANGE错误.因此,要忽略它:
在SdSendCmd()中加入了:
if( ( SdRespBuf[1] == 0x80 ) && //ignor OUT_OF_RANGE error
( SdRespBuf[2] == 0 ) && // when multi read last block
(( SectorStart >= SdAvailableBlocks-5)&&
( SectorStart <= SdAvailableBlocks))) //见MMC 4.0 SPEC--4.6.3(page 49)
return STATUS_SUCCESS; //不同的卡,出错的位置不同.
每种卡出错的位置不同,这里以最后5个block为准.
在此范围内出现的OUT_OF_RANG错误忽略掉~!
SD初始化时,McuInit()中,
SDMI_CTL = SDMI_CTL | bmSD_CLK_40 & (~bmSD_AUTO_CLK_EN);//2007.01.18
将bmSD_AUTO_CLK_EN位清掉,防止连续执行read single block命令时出现timeout.
因为,读完第一个后会将clock停掉.
2007.01.22
在连续读扇区时,会发生FIFO_FULL无法清零的问题.导致SetBulkInFull()中
死循环的发生.
为此,专门针对读扇区设计了 SetBulkInFullForReadSector(void)函数,
等待FIFO_FULL为空时,增加了对BUS RESET的判断:
while ((EPBFIFOCS & bmFIFO0_FULL) && (EPBFIFOCS & bmFIFO1_FULL)&&((EPINT&bmUSBRSTINT)==0));
从而能及时处理BUS RESET带来的问题.
2007.01.26
USB BUS RESET应该用if(STINT&bmUSBRSTINT)判断,
在以前的版本中,
SetBulkInFullForReadSector(void)
STATUS WriteNextSector()
中写成了(EPINT&bmUSBRSTINT).
2007.03.02
Firmware在连续读SanDisk的SD卡时,在SdReadNextSectorData()函数中,
总是有CRC16错误,返回STATUS_DATA_ERROR;
在SdReadNextSector()函数中,还要重试一次:
for(RetryCount = 0 ; RetryCount < 15; RetryCount ++)
{
Status = SdStopCmd();
if(Status != STATUS_SUCCESS)
continue;
Status = SdReadOneSector();
break;
}
才正确,很奇怪。
也浪费了时间。
2007.03.14
在SdWriteOneSector(),SdWriteNextSector()中加入
if(SdCardExist()==0)
return STATUS_NO_MEDIA; //Derek 2007.03.01
防止数据传输过程中,拔出卡,长时间重试,reset。
2007.07.02
对于HC SD卡,调用SdSendIFCon(),发送CMD8-SEND_IF_COND,
确定HC SD的电压。
进入data transfer后,调用SDCMD6Test(),发送CMD6,
check switchable function。
进入high speed模式。
在读写扇区时,
if(SdHcFlag) { //Derek 2007.07.02
*((UINT32 *)(&SdCmdBuf[1])) = SectorStart;
} else
*((UINT32 *)(&SdCmdBuf[1])) =
SectorStart << BYTES_PER_SECTOR_SHIFT;
对于HC SD卡,以sector为单位。
对于一般的SD卡,以字节为单位!!
总结HC SD与standard SD的不同:
2007.07.04
SdReadCSD(void)中,读取卡中参数,确定SDMI采用何种频率。
if(SdRespBuf[4] != 0x5A) //Derek 2007.07.04
SDMI_CTL &= ~bmSD_CLK_40; //根据卡的最大传输速率设定接口频率。
else //如果是0x5A,说明SD卡最大支持50MHz的接口速率。
SDMI_CTL |= bmSD_CLK_40;
2007.08.16 V1.22
增加对SCSI_READ_BUFFER命令的支持。
CMD8(SEND_IF_CON)命令只能判断是否V2.00卡,而不能确定是否HC SD卡。需要从CSD寄存器中
的CSD_STRUCTURE域中再次判断之~~
因为V2.00卡包含standard card和high capacity card两种类型。
SdReadCSD(void)中,
if(SdRespBuf[1]&0xC0) //2007.08.16-从CSD中判断是否HC SD。
SdHcFlag = 1;
else
SdHcFlag = 0;
另外,从V1.10开始,增加了CMD6命令,支持high speed mode,所以,对于V1.10或更高版本
的SD卡,要发送CMD6命令,切换到高速模式。而对于低版本的SD,要降低接口频率,防止读写出错。
//////////////////////////////////////////////////////////
V2.1
在V2.0基础上添加f_write功能。
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?