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;}这份东西还有很多不足的地方,报表那边的逻辑大小是需要对应触控屏的,触点是可以增加的,发送的数据坐标有些问题,目前还在调试中。。。
0 2023-08-03