STM32模拟USB多点触控屏
2023-08-03 13:39:34
ThanksView
  • 访问次数: 222
  • 注册日期: 2019-03-19
  • 最后登录: 2024-04-22

STM32模拟USB多点触控屏

开发准备

  • STM32的USB官方例程库JoyStickMouse
  • STM32F103RC
  • Windows7


代码修改

1.usb_pwr.c

RESULT 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.c

void 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.c

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






三维半岛官网: http://www.thanksview.com

进入首页