硬件准备
ADSP-EDU-BF533:BF533开发板
AD-HP530ICE:ADI DSP仿真器
软件准备
Visual DSP++软件
硬件链接
硬件设计原理图
功能介绍
跟网口一样,USB这个设计很勉强,因为BF533并不带USB口,当时是给一个大厂做MP4的方案,人家要求用BF533,我们没得选的情况下,弄了一个这样的设计,再去在裸核下移植USB协议,很是复杂费劲,当初做这个项目真是让我头发都白了三根!
这个设计就当原理看就行,纯属理论学习,放到现在已经没有啥实际意义了。现在让我做这个项目,我肯定就直接选带USB接口的IC啦。
ADSP-EDU-BF53x 板卡上设计了一个 USB1.1 标准的 USB 设备芯片,其型号为 PDIUSBD12,该芯片有 6 个数据传输断点,其控制命令简单,寄存器少,适合于广大初学者学习 USB 协议。ADSP-BF53x 处理器通过 EBIU 接口的 BANK3 连接 PDIUSBD12 芯片,通过 CPLD 为其分配访问地址,通过 CPLD 的 USB_DAT 寄存器和 USB_CMD
寄存器进行访问。
USB_DAT 寄存器(读写):
USB_DAT 寄存器地址:0x20300000
USB_DAT 寄存器:该寄存器用于发送和读出 PDIUSBD12 端点的数据。
USB_CMD 寄存器(写唯一):
USB_CMD 寄存器地址:0x20300040
USB_CMD 寄存器:该寄存器用于发送 PDIUSBD12 的指令。
硬件连接示意图
代码实现功能
代码实现了 USB 设备的枚举和大容量存储器盘符出现的功能。运行代码后,将 MINIUSB 连接线连接板卡的MINIUSB 接口,这时计算机端会出现有 USB 设备接入,板卡上的 USB GL 指示灯会不停的闪烁,待枚举完成后,
在计算机端会出现一个磁盘符号。由于代码还没有做完善,我们不能对该磁盘符号做任何的操作。
将串口设置波特率 9600,打开超级终端,可以看到 USB 与计算机通讯的数据信息。也可使用 USB 抓包工具抓举更详细的数据信息。
注意:必须先运行代码,然后再将 USB 线接入计算机,否则不会产生硬件响应。
调试步骤
1. 将仿真器(ICE)与 ADSP-EDU-BF53x 开发板和计算机连接好。
2. 先给 ADSP-EDU-BF53x 开发板上电,再为仿真器(ICE)上电。
3. 运行 VisualDSP++ 软件,选择合适的 BF533 的 session 将仿真器与软件连接。
4. 加载 VisualDSP++ 5.0 工程文件 BF53x_USB,编译并全速运行。
5. 采用 MINIUSB 线连接计算机和板卡。
调试结果
在计算机端能看到有 USB 设备接入的提示,等待片刻后能在计算机端看到有 USB 设备接入。
超级终端上打印的 USB 数据包信息
计算机端发现 USB 设备接入,识别出是一个磁盘驱动器。
设备管理器中大容量存储器被识别。
计算机端显示盘符。
程序源码
cpu.c
#include <cdefBF533.h>
void Set_PLL(unsigned int pmsel,unsigned int pssel)
{
unsigned int new_PLL_CTL;
*pPLL_DIV = pssel;
asm(“ssync;”);
new_PLL_CTL = (pmsel & 0x3f) << 9;
*pSIC_IWR |= 0xffffffff;
if (new_PLL_CTL != *pPLL_CTL)
{
*pPLL_CTL = new_PLL_CTL;
asm(“ssync;”);
asm(“idle;”);
}
}
void Init_EBIU(void)
{
*pEBIU_AMBCTL0 = 0x7bb07bb0;
*pEBIU_AMBCTL1 = 0xffc0ffc0;
*pEBIU_AMGCTL = 0x000f;
}
void delay(int count)
{
int i;
for(i=0;i<count;i++)
asm(“ssync;”);
}
d12int.c
#include <cdefBF533.h>
#include “DataType.h”
#include “D12Def.h”
#include “USBDesc.h”
#include “MASS.H”
void delay(int count);
static U8 usb_remote_wake;
static U8 usb_config;
static U8 UsbSendDescF;
static int send_remain;
static U32 send_ptr;
CBW cbw;
CSW csw;
U8 UsbInit()
{
UsbSendDescF = 0;
if(D12RdChipId()!=0x1210 )
return STATUS_ERR;
D12SetDma(MyD12DmaCfg);
if(D12GetDma()!=MyD12DmaCfg)
return STATUS_ERR;
D12SetMode(MyD12EpCfgOff, D12Pll24M);
delay(20000);
D12SetMode(MyD12EpCfgOn, D12Pll24M);
return STATUS_OK;
}
#define UsbDevDescType 1
#define UsbCfgDescType 2
#define UsbStrDescType 3
#define UsbItfDescType 4
#define UsbEndpDescType 5
#define UsbPwrDescType 6
#define UsbDevDescSize 18
#define UsbCfgDescSize 9
#define UsbItfDescSize 9
#define UsbEndpDescSize 7
//#define UsbStrDescSize 15
#define UsbEndpControl 0
#define UsbEndpIsochronous 1
#define UsbEndpBulk 2
#define UsbEndpInterrupt 3
#define UsbClassMassStorage 8
#define UsbSubClassRbc 1
#define UsbSubClassSff8020i 2
#define UsbSubClassQic157 3
#define UsbSubClassUfi 4
#define UsbSubClassSff8070i 5
#define UsbSubClassScsi 6
#define UsbProtocolCbi0 0
#define UsbProtocolCbi1 1
#define UsbProtocolBulk 0x50
#define UsbLanguage_ID 0 //语言ID描述符字符串索引
#define UsbManufacturer 2 //厂商描述符字符串索引
#define UsbProduct 3 //产品描述符字符串索引
#define UsbSerialNumber 4 //设备序列号字符串索引
#define UsbConfiguration 5 //配置字符串描述符索引
#define UsbInterface 6 //接口字符串描述符索引
#define Ep0PacketSize 16
#define Ep2PacketSize 64
#define EndpCnt 2
#define UsbTotalCfgDescSize UsbCfgDescSize+UsbItfDescSize+EndpCnt*UsbEndpDescSize//+15 //9 + 9 + 2 * 7
struct __packed {
UsbDevDesc DevDesc;
U8 CfgDesc[9];
U8 ItfDesc[9];
U8 Endp4Desc[7];
U8 Endp5Desc[7];
U8 Language_ID[4]; //字符串语言ID描述符字符串
U8 Manufacturer[18]; //厂商描述符字符串
U8 Product[28]; //产品描述符字符串
U8 SerialNumber[18]; //设备序列号字符串
U8 Configuration[24]; //配置字符串描述符
U8 Interface[24]; //接口字符串描述符
}ThisDevDesc =
{
{ //设备描述符
UsbDevDescSize, //18
UsbDevDescType, //1
0x0110, //版本号1.1
0, //设备类型
0, //设备子类型
0, //协议 见109页
Ep0PacketSize, //16
0x471,//0x7104, //供应商 ID
0xf0ff,// 0x222, //产品ID 决定计算机出现什么样的图标
0x113, //0x0100, //设备出厂编码
UsbManufacturer,// 100, //厂商描述符字符串索引
UsbProduct,//101, //产品描述符字符串索引
UsbSerialNumber,//102,// 0x02, // 0, //设备序列号字符串索引
1 //可能的配置数
},
{ //配置描述符
UsbCfgDescSize, //9 //描述符大小
UsbCfgDescType, //2 //配置描述符类型 2
UsbTotalCfgDescSize, //32 //返回整个数据的长度 2个字节
0, //同上
1, //配置所支持的接口数
1, //set config 参数选择配置值
UsbConfiguration,//103, //用于描述该配置字符串描述符的索引
0x80, //配置特性为总线供电
0x32 //总线供电最大电流
},
{ //接口描述符
UsbItfDescSize, //9 //接口描述符大小
UsbItfDescType, //4 //接口描述符类型 4
0, //接口编号
0, //用于为上一个字段选择可替换的位置
EndpCnt, //2 //使用的端点数目
UsbClassMassStorage, //8 //接口类型代码 8 大容量存储设备
6, //UsbSubClassUfi, //4 //接口类型子代码 ************************
UsbProtocolBulk, //0x50 //协议代码 0x50 单批量传输协议
UsbInterface//105 // 0 //字符串描述符索引
},
{ //端点4描述符
UsbEndpDescSize, //7 //端点描述符长度
UsbEndpDescType, //5 //端点描述符类型 5
0x82, //USB设备的端点地址 0x82代表为输入端点
UsbEndpBulk, //2 //端点属性 2为批量
Ep2PacketSize, //64 //端点大小 2字节
0, //端点大小
0 //轮寻数据传出端点的时间
},
{ //端点5描述符
UsbEndpDescSize, //7
UsbEndpDescType, //5
0x2, //输出端点
UsbEndpBulk, //2
Ep2PacketSize, //64
0,
0
},
{ //字符串描述符 LANGUAGE_ID
4, //4 //字符串描述符大小
UsbStrDescType, //3 //字符串描述符类型
//LANGUAGE_ID
0x04,
0x09,
},
{
18, //厂商描述符字符串
UsbStrDescType,
'A',0,'D',0,'S',0,'P',0,'B',0,'F',0,'5',0,'3',0
},
{
26, //产品描述符字符串索引
UsbStrDescType,
'A',0,'N',0,'D',0,'Y',0,'R',0,'E',0,'N',0,'-',0,'U',0,'D',0,'a',0,'s',0,'k',0,
},
{ //设备序列号字符串
18, //18 //字符串描述符大小
UsbStrDescType, //3 //字符串描述符类型
0x32,0x00,0x30,0x00,0x37,0x00,0x31,0x00,0x30,0x00,0x39,0x00,0x38,0x00,0x32,0x00
},
{
24, ///配置字符串描述符
UsbStrDescType,
'P',0,'H',0,'I',0,'L',0,'I',0,'S',0,'P',0,'-',0,'D',0,'1',0,'2',0
},
{
24, ///接口字符串描述符
UsbStrDescType,
'U',0,'S',0,'B',0,'1',0,'.',0,'1',0,'-',0,'A',0,'D',0,'S',0,'P',0
},
};
/****************** standard device request ****************/
U8 UsbGetStatus(U8 *SetupPkt)
{
if(SetupPkt[2]|SetupPkt[3]|SetupPkt[5]|SetupPkt[7])
return 1;
if(SetupPkt[6]!=2)
return 1;
if(SetupPkt[0]==0x80)
{
if(SetupPkt[4])
return 1;
SetupPkt[0] = usb_remote_wake?1:0;
SetupPkt[1] = 0;
}
else
if(SetupPkt[0]==0x81)
{
if(SetupPkt[4])
return 1;
SetupPkt[0] = 0;
SetupPkt[1] = 0;
}
else
if(SetupPkt[0]==0x82)
{
D12SelEp((SetupPkt[4]*2)|((SetupPkt[4]&0x80)?1:0));
SetupPkt[1] = (D12Dat&2)?1:0;
SetupPkt[0] = 0;
}
else
return 1;
D12WrEp(1, SetupPkt, 2);
delay(100);
return 0;
}
U8 UsbClrFeature(U8 *SetupPkt)
{
if(SetupPkt[0]&0x80)
return STATUS_ERR;
if(SetupPkt[3]|SetupPkt[5]|SetupPkt[6]|SetupPkt[7])
return STATUS_ERR;
if(SetupPkt[0]&0x1f)
{
if((SetupPkt[0]&0x1f)!=2)
return STATUS_ERR;
D12SetEpStat((SetupPkt[4]*2)|((SetupPkt[4]&0x80)?1:0),0);
}
else
{
if(SetupPkt[4])
return STATUS_ERR;
usb_remote_wake = 0;
}
D12WrEp(1, SetupPkt, 0);
delay(100);
return STATUS_OK;
}
U8 UsbSetFeature(U8 *SetupPkt)
{
if(!(SetupPkt[0]&0x80))
return STATUS_ERR;
if(SetupPkt[3]|SetupPkt[5]|SetupPkt[6]|SetupPkt[7])
return STATUS_ERR;
if(SetupPkt[0]&0x1f)
{
if((SetupPkt[0]&0x1f)!=2)
return STATUS_ERR;
D12SetEpStat((SetupPkt[4]*2)|((SetupPkt[4]&0x80)?1:0),1);
}
else
{
if(SetupPkt[4])
return STATUS_ERR;
usb_remote_wake = 1;
}
D12WrEp(1, SetupPkt, 0);
delay(100);
return STATUS_OK;
}
U8 UsbSetAddress(U8 *SetupPkt)
{
if(SetupPkt[0]|SetupPkt[3]|SetupPkt[4]|SetupPkt[5]|SetupPkt[6]|SetupPkt[7])
return STATUS_ERR;
D12SetAddr(SetupPkt[2]|0x80);
delay(100);
D12WrEp(1, SetupPkt, 0);
delay(100);
return STATUS_OK;
}
void UsbSendDesc()
{
U8 i;
UsbSendDescF = send_remain>=Ep0PacketSize;
D12WrEp(1, (U8 *)send_ptr, (send_remain>Ep0PacketSize)?Ep0PacketSize:send_remain);
delay(100);
U_printf("SendDesc is:");
for(i=0; i<((send_remain>Ep0PacketSize)?Ep0PacketSize:send_remain); i++)
U_printf("%x,", *(U8 *)(send_ptr+i));
U_printf("\n\r");
send_remain -= Ep0PacketSize;
send_ptr += Ep0PacketSize;
}
U8 UsbGetDescriptor(U8 *SetupPkt)
{
if(SetupPkt[0]!=0x80)
return STATUS_ERR;
switch (SetupPkt[3])
{
case UsbDevDescType: //
send_ptr = (U32)&ThisDevDesc;
send_remain = UsbDevDescSize;
break;
case UsbCfgDescType:
send_ptr = (U32)&ThisDevDesc.CfgDesc;
send_remain = UsbTotalCfgDescSize;
break;
case UsbStrDescType:
if(SetupPkt[2]==UsbLanguage_ID)
{
send_ptr = (U32)&ThisDevDesc.Language_ID;
send_remain = 4;
}
else if(SetupPkt[2]==UsbManufacturer)
{
send_ptr = (U32)&ThisDevDesc.Manufacturer;
send_remain = 18;
}
else if(SetupPkt[2]==UsbProduct)
{
send_ptr = (U32)&ThisDevDesc.Product;
send_remain = 28;
}
else if(SetupPkt[2]==UsbSerialNumber)
{
send_ptr = (U32)&ThisDevDesc.SerialNumber;
send_remain = 18;
}
else if(SetupPkt[2]==UsbConfiguration)
{
send_ptr = (U32)&ThisDevDesc.Configuration;
send_remain = 24;
}
else if(SetupPkt[2]==UsbInterface)
{
send_ptr = (U32)&ThisDevDesc.Interface;
send_remain = 24;
}
/*
switch(SetupPkt[2])
{
case UsbLanguage_ID:
send_ptr = (U32)&ThisDevDesc.Language_ID;
send_remain = 4;
break;
case UsbManufacturer:
send_ptr = (U32)&ThisDevDesc.Manufacturer;
send_remain = 18;
break;
case UsbProduct:
send_ptr = (U32)&ThisDevDesc.Product;
send_remain = 28;
break;
case UsbSerialNumber:
send_ptr = (U32)&ThisDevDesc.SerialNumber;
send_remain = 18;
break;
case UsbConfiguration:
send_ptr = (U32)&ThisDevDesc.Configuration;
send_remain = 24;
break;
case UsbInterface:
send_ptr = (U32)&ThisDevDesc.Interface;
send_remain = 24;
break;
default:
break;
}
*/
break;
default:
return STATUS_ERR;
}
// U_printf(“send_ptr is %x\n”,send_ptr);
// U_printf(“send_remain is %x\n”,send_remain);
if(!SetupPkt[7]&&(SetupPkt[6]<send_remain))
send_remain = SetupPkt[6];
UsbSendDesc();
delay(100);
return STATUS_OK;
}
U8 UsbGetConfiguration(U8 *SetupPkt)
{
if(SetupPkt[0]!=0x80)
return STATUS_ERR;
if(SetupPkt[2]|SetupPkt[3]|SetupPkt[4]|SetupPkt[5]|SetupPkt[7])
return STATUS_ERR;
if(SetupPkt[6]!=1)
return STATUS_ERR;
SetupPkt[0] = usb_config?1:0;
D12WrEp(1, SetupPkt, 1);
delay(100);
return STATUS_OK;
}
U8 UsbSetConfiguration(U8 *SetupPkt)
{
if(SetupPkt[0]|SetupPkt[3]|SetupPkt[4]|SetupPkt[5]|SetupPkt[6]|SetupPkt[7])
return STATUS_ERR;
if(SetupPkt[2]&0xfe)
return STATUS_ERR;
usb_config = SetupPkt[2]&1;
D12SetEp(usb_config);
delay(100);
D12SetEpStat(4, usb_config^1);
delay(100);
D12SetEpStat(5, usb_config^1);
delay(100);
D12WrEp(1, SetupPkt, 0);
delay(100);
return STATUS_OK;
}
U8 UsbGetInterface(U8 *SetupPkt)
{
if(SetupPkt[0]!=0x81)
return STATUS_ERR;
if(SetupPkt[2]|SetupPkt[3]|SetupPkt[4]|SetupPkt[5]|SetupPkt[7])
return STATUS_ERR;
if(SetupPkt[6]!=1)
return STATUS_ERR;
SetupPkt[0] = 0;
D12WrEp(1, SetupPkt, 1);
return STATUS_OK;
}
U8 UsbSetInterface(U8 *SetupPkt)
{
return STATUS_ERR;
}
U8 UsbReserved(U8 *SetupPkt)
{
return STATUS_ERR;
}
U8 (*StdDevReq[])(U8 *SetupPkt) = {
UsbGetStatus, //0
UsbClrFeature, //1
UsbReserved, //2
UsbSetFeature, //3
UsbReserved, //4
UsbSetAddress, //5
UsbGetDescriptor, //6
UsbReserved, //7
UsbGetConfiguration,//8
UsbSetConfiguration,//9
UsbGetInterface, //A
UsbSetInterface, //B
UsbReserved, //C
UsbReserved, //D
UsbReserved, //E
UsbReserved //F
};
void mass_storage_reset(void) //USB大容量存储设备复位
{
D12WrEp(1,0,0);
// USB_usb_endp0_in=0;
//USB_setup_packet_out=0;
// SCSI_Command=1;
// SCSI_Data=0;
}
void Return_CSW(unsigned long int DataResidue,unsigned char status) //返回CSW数据包
{
csw.dCSWTag=cbw.dCBWTag; //将命令块封包中的标签
csw.dCSWDataResidue=DataResidue;//将长度差别传到命令状态封包
csw.bCSWStatus=status; //将状态送入命令状态封包
}
/********************** D12 interrupt process ******************/
void D12Ep0IntProc()
{
U8 SetupPkt[8];
U8 i;
UsbSendDescF = 0;
D12RdLastTrStat(0);
delay(100);
if(D12Cmd&0x20)
if(D12RdEp(0, SetupPkt, 8)==8)
{
delay(100);
D12AckEp(0);
delay(100);
D12AckEp(1);
delay(100);
U_printf("\n\r");
U_printf("device request: ");
// putch('\n');
for(i=0; i<8; i++)
U_printf("%x,", SetupPkt[i]);
U_printf("\n\r");
if(!StdDevReq[SetupPkt[1]&0xf](SetupPkt)); //UsbClrFeature
return;
}
D12SetEpStat(0, D12EpStall);
delay(100);
D12SetEpStat(1, D12EpStall);
delay(100);
}
void D12Ep1IntProc()
{
U8 i;
i = D12RdLastTrStat(1);
delay(100);
if(UsbSendDescF)
UsbSendDesc();
delay(100);
}
void D12Ep2IntProc()
{
D12SetEpStat(2, D12EpStall);
delay(100);
}
void D12Ep3IntProc()
{
D12SetEpStat(3, D12EpStall);
delay(100);
}
void D12Ep4IntProc() //PC向接口输出
{
U8 i;
U8 size;
U8 Ep2OutBuf[Ep2PacketSize];
D12RdLastTrStat(4);
delay(100);
BulkOut();
}
void D12Ep5IntProc() //接口向PC输入
{
BulkIn();
}
void D12BusRstProc()
{
}
void D12SuspChgProc()
{
}
d12op.c
#include “DataType.h”
#include “D12Def.h”
void D12SetEpStat(U8 Ep,U8 Stat)
{
delay(1000);
D12Cmd = Ep+0x40;
delay(1000);
D12Dat = Stat;
delay(1000);
}
void D12SetAddr(U8 Addr)
{
delay(1000);
D12Cmd = 0xd0;
delay(1000);
D12Dat = Addr;
delay(1000);
}
void D12SetEp(U8 Val)
{
delay(1000);
D12Cmd = 0xd8;
delay(1000);
D12Dat = Val;
delay(1000);
}
void D12SetDma(U8 Dma)
{
delay(1000);
D12Cmd = 0xfb;
delay(1000);
D12Dat = Dma;
delay(1000);
}
void D12SetMode(U8 Val1, U8 Val2)
{
delay(1000);
D12Cmd = 0xf3;
delay(1000);
D12Dat = Val1;
delay(1000);
D12Dat = Val2;
delay(1000);
}
void D12SendResume()
{
delay(1000);
D12Cmd = 0xf6;
delay(1000);
}
void D12AckEp(U8 Ep)
{
delay(1000);
D12Cmd = Ep;
delay(1000);
D12Cmd = 0xf1;
delay(1000);
if(!Ep)
D12Cmd = 0xf2;
}
U32 D12RdChipId()
{
U32 tmp;
D12Cmd = 0xfd;
delay(1000);
tmp = D12Dat;
delay(1000);
tmp = tmp<<8|D12Dat;
return tmp;
}
U8 D12GetDma()
{
delay(1000);
D12Cmd = 0xfb;
delay(1000);
return D12Cmd;
}
U8 D12RdEp(U8 Ep,U8 buf[],U8 cnt)
{
U8 tmp;
delay(1000);
D12SelEp(Ep);
delay(1000);
if(D12Cmd&1)
{
D12Cmd = 0xf0;
delay(1000);
tmp = D12Cmd;
delay(1000);
tmp = D12Cmd;
delay(1000);
if(tmp<cnt)
cnt = tmp;
tmp = cnt;
while(cnt)
{
*buf++ = D12Cmd;
delay(1000);
cnt–;
}
D12Cmd = 0xf2;
delay(1000);
return tmp;
}
else
return 0;
}
void D12WrEp(U8 Ep, U8 buf[], U8 cnt)
{
while(1)
{
D12SelEp(Ep);
delay(1000);
if(!(D12Cmd&1))
break;
}
delay(1000);
D12Cmd = 0xf0;
delay(1000);
D12Dat = 0;
delay(1000);
D12Dat = cnt;
delay(1000);
while(cnt)
{
D12Dat = *buf++;
delay(1000);
cnt–;
}
D12Cmd = 0xfa;
delay(1000);
}
U8 D12RdInt()
{
delay(1000);
D12Cmd = 0xf4;
delay(1000);
return D12Cmd;
}
ufi.c
#include <cdefbf53x.h>
#include “DataType.h”
#include “D12Def.h”
#include “USBDesc.h”
/Flash相关********/
#define DISK_ADDRESS 0x00040000 //模拟U盘位于Flash 512k处
#define READ_DISK(addr) ((U16)((DISK_ADDRESS+addr)<<1))
#define ERASE_SECTOR(addr) Erase_Sector(DISK_ADDRESS+addr)
#define PROGRAM_SECTOR(src,dst) Program_Sector(src,DISK_ADDRESS+dst)
#define DISK_BUFFER_SIZE SECTOR_SIZE_1601*2
//andy
/****************************************************************************/
#define FALSE 0
#define TRUE 1
#define SECTOR_SIZE_1601 2048
/*****************************************************************************/
//
#define MAX_PACKAGE_SIZE 64
#define ReadPipeBulkOut(DBuffer) D12RdEp(4,DBuffer,MAX_PACKAGE_SIZE)
#define WritePipeBulkIn(DBuffer,DSize) D12WrEp(5,DBuffer,DSize)
//
#define UFI_INQUIRY 0x12
#define UFI_READ_CAPACITY 0x25
#define UFI_READ_FORMAT_CAPACITY 0x23
#define UFI_READ 0x28
#define UFI_WRITE 0x2a
#define UFI_MODE_SENSE 0x1a
#define UFI_TEST_UNIT_READY 0x00
#define UFI_PREVENT_ALLOW_MEDIA_REMOVAL 0x1e
#define UFI_VERIFY 0x2f
#define MAX_PACKAGE_SIZE 64
#define ReadPipeBulkOut(DBuffer) D12RdEp(4,DBuffer,MAX_PACKAGE_SIZE)
#define WritePipeBulkIn(DBuffer,DSize) D12WrEp(5,DBuffer,DSize)
#define SECTOR_SIZE 512
#define MAX_LUN 0
#define BULKOUT_SIZE 64
unsigned char DISK_INF[36]= //磁盘信息
{
0x00,
0x00,
0x02,
0x02,
0x1F,
0x00,0x00,0x00,
0xB5,0xE7,0XC4,0xD4,0xC8,0xA6,0xC8,0xA6,
0xD7,0xD4,0xBC,0xBA,0xD7,0xF6,0xB5,0xC4,0xBC,0xD9,0x55,0xC5,0xCC,0x00,0x00,0x00,
0x31,0x2E,0x30,0x31
};
unsigned char DISK_CAPACITY[8]= //磁盘容量
{
0x00,0x01,0xff,0x00,
0x00,0x00,0x02,0x00
};
unsigned char SENSE[0x12]= //模式探测返回数据
{
0x70, 0x00, 0x05, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00
};
//unsigned char DBR[512]= //DOS引导记录
U8 DiskBuffer[DISK_BUFFER_SIZE]=
{
0xeb, 0x3e, 0x90, //跳转指令
0x4d, 0x53, 0x44, 0x4f, 0x53, 0x35, 0x2e, 0x30, //文件系统版本信息
0x00, 0x02, //扇区字节数
0x20, //每簇扇区数
0x01, 0x00, //保留扇区数
0x02, //该分区的FAT副本数
0xF0, 0x01, //根目录项数
0x00, 0x00, //小扇区数
0xf8, //媒体描述符
0x10, 0x00, //每FAT扇区数
0x20, 0x00, //每道扇区数
0x40, 0x00, //磁头数
0x00, 0x00, 0x00, 0x00, //隐藏扇区数
0x40, 0xff, 0x01, 0x00, //大扇区数
0x80, //磁盘驱动器参数,80表示硬盘
0x00, //保留
0x29, //扩展引导标记,0x29表示后三个区可用
0x88, 0x09, 0x71, 0x20, //标卷序列号
0xBC, 0xD9, 0x55, 0xC5, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //磁盘标卷
0x46, 0x41, 0x54, 0x31, 0x36, 0x20, 0x20, 0x20, //文件系统类型信息
0xf1, 0x7d,
0xfa, 0x33, 0xc9, 0x8e, 0xd1, 0xbc, 0xfc, 0x7b, 0x16, 0x07, 0xbd, 0x78, 0x00, 0xc5, 0x76, 0x00,
0x1e, 0x56, 0x16, 0x55, 0xbf, 0x22, 0x05, 0x89, 0x7e, 0x00, 0x89, 0x4e, 0x02, 0xb1, 0x0b, 0xfc,
0xf3, 0xa4, 0x06, 0x1f, 0xbd, 0x00, 0x7c, 0xc6, 0x45, 0xfe, 0x0f, 0x8b, 0x46, 0x18, 0x88, 0x45,
0xf9, 0xfb, 0x38, 0x66, 0x24, 0x7c, 0x04, 0xcd, 0x13, 0x72, 0x3c, 0x8a, 0x46, 0x10, 0x98, 0xf7,
0x66, 0x16, 0x03, 0x46, 0x1c, 0x13, 0x56, 0x1e, 0x03, 0x46, 0x0e, 0x13, 0xd1, 0x50, 0x52, 0x89,
0x46, 0xfc, 0x89, 0x56, 0xfe, 0xb8, 0x20, 0x00, 0x8b, 0x76, 0x11, 0xf7, 0xe6, 0x8b, 0x5e, 0x0b,
0x03, 0xc3, 0x48, 0xf7, 0xf3, 0x01, 0x46, 0xfc, 0x11, 0x4e, 0xfe, 0x5a, 0x58, 0xbb, 0x00, 0x07,
0x8b, 0xfb, 0xb1, 0x01, 0xe8, 0x94, 0x00, 0x72, 0x47, 0x38, 0x2d, 0x74, 0x19, 0xb1, 0x0b, 0x56,
0x8b, 0x76, 0x3e, 0xf3, 0xa6, 0x5e, 0x74, 0x4a, 0x4e, 0x74, 0x0b, 0x03, 0xf9, 0x83, 0xc7, 0x15,
0x3b, 0xfb, 0x72, 0xe5, 0xeb, 0xd7, 0x2b, 0xc9, 0xb8, 0xd8, 0x7d, 0x87, 0x46, 0x3e, 0x3c, 0xd8,
0x75, 0x99, 0xbe, 0x80, 0x7d, 0xac, 0x98, 0x03, 0xf0, 0xac, 0x84, 0xc0, 0x74, 0x17, 0x3c, 0xff,
0x74, 0x09, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10, 0xeb, 0xee, 0xbe, 0x83, 0x7d, 0xeb, 0xe5,
0xbe, 0x81, 0x7d, 0xeb, 0xe0, 0x33, 0xc0, 0xcd, 0x16, 0x5e, 0x1f, 0x8f, 0x04, 0x8f, 0x44, 0x02,
0xcd, 0x19, 0xbe, 0x82, 0x7d, 0x8b, 0x7d, 0x0f, 0x83, 0xff, 0x02, 0x72, 0xc8, 0x8b, 0xc7, 0x48,
0x48, 0x8a, 0x4e, 0x0d, 0xf7, 0xe1, 0x03, 0x46, 0xfc, 0x13, 0x56, 0xfe, 0xbb, 0x00, 0x07, 0x53,
0xb1, 0x04, 0xe8, 0x16, 0x00, 0x5b, 0x72, 0xc8, 0x81, 0x3f, 0x4d, 0x5a, 0x75, 0xa7, 0x81, 0xbf,
0x00, 0x02, 0x42, 0x4a, 0x75, 0x9f, 0xea, 0x00, 0x02, 0x70, 0x00, 0x50, 0x52, 0x51, 0x91, 0x92,
0x33, 0xd2, 0xf7, 0x76, 0x18, 0x91, 0xf7, 0x76, 0x18, 0x42, 0x87, 0xca, 0xf7, 0x76, 0x1a, 0x8a,
0xf2, 0x8a, 0x56, 0x24, 0x8a, 0xe8, 0xd0, 0xcc, 0xd0, 0xcc, 0x0a, 0xcc, 0xb8, 0x01, 0x02, 0xcd,
0x13, 0x59, 0x5a, 0x58, 0x72, 0x09, 0x40, 0x75, 0x01, 0x42, 0x03, 0x5e, 0x0b, 0xe2, 0xcc, 0xc3,
0x03, 0x18, 0x01, 0x27, 0x0d, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x73, 0x79,
0x73, 0x74, 0x65, 0x6d, 0x20, 0x64, 0x69, 0x73, 0x6b, 0xff, 0x0d, 0x0a, 0x44, 0x69, 0x73, 0x6b,
0x20, 0x49, 0x2f, 0x4f, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xff, 0x0d, 0x0a, 0x52, 0x65, 0x70,
0x6c, 0x61, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x2c, 0x20, 0x61,
0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6e,
0x79, 0x20, 0x6b, 0x65, 0x79, 0x0d, 0x0a, 0x00, 0x49, 0x4f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x53, 0x59, 0x53, 0x4d, 0x53, 0x44, 0x4f, 0x53, 0x20, 0x20, 0x20, 0x53, 0x59, 0x53, 0x80, 0x01,
0x00, 0x57, 0x49, 0x4e, 0x42, 0x4f, 0x4f, 0x54, 0x20, 0x53, 0x59, 0x53, 0x00, 0x00, 0x55, 0xaa,
};
unsigned char FAT[64]= //模拟的文件分配表
{
0xF8, 0xFF, 0xFF, 0xFF, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned char ZERO[64]= //填充0
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned char ROOT_DIR[64]= //根目录
{
0xC2, 0xC3, 0xD3, 0xCE, 0xB5, 0xBC, 0xB2, 0xA5, 0xBB, 0xFA, 0x20, //磁盘标卷
0x08, //文件属性,表示磁盘标卷
0x00, //保留
0x00, //创建时间毫秒时间戳
0x00, 0x40, //文件创建时间
0x41, 0x31, //文件创建日期
0x42, 0x31, //最后访问日期
0x00, 0x00, //起始簇号高位字节,FAT12/16必须为0
0x00, 0x40, //最后写时间
0x42, 0x31, //最后写日期
0x00, 0x00, //起始簇低位字节
0x00, 0x00, 0x00, 0x00, //文件长度
‘T’, ‘E’, ‘S’, ‘T’, ’ ', ’ ', ’ ', ’ ', ‘T’, ‘X’, ‘T’, //文件名
0x01, //文件属性,表示磁盘标卷
0x00, //保留
0x00, //创建时间毫秒时间戳
0x00, 0x40, //文件创建时间
0x41, 0x31, //文件创建日期
0x42, 0x31, //最后访问日期
0x00, 0x00, //起始簇号高位字节,FAT12/16必须为0
0x00, 0x40, //最后写时间
0x42, 0x31, //最后写日期
0x02, 0x00, //起始簇低位字节
0xe9, 0x00, 0x00, 0x00, //文件长度
};
/!!!极其注意 int型 数据是字对齐的!!!/
typedef struct{
U8 OperationCode;
U8 LUN;
U8 LBA;
U8 LBA1;
U8 LBA2;
U8 LBA3;
U8 ReserveA;
U8 TransferLength;
U8 TransferLength1;
U8 ReserveB[3];
}UFI_TYPE;
/!!!极其注意 int型 数据是字对齐的!!!/
typedef struct{
U32 dCBWSignature;
U32 dCBWTag;
U32 dCBWDataTransferLength;
U8 bmCBWFlags;
U8 bCBWLUN;
U8 bCBWCBLength;
U8 CBWCB[16];
}CBW_TYPE;
typedef struct{
U32 dCSWSignature;
U32 dCSWTag;
U32 dCSWDataResidue;
U8 bCSWStatus;
}CSW_TYPE;
CSW_TYPE CSW;
//
U32 RemainSize;/及其注意当要求发送128扇区时值为65536,若为 U16 则溢出!!!!!!/
//
U8 CurSendSize;
U8 BulkOutDataBuffer[MAX_PACKAGE_SIZE];
U8 WriteDataBuffer[SECTOR_SIZE];
U8 TmpArray[MAX_PACKAGE_SIZE];
U8* pBulkInData;
U8* pWriteData;
//BOOL CSWSendFlag=TRUE;
int CSWSendFlag=TRUE;
//U8 DiskBuffer[DISK_BUFFER_SIZE];//4k Flash缓冲
U32 BulkOutDataSize,DiskSecIndex,CurDiskBufferDataAddr;
void UFIHandler(CBW_TYPE*);
void UFI_Inquiry(void);
void UFI_Read(UFI_TYPE*);
void UFI_ReadCapacity(void);
void UFI_ReadFormatCapacity(void);
void UFI_Write(UFI_TYPE* pUFI);
void UFI_ModeSense(void);
void UFI_TestUintReady(void);
void UFI_PreventAllowMediaRemoval(void);
void UFI_Init(void);
void UFI_Init(){}
void WriteToDisk(U8* pDataBuffer,int Size);
void UFI_Verify(void);
void ReadDisk(U8*,U32,U32);
U32 ConvertToU32(U8* pData){
U32 num;
num=pData[0]*16777216+pData[1]*65536+pData[2]*256+pData[3];
return num;
}
U16 ConvertToU16(U8* pData){
U16 num;
num=pData[0]*256+pData[1];
return num;
}
void BulkOut(){
int index,size;
CBW_TYPE* pCBW;
int i;
size=ReadPipeBulkOut(BulkOutDataBuffer);
U_printf("\n\r");
U_printf("CBW size is %x\n\r ",size);
U_printf("CBW Value is:\n\r");
for(i=0;i<size;i++)
{
U_printf(" %x,", BulkOutDataBuffer[i]);
if(i%8==0) U_printf("\n\r");
}
U_printf("\n");
if(size==31){
pCBW=(CBW_TYPE*)BulkOutDataBuffer;
if(pCBW->dCBWSignature==0x43425355){
UFIHandler(pCBW);
}
}else{
if(size==0){
//Uart_SendString("BulkOut zero");
return;
}
if(size!=64)
// Uart_Printf("Size=",size);
for(index=0;index<size;index++){
DiskBuffer[CurDiskBufferDataAddr+index]=BulkOutDataBuffer[index];
}
CurDiskBufferDataAddr+=size;
BulkOutDataSize-=size;
//Uart_Printf("\nBulkOutDataSize",BulkOutDataSize);
//Uart_Printf("\nCurDiskBufferDataAddr",CurDiskBufferDataAddr);
if(BulkOutDataSize==0){
//PROGRAM_SECTOR((U16*)DiskBuffer,SECTOR_SIZE_1601*DiskSecIndex);
//Uart_Printf("\nDiskSecIndex 1",DiskSecIndex);
}else if(CurDiskBufferDataAddr>=DISK_BUFFER_SIZE){
//PROGRAM_SECTOR((U16*)DiskBuffer,SECTOR_SIZE_1601*DiskSecIndex);
//Uart_Printf("\nDiskSecIndex 2",DiskSecIndex);
CurDiskBufferDataAddr=0;
DiskSecIndex++;
if(BulkOutDataSize<DISK_BUFFER_SIZE){
ReadDisk(DiskBuffer,DiskSecIndex*SECTOR_SIZE_1601*2,DISK_BUFFER_SIZE);
}
}
}
}
void BulkIn(){
int i;
if(RemainSize>0){
if(RemainSize>BULKOUT_SIZE){
CurSendSize=BULKOUT_SIZE;
RemainSize-=BULKOUT_SIZE;
WritePipeBulkIn(pBulkInData,CurSendSize);
pBulkInData+=BULKOUT_SIZE;
}else{
CurSendSize=RemainSize;
RemainSize=0;
WritePipeBulkIn(pBulkInData,CurSendSize);
}
}else{
if(CSWSendFlag==FALSE){
WritePipeBulkIn((U8*)(&CSW),13);
CSWSendFlag=TRUE;
}
}
}
void UFIHandler(CBW_TYPE* pCBW){
UFI_TYPE* pUFI;
pUFI=(UFI_TYPE*)(&(pCBW->CBWCB));
//Uart_Printf(“\nCommand:”,pUFI->OperationCode);
CSW.dCSWSignature=0x53425355;
CSW.dCSWTag=pCBW->dCBWTag;
switch(pUFI->OperationCode){
case UFI_INQUIRY: UFI_Inquiry(); break; //查询命令 0x12
case UFI_READ: UFI_Read(pUFI); break; //读10 0x28
case UFI_READ_CAPACITY: UFI_ReadCapacity(); break; //读容量 0x25
case UFI_READ_FORMAT_CAPACITY: UFI_ReadFormatCapacity(); break; //读格式容量 0x23
case UFI_WRITE: UFI_Write(pUFI); break; //写10 0x2a
case UFI_MODE_SENSE: UFI_ModeSense(); break; //模式感知 0x1a 找不到命令表,不知干什么
case UFI_TEST_UNIT_READY: UFI_TestUintReady(); break; //单元测试 0x00
case UFI_VERIFY: UFI_Verify(); break; //验证 0x2f
case UFI_PREVENT_ALLOW_MEDIA_REMOVAL:UFI_PreventAllowMediaRemoval();break; //写并验证 0x2E
default:
//CSW.bCSWStatus=0x00;
break;
}
}
//
//
void UFI_Inquiry(void){
U8 InquiryData[36]={
0x00,//外设类型 软磁盘设备
0x80,//RMB 可移除介质
0x00,//版本号
0x01,//响应数据的格式
0x1f,//附加数据长度
0,0,0,//保留
'B','F','5','3','x',0,0,0,//厂商信息
'U','D','i','s','k',0,0,0,0,0,0,0,0,0,0,0,
0,1,0,0//产品版本信息
};
CSW.dCSWDataResidue=0;
CSW.bCSWStatus=0;
pBulkInData=InquiryData;
RemainSize=36;
CSWSendFlag=FALSE;
}
void UFI_ReadCapacity(){
U8 pd[8]={0x00,0x00,0x08,0x00,
0x00,0x00,0x02,0x00};
CSW.dCSWDataResidue=0;
CSW.bCSWStatus=0;
//pBulkInData=pd;
pBulkInData= DISK_CAPACITY; //andy test modify
RemainSize=8;
CSWSendFlag=FALSE;
}
void UFI_ReadFormatCapacity(){
U8 bf[20]={0x00,0x00,0x00,0x10,
0x00,0x01,0xf4,0x00,
0x02,0x00,0x02,0x00,
0x00,0x01,0xf4,0x00,
0x00,0x00,0x02,0x00};
//CSW.dCSWDataResidue=0xe8;
CSW.bCSWStatus=0;
pBulkInData=bf;
RemainSize=20;
CSWSendFlag=FALSE;
}
void UFI_ModeSense(){
TmpArray[0]=0x03;
TmpArray[1]=0x00;
TmpArray[2]=0x00;
TmpArray[3]=0x00;
//pBulkInData=TmpArray;
//RemainSize=4;
pBulkInData=SENSE;
RemainSize=0x12;
CSWSendFlag=FALSE;
}
void UFI_TestUintReady(){
CSW.dCSWDataResidue=0;
CSW.bCSWStatus=0;
RemainSize=0;
CSWSendFlag=FALSE;
}
void UFI_Verify(){
CSW.dCSWDataResidue=0;
CSW.bCSWStatus=0;
RemainSize=0;
CSWSendFlag=FALSE;
}
void UFI_PreventAllowMediaRemoval(){
CSW.dCSWDataResidue=0;
CSW.bCSWStatus=0;
RemainSize=0;
CSWSendFlag=FALSE;
}
void UFI_Read(UFI_TYPE* pUFI){
U32 LBA;
U16 Length;
CSW.dCSWDataResidue=0;
CSW.bCSWStatus=0;
LBA=ConvertToU32(&pUFI->LBA);
Length=ConvertToU16(&pUFI->TransferLength);
//Uart_SendString("\nREAD");
U_printf("\n\r");(" LBA\n",LBA);
U_printf("\n\r");(" Length\n",Length);
U_printf("\n\r");
ReadDisk(DiskBuffer,SECTOR_SIZE*LBA,512*Length);
pBulkInData=DiskBuffer;
RemainSize=SECTOR_SIZE*Length;
CSWSendFlag=FALSE;
}
void UFI_Write(UFI_TYPE* pUFI){
U32 LBA;
U16 Length;
CSW.dCSWDataResidue=0;
CSW.bCSWStatus=0;
LBA=ConvertToU32(&pUFI->LBA);
Length=ConvertToU16(&pUFI->TransferLength);
//Uart_SendString("\nWrite");
//Uart_Printf(" LBA",LBA);
//Uart_Printf(" Length",Length);
BulkOutDataSize=Length*SECTOR_SIZE;
DiskSecIndex=(SECTOR_SIZE*LBA/2)/SECTOR_SIZE_1601;
CurDiskBufferDataAddr=SECTOR_SIZE*LBA-DiskSecIndex*SECTOR_SIZE_1601*2;
if(BulkOutDataSize<DISK_BUFFER_SIZE){
ReadDisk(DiskBuffer,DiskSecIndex*SECTOR_SIZE_1601*2,DISK_BUFFER_SIZE);
}
RemainSize=0;
CSWSendFlag=FALSE;
}
void WriteToDisk(U8* pData,int size){
static int CurSize=0;
int i;
for(i=0;i<size;i++){
WriteDataBuffer[CurSize+i]=pData[i];
}
CurSize+=size;
if(CurSize>=SECTOR_SIZE){
for(i=0;i<CurSize;i++){
pWriteData[i]=WriteDataBuffer[i];
}
pWriteData+=CurSize;
CurSize=0;
}
}
void ReadDisk(U8* pDataBuffer,U32 addr,U32 Size){
U32 Index,U16Size,U16Addr;
U16Size=Size>>1;
U16Addr=addr>>1;
for(Index=0;Index<U16Size;Index++){
*((U16*)pDataBuffer+Index)=READ_DISK(U16Addr+Index);
}
}
//#endif
main.c
#include “datatype.h”
#include “D12Def.h”
int main(void)
{
int i;
Set_PLL(16,4);
Init_EBIU();
UART_setbaudrate(9600);
UART_init();
U_printf("System Initialized.\n\r");
if(UsbRdChipId()==0x1210)
{
U_printf("Find Pdiusbd12, chip id = 0x1210\n\r");
UsbInit();
while(1)
{
i = UsbQueryInt();
UsbIntProc(i);
}
}
}