⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb.c

📁 一款硬盘MP3的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* USB.C File
   Created by Computer-lov. Date: 2004.9.27
   Last edited date: 2005.5.31
   Copyright (c) 2005 Computer-lov
   version 1.1
*/

#include "AT89C51SND1C.H"
#include "USB.H"
#include "MASS_STORAGE.H"
#include "IDE.h"
#include "LCD.H"
#include "hardware.h"
#include "keyboard.h"
#include "mp3.h"


CONTROL_DATA_BUFF xdata Control_Data;

CBW xdata cbw;
CSW xdata csw;

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, 
0xC1,0xF5,0xC8,0xD9,0xD7,0xD4,0xBC,0xBA,0xD7,0xF6,0xB5,0xC4,0x4D,0x50,0x33,0x20,
0x31,0x2E,0x30,0x31
};


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分配的设备协议代码
MAX_CONTROL_DATA_SIZE,                              //端点0的最大包大小
0x7111,                                             //厂商编号
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                                                            //中断扫描时间,对批量传输无效
}
}
};


unsigned int bdata usb_flags_Register;   //程序标志位

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_endp1_in     = usb_flags_Register^11;
sbit USB_usb_endp2_out    = usb_flags_Register^12;


unsigned char bdata status_Register;  ////状态寄存器

sbit status_control_out_port   =  status_Register^0;
sbit status_control_in_port    =  status_Register^1;
sbit status_main_out_port      =  status_Register^2;
sbit status_main_in_port       =  status_Register^3;
sbit status_bus_reset          =  status_Register^4;
sbit status_suspend_change     =  status_Register^5;
sbit status_setup_packet       =  status_Register^6;

//*****************   延时x毫秒函数 ***********
void delay(unsigned int x)                
{
unsigned int i;
unsigned int j;
for(i=0;i<x;i++)
for(j=0;j<230;j++);
}
//********************************************

unsigned char remove_enable;

void read_usb_status(void)             //读USB状态寄存器
{
status_Register=0;
if(EORINT){status_bus_reset=1;USBINT=USBINT & (~0x10);return;}
if(SPINT){status_suspend_change=1;USBINT=USBINT & (~0x01);return;}
UEPNUM=0;
if(RXSETUP){status_setup_packet=1;status_control_out_port=1;return;}
status_control_out_port = RXOUTB0;
status_control_in_port  = NAKIN;
cls_NAKIN();
UEPNUM=1;
status_main_in_port=NAKIN;
cls_NAKIN();
UEPNUM=2;
status_main_out_port=(RXOUTB0 || RXOUTB1);
USBINT=0x00;
}

void set_endpoint_enable(void)                  //端点使能
{
UEPNUM=0;
UEPCONX=0x80;
UEPNUM=1;
UEPCONX=0x86;
UEPNUM=2;
UEPCONX=0x82;
}


unsigned char error_count;
void error(unsigned char number)             //出错处理
{
number=0;
error_count++;
LCD_go_home();
prints("               ");
LCD_line_feed();
prints("               ");
LCD_go_home();
prints("Error:");
printf(error_count);
}

unsigned char read_endpoint_buff(unsigned char endp,unsigned char len,unsigned char * buff)   //读终端点缓冲
{
unsigned char i,j;
UEPNUM=endp;               //选择端点
j=UBYCTX;                  //读字节数
if(j>len)j=len;
for(i=0;i<j;i++)
  {
   buff[i]=UEPDATX;
  }
if(RXOUTB0){UEPSTAX=UEPSTAX & (~0x42); return j;}   //清除RXOUTB0 位
if(RXOUTB1){UEPSTAX=UEPSTAX & (~0x42); return j;}   //清除RXOUTB1 位
}

unsigned char write_endpoint_buff(unsigned char endp,unsigned char len,unsigned char * buff)    //写终端点缓冲
{
unsigned char i;
remove_enable=0;
UEPNUM=endp;               //选择端点
for(i=0;i<len;i++)         //填数据寄存器
  {
   UEPDATX=buff[i];
  }
UEPSTAX=UEPSTAX | 0x10;     //设置TXRDY位
while(!( UEPSTAX & 0x01 ));                //等待TXCMP
UEPSTAX=UEPSTAX & (~0x01);                    //清除TXCMP
return len;
}

void disconnect_usb(void)
{
USB_CONNECT=1;
delay(100);
}

void connect_usb(void)                            //连接USB
{
USB_CONNECT=0;
}

void init_usb(void)                              //初始化USB
{
usb_flags_Register=0;
SCSI_Command=1;
SCSI_Data=0;
csw.dCSWSignature=0x55534253;

USBIEN=0x00;                                    //不允许USB中断
USBCLK=0x03;                                   
USBCON=0x80;
set_endpoint_enable();
UEPRST=0x07;                                    //端点FIFO复位
UEPRST=0x00;
}

void usb_bus_reset(void)                         //USB总线复位处理
{
usb_flags_Register=0;
SCSI_Command=1;
SCSI_Data=0;
csw.dCSWSignature=0x55534253;
USBADDR=0x80;
LCD_go_home();
prints("               ");
LCD_line_feed();
prints("               ");
LCD_go_home();
prints("移动硬盘模式");
LCD_line_feed();
prints("运行中......");
remove_enable=0;
}

void usb_bus_suspend(void)                       //USB总线挂起处理
{
LCD_go_home();
prints("现在可以安全的 ");
LCD_line_feed();
prints("拔下USB 连线了 ");
remove_enable=1;
}

void set_usb_address(void)                       //设置地址
{
USB_set_addr=1;
write_endpoint_buff(0,0,0);
USBADDR=0x80 | (Control_Data.DeviceRequest.wValue);
USBCON=USBCON | 0x01;
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;
   }
  UEPNUM=0;
  UEPSTAX=(UEPSTAX | 0x80);       //数据阶段的输入
  write_endpoint_buff(0,2,status);
  UEPSTAX=(UEPSTAX & (~0x80));
  USB_usb_endp0_in=0;
}

void clear_feature(unsigned char receiver)    
{
receiver=0;
write_endpoint_buff(0,0,0);
USB_usb_endp0_in=0;
USB_setup_packet_out=0;
}

void set_feature(unsigned char receiver)
{
receiver=0;
write_endpoint_buff(0,0,0);
USB_usb_endp0_in=0;
USB_setup_packet_out=0;
}

void set_descriptor(void)
{
write_endpoint_buff(0,0,0);
USB_usb_endp0_in=0;
USB_setup_packet_out=0;
}

void set_configuration(void)
{
write_endpoint_buff(0,0,0);
USBCON=USBCON | 0x02;
USB_usb_endp0_in=0;
USB_setup_packet_out=0;
UEPNUM=1;
UEPCONX = 0x86 ;
UEPNUM=2;
UEPCONX = 0x82;
LCD_go_home();
prints("               ");
LCD_line_feed();
prints("               ");
LCD_go_home();
prints("移动硬盘模式");
LCD_line_feed();
prints("运行中......");
}

void get_configuration(void)               //获取配置状态
{
unsigned char value=0x01;
UEPNUM=0;
UEPSTAX=(UEPSTAX | 0x80);       //数据阶段的输入
write_endpoint_buff(0,1,&value);
UEPSTAX=(UEPSTAX & (~0x80));
USB_usb_endp0_in=0;
}

void set_interface(void)                   //设置接口
{
write_endpoint_buff(0,0,0);
USB_usb_endp0_in=0;
USB_setup_packet_out=0;
}

void get_interface(void)                  //获取接口状态
{
unsigned char value=0x01;
UEPNUM=0;
UEPSTAX=(UEPSTAX | 0x80);                //数据阶段的输入
write_endpoint_buff(0,1,&value);
UEPSTAX=(UEPSTAX & (~0x80));
USB_usb_endp0_in=0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -