📄 usb.c
字号:
void set_usb_address(void) //设置地址
{
USB_set_addr=1;
while(select_endpoint(1)&0x01);
write_endpoint_buff(1,0,0);
set_usb_addr(Control_Data.DeviceRequest.wValue);
USB_usb_endp0_in=0;
USB_setup_packet_out=0;
}
void get_status(unsigned char receiver) //获取状态响应
{
unsigned char status[2];
switch (receiver)
{
case 0: //获取设备状态
status[0]=0x00;
status[1]=0x00;
break;
case 1: //获取接口状态
status[0]=0x00;
status[0]=0x00;
break;
case 2: //获取端点状态
status[0]=0x00;
status[1]=0x00;
break;
}
write_endpoint_buff(1,2,status);
USB_usb_endp0_in=0;
}
void clear_feature(unsigned char receiver)
{
receiver=0;
write_endpoint_buff(1,0,0);
USB_usb_endp0_in=0;
USB_setup_packet_out=0;
}
void set_feature(unsigned char receiver)
{
receiver=0;
write_endpoint_buff(1,0,0);
USB_usb_endp0_in=0;
USB_setup_packet_out=0;
}
void set_descriptor(void)
{
USB_usb_endp0_in=0;
USB_setup_packet_out=0;
}
void set_configuration(void)
{
write_endpoint_buff(1,0,0);
USB_usb_endp0_in=0;
USB_setup_packet_out=0;
}
void get_configuration(void) //获取配置状态
{
unsigned char value=0x01;
write_endpoint_buff(1,1,&value);
USB_usb_endp0_in=0;
}
void set_interface(void) //设置接口
{
write_endpoint_buff(1,0,0);
USB_usb_endp0_in=0;
USB_setup_packet_out=0;
}
void get_interface(void) //获取接口状态
{
unsigned char value=0x01;
write_endpoint_buff(1,1,&value);
USB_usb_endp0_in=0;
}
void get_max_LUN(void) //获取磁盘最大逻辑单元号
{
unsigned char max_LUN=MAX_LUN; //只有一个逻辑单元
write_endpoint_buff(1,1,&(max_LUN));
USB_usb_endp0_in=0;
}
void mass_storage_reset(void) //USB大容量存储设备复位
{
write_endpoint_buff(1,0,0);
USB_usb_endp0_in=0;
USB_setup_packet_out=0;
SCSI_Command=1;
SCSI_Data=0;
}
void get_descriptor(void) //获取描述符
{
if(!USB_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.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_set_addr)USB_not_end=1;
else USB_usb_endp0_in=0;
return;
}
else
{
write_endpoint_buff(1,Control_Data.wCount,Control_Data.pData);
USB_setup_packet_in=0;
USB_usb_endp0_in=0;
return;
}
}
void endp0_out(void) //终端点0输出中断处理
{
Last_Status_Register=read_last_status(0);
if(Last_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_not_end=0;
USB_usb_endp0_in=1;
USB_setup_packet_in=0;
USB_setup_packet_out=0;
if(Control_Data.DeviceRequest.bmRequestType&0x80){USB_setup_packet_in=1;return;}
else {USB_setup_packet_out=1;return;}
}
else
{
select_endpoint(0);
clear_buffer();
}
}
void endp0_in(void) //终端点0输入处理
{
read_last_status(1);
if(USB_setup_packet_in||USB_not_end)
{
if((Control_Data.DeviceRequest.bmRequestType==0xA1)&&(Control_Data.DeviceRequest.bRequest==0xFE))
get_max_LUN();
switch(Control_Data.DeviceRequest.bmRequestType&0x7B)
{
case 0:
switch (Control_Data.DeviceRequest.bRequest)
{
case 0: get_status(0);break;
case 6: get_descriptor();break;
case 8: get_configuration();break;
default:break;
}
case 1:
switch (Control_Data.DeviceRequest.bRequest)
{
case 0: get_status(1);break;
case 10: get_interface();break;
default: break;
}
case 2:
{
if(Control_Data.DeviceRequest.bRequest==0)get_status(2);
}
default: break;
}
return;
}
if(USB_setup_packet_out)
{
if((Control_Data.DeviceRequest.bmRequestType==0x21)&&(Control_Data.DeviceRequest.bRequest==0xFF))
mass_storage_reset();
switch(Control_Data.DeviceRequest.bmRequestType&0x03)
{
case 0:
switch (Control_Data.DeviceRequest.bRequest)
{
case CLEAR_FEATURE: clear_feature(0);break;
case SET_FEATURE: set_feature(0);break;
case SET_ADDRESS: set_usb_address();break; //set_address
case SET_DESCRIPTOR: set_descriptor();break; //set_descriptor
case SET_CONFIGURATION: set_configuration(); break; //set_configurat
default: break;
}break;
case 1:
switch (Control_Data.DeviceRequest.bRequest)
{
case CLEAR_FEATURE: clear_feature(1);break;
case SET_FEATURE: set_feature(1); break;
case SET_INTERFACE: set_interface();break;
default: break;
}break;
case 2:
switch (Control_Data.DeviceRequest.bRequest)
{
case CLEAR_FEATURE: clear_feature(2);break;
case SET_FEATURE: set_feature(2);break;
default: break;
}break;
default: break;
}
}
}
/*void endp1_out(void)
{
printc(0xcc);
}*/
/*void endp1_in(void)
{
printc(0xcc);
}*/
void Return_CSW(unsigned long int DataResidue,unsigned char status) //返回CSW数据包
{
csw.dCSWTag=cbw.dCBWTag;
csw.dCSWDataResidue=DataResidue;
csw.bCSWStatus=status;
while(select_endpoint(5)&0x01);
write_endpoint_buff(5,sizeof(CSW),(unsigned char *)(&csw));
USB_usb_endp2_in=0;
USB_usb_endp2_out=0;
SCSI_Command=1;
SCSI_Data=0;
}
void write_10(void) //SCSI写操作
{
unsigned long int LBA,Byte_Count;
unsigned char i;
if(SCSI_Data)
{
((unsigned char*)&LBA)[0]=cbw.CBWCB[2];
((unsigned char*)&LBA)[1]=cbw.CBWCB[3];
((unsigned char*)&LBA)[2]=cbw.CBWCB[4];
((unsigned char*)&LBA)[3]=cbw.CBWCB[5];
((unsigned char*)&Byte_Count)[0]=0;
((unsigned char*)&Byte_Count)[1]=cbw.CBWCB[7];
((unsigned char*)&Byte_Count)[2]=cbw.CBWCB[8];
((unsigned char*)&Byte_Count)[3]=0;
Byte_Count<<=1;
while(USB_usb_endp2_out)
{
if((((unsigned char *)&Byte_Count)[3]==0)&&((((unsigned char *)&Byte_Count)[2]&0x01)==0))
{
write_IDE_LBA0(((unsigned char*)&LBA)[0]);
write_IDE_LBA1(((unsigned char*)&LBA)[1]);
write_IDE_LBA2(((unsigned char*)&LBA)[2]);
write_IDE_LBA3(((unsigned char*)&LBA)[3]);
LBA++;
write_IDE_sector_count(1);
wait_IDE_busy();
write_IDE_sector();
IDE_Address=IDE_Data;
set_IDE_address();
}
while(!(select_endpoint(4)&0x01));
if(Byte_Count>64)
{
read_endpoint_buff(4,64,buffer);
Byte_Count-=64;
}
else
{
read_endpoint_buff(4,Byte_Count,buffer);
Return_CSW(0x00,SUCCESS);
}
for(i=0;i<64;i++)
{
while(!IDE_IORDY);
IDE_DIOW=0;
IDE_DATA_L=buffer[i];
i++;
IDE_DATA_H=buffer[i];
IDE_DIOW=1;
}
}
wait_IDE_busy();
IDE_Address=IDE_Bus_Not_Use;
set_IDE_address();
}
}
void endp2_out(void) //主端点输出处理
{
if(SCSI_Command)
{
if(read_endpoint_buff(4,sizeof(CBW),(unsigned char *)(&cbw))!=sizeof(CBW)){error(2);return;}
if(cbw.dCBWSignature!=0x55534243){error(3);return;}
SCSI_Command=0;
SCSI_Data=1;
if(cbw.bmCBWFlags&0x80)
{
USB_usb_endp2_in=1;
USB_usb_endp2_out=0;
}
else
{
USB_usb_endp2_in=0;
USB_usb_endp2_out=1;
switch(cbw.CBWCB[0])
{
case Write_10: write_10();break;
case Test_Unit_Ready: Return_CSW(0x00,SUCCESS);break;
case Verify: Return_CSW(0x00,SUCCESS);break;
default : Return_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
}
}
}
else
{
read_last_status(4);
select_endpoint(4);
clear_buffer();
}
}
void read_10(void) //SCSI读处理
{
unsigned long int LBA=0,Byte_Count;
unsigned char i;
if(SCSI_Data)
{
((unsigned char*)&LBA)[0]=cbw.CBWCB[2];
((unsigned char*)&LBA)[1]=cbw.CBWCB[3];
((unsigned char*)&LBA)[2]=cbw.CBWCB[4];
((unsigned char*)&LBA)[3]=cbw.CBWCB[5];
((unsigned char*)&Byte_Count)[0]=0;
((unsigned char*)&Byte_Count)[1]=cbw.CBWCB[7];
((unsigned char*)&Byte_Count)[2]=cbw.CBWCB[8];
((unsigned char*)&Byte_Count)[3]=0;
Byte_Count<<=1;
pData=buffer;
while(USB_usb_endp2_in)
{
if((((unsigned char *)&Byte_Count)[3]==0)&&((((unsigned char *)&Byte_Count)[2]&0x01)==0))
{
write_IDE_LBA0(((unsigned char*)&LBA)[0]);
write_IDE_LBA1(((unsigned char*)&LBA)[1]);
write_IDE_LBA2(((unsigned char*)&LBA)[2]);
write_IDE_LBA3(((unsigned char*)&LBA)[3]);
LBA++;
write_IDE_sector_count(1);
read_IDE_sector();
IDE_Address=IDE_Data;
set_IDE_address();
}
IDE_DATA_H=0xFF;
for(i=0;i<64;i++)
{
while(!IDE_IORDY);
IDE_DIOR=0;
buffer[i]=IDE_DATA_L;
i++;
buffer[i]=IDE_DATA_H;
IDE_DIOR=1;
}
while(select_endpoint(5)&0x01);
if(Byte_Count>MAX_BULK_DATA_SIZE)
{
write_endpoint_buff(5,MAX_BULK_DATA_SIZE,pData);
Byte_Count-=MAX_BULK_DATA_SIZE;
}
else
{
write_endpoint_buff(5,Byte_Count,pData);
Return_CSW(0x00,SUCCESS);
IDE_Address=IDE_Bus_Not_Use;
set_IDE_address();
}
}
}
else error(2);return;
}
void endp2_in(void) //主端点输入处理
{
switch(cbw.CBWCB[0])
{
case Read_10: read_10();break;
case Inquiry: write_endpoint_buff(5,0x24,DISK_INF);Return_CSW(0x00,SUCCESS); break;
case Read_Capacity: write_endpoint_buff(5,0x08,DISK_CAPACITY);Return_CSW(0x00,SUCCESS);break;
case Read_Format_capacity: write_endpoint_buff(5,0x00,0x00);Return_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
case Request_Sense: write_endpoint_buff(5,0x12,SENSE);Return_CSW(0x00,SUCCESS);break;
case Medium_Removal: Return_CSW(0x00,SUCCESS);break;
case 0x1a: write_endpoint_buff(5,0x00,0x00);Return_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
default : write_endpoint_buff(5,0x00,0x00);Return_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
}
}
void main(void)
{
disconnect_usb();
system_initial();
init_usb();
connect_usb();
while(1)
{
if(!USB_INT)
{
read_interrupt_register();
if(Interrupt_bus_reset){usb_bus_reset();continue;}
if(Interrupt_suspend_change){usb_bus_suspend();continue;}
if(Interrupt_control_out_port){endp0_out();continue;}
if(Interrupt_control_in_port&&USB_usb_endp0_in){endp0_in();continue;}
if(Interrupt_main_out_port){endp2_out();continue;}
if(Interrupt_main_in_port&&USB_usb_endp2_in){endp2_in();continue;}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -