tinnu 发表于 2024-5-15 20:32

【AT-START-F405测评】B1.主题帖:基于USB HID的触摸屏设计

### 功能简介

[*]基于USB HID协议,制作触摸屏驱动板
[*]触摸芯片为FT5406,支持最多5点触摸

### 开发简介

1. 创建 workbench 工程
基于VSCODE和EIDE在linux等跨平台上开发的操作详见上一篇帖子:
【AT-START-F405测评】A1.workbench + ATIDE / 纯VSOCDE+EIDE 开发环境搭建 点灯

- 在上一篇的帖子的基础上增加 USB 驱动、ACC 驱动、IIC驱动、USART驱动
    - 其中IIC驱动需要将引脚重映射

2. 按照上一篇帖子的方法,倒入工程到EIDE环境中。
    - 加入工程所需的库文件、USB驱动库、开发板驱动文件
    - 加入EIDE倒入时缺失的.s文件


3. I2C驱动介绍
    - FT5406的IIC 7位地址为0x38
    - 由于SDK库是使用8位地址操作,并且无需考虑读写位,在底层会自动值位
    - 初始化 FT5406 :对0地址写0
int32_t FT5406_Init(i2c_handle_type *hi2cx)
{
uint8_t tx_buf = {0x0, 0x0};
i2c_status_type i2c_status;

if ((i2c_status = i2c_master_transmit(hi2cx, (FT5406_I2C_ADDR << 1), tx_buf, 2, 0xFFFFFFF)) != I2C_OK)
{
    printf("err send\n");
}

return 0;
}


    - 读取触摸信息

int32_t FT5406_GetSingleTouch(i2c_handle_type *hi2cx, int *touch_count, touch_point_t touch_array)
{
int32_t ret = 1;
uint8_t touch_buf = {0};
uint8_t tx_buf = {0x1, 0x20};
i2c_status_type i2c_status;

if ((i2c_status = i2c_master_transmit(hi2cx, (FT5406_I2C_ADDR << 1), tx_buf, 1, 0xFFFFFFF)) != I2C_OK)
{
    ret = 0;
    printf("err send\n");
}
if ((i2c_status = i2c_master_receive(hi2cx, FT5406_I2C_ADDR << 1, touch_buf, FT5406_TOUCH_DATA_LEN, 0xFFFFFFF)) != I2C_OK)
{
    ret = 0;
    printf("err read\n");
}

if (ret == 1)
{
    ft5406_touch_data_t *touch_data = (ft5406_touch_data_t *)(void *)(touch_buf);
    int i;

    /* Decode number of touches */
    if (touch_count)
    {
      *touch_count = touch_data->TD_STATUS < 5 ? touch_data->TD_STATUS : 0;
    }

    /* Decode valid touch points */
    for (i = 0; i < *touch_count; i++)
    {
      touch_array.TOUCH_ID = TOUCH_POINT_GET_ID(touch_data->TOUCH);
      touch_array.TOUCH_EVENT = TOUCH_POINT_GET_EVENT(touch_data->TOUCH);
      touch_array.TOUCH_X = TOUCH_POINT_GET_X(touch_data->TOUCH);
      touch_array.TOUCH_Y = TOUCH_POINT_GET_Y(touch_data->TOUCH);
    }

    /* Clear vacant elements of touch_array */
    for (; i < FT5406_MAX_TOUCHES; i++)
    {
      touch_array.TOUCH_ID = 0;
      touch_array.TOUCH_EVENT = kTouch_Reserved;
      touch_array.TOUCH_X = 0;
      touch_array.TOUCH_Y = 0;
    }
}

return 0;
}




4. USB HID驱动介绍

[*]    由于FT5406支持最多5点触摸,因此HID协议的报告描述符也设置为5点。
[*]    基于例程库里面的 CUSTOM HID 例程,创建一个 hid_print 驱动文件
[*]    加入如下的 设备描述符、设备配置符、报告描述符



[*]      设备描述符

      
ALIGNED_HEAD static uint8_t g_usbd_descriptor ALIGNED_TAIL =
{
USB_DEVICE_DESC_LEN,                   /* bLength */
USB_DESCIPTOR_TYPE_DEVICE,             /* bDescriptorType */
0x10,                                  /* bcdUSB */
0x01,
0x00,                                  /* bDeviceClass */
0x00,                                  /* bDeviceSubClass */
0x00,                                  /* bDeviceProtocol */
USB_MAX_EP0_SIZE,                      /* bMaxPacketSize */
LBYTE(USBD_CUSHID_VENDOR_ID),               /* idVendor */
HBYTE(USBD_CUSHID_VENDOR_ID),               /* idVendor */
LBYTE(USBD_CUSHID_PRODUCT_ID),                /* idProduct */
HBYTE(USBD_CUSHID_PRODUCT_ID),                /* idProduct */
0x00,                                  /* bcdDevice rel. 2.00 */
0x00,
USB_MFC_STRING,                        /* Index of manufacturer string */
USB_PRODUCT_STRING,                  /* Index of product string */
USB_LANGID_STRING,                     /* Index of serial number string */
1                                    /* bNumConfigurations */
};



[*]设备配置符

ALIGNED_HEAD static uint8_t g_usbd_configuration ALIGNED_TAIL =
{
        // 配置描述符
USB_DEVICE_CFG_DESC_LEN,               /* bLength: configuration descriptor size */
USB_DESCIPTOR_TYPE_CONFIGURATION,      /* bDescriptorType: configuration */
LBYTE(USBD_CUSHID_CONFIG_DESC_SIZE),          /* wTotalLength: bytes returned */
HBYTE(USBD_CUSHID_CONFIG_DESC_SIZE),          /* wTotalLength: bytes returned */
0x01,                                  /* bNumInterfaces: 1 interface */
0x01,                                  /* bConfigurationValue: configuration value */
0x00,                                  /* iConfiguration: index of string descriptor describing
                                          the configuration */
0xA0,                                  /* bmAttributes: self powered and support remote wakeup */
0x32,                                  /* MaxPower 100 mA: this current is used for detecting vbus */

        // 接口描述符
USB_DEVICE_IF_DESC_LEN,                /* bLength: interface descriptor size */
USB_DESCIPTOR_TYPE_INTERFACE,          /* bDescriptorType: interface descriptor type */
0x00,                                  /* bInterfaceNumber: number of interface */
0x00,                                  /* bAlternateSetting: alternate set */
0x01,                                  /* bNumEndpoints: number of endpoints */
USB_CLASS_CODE_HID,                  /* bInterfaceClass: class code hid */
0x00,                                  /* bInterfaceSubClass: subclass code */
0x00,                                  /* bInterfaceProtocol: protocol code */
0x00,                                  /* iInterface: index of string descriptor */

        // HID类描述符
0x09,                                  /* bLength: size of HID descriptor in bytes */
HID_CLASS_DESC_HID,                  /* bDescriptorType: HID descriptor type */
LBYTE(CUSHID_BCD_NUM),
HBYTE(CUSHID_BCD_NUM),               /* bcdHID: HID class specification release number */
0x00,                                  /* bCountryCode: hardware target conutry */
0x01,                                  /* bNumDescriptors: number of HID class descriptor to follow */
HID_CLASS_DESC_REPORT,               /* bDescriptorType: report descriptor type */
        0x86, 0x01,                                                                                                                /* wDescriptorLength: total length of reprot descriptor */

        // 端点描述符
        0x07, 0x05, 0x81, 0x03, THIS_ENDP0_SIZE, 0x00, 0x0A,//端点描述符
};




[*]报告描述符(过长,这里省略,详见代码)


ALIGNED_HEAD uint8_t g_usbd_custom_hid_report ALIGNED_TAIL =...



[*]将读取到的FT5406数据转化为 HID 协议


    hidFlagLast = hidFlagNow;
    hidFlagNow = 0;
    for (size_t i = 0; i < 5; i++)
    {
      hidOneReport = &hidReport.w;
      hidOneReport->id = i;
      hidOneReport->isPressed = (touch_array.TOUCH_EVENT == kTouch_Down) || (touch_array.TOUCH_EVENT == kTouch_Contact);
      if (hidOneReport->isPressed)
      {
      hidOneReport->x = touch_array.TOUCH_X;
      hidOneReport->y = touch_array.TOUCH_Y;
      hidOneReport->w = 30;
      hidFlagNow++;
      }
      printf("%x,%x,%x,%x,%x\t", i, touch_array.TOUCH_EVENT,
             touch_array.TOUCH_ID, touch_array.TOUCH_X, touch_array.TOUCH_Y);
    }
    printf("\n");
    hidReport.num = hidFlagNow;


5. 驱动演示
    - 目前仅能在linux系统下驱动成功,可能是windows下需要打驱动和配置特殊的 product id 到设备描述符。
    - 演示:
    - 代码:mcu_at32f405_hid_touch_screen



页: [1]
查看完整版本: 【AT-START-F405测评】B1.主题帖:基于USB HID的触摸屏设计