大家好,我的U盘写扇区函数,假如整个扇区都写0x55,但只能有些字节变为0x55,有些字节改变为其他值。大家有没有相关的经验?
我把函数贴出来。应该标的很明白,按UFI协议编的,查了几遍流程,流程应该符合UFI
uint8_t MassStorageDevSectWrite(uint32_t LBAddr,uint16_t Len,uint8_t *BufPtr)
{
uint32_t *tmp;
uint32_t Tag=0x00000008,TotalByteNum_32,MassStorageDevSectWriteTryCnt;
uint16_t TotalByteNum_16;
CBW.dCBWSignature=dCBWSignatureValue; //'命令块包标识':表明这是一个CBW包,值为43425355H(固定值)
CBW.dCBWTag=Tag; //主机发送的'命令块标签',设备返回的CSW包中,有相同的'命令块标签'作为对应
TotalByteNum_32=Len*UsbDevHandler.BPB_BytesPerSect;//len*扇区字节数
TotalByteNum_16=Len*UsbDevHandler.BPB_BytesPerSect;//len*扇区字节数
CBW.dCBWDataTransferLength=TotalByteNum_32; //bulk端点期望输出(OUT)数据字节数
CBW.bmCBWFlags=0x00; //bit7:指示数据传输方向 1: DataIn from device 0: DataOut to device 其他位保留
CBW.bCBWLUN=UsbDevHandler.LunToBeUsed; //逻辑单元号,几乎所有U盘都只有一个LUN,一个LUN时LunToBeUsed赋0。
CBW.bCBWCBLength=12; //CBWCB的有效长度(bytes),合法值1~16
//清除命令阵列 共16个字节
tmp=(uint32_t *)CBW.CmdBlockByteArray;
*tmp++=0;*tmp++=0;*tmp++=0;*tmp++=0;
//对命令阵列CBWCB赋值,设备将执行的命令块,对于U盘主机系统来说,就是将执行的UFI命令块。
//这个命令块对应UFI协议(12个字节)
CBW.CmdBlockByteArray[0]=RBC_CMD_WRITE10; //请求写mass storage设备命令 (host会通过bulk in endpoint写设备扇区)
CBW.CmdBlockByteArray[1]=0x00; //逻辑单元号0
CBW.CmdBlockByteArray[2]=(uint8_t)((LBAddr>>24)&0xff); //4个字节的logical block address.LBAddr(扇区地址)
CBW.CmdBlockByteArray[3]=(uint8_t)((LBAddr>>16)&0xff); //逻辑块地址定义了读操作的起始逻辑块
CBW.CmdBlockByteArray[4]=(uint8_t)((LBAddr>>8)&0xff);
CBW.CmdBlockByteArray[5]=(uint8_t)(LBAddr&0xff);
CBW.CmdBlockByteArray[6]=0x00; //reserved
CBW.CmdBlockByteArray[7]=(uint8_t)((Len>>8)&0xff); //两个字节的transfer length(需传送的扇区个数)
CBW.CmdBlockByteArray[8]=(uint8_t)(Len&0xff);
CBW.CmdBlockByteArray[9]=0x00; //RBC_CMD_READ10命令时9 10 11为保留字节,只列出9
PrepareCBWTxBuf(); //准备31个字节的CBW发送缓冲 CBWTxBuf[0~30]
//通过bulk端点输出数据至device
//CBWTxBuf 输出缓冲区
//31为输出数据字节个数
if(epBulkOutTransfer(CBWTxBuf,31)) return(1); //发送函数返回error(1)时,结束扇区写函数 返回error(1)
//CBW should be transferred at the start of a packet
//and end as a short packet, with exactly 31 bytes transferred
//UsDelay(1000); //how much needs to be delayed needs to be tuned
MassStorageDevSectWriteTryCnt=0; //当前写扇区尝试次数初始化为0
while(1)
{
//通过bulk端点从device读数据
//BufPtr 保存读入数据的缓冲区首地址
//TotalByteNum_16 读入数据字节数(CBW包中已定义)
if(!epBulkOutTransfer(BufPtr,TotalByteNum_16))
{
break; //写函数返回success(0)时,退出循环
}
else
{
MassStorageDevSectWriteTryCnt++;
if (MassStorageDevSectWriteTryCnt>5) return(1); //尝试5次以上仍然没有写成功,退出函数返回error(1)
};
};
//medial normal data
//received data is not analyzed, see UFI.pdf
//CSWRxBuf 读入缓冲区
//13为读入数据字节个数
//读入返回的CSW块,读错误时,返回错误状态(3)
if(epBulkInTransfer(CSWRxBuf,13)) return(3);
InterpretCSWRxBuf(); //CSWRxBuf内的值对应填充CSW函数 interpret:交互
if(AuditCSWReturned(&CSW,Tag)) return(4); //CSW判断函数
return(0);
} |