📄 usb.c
字号:
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 {usb_flags.flags.setup_packet_out=1;return;}
}
else
{
select_endpoint(0);
clear_buffer();
}
}
void endp0_in(void) //终端点0输入处理
{
read_last_status(1);
if(usb_flags.flags.setup_packet_in||usb_flags.flags.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_flags.flags.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_flags.flags.usb_endp2_in=0;
usb_flags.flags.usb_endp2_out=0;
SCSI.Status.Command=1;
SCSI.Status.Data=0;
}
void write_10(void) //SCSI写操作
{
unsigned long int LBA,Byte_Count;
unsigned char i;
if(SCSI.Status.Data)
{
for(i=0;i<4;i++)
{
LBA<<=8;
LBA+=cbw.CBWCB[2+i];
}
// pData=get_physical_addr(LBA);
Byte_Count=0;
Byte_Count+=cbw.CBWCB[7];
Byte_Count<<=8;
Byte_Count+=cbw.CBWCB[8];
Byte_Count<<=9;
while(usb_flags.flags.usb_endp2_out)
{
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);
}
}
}
}
void endp2_out(void) //主端点输出处理
{
// printc(0xcc);
if(SCSI.Status.Command)
{
if(read_endpoint_buff(4,sizeof(CBW),(unsigned char *)(&cbw))!=sizeof(CBW)){error(2);return;}
if(cbw.dCBWSignature!=0x55534243){error(3);return;}
SCSI.Status.Command=0;
SCSI.Status.Data=1;
if(cbw.bmCBWFlags&0x80)
{
usb_flags.flags.usb_endp2_in=1;
usb_flags.flags.usb_endp2_out=0;
}
else
{
usb_flags.flags.usb_endp2_in=0;
usb_flags.flags.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();
}
}
unsigned char *get_physical_addr(unsigned long int LBA) //从LBA获取物理地址
{
if(LBA==0)return DBR;
if(LBA==2)return FAT;
if(LBA==0x40)return ZERO;
if(LBA==0X0A)return FAT;
}
void read_10(void) //SCSI读处理
{
unsigned long int LBA=0,Byte_Count;
unsigned long int count=0;
unsigned char i;
if(SCSI.Status.Data)
{
for(i=0;i<4;i++)
{
LBA<<=8;
LBA+=cbw.CBWCB[2+i];
}
pData=get_physical_addr(LBA);
Byte_Count=0;
Byte_Count+=cbw.CBWCB[7];
Byte_Count<<=8;
Byte_Count+=cbw.CBWCB[8];
Byte_Count<<=9;
i=0;
while(usb_flags.flags.usb_endp2_in)
{
if(LBA==0)
if(count<512)pData=DBR+count;
else
if(count==512)pData=FAT;
else pData=ZERO;
if(LBA==2)
// if(count<64)pData=FAT;
// else
// if(count==512*7)pData=FAT;
// else
pData=ZERO;
if(LBA==8)
// if(count<512)pData=ZERO;
// else
// if(count==512)pData=FAT;
// else
pData=ZERO;
if(LBA==0x10)
if(count==512)pData=FAT;
else pData=ZERO;
if(LBA==0x21)
if(count==0)
// else
pData=ROOT_DIR;
else pData=ZERO;
if(LBA==0x40)
if(count<240)pData=FILE_DATA+count;
else
pData=ZERO;
while(select_endpoint(5)&0x01);
if(Byte_Count>MAX_BULK_DATA_SIZE)
{
write_endpoint_buff(5,MAX_BULK_DATA_SIZE,pData);
// pData+=MAX_BULK_DATA_SIZE;
Byte_Count-=MAX_BULK_DATA_SIZE;
// SCSI.Status.Data=1;
}
else
{
write_endpoint_buff(5,Byte_Count,pData);
Return_CSW(0x00,SUCCESS);
}
count+=64;
}
}
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();
// delay(1000);
// init_comport(57600);
init_usb();
connect_usb();
// send_to_comport('O');
// send_to_comport('K');
while(1)
{
if(!USB_INT)
{
read_interrupt_register();
// delay(10);
// printc(Interrupt_Register.Register[0]);
if(Interrupt_Register.Interrupt.bus_reset){usb_bus_reset();continue;}
if(Interrupt_Register.Interrupt.suspend_change){usb_bus_suspend();continue;}
if(Interrupt_Register.Interrupt.control_out_port){endp0_out();continue;}
if(Interrupt_Register.Interrupt.control_in_port&&usb_flags.flags.usb_endp0_in){endp0_in();continue;}
// if(Interrupt_Register.Interrupt.port_out_1)endp1_out();
// if(Interrupt_Register.Interrupt.port_in_1)endp1_in();
if(Interrupt_Register.Interrupt.main_out_port){endp2_out();continue;}
if(Interrupt_Register.Interrupt.main_in_port&&usb_flags.flags.usb_endp2_in){endp2_in();continue;}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -