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

📄 usb.c

📁 PDIUSBD12 HID固件源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
**
**  Filename:     Usb.c
**
**  System:       RISC
**
**  Platform:     dsPIC33F
**
**  Description:  
******************************************************************************/

#include <p33Fxxxx.h>
#include "Common.h"
#include "Usb.h"
#include "PDIUSBD12.h"

//-----------------------------------------------------------------------------
//Global Variables
//-----------------------------------------------------------------------------

/*-----------------------------------------------------------------------------
                                  Macro instantiation
------------------------------------------------------------------------------*/

/******************************************************************************
**
**  FunctionName: Usb.c
**
**  Description:  
******************************************************************************/

#define USB_COMMAND_ADD           1
#define USB_DATA_ADD              0

#define D12_DB                  LATB

#define ENDPOINT_NUMBER           2
#define MAX_CONTROL_DATA_SIZE    16
#define MAX_LUN                   0
#define MAX_BULK_DATA_SIZE       64

CONTROL_DATA_BUFF Control_Data;

unsigned char buffer[64];

void libuart2Init ( )
{
  U2MODE = 0x0000;                            //Initialize and Enable UART2
                                              //for Tx and Rx
  U2STAbits.URXISEL = 0x00 ;                  //Buffer length for uart receive
                                              //to 1 characters.							                
  U2BRG = BRG;	                              //Initialize baudrate
  U2MODEbits.UARTEN = 0x01;					  //Enable UART
  U2STA |= 0x0400;
  _U2RXIP = 0x04;	 				          //Set UART RX interrupt priority
  _U2TXIF = 0x00;							  //Clear Rx interrupt flag     		
}

void U2_TX_B(unsigned char Tx_Byte)
{
  U2TXREG = (unsigned int)Tx_Byte;
  while( !U2STAbits.TRMT );
}

void U2_TX_W(unsigned int Tx_Word)
{
  U2TXREG = Tx_Word>>8;
  while( !U2STAbits.TRMT );
  U2TXREG = Tx_Word;
  while( !U2STAbits.TRMT );
}

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);
}

unsigned char __attribute__ ((space(auto_psv))) LANGUAGE_ID[4]={0x04,0x03,0x09,0x04};            //字符串描述符所用的语言种类        

unsigned char __attribute__ ((space(auto_psv))) device_serial_number[18]=                         //设备序列号
 {0x12,0x03,0x32,0x00,0x30,0x00,0x37,0x00,0x31,0x00,0x30,0x00,0x39,0x00,0x38,0x00,0x32,0x00};

DEVICE_DESCRIPTOR_STRUCT __attribute__ ((space(auto_psv))) device_descriptor=     //设备描述符
{
 sizeof(DEVICE_DESCRIPTOR_STRUCT),                   //设备描述符的字节数大小
 DEVICE_DESCRIPTOR,	                             //设备描述符类型编号
 0x0110,                                             //USB版本号
 0x00,                                               //USB分配的设备类代码
 0x00,                                               //USB分配的子类代码
 0x00,                                               //USB分配的设备协议代码
 0x10,                                               //端点0的最大包大小
 0x0471,                                             //厂商编号
 0x0f1f,                                             //产品编号
 0x0001,                                             //设备出厂编号
 0x00,                                               //设备厂商字符串的索引
 0x00,                                               //描述产品字符串的索引
 0x02,                                               //描述设备序列号字符串的索引
 0x01                                                //可能的配置数量
};

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

//interface_descritor                                             //接口描述符
 0x09,                                                            //接口描述符的字节数大小
 INTERFACE_DESCRIPTOR,                                            //接口描述符类型编号
 0x00,                                                            //接口编号为0
 0x00,                                                            //该接口描述符的编号
 ENDPOINT_NUMBER,                                                 //非0端点数量为2,只使用端点主端点输入和输出
 0x03,                                                            //USB大容量存储设备
 0x00,                                                            //使用的子类,为简化块命令
 0x00,                                                            //使用的协议,这里使用单批量传输协议
 0x00,                                                            //接口描述符字符串索引

//class_descriptor[]
 0x09,                                                            //类描述符的字节数大小
 CLASS_DESCRIPTOR,                                                //类描述符类型编号
 0x00,                                                            //HID类发布号
 0x01,                                                            //
 0x00,                                                            //本地国家代码
 0x01,                                                            //HID描述符要遵循的号(1)
 0x22,                                                            //报告描述符类型(HID)
 0x22,                                                            //总报告描述符总长度
 0x00,                                                            //
  
                                                                  //主端点输出描述
//endpoint_descriptor[]
 0x07,                                                            //端点描述符的字节数大小
 ENDPOINT_DESCRIPTOR,                                             //端点描述符类型编号
 MAIN_POINT_IN,                                                   //端点号,主输入端点
 ENDPOINT_TYPE_INTERRUPT,                                         //使用的传输类型,中断传输
 0x40,                                                            //该端点支持的最大包尺寸,64字节
 0x00,
 0x01,                                                            //中断扫描时间,对批量传输无效
  
 0x07,                                                            //端点描述符的字节数大小
 ENDPOINT_DESCRIPTOR,                                             //端点描述符类型编号
 MAIN_POINT_OUT,                                                  //端点号,主输出端点
 ENDPOINT_TYPE_INTERRUPT,                                         //使用的传输类型,中断传输
 0x40,                                                            //该端点支持的最大包尺寸,64字节
 0x00,
 0x01,                                                            //中断扫描时间,对批量传输无效
};

REPORT_DESCRIPTOR_STRUCT __attribute__ ((space(auto_psv))) report_descriptor=     //报告描述符
{
 0x06,                                              //用法页
 0x00,                                              //用法页
 0xff,                                              //用法页
 0x09,                                              //用法行
 0xa5,                                              //用法行

 0xa1,                                              //集合
 0x01,                                              //
 0x09,                                              //
 0xa6,                                              //

 0x09,                                              //输入报告
 0xa7,                                              //
 0x15,                                              //逻辑最小值
 0x80,                                              //
 0x25,                                              //逻辑最大值
 0x7f,                                              //
 0x75,                                              //报告行值
 0x08,                                              //
 0x95,                                              //报告数据行
 0x02,                                              //
 0x81,                                              //输入
 0x02,                                              //

 0x09,                                              //输出报告
 0xa9,                                              //
 0x15,                                              //逻辑最小值
 0x80,                                              //
 0x25,                                              //逻辑最大值
 0x7f,                                              //
 0x75,                                              //报告行值
 0x08,                                              //
 0x95,                                              //报告数据行
 0x02,                                              //
 0x91,                                              //输出
 0x02,                                              //

 0xc0,                                              //集合结束
};

//*****************   延时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 usb_delay(void)                
{
 unsigned char i;
 for(i=0;i<10;i++);
}
//********************************************

void Write_D12_DATA(unsigned char data)             //写D12(PORTB)数据口高字节
{
  unsigned int D12_DATA_buff = D12_DB;
  D12_DATA_buff &= 0x00ff;
  D12_DATA_buff |= (unsigned int)(data<<8);
  D12_DB = D12_DATA_buff;
}

void write_usb_command(unsigned char usb_command)    //写USB命令
{
 TRISB &= 0x00FF;
 D12_A0=USB_COMMAND_ADD;
 Write_D12_DATA(usb_command);
 D12_WR=0;
 usb_delay();
 D12_WR=1;
}

void write_a_usb_data(unsigned char usb_data)        //写一字节USB数据
{
 TRISB &= 0x00FF;
 D12_A0=USB_DATA_ADD;
 Write_D12_DATA(usb_data);
 D12_WR=0;
 usb_delay();
 D12_WR=1;
}

unsigned int yybuf;
unsigned char read_a_usb_data(void)                  //读一字节USB数据
{
 unsigned char temp;
 TRISB |= 0xFF00;
 D12_A0=USB_DATA_ADD;
 D12_RD=0;
 usb_delay();
 temp = (unsigned char)(PORTB>>8);
 D12_RD=1;
 return temp;
}


void read_interrupt_register(void)             //读USB中断寄存器
{
 write_usb_command(Read_Interrupt_Register);
 Flag.Interrupt_Register=read_a_usb_data();
 Flag.Interrupt_Register|=read_a_usb_data()<<8;
}

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++)
  {
   D12_RD=0;
   usb_delay();
   buff[i]=(unsigned char)(PORTB>>8);
   D12_RD=1;
   U2_TX_B(buff[i]);        // 调试用, 在串口上可以看到HOST发来的命令和数据
  }
 BUZZER ^= 1;
 clear_buffer();
 return j;
}

unsigned char write_endpoint_buff(unsigned char endp,unsigned char len,unsigned char * buff)    //写终端点缓冲
{

⌨️ 快捷键说明

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