STM32模拟USB多点触控屏开发准备 STM32的USB官方例程库JoyStickMouse STM32F103RC Windows7代码修改1.usb_pwr.cRESULT PowerOn(void){ u16 wRegVal; //USB_Cable_Config(ENABLE);//这里由于硬件问题用不到,注释 /*** CNTR_PWDN = 0 ***/ wRegVal = CNTR_FRES; _SetCNTR(wRegVal); /*** CNTR_FRES = 0 ***/ wInterrupt_Mask = 0; _SetCNTR(wInterrupt_Mask); /*** Clear pending interrupts ***/ _SetISTR(0); /*** Set interrupt mask ***/ wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM; _SetCNTR(wInterrupt_Mask); return USB_SUCCESS;}2.usb_proc.cvoid Joystick_Reset(void){ /* Set Joystick_DEVICE as not configured */ pInformation->Current_Configuration = 0; pInformation->Current_Interface = 0;/* the default Interface */ /* Current Feature initialization */ pInformation->Current_Feature = Joystick_ConfigDescriptor[7]; SetBTABLE(BTABLE_ADDRESS); /* Initialize Endpoint 0 */ SetEPType(ENDP0, EP_CONTROL); SetEPTxStatus(ENDP0, EP_TX_STALL); SetEPRxAddr(ENDP0, ENDP0_RXADDR); SetEPTxAddr(ENDP0, ENDP0_TXADDR); Clear_Status_Out(ENDP0); SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); SetEPRxValid(ENDP0); /* Initialize Endpoint In 1 */ SetEPType(ENDP1, EP_INTERRUPT); //初始化为中断端点类型 SetEPTxAddr(ENDP1, ENDP1_TXADDR); //设置发送数据的地址 SetEPTxCount(ENDP1, 14); //设置发送的长度,这里由于使用的两点触控的触控屏需要发送的数据为14Bytes一次 SetEPTxStatus(ENDP1, EP_TX_NAK); //设置端点处于忙状态 /* Initialize Endpoint Out 1 */ SetEPRxAddr(ENDP1, ENDP1_RXADDR); //设置接收数据的地址 SetEPRxCount(ENDP1, 2); //设置接收长度 SetEPRxStatus(ENDP1, EP_RX_VALID); //设置端点有效,可以接收数据 bDeviceState = ATTACHED; /* Set this device to response on default address */ SetDeviceAddress(0);}由于需要枚举的是多点触控屏,需要处理Get_Report和Set_Report,虽然有些人说Set_Report不需要处理,但是我还是顺手处理掉了。/*******************************************************************************添加上获取HID描述符和报告描述符函数*******************************************************************************/ONE_DESCRIPTOR Test_Hid_Descriptor = { (u8*)Joystick_ConfigDescriptor + Test_OFF_HID_DESC, JOYSTICK_SIZ_HID_DESC };ONE_DESCRIPTOR Test_Report_Descriptor = { (u8 *)TestReportDescriptor, Test_ReportDescriptor_Size }; u8 *Test_GetHIDDescriptor(u16 Length){ return Standard_GetDescriptorData(Length, &Test_Hid_Descriptor);}u8 *Test_GetReportDescriptor(u16 Length){ return Standard_GetDescriptorData(Length, &Test_Report_Descriptor);}/*******************************************************************************这里用来处理Get_Report Set_Report*******************************************************************************/u8 Report_Buffer[2] = {0x02, 0x02}; //Report_Buffer[0]为FeatureID, //Report_Buffer[1]为最大触控点数u8 *Joystick_GetReport(u16 Length) //处理Get_Report{ if(Length == 0) { pInformation->Ctrl_Info.Usb_wLength = 2; return NULL; } return &Report_Buffer[pInformation->Ctrl_Info.Usb_wOffset];}u8 *Joystick_SetReport(u16 Length)//处理Set_Report{ if(Length == 0) { pInformation->Ctrl_Info.Usb_wLength = 2; return NULL; } return &Report_Buffer[pInformation->Ctrl_Info.Usb_wOffset];}RESULT Joystick_Data_Setup(u8 RequestNo){ u8 *(*CopyRoutine)(u16); CopyRoutine = NULL; if ((RequestNo == GET_DESCRIPTOR) && (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) && (pInformation->USBwIndex0 < 3)) { if (pInformation->USBwValue1 == REPORT_DESCRIPTOR) { CopyRoutine = Test_GetReportDescriptor; } else if (pInformation->USBwValue1 == HID_DESCRIPTOR_TYPE) { CopyRoutine = Test_GetHIDDescriptor; } } /* End of GET_DESCRIPTOR */ /*** GET_PROTOCOL ***/ else if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) && RequestNo == GET_PROTOCOL) { CopyRoutine = Joystick_GetProtocolValue; }/******************************************************************Add Handle Get_Report and Set_Report CTL:******************************************************************/ else if((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))) { switch(RequestNo) { case GET_REPORT: CopyRoutine = Joystick_GetReport; break; case SET_REPORT: CopyRoutine = Joystick_SetReport; break; default: break; } } if (CopyRoutine == NULL) { return USB_UNSUPPORT; } pInformation->Ctrl_Info.CopyData = CopyRoutine; pInformation->Ctrl_Info.Usb_wOffset = 0; (*CopyRoutine)(0); return USB_SUCCESS;}3.usb_conf.h//地址为32位对其,位4的倍数,不能超过 bMaxPacketSize/* EP0 *//* rx/tx buffer base address */#define ENDP0_RXADDR (0x40)#define ENDP0_TXADDR (0x80)/* EP1 *//* rx/tx buffer base address */#define ENDP1_RXADDR (0xc0)#define ENDP1_TXADDR (0x100)4.usb_desc.h#define JOYSTICK_SIZ_CONFIG_DESC 41 //配置描述符的大写改为41,即0x29#define Test_ReportDescriptor_Size 202 //触控屏报表描述符长度#define Test_OFF_HID_DESC 18 //触控屏HID描述符的偏移量extern const u8 TestReportDescriptor[Test_ReportDescriptor_Size];//extern一下5.usb_desc.cconst u8 Joystick_ConfigDescriptor[JOYSTICK_SIZ_CONFIG_DESC] ={/***************配置描述符***********************/ 0x09, //bLength字段 USB_CONFIGURATION_DESCRIPTOR_TYPE, //bDescriptorType字段 JOYSTICK_SIZ_CONFIG_DESC&0xff, //wTotalLength字段 (JOYSTICK_SIZ_CONFIG_DESC>>8)&0xff, 0x01, //bNumInterfaces字段 0x01, //bConfiguration字段 0x00, //iConfigurationz字段 0x80, //bmAttributes字段 0x20, //bMaxPower字段/* 9 *//*******************第一个接口描述符*********************/ 0x09, //bLength字段 USB_INTERFACE_DESCRIPTOR_TYPE, //bDescriptorType字段 0x00, //bInterfaceNumber字段 0x00, //bAlternateSetting字段 0x02, //bNumEndpoints字段 0x03, //bInterfaceClass字段 0x00, //bInterfaceSubClass字段 0x00, //bInterfaceProtocol字段 0x00, //iConfiguration字段/* 18 *//******************HID描述符************************/0x09, //bLength字段0x21, //bDescriptorType字段0x01, //bcdHID字段0x01,0x00, //bCountyCode字段0x01, //bNumDescriptors字段0x22, //bDescriptorType字段Test_ReportDescriptor_Size&0xFF,(Test_ReportDescriptor_Size>>8)&0xFF,/* 27 *//**********************输入端点描述符***********************/ 0x07, //bLength字段 USB_ENDPOINT_DESCRIPTOR_TYPE, //bDescriptorType字段 0x81, //bEndpointAddress字段 0x03, //bmAttributes字段 0x10, //wMaxPacketSize字段 0x00, 0x0A, //bInterval字段/* 34 *//**********************输出端点描述符***********************/ 0x07, //bLength字段 USB_ENDPOINT_DESCRIPTOR_TYPE, //bDescriptorType字段 0x01, //bEndpointAddress字段 0x03, //bmAttributes字段 0x10, //wMaxPacketSize字段 0x00, 0x0A, //bInterval字段/* 41 */const u8 TestReportDescriptor[Test_ReportDescriptor_Size] = { /* 多点触控设备 */ 0x05, 0x0d,// USAGE_PAGE (Digitizers) 0x09, 0x04,// USAGE (Touch Screen) 0xa1, 0x01,// COLLECTION (Application) 0x85, 0x01,//REPORTID_MTOUCH, // REPORT_ID (Touch) /* 8 */ /* 第一点 */ /* 手指和z轴 */ 0x09, 0x22,// USAGE (Finger) 0xa1, 0x02,// COLLECTION (Logical) 0x09, 0x42,// USAGE (Tip Switch) 0x15, 0x00,// LOGICAL_MINIMUM (0) 0x25, 0x01,// LOGICAL_MAXIMUM (1) 0x75, 0x01,// REPORT_SIZE (1) 0x95, 0x01,// REPORT_COUNT (1) 0x81, 0x02,// INPUT (Data,Var,Abs) 0x09, 0x32,// USAGE (In Range) 0x81, 0x02,// INPUT (Data,Var,Abs) 0x95, 0x06,// REPORT_COUNT (6) 0x81, 0x01,// INPUT (Cnst,Ary,Abs) /* 32 */ /* 手指ID */ 0x75, 0x08,// REPORT_SIZE (8) 0x09, 0x51,// USAGE ( Contact Identifier) 0x25, 0xFF,// LOGICAL_MAXIMUM (255) 0x95, 0x01,// REPORT_COUNT (1) 0x81, 0x02,// INPUT (Data,Var,Abs) /* 42 */ /* X和Y */ 0x05, 0x01,// USAGE_PAGE (Generic Desk) 0x16, 0x00,0x00,//HID_LogicalMinS (0) 0x26, 0x56, 0x05,// LOGICAL_MAXIMUM (1366) 0x75, 0x10,// REPORT_SIZE (16) 0x55, 0x00,// UNIT_EXPONENT (0) 0x65, 0x00,// UNIT (00) 0x09, 0x30,// USAGE (X) 0x36, 0x00,0x00,// PHYSICAL_MINIMUM (0) 0x46, 0x56, 0x05,// PHYSICAL_MAXIMUM (1366) 0x95, 0x01,// REPORT_COUNT (1) 0x81, 0x02,// INPUT (Data,Var,Abs) 0x26, 0x00, 0x03,// LOGICAL_MAXIMUM (4095) 0x46, 0x00, 0x03,// PHYSICAL_MAXIMUM (4095) 0x09, 0x31,// USAGE (Y) 0x81, 0x02,// INPUT (Data,Var,Abs) 0xc0, // END_COLLECTION /* 79 */ /* 第二点 */ /* 手指和z轴 */ 0x05, 0x0d,// USAGE_PAGE (Digitizers) 0x09, 0x22,// USAGE (Finger) 0xa1, 0x02,// COLLECTION (Logical) 0x09, 0x42,// USAGE (Tip Switch) 0x15, 0x00,// LOGICAL_MINIMUM (0) 0x25, 0x01,// LOGICAL_MAXIMUM (1) 0x75, 0x01,// REPORT_SIZE (1) 0x95, 0x01,// REPORT_COUNT (1) 0x81, 0x02,// INPUT (Data,Var,Abs) 0x09, 0x32,// USAGE (In Range) 0x81, 0x02,// INPUT (Data,Var,Abs) 0x95, 0x06,// REPORT_COUNT (6) 0x81, 0x01,// INPUT (Cnst,Ary,Abs) /* 105 */ /* 手指ID */ 0x75, 0x08,// REPORT_SIZE (8) 0x09, 0x51,// USAGE ( Contact Identifier) 0x95, 0x01,// REPORT_COUNT (1) 0x25, 0xFF,// LOGICAL_MAXIMUM (255) 0x81, 0x02,// INPUT (Data,Var,Abs) /* 115 */ /* X和Y */ 0x05, 0x01,// USAGE_PAGE (Generic Desk.. 0x26, 0x56, 0x05, // LOGICAL_MAXIMUM (1366) 0x75, 0x10,// REPORT_SIZE (16) 0x55, 0x00,// UNIT_EXPONENT (0) 0x65, 0x00,// UNIT (0) 0x09, 0x30,// USAGE (X) 0x36, 0x00,0x00,// PHYSICAL_MINIMUM (0) 0x46, 0x56, 0x05,// PHYSICAL_MAXIMUM (1366) 0x81, 0x02,// INPUT (Data,Var,Abs) 0x26, 0x00, 0x03, 0x46, 0x00, 0x03,// PHYSICAL_MAXIMUM (0) 0x09, 0x31,// USAGE (Y) 0x81, 0x02,// INPUT (Data,Var,Abs) 0xc0, //END_COLLECTION /* 147 */ /* 实际点数 */ 0x05, 0x0d,// USAGE_PAGE (Digitizers) 0x09, 0x54,// USAGE (Actual count) 0x95, 0x01,// REPORT_COUNT (1) 0x75, 0x08,// REPORT_SIZE (8) 0x15, 0x00,// LOGICAL_MINIMUM (0) 0x25, 0x08,// LOGICAL_MAXIMUM (8) 0x81, 0x02,// INPUT (Data,Var,Abs) /* 161 */ /* 硬件支持点数 */ 0x85, 0x02,// REPORT_ID (Feature) 0x75, 0x08,// REPORT_SIZE (8) 0x95, 0x01,// REPORT_COUNT (1) 0x15, 0x01,// LOGICAL_MINIMUM (1) 0x25, 0x08,// LOGICAL_MAXIMUM (8) 0x09, 0x55,// USAGE(Maximum Count) 0xB1, 0x02,// FEATURE (Data,Var,Abs) 0xc0, // END_COLLECTION /* 176 */ /* 上位机特性设定 */ 0x09, 0x0E,// USAGE (Device Configuration) 0xa1, 0x01,// COLLECTION (Application) 0x85, 0x04,// REPORT_ID (Configuration) 0x09, 0x23,// USAGE (Device Settings) 0xa1, 0x02,// COLLECTION (logical) 0x09, 0x52,// USAGE (Device Mode) 0x15, 0x00,// LOGICAL_MINIMUM (0) 0x25, 0x0a,// LOGICAL_MAXIMUM (10) 0x75, 0x08,// REPORT_SIZE (8) 0x09, 0x53,// USAGE (Device Identifier) 0x95, 0x01,// REPORT_COUNT (2) 0xb1, 0x02,// FEATURE (Data,Var,Abs 0xc0, // END_COLLECTION 0xc0, // END_COLLECTION /* 202 */}; 枚举成功就可以在系统设备中找到枚举的触控屏设备信息了,这里使用的是Usblyer。 如何测试void Test_Send(uint8_t *buf, uint16_t len){ // 对于本代码2点触控每个数据包由14个字节组成分别为 // InReport[0] 设备ID 固定值为TOUCH_REPORT_ID // InReport[1] 第一点触摸情况 bit1:1有触摸 0没触摸 bit2: 1在范围内 0不在范围内 // InReport[2] 第一点ID 每个点在抬起之前不能改变 0~255 // InReport[3] 第一点X坐标低8位 // InReport[4] 第一点X坐标高8位 // InReport[5] 第一点Y坐标低8位 // InReport[6] 第一点Y坐标高8位 // InReport[7] 第二点触摸情况 bit1:1有触摸 0没触摸 bit2: 1在范围内 0不在范围内 // InReport[8] 第二点ID 每个点在抬起之前不能改变 0~255 // InReport[9] 第二点X坐标低8位 // InReport[10] 第二点X坐标高8位 // InReport[11] 第二点Y坐标低8位 // InReport[12] 第二点Y坐标高8位 // InReport[13] 此数据包中有效的点数 static uint8_t i = 0; uint8_t Buffer[14]; if(i > 0 && i < 20) { Buffer[0] = 0x01; Buffer[1] = 0x07; Buffer[2] = 0x01; Buffer[3] = 0x88; Buffer[4] = 0x07; Buffer[5] = 0x85; Buffer[6] = 0x04; Buffer[7] = 0x00; Buffer[8] = 0x00; Buffer[9] = 0x00; Buffer[10] = 0x00; Buffer[11] = 0x00; Buffer[12] = 0x00; Buffer[13] = 0x01; } if(i < 40 && i > 20) { Buffer[0] = 0x01; Buffer[1] = 0x06; Buffer[2] = 0x01; Buffer[3] = 0x88; Buffer[4] = 0x07; Buffer[5] = 0x85; Buffer[6] = 0x04; Buffer[7] = 0x00; Buffer[8] = 0x00; Buffer[9] = 0x00; Buffer[10] = 0x00; Buffer[11] = 0x00; Buffer[12] = 0x00; Buffer[13] = 0x01; } if(i > 40) { Buffer[0] = 0x01; Buffer[1] = 0x00; Buffer[2] = 0x00; Buffer[3] = 0x00; Buffer[4] = 0x00; Buffer[5] = 0x00; Buffer[6] = 0x00; Buffer[7] = 0x00; Buffer[8] = 0x00; Buffer[9] = 0x00; Buffer[10] = 0x00; Buffer[11] = 0x00; Buffer[12] = 0x00; Buffer[13] = 0x00; } i++; if(i > 60) { i = 0; } UserToPMABufferCopy(Buffer, GetEPTxAddr(ENDP1) , 14); SetEPTxValid(ENDP1); return;}这份东西还有很多不足的地方,报表那边的逻辑大小是需要对应触控屏的,触点是可以增加的,发送的数据坐标有些问题,目前还在调试中。。。
5
2023-08-03

