📄 usb.c
字号:
/******************************************************************
本程序只供学习使用,未经作者许可,不得用于其它任何用途
我的邮箱:computer-lov@tom.com
欢迎访问我的blog: http://computer00.21ic.org
USB.C file
Created by Computer-lov
Date: 2004.9.21
Edit date:2006.3.2
Version V1.1
Copyright(C) Computer-lov 2004-2014
All rigths reserved
*******************************************************************/
#include<AT89x52.H>
#include "USB.H"
#include "PDIUSBD12.H"
#include "MASS_STORAGE.H"
//#include<serial.h>
#include "ide.h"
#define USB_COMMAND_ADD 1
#define USB_DATA_ADD 0
#define USB_DATA P0
#define USB_A0 P3_5
#define USB_WR P3_6
#define USB_RD P3_7
#define USB_INT P3_2
#define ENDPOINT_NUMBER 2
#define MAX_CONTROL_DATA_SIZE 16
#define MAX_LUN 0
#define MAX_BULK_DATA_SIZE 64
CONTROL_DATA_BUFF idata Control_Data;
unsigned char idata buffer[64];
CBW idata cbw;
CSW idata csw;
/*union
{
unsigned char Register;
struct
{
unsigned char Command :1;
unsigned char Data :1;
}Status;
}SCSI;*/
unsigned char bdata SCSI_Register;
sbit SCSI_Command = SCSI_Register^0;
sbit SCSI_Data = SCSI_Register^1;
unsigned char *pData;
unsigned char code DISK_INF[36]
= //磁盘信息
{
0x00,
0x00,
0x02,
0x02,
0x1F,
0x00,0x00,0x00,
0x49,0x44,0x45,0xA1,0xFA,0x55,0x53,0x42,
0xD7,0xD4,0xBC,0xBA,0xD7,0xF6,0xB5,0xC4,0xD2,0xC6,0xB6,0xAF,0xD3,0xB2,0xC5,0xCC,
0x31,0x2E,0x30,0x31
};
unsigned char DISK_CAPACITY[8]= //磁盘容量
{
0x00,0x01,0xff,0x00,
0x00,0x00,0x02,0x00
};
code unsigned char SENSE[0x12]= //模式探测返回数据
{
0x70, 0x00, 0x05, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned int SWAP(unsigned int temp) //高低字节交换
{
unsigned char i;
i=((unsigned char *)&temp)[0];
((unsigned char *)&temp)[0]=((unsigned char *)&temp)[1];
((unsigned char *)&temp)[1]=i;
return temp;
}
unsigned char LSB(unsigned int temp) //取一个整数的低字节
{
return (unsigned char)temp;
}
unsigned char MSB(unsigned int temp) //取一个整数的高字节
{
return (unsigned char)(temp>>8);
}
code unsigned char LANGUAGE_ID[4]={0x04,0x03,0x09,0x04}; //字符串描述符所用的语言种类
code unsigned char device_serial_number[18]= //设备序列号
{0x12,0x03,0x32,0x00,0x30,0x00,0x37,0x00,0x31,0x00,0x30,0x00,0x39,0x00,0x38,0x00,0x32,0x00};
code DEVICE_DESCRIPTOR_STRUCT device_descriptor= //设备描述符
{
sizeof(DEVICE_DESCRIPTOR_STRUCT), //设备描述符的字节数大小
DEVICE_DESCRIPTOR, //设备描述符类型编号
0x1001, //USB版本号
0x00, //USB分配的设备类代码
0x00, //USB分配的子类代码
0x00, //USB分配的设备协议代码
0x10, //端点0的最大包大小
0x7104, //厂商编号
0xf0ff, //产品编号
0x0100, //设备出厂编号
0x00, //设备厂商字符串的索引
0x00, //描述产品字符串的索引
0x02, //描述设备序列号字符串的索引
0x01 //可能的配置数量
};
typedef struct _CON_INT_ENDP_DESCRIPTOR_STRUCT
{
CONFIGURATION_DESCRIPTOR_STRUCT configuration_descriptor;
INTERFACE_DESCRIPTOR_STRUCT interface_descritor;
ENDPOINT_DESCRIPTOR_STRUCT endpoint_descriptor[ENDPOINT_NUMBER];
}CON_INT_ENDP_DESCRIPTOR_STRUCT;
code 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 //中断扫描时间,对批量传输无效
}
}
};
/*union //程序标志位
{
unsigned int Register;
struct
{
unsigned char bus_reset :1;
unsigned char suspend :1;
unsigned char remote_wakeup :1;
unsigned char int_isr :1;
unsigned char not_end :1;
unsigned char usb_idle :1;
unsigned char usb_busy :1;
unsigned char setup_packet_in :1;
unsigned char setup_packet_out :1;
unsigned char set_addr :1;
unsigned char usb_endp0_in :1;
unsigned char usb_endp2_in :1;
unsigned char usb_endp2_out :1;
}flags;
}usb_flags;
*/
unsigned int bdata usb_flags_Register;
//unsigned bdata usb_flags_Register2;
sbit USB__bus_reset = usb_flags_Register^0;
sbit USB_suspend = usb_flags_Register^1;
sbit USB_remote_wakeup = usb_flags_Register^2;
sbit USB_int_isr = usb_flags_Register^3;
sbit USB_not_end = usb_flags_Register^4;
sbit USB_usb_idle = usb_flags_Register^5;
sbit USB_usb_busy = usb_flags_Register^6;
sbit USB_setup_packet_in = usb_flags_Register^7;
sbit USB_setup_packet_out = usb_flags_Register^8;
sbit USB_set_addr = usb_flags_Register^9;
sbit USB_usb_endp0_in = usb_flags_Register^10;
sbit USB_usb_endp2_in = usb_flags_Register^11;
sbit USB_usb_endp2_out = usb_flags_Register^12;
/*union //中断寄存器
{
unsigned char Register[2];
struct
{
unsigned char control_out_port :1;
unsigned char control_in_port :1;
unsigned char port_out_1 :1;
unsigned char port_in_1 :1;
unsigned char main_out_port :1;
unsigned char main_in_port :1;
unsigned char bus_reset :1;
unsigned char suspend_change :1;
unsigned char DMA_EOT :1;
unsigned char not_use :7;
}Interrupt;
}Interrupt_Register;
*/
unsigned char bdata Interrupt_Register[2];
sbit Interrupt_control_out_port = Interrupt_Register[0]^0;
sbit Interrupt_control_in_port = Interrupt_Register[0]^1;
sbit Interrupt_port_out_1 = Interrupt_Register[0]^2;
sbit Interrupt_port_in_1 = Interrupt_Register[0]^3;
sbit Interrupt_main_out_port = Interrupt_Register[0]^4;
sbit Interrupt_main_in_port = Interrupt_Register[0]^5;
sbit Interrupt_bus_reset = Interrupt_Register[0]^6;
sbit Interrupt_suspend_change = Interrupt_Register[0]^7;
sbit Interrupt_DMA_EOT = Interrupt_Register[1]^0;
/*union //端点最后处理状态
{
unsigned char Register;
struct
{
unsigned char successful :1;
unsigned char error_code :4;
unsigned char setup_packet :1;
unsigned char data_1 :1;
unsigned char prestatus_not_read :1;
}Status;
}Last_Status;*/
unsigned char bdata Last_Status_Register;
sbit Last_Status_successful = Last_Status_Register^0;
sbit Last_Status_error_code0 = Last_Status_Register^1;
sbit Last_Status_error_code1 = Last_Status_Register^2;
sbit Last_Status_error_code2 = Last_Status_Register^3;
sbit Last_Status_error_code3 = Last_Status_Register^4;
sbit Last_Status_setup_packet = Last_Status_Register^5;
sbit Last_Status_data_1 = Last_Status_Register^6;
sbit Last_Status_prestatus_not_read = Last_Status_Register^7;
//***************** 延时x毫秒函数 ***********
void delay(unsigned int x)
{
unsigned int i;
unsigned int j;
for(i=0;i<x;i++)
for(j=0;j<230;j++);
}
//********************************************
void write_usb_command(unsigned char usb_command) //写USB命令
{
USB_A0=USB_COMMAND_ADD;
USB_DATA=usb_command;
USB_WR=0;
USB_WR=1;
USB_DATA=0xFF;
}
void write_a_usb_data(unsigned char usb_data) //写一字节USB数据
{
USB_A0=USB_DATA_ADD;
USB_DATA=usb_data;
USB_WR=0;
USB_WR=1;
USB_DATA=0XFF;
}
unsigned char read_a_usb_data(void) //读一字节USB数据
{
unsigned char temp;
USB_A0=USB_DATA_ADD;
USB_RD=0;
temp=USB_DATA;
USB_RD=1;
return temp;
}
void read_interrupt_register(void) //读USB中断寄存器
{
write_usb_command(Read_Interrupt_Register);
Interrupt_Register[0]=read_a_usb_data();
Interrupt_Register[1]=read_a_usb_data();
}
void set_usb_addr(unsigned char addr) //设置USB地址
{
write_usb_command(Set_Address);
write_a_usb_data(0x80|addr);
}
void set_endpoint_enable(void) //端点使能
{
write_usb_command(Set_Endpoint_Enable);
write_a_usb_data(0x01);
}
unsigned char select_endpoint(unsigned char endp) //选择终端点
{
write_usb_command(Select_EndPoint+endp);
return read_a_usb_data();
}
unsigned char read_last_status(unsigned char endp) //读端点最后状态
{
write_usb_command(Read_Last_Status+endp);
return read_a_usb_data();
}
void set_endpoint_status(unsigned char endp,unsigned char status) //设置端点状态
{
write_usb_command(0x40+endp);
write_a_usb_data(!status);
}
unsigned char read_endpoint_status(unsigned char endp) //读端点状态
{
write_usb_command(0x80+endp);
return read_a_usb_data();
}
void clear_buffer(void) //清缓冲,在读取缓冲数据后调用
{
write_usb_command(Clear_Buffer);
}
void validate_buffer(void) //缓冲区数据有效,在写缓冲后调用
{
write_usb_command(Validate_Buffer);
}
void ack_setup(unsigned char endp) //应答建立包
{
select_endpoint(endp);
write_usb_command(Ack_Setup);
}
void error(unsigned char number) //出错处理
{
// unsigned char Error[]={"ERROR: "};
// prints(Error);
// printc(number);
number=0;
}
unsigned char read_endpoint_buff(unsigned char endp,unsigned char len,unsigned char * buff) //读终端点缓冲
{
unsigned char i,j;
read_last_status(endp);
if(!(select_endpoint(endp))&0x01){error(0); return 0;}
read_endpoint_status(endp);
write_usb_command(Read_Buffer);
read_a_usb_data();
j=read_a_usb_data();
if(j>len)
j=len;
for(i=0;i<j;i++)
{
USB_RD=0;
buff[i]=USB_DATA;
USB_RD=1;
}
clear_buffer();
return j;
}
unsigned char write_endpoint_buff(unsigned char endp,unsigned char len,unsigned char * buff) //写终端点缓冲
{
unsigned char i;
read_last_status(endp);
select_endpoint(endp);
write_usb_command(Write_Buffer);
write_a_usb_data(0);
write_a_usb_data(len);
for(i=0;i<len;i++)
{
USB_DATA=*(buff+i);
USB_WR=0;
USB_WR=1;
}
USB_DATA=0XFF;
validate_buffer();
return len;
}
void disconnect_usb(void)
{
write_usb_command(0xf3);
write_a_usb_data(0x0e);
write_a_usb_data(0x47);
delay(100);
}
void connect_usb(void) //连接USB
{
write_usb_command(0xf3); //初始化USBD12
write_a_usb_data(0x1e); //连接USB
write_a_usb_data(0x47); //设置频率
}
void init_usb(void) //初始化USB
{
set_usb_addr(0);
set_endpoint_enable();
}
void usb_bus_reset(void) //USB总线复位处理
{
// code unsigned char Usb_Bus_Reset[]={"USB BUS RESET"};
// prints(Usb_Bus_Reset);
usb_flags_Register=0;
set_endpoint_enable();
SCSI_Command=1;
SCSI_Data=0;
csw.dCSWSignature=0x55534253;
}
void usb_bus_suspend(void) //USB总线挂起处理
{
// code unsigned char Usb_Bus_Suspend[]={"USB BUS SUSPEND"};
// prints(Usb_Bus_Suspend);
// send_to_comport(10);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -