📄 usb.c
字号:
/******************************************************************************
**
** 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 + -