📄 usb.c
字号:
UEPSTAX=(UEPSTAX & (~0x80));
USB_usb_endp0_in=0;
}
void get_max_LUN(void) //获取磁盘最大逻辑单元号
{
unsigned char max_LUN=MAX_LUN; //只有一个逻辑单元
UEPNUM=0;
UEPSTAX=(UEPSTAX | 0x80); //数据阶段的输入
write_endpoint_buff(0,1,&(max_LUN));
UEPSTAX=(UEPSTAX & (~0x80));
USB_usb_endp0_in=0;
}
void mass_storage_reset(void) //USB大容量存储设备复位
{
write_endpoint_buff(0,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)
{
UEPNUM=0;
UEPSTAX=(UEPSTAX | 0x80); //数据阶段的输入
write_endpoint_buff(0,MAX_CONTROL_DATA_SIZE,Control_Data.pData);
UEPSTAX=(UEPSTAX & (~0x80));
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
{
UEPNUM=0;
UEPSTAX=(UEPSTAX | 0x80); //数据阶段的输入
write_endpoint_buff(0,Control_Data.wCount,Control_Data.pData);
UEPSTAX=(UEPSTAX & (~0x80));
USB_setup_packet_in=0;
USB_usb_endp0_in=0;
return;
}
}
void endp0_out(void) //终端点0输出中断处理
{
if(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))
{
error(1);
return;
}
UEPNUM=0;
UEPSTAX= UEPSTAX & (~0x04); //清除SETUP标记
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);
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
{
read_endpoint_buff(0,0,0);
}
}
void endp0_in(void) //终端点0输入处理
{
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 Return_CSW(unsigned long int DataResidue,unsigned char status) //返回CSW数据包
{
csw.dCSWTag=cbw.dCBWTag;
csw.dCSWDataResidue=DataResidue;
csw.bCSWStatus=status;
write_endpoint_buff(1,sizeof(CSW),(unsigned char *)(&csw));
USB_usb_endp1_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;
pData=buffer;
while(USB_usb_endp2_out)
{
if((((unsigned char *)&Byte_Count)[3]==0)&&((((unsigned char *)&Byte_Count)[2]&0x01)==0))
{
wait_IDE_busy();
write_IDE_LBA(LBA);
write_IDE_sector_count(1);
write_IDE_command(IDE_Write_Sectors);
IDE_Address=IDE_Data;
set_IDE_address();
LBA++;
}
while(!(RXOUTB0||RXOUTB1));
if(Byte_Count>MAX_BULK_DATA_SIZE)
{
UEPNUM=2; //选择端点
for(i=0;i<MAX_BULK_DATA_SIZE;i++)
{
while(!IDE_IORDY);
IDE_DIOW=0;
IDE_DATA_L=UEPDATX;
i++;
IDE_DATA_H=UEPDATX;
IDE_DIOW=1;
}
UEPSTAX=UEPSTAX & (~0x42);//清除RXOUTB 位
Byte_Count-=MAX_BULK_DATA_SIZE;
}
else
{
UEPNUM=2; //选择端点
for(i=0;i<Byte_Count;i++)
{
while(!IDE_IORDY);
IDE_DIOW=0;
IDE_DATA_L=UEPDATX;
i++;
IDE_DATA_H=UEPDATX;
IDE_DIOW=1;
}
UEPSTAX=UEPSTAX & (~0x42);//清除RXOUTB 位
Return_CSW(0x00,SUCCESS);
wait_IDE_busy();
IDE_Address=IDE_Bus_Not_Use;
set_IDE_address();
}
}
}
else
{
error(3);
}
}
void endp2_out(void) //主端点输出处理
{
if(SCSI_Command)
{
if(read_endpoint_buff(2,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_endp1_in=1;
USB_usb_endp2_out=0;
}
else
{
USB_usb_endp1_in=0;
USB_usb_endp2_out=1;
switch(cbw.CBWCB[0])
{
case Write_10: USB_LED=!USB_LED;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_endpoint_buff(2,0,0);
}
}
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_endp1_in)
{
if((((unsigned char *)&Byte_Count)[3]==0)&&((((unsigned char *)&Byte_Count)[2]&0x01)==0))
{
write_IDE_LBA(LBA);
write_IDE_sector_count(1);
write_IDE_command(IDE_Read_Sectors);
IDE_Address=IDE_Data;
set_IDE_address();
IDE_DATA_H=0xFF;
IDE_DATA_L=0xFF;
LBA++;
}
if(Byte_Count>MAX_BULK_DATA_SIZE)
{
UEPNUM=1; //选择端点
for(i=0;i<MAX_BULK_DATA_SIZE;i++) //填数据寄存器
{
while(!IDE_IORDY); //等待IDE IO口忙
IDE_DIOR=0; //发读信号
UEPDATX=IDE_DATA_L; //读低字节
i++;
UEPDATX=IDE_DATA_H; //读高字节
IDE_DIOR=1; //
}
UEPSTAX=UEPSTAX | 0x10; //设置TXRDY位
while(!( UEPSTAX & 0x01 )); //等待TXCMP
UEPSTAX=UEPSTAX & (~0x01); //清除TXCMP
Byte_Count-=MAX_BULK_DATA_SIZE;
}
else
{
UEPNUM=1; //选择端点
for(i=0;i<Byte_Count;i++) //填数据寄存器
{
while(!IDE_IORDY);
IDE_DIOR=0;
UEPDATX=IDE_DATA_L;
i++;
UEPDATX=IDE_DATA_H;
IDE_DIOR=1;
}
UEPSTAX=UEPSTAX | 0x10; //设置TXRDY位
while(!( UEPSTAX & 0x01 )); //等待TXCMP
UEPSTAX=UEPSTAX & (~0x01); //清除TXCMP
Return_CSW(0x00,SUCCESS);
IDE_Address=IDE_Bus_Not_Use;
set_IDE_address();
IDE_DATA_L=0xFF;
}
}
}
else error(2);return;
}
void endp1_in(void) //主端点输入处理
{
switch(cbw.CBWCB[0])
{
case Read_10: USB_LED=!USB_LED;read_10();break;
case Inquiry: write_endpoint_buff(1,0x24,DISK_INF);Return_CSW(0x00,SUCCESS); break;
case Read_Capacity: write_endpoint_buff(1,0x08,DISK_CAPACITY);Return_CSW(0x00,SUCCESS);break;
case Read_Format_capacity: write_endpoint_buff(1,0x00,0x00);Return_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
case Request_Sense: write_endpoint_buff(1,0x12,SENSE);Return_CSW(0x00,SUCCESS);break;
case Medium_Removal: Return_CSW(0x00,SUCCESS);break;
case 0x1a: write_endpoint_buff(1,0x00,0x00);Return_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
default : write_endpoint_buff(1,0x00,0x00);Return_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
}
}
void usb(void)
{
LCD_go_home();
prints("移动硬盘模式 ");
LCD_line_feed();
prints(" ");
disconnect_usb();
init_usb();
connect_usb();
while(1)
{
read_usb_status();
if(status_bus_reset){usb_bus_reset();continue;}
if(status_suspend_change){usb_bus_suspend();continue;}
if(status_control_out_port){endp0_out();continue;}
if(status_control_in_port&&USB_usb_endp0_in){endp0_in();continue;}
if(status_main_out_port){endp2_out();continue;}
if(status_main_in_port&&USB_usb_endp1_in){endp1_in();continue;}
if(key)
{
if(remove_enable)
{
if(key==KEY_OK)
{
key=0;
status=STOP;
USBCON=0x40;
disconnect_usb();
return;
}
}
else
{
key=0;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -