📄 usb.c
字号:
#include "usb.h"
#include "d12.h"
#include "MASS_STORAGE.H"
#include "fat.h"
CONTROL_DATA_BUFF Control_Data;
unsigned char buffer[64];
CBW cbw;
CSW csw;
SCSI_DEF SCSI;
unsigned char const *pData;
const unsigned char LANGUAGE_ID[4]={0x04,0x03,0x09,0x04}; //字符串描述符所用的语言种类
const unsigned char device_serial_number[18]= //设备序列号
{0x12,0x03,0x32,0x00,0x30,0x00,0x37,0x00,0x31,0x00,0x30,0x00,0x39,0x00,0x38,0x00,0x32,0x00};
const DEVICE_DESCRIPTOR_STRUCT device_descriptor= //设备描述符
{
sizeof(DEVICE_DESCRIPTOR_STRUCT), //设备描述符的字节数大小
DEVICE_DESCRIPTOR, //设备描述符类型编号
0x1001, //USB版本号
0x00, //USB分配的设备类代码
0x00, //USB分配的子类代码
0x00, //USB分配的设备协议代码
0x10, //端点0的最大包大小
0x7104, //厂商编号
0xf0ff, //产品编号
// 0x0100, //设备出厂编号
0x0001, //设备出厂编号
0x00, //设备厂商字符串的索引
0x00, //描述产品字符串的索引
0x02, //描述设备序列号字符串的索引
0x01 //可能的配置数量
};
const CON_INT_ENDP_DESCRIPTOR_STRUCT con_int_endp_descriptor=
{
//configuration_descriptor //配置描述符
{
sizeof(CONFIGURATION_DESCRIPTOR_STRUCT), //配置描述符的字节数大小
CONFIGURATION_DESCRIPTOR, //配置描述符类型编号
(sizeof(CONFIGURATION_DESCRIPTOR_STRUCT)+sizeof(INTERFACE_DESCRIPTOR_STRUCT)+sizeof(ENDPOINT_DESCRIPTOR_STRUCT)*ENDPOINT_NUMBER)*256+
(sizeof(CONFIGURATION_DESCRIPTOR_STRUCT)+sizeof(INTERFACE_DESCRIPTOR_STRUCT)+sizeof(ENDPOINT_DESCRIPTOR_STRUCT)*ENDPOINT_NUMBER)/256,
0x01, //只包含一个接口
0x01, //该配置的编号
0x00, //iConfiguration字段
0x80, //采用总线供电,不支持远程唤醒
0xC8 //从总线获取最大电流400mA
},
//interface_descritor //接口描述符
{
sizeof(INTERFACE_DESCRIPTOR_STRUCT), //接口描述符的字节数大小
INTERFACE_DESCRIPTOR, //接口描述符类型编号
0x00, //接口编号为0
0x00, //该接口描述符的编号
ENDPOINT_NUMBER, //非0端点数量为2,只使用端点主端点输入和输出
0x08, //USB大容量存储设备
0x06, //使用的子类,为简化块命令
0x50, //使用的协议,这里使用单批量传输协议
0x00 //接口描述符字符串索引
},
//endpoint_descriptor[]
{
{ //主端点输入描述
sizeof(ENDPOINT_DESCRIPTOR_STRUCT), //端点描述符的字节数大小
ENDPOINT_DESCRIPTOR, //端点描述符类型编号
MAIN_POINT_IN, //端点号,主输入端点
ENDPOINT_TYPE_BULK, //使用的传输类型,批量传输
0x4000, //该端点支持的最大包尺寸,64字节
0x00 //中断扫描时间,对批量传输无效
},
{ //主端点输出描述
sizeof(ENDPOINT_DESCRIPTOR_STRUCT), //端点描述符的字节数大小
ENDPOINT_DESCRIPTOR, //端点描述符类型编号
MAIN_POINT_OUT, //端点号,主输出端点
ENDPOINT_TYPE_BULK, //使用的传输类型,批量传输
0x4000, //该端点支持的最大包尺寸,64字节
0x00 //中断扫描时间,对批量传输无效
}
}
};
unsigned int SWAP(unsigned short temp) //高低字节交换
{
unsigned short i;
i=temp;
i<<=8;
temp>>=8;
i|=temp;
return i;
}
/*unsigned long int SWAP_long(unsigned long int temp) //四字节交换
{
unsigned long int i;
i=temp<<24;
i|=(temp<<8)&0x00FF0000;
i|=(temp>>8)&0x0000FF00;
i|=(temp>>24)&0x000000FF;
return i;
}*/
unsigned char LSB(unsigned short temp) //取一个整数的低字节
{
return (unsigned char)temp;
}
unsigned char MSB(unsigned short temp) //取一个整数的高字节
{
return (unsigned char)(temp>>8);
}
void clear_feature(unsigned char receiver)
{
receiver=0;
write_endpoint_buff(1,0,0);
usb_flags.flags.usb_endp0_in=0;
usb_flags.flags.setup_packet_out=0;
}
void set_feature(unsigned char receiver)
{
receiver=0;
write_endpoint_buff(1,0,0);
usb_flags.flags.usb_endp0_in=0;
usb_flags.flags.setup_packet_out=0;
}
void set_descriptor(void)
{
usb_flags.flags.usb_endp0_in=0;
usb_flags.flags.setup_packet_out=0;
}
void set_configuration(void)
{
write_endpoint_buff(1,0,0);
usb_flags.flags.usb_endp0_in=0;
usb_flags.flags.setup_packet_out=0;
}
void get_configuration(void) //获取配置状态
{
unsigned char value=0x01;
write_endpoint_buff(1,1,&value);
usb_flags.flags.usb_endp0_in=0;
}
void set_interface(void) //设置接口
{
write_endpoint_buff(1,0,0);
usb_flags.flags.usb_endp0_in=0;
usb_flags.flags.setup_packet_out=0;
}
void get_interface(void) //获取接口状态
{
unsigned char value=0x01;
write_endpoint_buff(1,1,&value);
usb_flags.flags.usb_endp0_in=0;
}
void get_max_LUN(void) //获取磁盘最大逻辑单元号
{
unsigned char max_LUN=MAX_LUN; //只有一个逻辑单元
write_endpoint_buff(1,1,&(max_LUN));
usb_flags.flags.usb_endp0_in=0;
}
void mass_storage_reset(void) //USB大容量存储设备复位
{
write_endpoint_buff(1,0,0);
usb_flags.flags.usb_endp0_in=0;
usb_flags.flags.setup_packet_out=0;
SCSI.SCSI_Status.Command=1;
SCSI.SCSI_Status.Data=0;
}
void get_descriptor(void) //获取描述符
{
if(!usb_flags.flags.not_end)
{
switch(MSB(Control_Data.DeviceRequest.wValue))
{
case DEVICE_DESCRIPTOR:
Control_Data.wCount=sizeof(DEVICE_DESCRIPTOR_STRUCT);
Control_Data.pData=(unsigned char *)(&device_descriptor);
break;
case CONFIGURATION_DESCRIPTOR:
Control_Data.wCount=SWAP(con_int_endp_descriptor.configuration_descriptor.wTotalLength);
Control_Data.pData=(unsigned char *)(&con_int_endp_descriptor);
if( Control_Data.DeviceRequest.wLength == 0x2300)
{
Control_Data.DeviceRequest.wLength = Control_Data.DeviceRequest.wLength;
}
if(Control_Data.wLength<Control_Data.wCount)
Control_Data.wCount=Control_Data.wLength;
break;
case STRING_DESCRIPTOR:
if(LSB(Control_Data.DeviceRequest.wValue)==0)
{
Control_Data.wCount=LANGUAGE_ID[0];
Control_Data.pData=LANGUAGE_ID;
}
if(LSB(Control_Data.DeviceRequest.wValue)==2)
{
Control_Data.wCount=device_serial_number[0];
Control_Data.pData=device_serial_number;
}
break;
}
if(Control_Data.wLength<Control_Data.wCount)
Control_Data.wCount=Control_Data.wLength;
}
if(Control_Data.wCount>=MAX_CONTROL_DATA_SIZE)
{
write_endpoint_buff(1,MAX_CONTROL_DATA_SIZE,Control_Data.pData);
Control_Data.pData+=MAX_CONTROL_DATA_SIZE;
Control_Data.wCount-=MAX_CONTROL_DATA_SIZE;
if(usb_flags.flags.set_addr)usb_flags.flags.not_end=1;
else usb_flags.flags.usb_endp0_in=0;
return;
}
else
{
write_endpoint_buff(1,Control_Data.wCount,Control_Data.pData);
usb_flags.flags.setup_packet_in=0;
usb_flags.flags.usb_endp0_in=0;
return;
}
}
void endp0_out(void) //终端点0输出中断处理
{
Last_Status.Register=read_last_status(0);
if(Last_Status.Status.setup_packet)
{
Control_Data.wLength=0;
Control_Data.wCount=0;
if(read_endpoint_buff(0,sizeof(Control_Data.DeviceRequest),(unsigned char *)(&(Control_Data.DeviceRequest)))!=sizeof(REQUESTCMD))
{
set_endpoint_status(0,0);
set_endpoint_status(1,0);
return;
}
// Control_Data.DeviceRequest.wValue=SWAP(Control_Data.DeviceRequest.wValue);
// Control_Data.DeviceRequest.wIndex=SWAP(Control_Data.DeviceRequest.wIndex);
// Control_Data.DeviceRequest.wLength=SWAP(Control_Data.DeviceRequest.wLength);
ack_setup(0);
ack_setup(1);
Control_Data.wLength=Control_Data.DeviceRequest.wLength;
usb_flags.flags.not_end=0;
usb_flags.flags.usb_endp0_in=1;
usb_flags.flags.setup_packet_in=0;
usb_flags.flags.setup_packet_out=0;
if(Control_Data.DeviceRequest.bmRequestType&0x80)
{
usb_flags.flags.setup_packet_in=1;return;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -