#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "CH375.H"
#include <string.h>
unsigned char ch,ch1,dat1;
UINT8 status;
GPIO_InitTypeDef GPIO_InitStructure;
unsigned char a,temp3,temp4,num,i;
unsigned char fs,tmpformt;
unsigned char suju[32];
UINT8 data_buf[90];
unsigned char flag_config_2; //第二次获取配置描述符标志
// 获取设备描述符
unsigned char SetupGetDevDescr[] = { 0x80, 0x06, 0x00, 0x01, 0x00, 0x00, 0x12, 0x00 };
// 获取配置描述符
unsigned char SetupGetCfgDescr[] = { 0x80, 0x06, 0x00, 0x02, 0x00, 0x00, 0x09, 0x00 };
// 设置USB地址
unsigned char SetupSetUsbAddr[] = { 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 };
// 设置USB配置
//const unsigned char code SetupSetUsbConfig[] = { 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
// SET IDLE
unsigned char SetupSetidle[]={0x21,0x0a,0x00,0x00,0x00,0x00,0x00,0x00};
// 获取HID 报告描述符
unsigned char SetupGetHidDes[]={0x81,0x06,0x00,0x22,0x00,0x00,0x81,0x00};
// SET REPORT
unsigned char SetupSetReport[]={0x21,0x09,0x00,0x02,0x00,0x00,0x01,0x00};
#define ch375_a0 GPIO_Pin_12 //ao=1写命令
#define ch375_rd GPIO_Pin_11
#define ch375_wr GPIO_Pin_10
#define ch375_cs GPIO_Pin_9
#define ch375_int GPIO_Pin_8
#define CH375_INT_WIRE_IN ((GPIOC->IDR&GPIO_Pin_8)>>1)
//#define USB_DBA GPIOC
//#define LCD_DBB GPIOB
#define USB1_DB0_H GPIOC->BSRR=GPIO_Pin_0
#define USB1_DB0_L GPIOC->BRR=GPIO_Pin_0
#define USB1_DB1_H GPIOC->BSRR=GPIO_Pin_1
#define USB1_DB1_L GPIOC->BRR=GPIO_Pin_1
#define USB1_DB2_H GPIOC->BSRR=GPIO_Pin_2
#define USB1_DB2_L GPIOC->BRR=GPIO_Pin_2
#define USB1_DB3_H GPIOC->BSRR=GPIO_Pin_3
#define USB1_DB3_L GPIOC->BRR=GPIO_Pin_3
#define USB1_DB4_H GPIOC->BSRR=GPIO_Pin_4
#define USB1_DB4_L GPIOC->BRR=GPIO_Pin_4
#define USB1_DB5_H GPIOC->BSRR=GPIO_Pin_5
#define USB1_DB5_L GPIOC->BRR=GPIO_Pin_5
#define USB1_DB6_H GPIOC->BSRR=GPIO_Pin_6
#define USB1_DB6_L GPIOC->BRR=GPIO_Pin_6
#define USB1_DB7_H GPIOC->BSRR=GPIO_Pin_7
#define USB1_DB7_L GPIOC->BRR=GPIO_Pin_7
/* 常用USB结构和相关常量 */
typedef struct _USB_SETUP_REQ {
UINT8 bType;
UINT8 bReq;
UINT8 wValueL;
UINT8 wValueH;
UINT8 wIndexL;
UINT8 wIndexH;
UINT8 wLengthL;
UINT8 wLengthH;
} USB_SETUP_REQ, *PUSB_SETUP_REQ;
typedef struct _USB_DEVICE_DESCRIPTOR {
UINT8 bLength;
UINT8 bDescriptorType;
UINT8 bcdUSBL;
UINT8 bcdUSBH;
UINT8 bDeviceClass;
UINT8 bDeviceSubClass;
UINT8 bDeviceProtocol;
UINT8 bMaxPacketSize0;
UINT8 idVendorL;
UINT8 idVendorH;
UINT8 idProductL;
UINT8 idProductH;
UINT8 bcdDeviceL;
UINT8 bcdDeviceH;
UINT8 iManufacturer;
UINT8 iProduct;
UINT8 iSerialNumber;
UINT8 bNumConfigurations;
} USB_DEV_DESCR, *PUSB_DEV_DESCR;
typedef struct _USB_CONFIG_DESCRIPTOR {
UINT8 bLength;
UINT8 bDescriptorType;
UINT8 wTotalLengthL;
UINT8 wTotalLengthH;
UINT8 bNumInterfaces;
UINT8 bConfigurationValue;
UINT8 iConfiguration;
UINT8 bmAttributes;
UINT8 MaxPower;
} USB_CFG_DESCR, *PUSB_CFG_DESCR;
typedef struct _USB_INTERF_DESCRIPTOR {
UINT8 bLength;
UINT8 bDescriptorType;
UINT8 bInterfaceNumber;
UINT8 bAlternateSetting;
UINT8 bNumEndpoints;
UINT8 bInterfaceClass;
UINT8 bInterfaceSubClass;
UINT8 bInterfaceProtocol;
UINT8 iInterface;
} USB_ITF_DESCR, *PUSB_ITF_DESCR;
typedef struct _USB_ENDPOINT_DESCRIPTOR {
UINT8 bLength;
UINT8 bDescriptorType;
UINT8 bEndpointAddress;
UINT8 bmAttributes;
UINT8 wMaxPacketSize;
UINT8 wMaxPacketSize1;
UINT8 bInterval;
} USB_ENDP_DESCR, *PUSB_ENDP_DESCR;
typedef struct _USB_CONFIG_DESCRIPTOR_LONG {
USB_CFG_DESCR cfg_descr;
USB_ITF_DESCR itf_descr;
USB_ENDP_DESCR endp_descr[2];
} USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG;
typedef struct _USB_HID_CLASS_DESCRIPTOR{
UINT8 bLength;
UINT8 bDescriptorType;
UINT16 bcdHID;
UINT8 bCountryCode;
UINT8 bNumDescriptors;
UINT8 bDescriptType;
UINT16 wDescriptorLength;
}USB_HID_CLASS_DESCR,*PUSB_HID_CLASS_DESCR;
typedef struct _HID_DEVICE{
USB_CFG_DESCR hid_cfg_descr;
USB_ITF_DESCR hid_itf_descr;
USB_HID_CLASS_DESCR hid_class_descr;
USB_ENDP_DESCR endp_descr;
}HID_DEVICE,*PHID_DEVICE;
typedef struct _USB_HID_COMPOSITE_DEVICE1{
USB_CFG_DESCR hid_cfg_descr;
USB_ITF_DESCR hid_itf_descr1;
USB_HID_CLASS_DESCR hid_class_descr1;
USB_ENDP_DESCR endp_descr1;
USB_ITF_DESCR hid_itf_descr2;
USB_HID_CLASS_DESCR hid_class_descr2;
USB_ENDP_DESCR endp_descr2;
}HID_COMPOSITE_DEVICE1,*PHID_COMPOSITE_DEVICE1;
typedef struct _USB_HID_COMPOSITE_DEVICE2{
USB_CFG_DESCR hid_cfg_descr;
USB_ITF_DESCR hid_itf_descr1;
USB_HID_CLASS_DESCR hid_class_descr1;
USB_ENDP_DESCR endp_descr1;
USB_ITF_DESCR hid_itf_descr1_1;
USB_ENDP_DESCR endp_descr1_1;
USB_ITF_DESCR hid_itf_descr2;
USB_HID_CLASS_DESCR hid_class_descr2;
USB_ENDP_DESCR endp_descr2;
USB_ITF_DESCR hid_itf_descr2_1;
USB_ENDP_DESCR endp_descr2_1;
}HID_COMPOSITE_DEVICE2,*PHID_COMPOSITE_DEVICE2;
struct _Device_Atti{
UINT8 Device_connect; //设备连接状态 1:连接,0:断开
UINT8 Device_compat; //0:非复合设备,1表示复合设备
UINT8 Cfg_value; //设备配置描述符中配置值
struct _Device{
UINT8 Device_type; //设备类型 1:键盘,2:鼠标
UINT8 Device_inf; //设备接口号 默认为0 最多支持两个接口设备
UINT8 Device_endp; //设备端点地址 最多支持一个端点
UINT8 Device_size; //设备端点大小
UINT16 Device_report_len; //设备报表长度
UINT8 tog; //端点的同步标志
}Device[2];
}Device_Atti = { 0 };
UINT8 receive_mode = 0x00,send_mode = 0x00;
void mDelay1_2uS(void) /* 至少延时1uS,根据单片机主频调整 */
{
UINT32 i;
for ( i = 25; i != 0; i -- ); /* 本例由于模拟I/O较慢故只需少量延时 */
}
/****************************************************************************
* 名 称:delay_us(u32 nus)
* 功 能:微秒延时函数
* 入口参数:u32 nus
* 出口参数:无
* 说 明:
* 调用方法:无
****************************************************************************/
void delay_us(u32 nus)//延时一微秒
{
u32 temp;
SysTick->LOAD = 9*nus;
SysTick->VAL=0X00;//清空计数器
SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
do
{
temp=SysTick->CTRL;//读取当前倒计数值
}while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//1秒等1000毫秒,一毫秒等1000微秒
/****************************************************************************
* 名 称:delay_ms(u16 nms)
* 功 能:毫秒延时函数
* 入口参数:u16 nms
* 出口参数:无
* 说 明:
* 调用方法:无
****************************************************************************/
void delay_ms(u16 nms)//延时一毫秒
{
u32 temp;
SysTick->LOAD = 9000*nms;
SysTick->VAL=0X00;//清空计数器
SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
do
{
temp=SysTick->CTRL;//读取当前倒计数值
}while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//ch375 data input
void ch375_data_input(void)
{
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|
GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
//ch375 data output
void ch375_data_output(void)
{
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|
GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
void myinit(void)
{
uint32_t i;
//ch375 控制
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //cs
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //int
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
USART_Cmd(USART1, ENABLE);
for(i=0;i<200000;i++);
//USART_SendData(USART1, 0x99);
}
void CH376_DATA_DAT_OUT (UINT8 data) /* 写并口低八位输出数据 */
{
//ch375_data_output();
if(data&0x01)
{
USB1_DB0_H;
}
else
{
USB1_DB0_L;
}
if(data&0x02)
{
USB1_DB1_H;
}
else
{
USB1_DB1_L;
}
if(data&0x04)
{
USB1_DB2_H;
}
else
{
USB1_DB2_L;
}
if(data&0x08)
{
USB1_DB3_H;
}
else
{
USB1_DB3_L;
}
if(data&0x10)
{
USB1_DB4_H;
}
else
{
USB1_DB4_L;
}
if(data&0x20)
{
USB1_DB5_H;
}
else
{
USB1_DB5_L;
}
if(data&0x40)
{
USB1_DB6_H;
}
else
{
USB1_DB6_L;
}
if(data&0x80)
{
USB1_DB7_H;
}
else
{
USB1_DB7_L;
}
}
/*{
unsigned int D_Temp = 0;
D_Temp = D_Temp + d;
GPIO_Write(GPIOC,D_Temp);
} */
UINT8 CH376_DATA_DAT_IN(void ) /* 读并口低八位输入数据 */
/*{ UINT8 db_data=0x00;
// data_io_in();
if(GPIOC->BSRR&GPIO_Pin_0)
{
db_data|=GPIO_Pin_0;
}
if(GPIOC->BSRR&GPIO_Pin_1)
{
db_data|=GPIO_Pin_1;
}
if(GPIOC->BSRR&GPIO_Pin_2)
{
db_data|=GPIO_Pin_2;
}
if(GPIOC->BSRR&GPIO_Pin_3)
{
db_data|=GPIO_Pin_3;
}
if(GPIOC->BSRR&GPIO_Pin_4)
{
db_data|=GPIO_Pin_4;
}
if(GPIOC->BSRR&GPIO_Pin_5)
{
db_data|=GPIO_Pin_5;
}
if(GPIOC->BSRR&GPIO_Pin_6)
{
db_data|=GPIO_Pin_6;
}
if(GPIOC->BSRR&GPIO_Pin_7)
{
db_data|=GPIO_Pin_7;
}
return db_data; }*/
{
unsigned int D_Temp;
UINT8 d;
D_Temp = GPIO_ReadInputData(GPIOC);
d = (UINT8)D_Temp;
return d;
}
//**********************************************
//* NAME: CH376_WR_CMD_PORT( UINT8 cmd )
//* FUCTION: 写CH376命令子函数
//* 输入参数:8位命令码
//* 输出参数:无
//* 说明:对于速度较快的单片机,则需要1.5uS延时
//**********************************************
void CH376_WR_CMD_PORT( UINT8 cmd )
{
uint16_t i;
//GPIO_WriteBit(GPIOE, ch375_cs, Bit_RESET);
for(i=0;i<1000;i++);
ch375_data_output(); //定义端口
//for(i=0;i<5;i++);
CH376_DATA_DAT_OUT (cmd);
GPIO_WriteBit(GPIOC, ch375_a0, Bit_SET);
GPIO_WriteBit(GPIOC, ch375_rd, Bit_SET);
GPIO_WriteBit(GPIOC, ch375_wr, Bit_RESET);
for(i=0;i<100;i++);
GPIO_WriteBit(GPIOC, ch375_wr, Bit_SET);
//for(i=0;i<100;i++);
}
//**********************************************
//* NAME: CH376_WR_DAT_PORT( UINT8 dat )
//* FUCTION: 写CH376数据子函数
//* 输入参数:8位数据
//* 输出参数:无
//* 说明:对于速度较快的单片机,则需要0.6uS延时
//**********************************************
void CH376_WR_DAT_PORT( UINT8 dat )
{
uint16_t i;
//GPIO_WriteBit(GPIOE, ch375_cs, Bit_RESET);
for(i=0;i<1000;i++);
ch375_data_output(); //定义端口
GPIO_WriteBit(GPIOC, ch375_a0, Bit_RESET);
GPIO_WriteBit(GPIOC, ch375_rd, Bit_SET);
CH376_DATA_DAT_OUT(dat);
GPIO_WriteBit(GPIOC, ch375_wr, Bit_RESET);
for(i=0;i<100;i++);
GPIO_WriteBit(GPIOC, ch375_wr, Bit_SET);
//for(i=0;i<100;i++);
}
//**********************************************
//* NAME: CH376_RD_DAT_PORT( void )
//* FUCTION: 读CH376数据子函数
//* 输入参数:无
//* 输出参数:8位数据
//* 说明:对于速度较快的单片机,则需要0.6uS延时
//**********************************************
UINT8 CH376_RD_DAT_PORT( void )
{
uint8_t temp;
uint16_t i;
//GPIO_WriteBit(GPIOE, ch375_cs, Bit_RESET);
for(i=0;i<1000;i++);
ch375_data_input(); //定义端口
//for ( i = 5; i != 0; i -- );
GPIO_WriteBit(GPIOC, ch375_a0, Bit_RESET);
GPIO_WriteBit(GPIOC, ch375_wr, Bit_SET);
GPIO_WriteBit(GPIOC, ch375_rd, Bit_RESET);
for(i=0;i<10;i++);
temp = CH376_DATA_DAT_IN();
// USART_SendData(USART1,temp);
//for(i=0;i<50;i++);
GPIO_WriteBit(GPIOC, ch375_rd, Bit_SET);
return( temp );
}
void StdioInit( void ) //串口初始化
{ GPIO_InitTypeDef GPIO_InitStructure;//io口配置结构体
NVIC_InitTypeDef NVIC_InitStructure;//优先级配置结构体
USART_InitTypeDef USART_InitStructure;//串口配置结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//打开GPIOA的时钟打开串口一的时钟打开io口复用功能的时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX 串口输出用GPIOA9
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;//输出速度50MHz
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//使用复用推挽输出
GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIO9
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX串口输入用GPIOA10
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//使用浮空输入
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化GPIO10
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//中断优先级分组,分到1组
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//使用中断对应的入口函数
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//打开优先级的使能
NVIC_Init(&NVIC_InitStructure); //优先级初始化
USART_InitStructure.USART_BaudRate=9600; //串口波特率9600
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//数据位8位
USART_InitStructure.USART_StopBits=USART_StopBits_1;//停止位1
USART_InitStructure.USART_Parity=USART_Parity_No;//不效验
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件控制流无
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//指定使能收发模式都打开
USART_Init(USART1,&USART_InitStructure);//串口初始化
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//配置打开接收中断函数
USART_Cmd(USART1,ENABLE);//打开串口1全部使能
USART_ClearFlag(USART1,USART_FLAG_TC);//清除中断USART_FLAG_TC发送完成标志位清空
}
void PrintCom(unsigned char *DAT)//串口字符口串输出
{
while(*DAT)
{ USART_SendData(USART1,*DAT++);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}
USART_SendData(USART1,0x0a);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}
//**********************************************
//* NAME: Set_USB_Mode( UINT8 mode )
//* FUCTION: 设置CH376的工作模式 0x06 为主机模式
//* 输入参数:模式代码
//* 输出参数:操作状态 TRUE:成功,FALSE失败
//* 说明: 设置CH376的工作模式
//**********************************************
UINT8 Set_USB_Mode( UINT8 mode ) {
UINT8 i;
CH376_WR_CMD_PORT( CMD_SET_USB_MODE );
CH376_WR_DAT_PORT( mode );
receive_mode=send_mode=0x00; //主机端复位USB数据同步标志
for( i=0; i!=100; i++ ) { //等待设置模式操作完成,不超过30uS
if ( CH376_RD_DAT_PORT()==CMD_RET_SUCCESS ) return( 1 ); //成功
}
return( 0 ); //CH376出错,例如芯片型号错或者处于串口方式或者不支持
}
//*****************************************************
//* NAME: set_freq(void)
//* FUCTION: 设置CH376的进入低速模式
//* 输入参数:无
//* 输出参数:无
//* 说明: 对于鼠标键盘等低速设备,要先设置ch376为低速模式
//******************************************************
void set_freq(void)
{
CH376_WR_CMD_PORT(0x0b); // 切换使375B进入低速模式
delay_us(1);
CH376_WR_DAT_PORT(0x17);
delay_us(1);
CH376_WR_DAT_PORT(0xd8);
delay_us(1);
}
//*****************************************************
//* NAME: RD_USB_DATA( UINT8 *buf )
//* FUCTION: 从CH376的端点缓冲区读取接收到的数据
//* 输入参数: 数据缓冲区的地址
//* 输出参数:返回接收的数据长度
//* 说明: 从CH376的主机端点缓冲区中读取接收到的数据
//******************************************************
UINT8 RD_USB_DATA( UINT8 *buf ) {
UINT8 i, len;
CH376_WR_CMD_PORT( 0x27 ); // 从CH37X读取数据块
delay_us(3);
len=CH376_RD_DAT_PORT(); // 后续数据长度
delay_us(1);
for ( i=0; i!=len; i++ ) *buf++=CH376_RD_DAT_PORT();
return( len );
}
//*****************************************************
//* NAME: WR_USB_DATA( UINT8 len, UINT8 *buf )
//* FUCTION: 往CH376的端点缓冲区写入数据块
//* 输入参数: 要写入数据块的长度,写入数据缓冲区的地址
//* 输出参数:无
//* 说明: 往CH376的主机端点缓冲区中写入要发送的数据块
//******************************************************
void WR_USB_DATA( UINT8 len, UINT8 *buf ) {
CH376_WR_CMD_PORT( 0x2B ); // 向CH376的端点缓冲区写入准备发送的数据
delay_us(2);
CH376_WR_DAT_PORT( len ); // 后续数据长度, len不能大于64
delay_us(1);
while( len-- ) CH376_WR_DAT_PORT( *buf++ );
}
//*****************************************************
//* NAME: issue_token(UINT8 endptog, UINT8 endp_and_pid )
//* FUCTION: 执行USB事务
//* 输入参数: 同步标志,端点号和令牌
//* 输出参数:无
//* 说明: 高4位目的端点号, 低4位令牌PID
//******************************************************
void issue_token(UINT8 endptog, UINT8 endp_and_pid ) {
CH376_WR_CMD_PORT( 0x4E );
delay_us(3);
CH376_WR_DAT_PORT( endptog );
delay_us(3);
CH376_WR_DAT_PORT( endp_and_pid );
delay_us(3) ;
}
//*****************************************************
//* NAME: wait_interrupt( )
//* FUCTION: 等待中断,并且获取中断状态
//* 输入参数: 无
//* 输出参数:中断状态
//* 说明: CH376操作完成中断(INT#低电平)
//******************************************************
UINT8 wait_interrupt( )
{ uint16_t i;
while(1) // 查询等待CH375操作完成中断(INT#低电平)
{if(GPIO_ReadInputDataBit(GPIOC, ch375_int)==0)
{
//LED 熄灭
break;
}
}
delay_ms(2);
CH376_WR_CMD_PORT(0x22); // 产生操作完成中断,获取中断状态
// PrintCom("
产生操作完成中断,获取中断状
");
for ( i = 1000; i!= 0; i -- );
return( CH376_RD_DAT_PORT( ) );
}
//*****************************************************
//* NAME: Get_Dev_Descr( )
//* FUCTION: 获取设备描述符
//* 输入参数: 无
//* 输出参数:成功返回1,否则返回0
//* 说明: 该程序采用外置固件模式获取设备描述符
//******************************************************
UINT8 Get_Dev_Descr( )
{
UINT8 descr_len;
UINT8 *p=data_buf;
send_mode=0x00;
WR_USB_DATA(8,SetupGetDevDescr);
issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();
if(status==USB_INT_SUCCESS) //SETUP阶段操作成功
{
receive_mode=0x80;
}
else return(0);
issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
if(status==USB_INT_SUCCESS) //DATA阶段操作成功
{
descr_len=data_buf[0]-RD_USB_DATA(data_buf);
while(descr_len>0)
{
receive_mode ^= 0x80;
p+=0x08;
issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
if(status==USB_INT_SUCCESS) //DATA阶段操作成功
descr_len-=RD_USB_DATA(p);
else return(0);
}
}
else return(0);
send_mode=0x40;
WR_USB_DATA(0,SetupGetDevDescr);
issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();
if(status==USB_INT_SUCCESS) //状态阶段操作成功
return(1);
else return(0);
}
//*****************************************************
//* NAME: Get_Cfg_Descr( PUINT8 buf )
//* FUCTION: 获取配置描述符
//* 输入参数: 接收缓冲区地址
//* 输出参数:成功返回1,否则返回0
//* 说明: 该程序采用外置固件模式获取配置描述符
//******************************************************
UINT8 Get_Cfg_Descr( PUINT8 buf )
{
unsigned char descr_len;
unsigned char *p=data_buf;
send_mode=0x00;
WR_USB_DATA(8,buf);
issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();
if(status==USB_INT_SUCCESS) //SETUP阶段操作成功
{
receive_mode=0x80;
}
else return(0);
issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
if(status==USB_INT_SUCCESS) //DATA阶段操作成功
{
receive_mode ^= 0x80;
if(flag_config_2) //第二次获取设备的配置描述符
descr_len=data_buf[2]-RD_USB_DATA(data_buf);
else descr_len=data_buf[0]-RD_USB_DATA(data_buf);
while(descr_len>0)
{
p+=0x08;
issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
if(status==USB_INT_SUCCESS) //DATA阶段操作成功
{
receive_mode ^= 0x80;
descr_len-=RD_USB_DATA(p);
}
else return(0);
}
}
else return(0);
send_mode = 0x40;
WR_USB_DATA(0,SetupGetCfgDescr);
issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();
if(status==USB_INT_SUCCESS) //状态阶段操作成功
return(1);
else return(0);
}
//*****************************************************
//* NAME: parse_config_descr( )
//* FUCTION: 简单的分析配置描述符中的相关信息,并保存
//* 输入参数: 无
//* 输出参数:无
//* 说明: 保存设备的接口号,端点地址,报表长度,支持复合设备
//******************************************************
void parse_config_descr( )
{
Device_Atti.Device_connect = 1; //表示设备连接
Device_Atti.Cfg_value = ((PUSB_CFG_DESCR)data_buf)->bConfigurationValue; //保留配置描述符中的配置值
if(((PUSB_CFG_DESCR)data_buf)->bNumInterfaces==1) //只有一个接口设备
{
Device_Atti.Device_compat = 0; //非复合设备
#define HID_Dev ((PHID_DEVICE)data_buf)
Device_Atti.Device[0].Device_type = HID_Dev->hid_itf_descr.bInterfaceProtocol; //设备类型:0x01 键盘,0x02 鼠标
Device_Atti.Device[0].Device_inf = HID_Dev->hid_itf_descr.bInterfaceNumber; //设备的接口号
Device_Atti.Device[0].Device_endp = HID_Dev->endp_descr.bEndpointAddress; //设备端点地址
Device_Atti.Device[0].Device_size = HID_Dev->endp_descr.wMaxPacketSize; //设备端点大小
Device_Atti.Device[0].Device_report_len = (HID_Dev->hid_class_descr.wDescriptorLength>>8)|(HID_Dev->hid_class_descr.wDescriptorLength<<8); //报表长度,大小端数据格式转换
}
else if(((PUSB_CFG_DESCR)data_buf)->bNumInterfaces==2) //2个接口设备
{
Device_Atti.Device_compat = 1; //复合设备
#define HID_Dev1 ((PHID_COMPOSITE_DEVICE1)data_buf)
Device_Atti.Device[0].Device_type = HID_Dev1->hid_itf_descr1.bInterfaceProtocol;
Device_Atti.Device[0].Device_inf = HID_Dev1->hid_itf_descr1.bInterfaceNumber;
Device_Atti.Device[0].Device_endp = HID_Dev1->endp_descr1.bEndpointAddress;
Device_Atti.Device[0].Device_size = HID_Dev1->endp_descr1.wMaxPacketSize;
Device_Atti.Device[0].Device_report_len = (HID_Dev1->hid_class_descr1.wDescriptorLength>>8)|(HID_Dev1->hid_class_descr1.wDescriptorLength<<8); //报表长度,大小端数据格式转换
Device_Atti.Device[1].Device_type = HID_Dev1->hid_itf_descr2.bInterfaceProtocol;
Device_Atti.Device[1].Device_inf = HID_Dev1->hid_itf_descr2.bInterfaceNumber;
Device_Atti.Device[1].Device_endp = HID_Dev1->endp_descr2.bEndpointAddress;
Device_Atti.Device[1].Device_size = HID_Dev1->endp_descr2.wMaxPacketSize;
Device_Atti.Device[1].Device_report_len = (HID_Dev1->hid_class_descr2.wDescriptorLength>>8)|(HID_Dev1->hid_class_descr2.wDescriptorLength<<8); //报表长度,大小端数据格式转换
}
}
//*****************************************************
//* NAME: set_config( UINT8 cfg )
//* FUCTION: 配置USB设备
//* 输入参数: 配置值
//* 输出参数:操作状态 成功返回0x14
//* 说明: 该配置值取自配置描述符中
//******************************************************
UINT8 set_config( UINT8 cfg ) {
CH376_WR_CMD_PORT( CMD_SET_CONFIG );
delay_us(3);
CH376_WR_DAT_PORT( cfg );
delay_us(2);
return( wait_interrupt() );
}
//*****************************************************
//* NAME: set_idle( UINT8 inf )
//* FUCTION: 设置HID设备的IDLE &n
一周热门 更多>