打印
[AT32F405]

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

[复制链接]
157|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tinnu|  楼主 | 2024-5-15 20:32 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
### 功能简介
  • 基于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[8] = {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[FT5406_MAX_TOUCHES])
{
  int32_t ret = 1;
  uint8_t touch_buf[FT5406_TOUCH_DATA_LEN] = {0};
  uint8_t tx_buf[8] = {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[i].TOUCH_ID = TOUCH_POINT_GET_ID(touch_data->TOUCH[i]);
      touch_array[i].TOUCH_EVENT = TOUCH_POINT_GET_EVENT(touch_data->TOUCH[i]);
      touch_array[i].TOUCH_X = TOUCH_POINT_GET_X(touch_data->TOUCH[i]);
      touch_array[i].TOUCH_Y = TOUCH_POINT_GET_Y(touch_data->TOUCH[i]);
    }

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

  return 0;
}




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


  •         设备描述符

        
ALIGNED_HEAD static uint8_t g_usbd_descriptor[USB_DEVICE_DESC_LEN] 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[USBD_CUSHID_CONFIG_DESC_SIZE] 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[USBD_CUSHID_SIZ_REPORT_DESC] ALIGNED_TAIL =...



  • 将读取到的FT5406数据转化为 HID 协议


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



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



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

68

帖子

0

粉丝