首先是对于端点的数据处理
#ifndef __USBEP2_H_
#define __USBEP2_H_
#include "usb.h"
#include "usbhw.h"
#include "msc.h"
#include "mscuser.h"
void usb_ep2_in_process(void);
void usb_ep2_out_process(void);
#endif
#include "usbep2.h"
//批量输入事件
void usb_ep2_in_process(void)
{
switch (BulkStage)
{
case MSC_BS_DATA_IN:
switch (CBW.CB[0])
{
case SCSI_READ10:
MSC_MemoryRead();//读取数据并等待下一次传输
break;
}
break;
case MSC_BS_DATA_IN_LAST:
MSC_SetCSW();//上一次传输并且传输已经完成
break;
case MSC_BS_DATA_IN_LAST_STALL:
USB_SetStallEP(MSC_EP_IN);
MSC_SetCSW();
break;
case MSC_BS_CSW:
BulkStage = MSC_BS_CBW;//简单的进行状态切换
break;
}
}
//批量输出事件
void usb_ep2_out_process(void)
{
BulkLen = USB_ReadEP(MSC_EP_OUT, BulkBuf);//读取缓存
switch (BulkStage)//根据阶段判定
{
case MSC_BS_CBW://最开始的阶段必然是命令阶段
MSC_GetCBW();//获取并处理cbw命令
break;
case MSC_BS_DATA_OUT://数据输出阶段
switch (CBW.CB[0]) //分辨写入指令
{
case SCSI_WRITE10:
MSC_MemoryWrite();
break;
case SCSI_VERIFY10:
MSC_MemoryVerify();
break;
}
break;
default://不支持的状态
USB_SetStallEP(MSC_EP_OUT);
CSW.bStatus = CSW_PHASE_ERROR;
MSC_SetCSW();
break;
}
}
然后再在子程序中对命令详细分析
#ifndef __MSCUSER_H_
#define __MSCUSER_H_
#include "msc.h"
#include "usbhw.h"
#include "memory.h"
//批量传输节点的最大包长度
#define MSC_MAX_PACKET 64
//批量传输节点地址
#define MSC_EP_IN 0x82
#define MSC_EP_OUT 0x02
extern uint8_t BulkStage; //传输状态,指明下一次如何传输
extern uint8_t BulkLen; //输出接点,主机输出的数据长度
extern uint8_t BulkBuf[MSC_MAX_PACKET]; //数据缓存中心
extern MSC_CBW CBW; //cbw块
extern MSC_CSW CSW; //csw块
extern uint32_t MemOK; /* 测试mem是否完好 */
#define MSC_DEBUG 0
#if MSC_DEBUG
#define msc_debug_printf(format,args...) printf(format,##args) //变参宏定义
#else
#define msc_debug_printf(x,...) while(0);
#endif
//枚举过程中的重要节点
extern uint32_t MSC_Reset (void);
extern uint32_t MSC_GetMaxLUN (void);
//msc设备的方法
extern void MSC_GetCBW (void);
extern void MSC_SetCSW (void);
void MSC_MemoryRead (void) ;
void MSC_MemoryWrite(void);
void MSC_MemoryVerify(void);
#endif
#include "mscuser.h"
uint32_t MemOK = __TRUE; /* 测试mem是否完好 */
uint32_t Offset; /* 读取写入的定位 */
uint32_t Length; /* 读取写入的长度 */
uint8_t BulkStage; /* 批量传输的阶段, 数据阶段 命令阶段 状态阶段 */
uint8_t BulkBuf[MSC_MAX_PACKET]; /* 读取批量端点传输来的数据 */
uint8_t BulkLen; /* 传输长度 */
MSC_CBW CBW; /*CBW结构体 */
MSC_CSW CSW; /*CSW结构体 */
#if NORFLASH
u8 usb_mac_global_buffer[MSC_MAX_PACKET];
#endif
#if NANDFLASH
u8 usb_mac_global_buffer[MSC_MAX_PACKET];
#endif
//msc设备复位
uint32_t MSC_Reset (void)
{
BulkStage = MSC_BS_CBW;
return (__TRUE);
}
//获取标号
uint32_t MSC_GetMaxLUN (void)
{
EP0Buf[0] = 0; //0为一个设备
return (__TRUE);
}
//设备读取数据,在in阶段发送出去
void MSC_MemoryRead (void)
{
uint32_t n;
if (Length > MSC_MAX_PACKET) //根据长度来计算,不能大于包长度
{
n = MSC_MAX_PACKET;
}
else
{
n = Length;
}
if ((Offset + n) > MSC_MemorySize) //缓冲区最大长度
{
n = MSC_MemorySize - Offset;
BulkStage = MSC_BS_DATA_IN_LAST_STALL;//传输失败的发送
}
#if NORFLASH
NOR_FLASH_Read_Buffer_Mal(Offset,usb_mac_global_buffer,n);//读取数据
USB_WriteEP(MSC_EP_IN, (u8*)usb_mac_global_buffer, n);
#endif
#if NANDFLASH
while(nandReady == 0);
nandReady = 0;
NAND_Read_Addr_Mal(Offset,usb_mac_global_buffer,n);
USB_WriteEP(MSC_EP_IN, (u8*)usb_mac_global_buffer, n);
nandReady = 1;
#endif
Offset += n;
Length -= n;//传输完成后对指针进行相应的处理
CSW.dDataResidue -= n;
if (Length == 0)
{
BulkStage = MSC_BS_DATA_IN_LAST;//数据传输成功
}
if (BulkStage != MSC_BS_DATA_IN) //上一次传输为0 ,命令通过
{
CSW.bStatus = CSW_CMD_PASSED;
}
}
u8 norflash_buffer[2048] = {0};
//写入数据到设备
void MSC_MemoryWrite (void)
{
if ((Offset + BulkLen) > MSC_MemorySize) //防止超界
{
BulkLen = MSC_MemorySize - Offset;
BulkStage = MSC_BS_CSW;
USB_SetStallEP(MSC_EP_OUT);
}
#if NORFLASH
NOR_FLASH_Write_Mal(Offset,BulkBuf,BulkLen);
msc_idle_time_count = 0;//发生写入时,空闲时间设置为0
#endif
#if NANDFLASH
while(nandReady == 0);
nandReady = 0;
NAND_Write_Addr_Mal(Offset,BulkBuf,BulkLen);
nandReady = 1;
msc_idle_time_count = 0;
#endif
Offset += BulkLen;//指针变换(写入和删除都有相应的执指针变化,自动切换位置)
Length -= BulkLen;
CSW.dDataResidue -= BulkLen;
if ((Length == 0) || (BulkStage == MSC_BS_CSW))
{
CSW.bStatus = CSW_CMD_PASSED;
MSC_SetCSW();//指令通过
}
}
//数据校验
void MSC_MemoryVerify (void)
{
uint32_t n;
if ((Offset + BulkLen) > MSC_MemorySize) //防止超界
{
BulkLen = MSC_MemorySize - Offset;
BulkStage = MSC_BS_CSW;
USB_SetStallEP(MSC_EP_OUT);
}
#if NORFLASH
NOR_FLASH_Read_Buffer_Mal(Offset,usb_mac_global_buffer,BulkLen);
for(n = 0; n < BulkLen;n++)
{
if(usb_mac_global_buffer[n] != BulkBuf[n])
{
MemOK = __FALSE;
break;
}
}
#endif
#if NANDFLASH
while(nandReady == 0);
nandReady = 0;
NAND_Read_Addr_Mal(Offset,usb_mac_global_buffer,BulkLen);
nandReady = 1;
for(n = 0; n < BulkLen;n++)
{
if(usb_mac_global_buffer[n] != BulkBuf[n])
{
MemOK = __FALSE;
break;
}
}
#endif
Offset += BulkLen;
Length -= BulkLen;
CSW.dDataResidue -= BulkLen;
if ((Length == 0) || (BulkStage == MSC_BS_CSW))
{
CSW.bStatus = (MemOK) ? CSW_CMD_PASSED : CSW_CMD_FAILED;//根据校验的最终状态,选择返回命令失败或者成功
MSC_SetCSW();
}
}
//usb实际与数据相关的处理工作
uint32_t MSC_RWSetup (void)
{
uint32_t n;
//首先获得逻辑地址对应的物理地址,主机发送下来的block地址,我们要转换成响应的nand block和nand page
n = (CBW.CB[2] << 24) |(CBW.CB[3] << 16) |(CBW.CB[4] << 8) | (CBW.CB[5] << 0);
Offset = n * MSC_BlockSize;//定位逻辑位置
//需要传输的块数量
n = (CBW.CB[7] << 8) |
(CBW.CB[8] << 0);
//要传输的数据总长度
Length = n * MSC_BlockSize;
if (CBW.dDataLength != Length) //接受长度必须和发送的要读取长度计算一致,否则不能起作用
{
USB_SetStallEP(MSC_EP_IN);
USB_SetStallEP(MSC_EP_OUT);
CSW.bStatus = CSW_PHASE_ERROR;
MSC_SetCSW();
return (__FALSE);
}
return (__TRUE);//算好了,核心是offect 和length
}
//检测数据是否符合规则
uint32_t DataInFormat (void)
{
if (CBW.dDataLength == 0) //检测数据长度
{
CSW.bStatus = CSW_PHASE_ERROR;
MSC_SetCSW();
return (__FALSE);
}
if ((CBW.bmFlags & 0x80) == 0) //检测数据方向
{
USB_SetStallEP(MSC_EP_OUT);
CSW.bStatus = CSW_PHASE_ERROR;
MSC_SetCSW();
return (__FALSE);
}
return (__TRUE);//数据ok
}
void DataInTransfer (void)
{
if (BulkLen > CBW.dDataLength) {
BulkLen = CBW.dDataLength;
}
USB_WriteEP(MSC_EP_IN, BulkBuf, BulkLen);
BulkStage = MSC_BS_DATA_IN_LAST;
CSW.dDataResidue -= BulkLen;
CSW.bStatus = CSW_CMD_PASSED;
}
//scsi指明测试存储单元是否准备好
void MSC_TestUnitReady (void)
{
if (CBW.dDataLength != 0) //发送来的cbw不带数据就准备好了
{
if ((CBW.bmFlags & 0x80) != 0)
{
USB_SetStallEP(MSC_EP_IN);//设置断点暂停
} else
{
USB_SetStallEP(MSC_EP_OUT);
}
}
#if NANDFLASH
if(nandReady == 0)MemOK = __FALSE;
else MemOK = __TRUE;
#endif
if(MemOK == __TRUE)
{
CSW.bStatus = CSW_CMD_PASSED;//准备好存储空间
MSC_SetCSW();
}
else
{
CSW.bStatus = CSW_CMD_FAILED;//还没准备好存储空间
MSC_SetCSW();
}
#if NORFLASH
if(msc_idle_time_count < MSC_IDLE_TIME_LIMIT)msc_idle_time_count++;//设备空闲时间(没发生写入的时间)
else NOR_FLASH_Flush();
#endif
#if NANDFLASH
if(msc_idle_time_count < MSC_IDLE_TIME_LIMIT)msc_idle_time_count++;//设备空闲时间(没发生写入的时间)
else Nand_Flush();
#endif
}
//检测上一次传输失败的原因 返回失败原因代码
void MSC_RequestSense (void)
{
if (!DataInFormat()) return;
BulkBuf[ 0] = 0x70; //错误代码,固定为0x70
BulkBuf[ 1] = 0x00; //保留
BulkBuf[ 2] = 0x00; //Sense Key为0x05,表示无效请求(ILLEGAL REQUEST)
BulkBuf[ 3] = 0x00; //Information为0 四个字节
BulkBuf[ 4] = 0x00;
BulkBuf[ 5] = 0x00;
BulkBuf[ 6] = 0x00;
BulkBuf[ 7] = 0x0A; //附加数据长度为10字节
BulkBuf[ 8] = 0x00; //保留 四字节
BulkBuf[ 9] = 0x00;
BulkBuf[10] = 0x00;
BulkBuf[11] = 0x00;
BulkBuf[12] = 0x00; //Additional Sense Code(ASC)为0x20,表示无效命令操作码(INVALID COMMAND OPERATION CODE)
BulkBuf[13] = 0x00; //Additional Sense Code Qualifier(ASCQ)为0
BulkBuf[14] = 0x00; //保留 四字节
BulkBuf[15] = 0x00;
BulkBuf[16] = 0x00;
BulkBuf[17] = 0x00;
if (CBW.CB[4] <= 18)
{
BulkLen = CBW.CB[4];
}
else
{
BulkLen = 18;
}
DataInTransfer();
}
void MSC_Inquiry (void)
{
if (!DataInFormat()) return;
BulkBuf[ 0] = 0x00; //磁盘设备
BulkBuf[ 1] = 0x80; //其中最高位D7为RMB。RMB=0,表示不可移除设备。如果RMB=1,则为可移除设备。
BulkBuf[ 2] = 0x00; //各种版本号0
BulkBuf[ 3] = 0x01; //数据响应格式
BulkBuf[ 4] = 36-4; //附加数据长度,为32字节
BulkBuf[ 5] = 0x80; /* SCCS = 1: Storage Controller Component */
BulkBuf[ 6] = 0x00; //保留
BulkBuf[ 7] = 0x00; //保留
BulkBuf[ 8] = ‘D‘; //厂商标识
BulkBuf[ 9] = ‘I‘;
BulkBuf[10] = ‘N‘;
BulkBuf[11] = ‘K‘;
BulkBuf[12] = ‘ ‘;
BulkBuf[13] = ‘ ‘;
BulkBuf[14] = ‘ ‘;
BulkBuf[15] = ‘ ‘;
BulkBuf[16] = ‘D‘; //产品标识,
BulkBuf[17] = ‘E‘;
BulkBuf[18] = ‘N‘;
BulkBuf[19] = ‘G‘;
BulkBuf[20] = ‘X‘;
BulkBuf[21] = ‘I‘;
BulkBuf[22] = ‘A‘;
BulkBuf[23] = ‘O‘;
BulkBuf[24] = ‘J‘;
BulkBuf[25] = ‘U‘;
BulkBuf[26] = ‘N‘;
BulkBuf[27] = ‘D‘;
BulkBuf[28] = ‘I‘;
BulkBuf[29] = ‘S‘;
BulkBuf[30] = ‘K‘;
BulkBuf[31] = ‘ ‘;
BulkBuf[32] = ‘1‘; //产品版本号
BulkBuf[33] = ‘.‘;
BulkBuf[34] = ‘0‘;
BulkBuf[35] = ‘ ‘;
BulkLen = 36;
DataInTransfer();
}
//scsi响应函数
void MSC_ModeSense6 (void)
{
if (!DataInFormat()) return;
BulkBuf[ 0] = 0x03;
BulkBuf[ 1] = 0x00;
BulkBuf[ 2] = 0x00;
BulkBuf[ 3] = 0x00;
BulkLen = 4;
DataInTransfer();
}
void MSC_ModeSense10 (void) {
if (!DataInFormat()) return;
BulkBuf[ 0] = 0x00;
BulkBuf[ 1] = 0x06;
BulkBuf[ 2] = 0x00;
BulkBuf[ 3] = 0x00;
BulkBuf[ 4] = 0x00;
BulkBuf[ 5] = 0x00;
BulkBuf[ 6] = 0x00;
BulkBuf[ 7] = 0x00;
BulkLen = 8;
DataInTransfer();
}
//读取设备的实际容量
void MSC_ReadCapacity (void)
{
if (!DataInFormat()) return;
//最大逻辑块大小 因为逻辑块从0开始,所以需要-1
BulkBuf[ 0] = ((MSC_BlockCount - 1) >> 24) & 0xFF;
BulkBuf[ 1] = ((MSC_BlockCount - 1) >> 16) & 0xFF;
BulkBuf[ 2] = ((MSC_BlockCount - 1) >> 8) & 0xFF;
BulkBuf[ 3] = ((MSC_BlockCount - 1) >> 0) & 0xFF;
//逻辑块长度
BulkBuf[ 4] = (MSC_BlockSize >> 24) & 0xFF;
BulkBuf[ 5] = (MSC_BlockSize >> 16) & 0xFF;
BulkBuf[ 6] = (MSC_BlockSize >> 8) & 0xFF;
BulkBuf[ 7] = (MSC_BlockSize >> 0) & 0xFF;
BulkLen = 8;
DataInTransfer();
}
//读格式化容量信息,返回最大能格式化的数据信息
void MSC_ReadFormatCapacity (void)
{
if (!DataInFormat()) return;
BulkBuf[ 0] = 0x00;
BulkBuf[ 1] = 0x00;
BulkBuf[ 2] = 0x00;
BulkBuf[ 3] = 0x08; //容量列表描述符长度
//设备块数量 正对于不同的介质这里可以有不同的设置
BulkBuf[ 4] = (MSC_BlockCount >> 24) & 0xFF;
BulkBuf[ 5] = (MSC_BlockCount >> 16) & 0xFF;
BulkBuf[ 6] = (MSC_BlockCount >> 8) & 0xFF;
BulkBuf[ 7] = (MSC_BlockCount >> 0) & 0xFF;
//每一块的长度
BulkBuf[ 8] = 0x02; /* Descriptor Code: Formatted Media */
BulkBuf[ 9] = (MSC_BlockSize >> 16) & 0xFF;
BulkBuf[10] = (MSC_BlockSize >> 8) & 0xFF;
BulkBuf[11] = (MSC_BlockSize >> 0) & 0xFF;
BulkLen = 12;
DataInTransfer();
}
void MSC_GetCBW (void)
{
uint32_t n;//将buf数据拷贝入cbw结构体,便于下一次处理
for (n = 0; n < BulkLen; n++)
{
*((uint8_t *)&CBW + n) = BulkBuf[n];
}
if ((BulkLen == sizeof(CBW)) && (CBW.dSignature == MSC_CBW_Signature)) //检测命令长度以及命令头 usbc
{
//完整有效地cbw
CSW.dTag = CBW.dTag;//发送来的cbw需要csw返回,csw的tag必须对应发送来的cbw tag
CSW.dDataResidue = CBW.dDataLength;//需要传输的数据长度
if ((CBW.bLUN != 0) || (CBW.bCBLength < 1) || CBW.bCBLength > 16) //目标逻辑单元不对或者长度不对都会导致命令失败
{
fail: CSW.bStatus = CSW_CMD_FAILED;//命令失败,0x01
MSC_SetCSW();//返回失败csw
}
else
{
switch (CBW.CB[0]) //检测命令代码,进行散转处理
{
case SCSI_TEST_UNIT_READY://测试设备是否准备好
MSC_TestUnitReady();
msc_debug_printf("SCSI_TEST_UNIT_READY\r\n");
break;
case SCSI_REQUEST_SENSE://检测上一次传输失败的原因
MSC_RequestSense();
msc_debug_printf("SCSI_REQUEST_SENSE\r\n");
break;
case SCSI_FORMAT_UNIT: //格式化单元,不支持
msc_debug_printf("SCSI_FORMAT_UNIT\r\n");
goto fail;
case SCSI_INQUIRY:
MSC_Inquiry(); //查询设备的基本信息
msc_debug_printf("SCSI_INQUIRY\r\n");
break;
case SCSI_START_STOP_UNIT://不支持
msc_debug_printf("SCSI_START_STOP_UNIT\r\n");
goto fail;
case SCSI_MEDIA_REMOVAL:
CSW.bStatus = CSW_CMD_PASSED;
MSC_SetCSW();//返回失败csw
msc_debug_printf("SCSI_MEDIA_REMOVAL\r\n");
//goto fail;
break;
case SCSI_MODE_SELECT6://不支持
msc_debug_printf("SCSI_MODE_SELECT6\r\n");
goto fail;
case SCSI_MODE_SENSE6://不知干嘛的
MSC_ModeSense6();
msc_debug_printf("SCSI_MODE_SENSE6\r\n");
break;
case SCSI_MODE_SELECT10:
msc_debug_printf("SCSI_MODE_SELECT10\r\n");
goto fail;
case SCSI_MODE_SENSE10:
MSC_ModeSense10();
msc_debug_printf("SCSI_MODE_SENSE10\r\n");
break;
case SCSI_READ_FORMAT_CAPACITIES://读格式化容量信息
MSC_ReadFormatCapacity();
msc_debug_printf("SCSI_READ_FORMAT_CAPACITIES\r\n");
break;
case SCSI_READ_CAPACITY://读容量信息
MSC_ReadCapacity();
msc_debug_printf("SCSI_READ_CAPACITY\r\n");
break;
case SCSI_READ10://读取实际的磁盘数据
if (MSC_RWSetup())
{
if ((CBW.bmFlags & 0x80) != 0) //方向没有错误
{
BulkStage = MSC_BS_DATA_IN;//数据输入状态,下次in事件来的时候就能传输正确数据
MSC_MemoryRead();
msc_debug_printf("SCSI_READ10 right\r\n");
}
else
{
USB_SetStallEP(MSC_EP_OUT);//方向错误,暂停端点
CSW.bStatus = CSW_CMD_FAILED;
MSC_SetCSW();
msc_debug_printf("SCSI_READ10 error\r\n");
}
}
break;
case SCSI_WRITE10://写入实际磁盘数据
if (MSC_RWSetup())
{
if ((CBW.bmFlags & 0x80) == 0) //检查方向
{
BulkStage = MSC_BS_DATA_OUT;//说明下一次out带来就是要写入数据,修改设备的状态
msc_debug_printf("SCSI_WRITE10 right\r\n");
}
else
{
USB_SetStallEP(MSC_EP_IN);//命令不支持(核心思想状态机)
CSW.bStatus = CSW_PHASE_ERROR;
MSC_SetCSW();
msc_debug_printf("SCSI_WRITE10 error\r\n");
}
}
msc_debug_printf("SCSI_WRITE10\r\n");
break;
case SCSI_VERIFY10://校验数据
if (MSC_RWSetup())
{
if ((CBW.bmFlags & 0x80) == 0)
{
BulkStage = MSC_BS_DATA_OUT;
MemOK = __TRUE;//直接返回数据校验ok
}
else
{
USB_SetStallEP(MSC_EP_IN);
CSW.bStatus = CSW_PHASE_ERROR;//方向不对,命令错误
MSC_SetCSW();
}
}
msc_debug_printf("SCSI_VERIFY10\r\n");
break;
default:
goto fail;
}
}
}
else
{//无效的cbw指令,直接禁用全部端点,等待usb重新设置端点 从错误中恢复
USB_SetStallEP(MSC_EP_IN);
USB_SetStallEP(MSC_EP_OUT);
BulkStage = MSC_BS_ERROR;
msc_debug_printf("无效的cbw指令\r\n");
}
}
//设备返回的状态封包
void MSC_SetCSW (void) {
CSW.dSignature = MSC_CSW_Signature;
USB_WriteEP(MSC_EP_IN, (uint8_t *)&CSW, sizeof(CSW));
BulkStage = MSC_BS_CSW;
}
Usb大容量存储器的宏如下
#ifndef __MSC_H__
#define __MSC_H__
#include "sys.h"
/* MSC Subclass Codes */
#define MSC_SUBCLASS_RBC 0x01
#define MSC_SUBCLASS_SFF8020I_MMC2 0x02
#define MSC_SUBCLASS_QIC157 0x03
#define MSC_SUBCLASS_UFI 0x04
#define MSC_SUBCLASS_SFF8070I 0x05
#define MSC_SUBCLASS_SCSI 0x06
/* MSC Protocol Codes */
#define MSC_PROTOCOL_CBI_INT 0x00
#define MSC_PROTOCOL_CBI_NOINT 0x01
#define MSC_PROTOCOL_BULK_ONLY 0x50
/* MSC Request Codes */
#define MSC_REQUEST_RESET 0xFF
#define MSC_REQUEST_GET_MAX_LUN 0xFE
/* MSC Bulk-only Stage */
#define MSC_BS_CBW 0 /* Command Block Wrapper */
#define MSC_BS_DATA_OUT 1 /* Data Out Phase */
#define MSC_BS_DATA_IN 2 /* Data In Phase */
#define MSC_BS_DATA_IN_LAST 3 /* Data In Last Phase */
#define MSC_BS_DATA_IN_LAST_STALL 4 /* Data In Last Phase with Stall */
#define MSC_BS_CSW 5 /* Command Status Wrapper */
#define MSC_BS_ERROR 6 /* Error */
typedef __packed struct _MSC_CBW {
uint32_t dSignature; //cbw标志 为USBC四个字符
uint32_t dTag; //cbw标签,返回csw的时候需要添加
uint32_t dDataLength; //需要在数据阶段传送的字节数,低字节在前
uint8_t bmFlags; //cbw标志,最高位标识数据方向
uint8_t bLUN; //目标逻辑单元编号,仅仅使用低四位
uint8_t bCBLength; //cbw cb的长度,使用低五位
uint8_t CB[16]; //选择执行的命令,由选择的子类决定使用的命令,(一般是scsi命令集)
} MSC_CBW;
typedef __packed struct _MSC_CSW {
uint32_t dSignature; //csw标志,为字符 usbs
uint32_t dTag; //命令状态标签,从cbw的标签中来
uint32_t dDataResidue; //命令完成时的完成字节数
uint8_t bStatus; //命令执行状态 00代表执行成功
} MSC_CSW;
#define MSC_CBW_Signature 0x43425355 //usbc
#define MSC_CSW_Signature 0x53425355 //usbs
/* CSW Status Definitions */
#define CSW_CMD_PASSED 0x00
#define CSW_CMD_FAILED 0x01
#define CSW_PHASE_ERROR 0x02
/* SCSI Commands */
#define SCSI_TEST_UNIT_READY 0x00
#define SCSI_REQUEST_SENSE 0x03
#define SCSI_FORMAT_UNIT 0x04
#define SCSI_INQUIRY 0x12
#define SCSI_MODE_SELECT6 0x15
#define SCSI_MODE_SENSE6 0x1A
#define SCSI_START_STOP_UNIT 0x1B
#define SCSI_MEDIA_REMOVAL 0x1E
#define SCSI_READ_FORMAT_CAPACITIES 0x23
#define SCSI_READ_CAPACITY 0x25
#define SCSI_READ10 0x28
#define SCSI_WRITE10 0x2A
#define SCSI_VERIFY10 0x2F
#define SCSI_MODE_SELECT10 0x55
#define SCSI_MODE_SENSE10 0x5A
#endif
在之前的代码中会调用两个存储设备读写命令,如下
#ifndef __MEMORY_H_
#define __MEMORY_H_
#include "sst39vf32.h"
#include "k9f1g08.h"
#include "hy57v256.h"
#define NORFLASH 0
#define NANDFLASH 1
#if NORFLASH
#define MSC_MemorySize NOR_FLASH_SIZE //norflash大小
#define MSC_BlockSize SECTOR_SIZE //norflash扇区大小
#define MSC_BlockCount SECTOR_COUNT //norflash扇区总数
extern u8 msc_idle_time_count;
#define MSC_IDLE_TIME_LIMIT 90
#endif
#if NANDFLASH
#define MSC_MemorySize NAND_USE_NUMOF_BLOCK*NAND_PAGE_NUM*NAND_SERECT_SIZE //nand flash大小
#define MSC_BlockSize NAND_SERECT_SIZE //nand flash扇区大小
#define MSC_BlockCount NAND_USE_NUMOF_BLOCK*NAND_PAGE_NUM //nand flash扇区数量
extern u8 msc_idle_time_count;
#define MSC_IDLE_TIME_LIMIT 90
#endif
#endif
#include "memory.h"
#if NORFLASH
u8 msc_idle_time_count; //岣д?????
#endif
#if NANDFLASH
u8 msc_idle_time_count;
#endif