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

📄 usbofcompuer00.c

📁 基于PHILIPS的D12芯片USB固件的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************
   本程序只供学习使用,未经作者许可,不得用于其它任何用途

        欢迎访问我的USB专区:http://group.ednchina.com/93/
        欢迎访问我的blog:   http://www.ednchina.com/blog/computer00
                             http://computer00.21ic.org

  感谢wang1jin为本PCB的检查以及元件的采购,欢迎大家访问wang1jin的博客:
                             http://www.ednchina.com/blog/wang1jin/

UsbOfComputer00.C  file

作者:Computer-lov
建立日期: 2007.03.20
修改日期: 2008.03.13
版本:V1.1
版权所有,盗版必究。
Copyright(C) Computer-lov 2007-2017
All rights reserved            
*******************************************************************/

#include "AT89x52.H"
#include "USB.H"
#include "PDIUSBD12.H"
#include "My_type.h"
#include "UART.H"
#include "led.h"
#include "Key.h"

#define DispLineInf()      \
{                          \
 Prints(" in file \"");    \
 Prints(__FILE__);         \
 Prints(", @ line ");      \
 PrintLongInt(__LINE__-1); \
 Prints("\r\n");           \
}

//#define debug

#define USB_COMMAND_ADD           1
#define USB_DATA_ADD              0

//USB芯片连接引脚
#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


//控制传输时保存数据
CONTROL_DATA_BUFF Control_Data;

//缓冲
uint8 idata OutBuffer[64],InBuffer[64];
//数据计数器
uint8 idata InCount;
//数据位置
uint8 idata pIn;
//溢出标志
uint8 idata Overflow;

//交换数据时用的指针
uint8 *pData;

uint8 idle;     //空闲状态
uint8 protocol; //当前协议

//高低字节交换

#define SWAP16(x)  ((((uint16)(x))<<8)|(((uint16)(x))>>8))

#define SWAP32(x)  ((((uint32)SWAP16(x))<<16)|SWAP16((x)>>16))

//取一个整数的低字节 
#define LSB(x) ((uint8)(x))

//取一个整数的高字节
#define MSB(x) ((uint8)(((uint16)(x))>>8))                               

//字符串描述符所用的语言种类 
code uint8 LANGUAGE_ID[4]={0x04,0x03,0x09,0x04};                   

//设备序列号										
code uint8 device_serial_number[]=
{22,STRING_DESCRIPTOR,'2',0,'0',0,'0',0,'7',0,'-',0,'1',0,'1',0,'-',0,'2',0,'9',0};

//厂商字符串 电脑圈圈的USB专区 http://group.ednchina.com/93
//汉字Unicode编码,使用http://computer00.21ic.org/user1/2198/archives/2007/42769.html转换
code uint8 ManufacturerString[80]=
{80,STRING_DESCRIPTOR,0x35,0x75,0x11,0x81,0x08,0x57,0x08,0x57,0x84,0x76,'U',0x00,
 'S',0x00,'B',0x00,0x13,0x4E,0x3A,0x53,0x20,0x00,'H',0,'t',0,'t',0,
 'p',0,':',0,'/',0,'/',0,'g',0,'r',0,'o',0,'u',0,'p',0,'.',0,'e',0,'d',0,'n',0,
 'c',0,'h',0,'i',0,'n',0,'a',0,'.',0,'c',0,'o',0,'m',0,'/',0,'9',0,'3',0};

//产品字符串 电脑圈圈的USB专区活动之Computer00'sUSB http://group.ednchina.com/93
//汉字Unicode编码,使用http://computer00.21ic.org/user1/2198/archives/2007/42769.html转换
code uint8 ProducterString[120]=
{120,STRING_DESCRIPTOR,0x35,0x75,0x11,0x81,0x08,0x57,0x08,0x57,0x84,0x76,'U',0x00,
 'S',0x00,'B',0x00,0x13,0x4E,0x3A,0x53,0x3B,0x6D,0xA8,0x52,0x4B,0x4E,
 ' ',0x00,'C',0,'o',0,'m',0,'p',0,'u',0,'t',0,'e',0,'r',0,'0',0,'0',0,
 '\'',0,'s',0,' ',0,'U',0,'S',0,'B',0,' ',0,'H',0,'t',0,'t',0,
 'p',0,':',0,'/',0,'/',0,'g',0,'r',0,'o',0,'u',0,'p',0,'.',0,'e',0,'d',0,'n',0,
 'c',0,'h',0,'i',0,'n',0,'a',0,'.',0,'c',0,'o',0,'m',0,'/',0,'9',0,'3',0};

code DEVICE_DESCRIPTOR_STRUCT device_descriptor=     //设备描述符
{
 sizeof(DEVICE_DESCRIPTOR_STRUCT),                   //设备描述符的字节数大小
 DEVICE_DESCRIPTOR,	                                 //设备描述符类型编号
 SWAP16(0x0110),                                     //USB版本号,USB1.1
 0xFF,                                               //USB分配的设备类代码,0xFF为厂家自定义类
 0x00,                                               //USB分配的子类代码
 0x00,                                               //USB分配的设备协议代码
 0x10,                                               //端点0的最大包大小
 SWAP16(0x8888),                                     //厂商编号VID,这里只是作为测试用,请使用自己的VID
 SWAP16(0x0088),                                     //产品编号PID,这里只是作为测试用,请使用自己的PID
 SWAP16(0x0001),                                     //设备出厂编号
 0x01,                                               //设备厂商字符串的索引
 0x02,                                               //描述产品字符串的索引
 0x03,                                               //描述设备序列号字符串的索引
 0x01                                                //可能的配置数量
};

//定义配置,接口,端点等描述符结构体,因为它们是随配置描述符一起返回的
typedef struct _CON_INT_ENDP_DESCRIPTOR_STRUCT
{
 CONFIGURATION_DESCRIPTOR_STRUCT configuration_descriptor;
 INTERFACE_DESCRIPTOR_STRUCT  interface_descriptor;
 ENDPOINT_DESCRIPTOR_STRUCT  endpoint1in_descriptor;
 ENDPOINT_DESCRIPTOR_STRUCT  endpoint1out_descriptor;
 ENDPOINT_DESCRIPTOR_STRUCT  endpoint2in_descriptor;
 ENDPOINT_DESCRIPTOR_STRUCT  endpoint2out_descriptor;
}CON_INT_ENDP_DESCRIPTOR_STRUCT;

code CON_INT_ENDP_DESCRIPTOR_STRUCT con_int_endp_descriptor=
{
//configuration_descriptor                                        //配置描述符
{
 sizeof(CONFIGURATION_DESCRIPTOR_STRUCT),                         //配置描述符的字节数大小
 CONFIGURATION_DESCRIPTOR,                                        //配置描述符类型编号
 SWAP16(sizeof(CON_INT_ENDP_DESCRIPTOR_STRUCT)),
 0x01,                                                            //只包含一个接口
 0x01,                                                            //该配置的编号
 0x00,                                                            //iConfiguration字段
 0xA0,                                                            //采用总线供电,支持远程唤醒
 0xC8                                                            //从总线获取最大电流400mA
},

//interface_descritor                                             //接口描述符
{
 sizeof(INTERFACE_DESCRIPTOR_STRUCT),                             //接口描述符的字节数大小
 INTERFACE_DESCRIPTOR,                                            //接口描述符类型编号
 0x00,                                                            //接口编号为0
 0x00,                                                            //该接口描述符的备用编号
 0x04,                                                            //端点数量为4
 0x00,                                                            //所使用的类
 0x00,                                                            //使用的子类
 0x00,                                                            //使用的协议
 0x00                                                             //接口描述符字符串索引
},

//endpoint1in_descriptor
{                                                                //中断输入端点描述
 sizeof(ENDPOINT_DESCRIPTOR_STRUCT),                             //端点描述符的字节数大小
 ENDPOINT_DESCRIPTOR,                                            //端点描述符类型编号
 POINT_1_IN,                                                     //端点号,输入端点1
 ENDPOINT_TYPE_INTERRUPT,                                        //使用的传输类型:中断传输
 SWAP16(0x0010),                                                 //该端点支持的最大包尺寸,16字节
 0x0A                                                            //中断扫描时间:设置为10ms
},

//endpoint1in_descriptor
{                                                                //中断输出端点描述
 sizeof(ENDPOINT_DESCRIPTOR_STRUCT),                             //端点描述符的字节数大小
 ENDPOINT_DESCRIPTOR,                                            //端点描述符类型编号
 POINT_1_OUT,                                                    //端点号,输出端点1
 ENDPOINT_TYPE_INTERRUPT,                                        //使用的传输类型:中断传输
 SWAP16(0x0010),                                                 //该端点支持的最大包尺寸,16字节
 0x0A                                                            //中断扫描时间:设置为10ms
},

//endpoint2in_descriptor
 {                                                                //主端点输入描述
  sizeof(ENDPOINT_DESCRIPTOR_STRUCT),                             //端点描述符的字节数大小
  ENDPOINT_DESCRIPTOR,                                            //端点描述符类型编号
  MAIN_POINT_IN,                                                  //端点号,主输入端点
  ENDPOINT_TYPE_BULK,                                             //使用的传输类型:批量传输
  SWAP16(0x0040),                                                 //该端点支持的最大包尺寸,64字节
  0x00                                                            //中断扫描时间:批量端点无效
 },

 {                                                                //主端点输出描述
  sizeof(ENDPOINT_DESCRIPTOR_STRUCT),                             //端点描述符的字节数大小
  ENDPOINT_DESCRIPTOR,                                            //端点描述符类型编号
  MAIN_POINT_OUT,                                                 //端点号,主输出端点
  ENDPOINT_TYPE_BULK,                                             //使用的传输类型:批量传输
  SWAP16(0x0040),                                                 //该端点支持的最大包尺寸,64字节
  0x00                                                            //中断扫描时间:批量端点无效
 }
};

union                                          //程序标志位
{
uint16 Register;
struct 
{
 uint8 bus_reset        :1;
 uint8 suspend          :1;
 uint8 remote_wakeup    :1;
 uint8 int_isr          :1;
 uint8 not_end          :1;
 uint8 usb_idle         :1;
 uint8 usb_busy         :1;
 uint8 setup_packet_in  :1;
 uint8 setup_packet_out :1;
 uint8 set_addr         :1;
 uint8 usb_endp0_in     :1;
 uint8 usb_endp2_in     :1;
 uint8 usb_endp2_out    :1;
}flags;
}usb_flags;

union                                         //中断寄存器
{
 uint8 Register[2];
 struct 
  {
   uint8 control_out_port  :1;
   uint8 control_in_port   :1;
   uint8 port_out_1        :1;
   uint8 port_in_1         :1;
   uint8 main_out_port     :1;
   uint8 main_in_port      :1;
   uint8 bus_reset         :1;
   uint8 suspend_change    :1;
   uint8 DMA_EOT           :1;
   uint8 not_use           :7;
  }Interrupt;
}Interrupt_Register;


union                                    //端点最后处理状态
{
 uint8 Register;
 struct
 {
  uint8 successful          :1;
  uint8 error_code          :4;
  uint8 setup_packet        :1;
  uint8 data_1              :1;
  uint8 prestatus_not_read  :1;
 }Status;
}Last_Status;


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

/*******************************写USB命令******************************************/
void write_usb_command(uint8 usb_command)
{
 USB_A0=USB_COMMAND_ADD;
 USB_DATA=usb_command;
 USB_WR=0;
 USB_WR=1;
 USB_DATA=0xFF;
}
/******************************************************************************/

/*********************写一字节USB数据*******************************************/
void write_a_usb_data(uint8 usb_data)       
{
 USB_A0=USB_DATA_ADD;
 USB_DATA=usb_data;
 USB_WR=0;
 USB_WR=1;
 USB_DATA=0XFF;
}
/******************************************************************************/

/****************************读一字节USB数据************************************/
uint8 read_a_usb_data(void)
{
 uint8 temp;
 USB_A0=USB_DATA_ADD;
 USB_RD=0;
 temp=USB_DATA;
 USB_RD=1;
 return temp;
}
/******************************************************************************/

/************************读USB中断寄存器**************************************/
void read_interrupt_register(void)
{
 write_usb_command(Read_Interrupt_Register);
 Interrupt_Register.Register[0]=read_a_usb_data();
 Interrupt_Register.Register[1]=read_a_usb_data();
}
/******************************************************************************/

/************************设置USB地址*******************************************/
void set_usb_addr(uint8 addr)
{
 write_usb_command(Set_Address);
 write_a_usb_data(0x80|addr);
#ifdef debug
 Prints("   设置地址.\r\n");
 Prints("       地址为:  ");
 PrintLongInt(addr);
 Prints("\r\n");
#endif
}
/******************************************************************************/

/*************************端点使能******************************************/
void set_endpoint_enable(void)
{
 write_usb_command(Set_Endpoint_Enable);
 write_a_usb_data(0x01);
}
/******************************************************************************/

/****************************选择终端点*************************************/
uint8 select_endpoint(uint8 endp)
{
 write_usb_command(Select_EndPoint+endp);
 return read_a_usb_data();
}
/******************************************************************************/

/****************************读端点最后状态**********************************/
uint8  read_last_status(uint8 endp)
{
 write_usb_command(Read_Last_Status+endp);
 return read_a_usb_data();
}
/******************************************************************************/

/****************************设置端点状态**************************************/
void set_endpoint_status(uint8 endp,uint8 status)  
{
 write_usb_command(0x40+endp);
 write_a_usb_data(!status);
}
/******************************************************************************/

/*****************************读端点状态**************************************/
uint8 read_endpoint_status(uint8 endp)
{
 write_usb_command(0x80+endp);
 return read_a_usb_data();
}
/******************************************************************************/

/************************清缓冲,在读取缓冲数据后调用**************************/
void clear_buffer(void)
{
 write_usb_command(Clear_Buffer);
#ifdef debug
 Prints("Clear buffer.\r\n");
#endif
}
/******************************************************************************/

/***********************缓冲区数据有效,在写缓冲后调用**************************/
void validate_buffer(void)
{
 write_usb_command(Validate_Buffer);
#ifdef debug
 Prints("Validate buffer.\r\n");
#endif
}
/******************************************************************************/

/***************************应答建立包************************************/
void ack_setup(uint8 endp)
{
 select_endpoint(endp);
 write_usb_command(Ack_Setup);
#ifdef debug
 Prints("Ack setup ");
 PrintLongInt(endp);
 Prints(".\r\n");
#endif
}
/******************************************************************************/

//#define debug2
/***********************出错处理******************************************/
void error(uint8 number)
{
#ifdef debug2
 Prints("有错误发生!!!\r\n错误号: ");
 PrintHex(number);
#endif
 number=0;
}
/******************************************************************************/

/*************************读终端点缓冲****************************************/
uint8 read_endpoint_buff(uint8 endp,uint8 len,uint8 * buff)
{
 uint8 i,j;
 
 if(!(select_endpoint(endp)&0x01)){error(0); return 0;}
 if((read_endpoint_status(endp)&0x60)!=0x60)  //两个缓冲没有都满,才能清中断
 {
  read_last_status(endp);  //清中断
 }
 write_usb_command(Read_Buffer);
 read_a_usb_data();
 j=read_a_usb_data();
 if(j>len)
  j=len;  
#ifdef debug
 Prints("Read endpoint");
 PrintLongInt(endp);
 Prints("\'s buffer ");
 PrintLongInt(j);
 Prints(" bytes.\r\n");
#endif  
 for(i=0;i<j;i++)
  {
   USB_RD=0;
   *(buff+i)=USB_DATA;
   USB_RD=1;
#ifdef debug
   PrintHex(*(buff+i));
#endif
  }
#ifdef debug
 Prints("\r\n");
#endif
 if(endp)
 {
  select_endpoint(endp);
  clear_buffer();
 }
 return j;
}
/******************************************************************************/

/*************************写终端点缓冲*****************************************/
uint8 write_endpoint_buff(uint8 endp,uint8 len,uint8 * buff)
{
 uint8 i;
 read_last_status(endp);
 select_endpoint(endp);
 write_usb_command(Write_Buffer);
 write_a_usb_data(0);
 write_a_usb_data(len);
#ifdef debug
 Prints("Write endpoint");
 PrintLongInt(endp);
 Prints("\'s buffer ");
 PrintLongInt(len);
 Prints(" bytes.\r\n");
#endif
 for(i=0;i<len;i++)
  {
   USB_DATA=*(buff+i);
   USB_WR=0;
   USB_WR=1;
#ifdef debug
   PrintHex(*(buff+i));
#endif
  }
#ifdef debug
 Prints("\r\n");
#endif  
 USB_DATA=0xFF;
 validate_buffer();
 return len;
}
/******************************************************************************/

/***************************断开USB连接****************************************/
void disconnect_usb(void)
{
#ifdef debug
 Prints("断开USB连接.\r\n");
#endif
 write_usb_command(0xf3);
 write_a_usb_data(0x0e);
 write_a_usb_data(0x47);

⌨️ 快捷键说明

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