设计介绍
使用南京沁恒微电子研发的国产芯片CH643为主控MCU模拟键盘设备;CH643是基于青稞RISC-V内核设计的RGB显示驱动工业级微控制器,其内置RGB三色LED脉冲宽度调制LED_PWM可以轻松实现RGB灯效的控制,作为键盘主控具有独特优势;此设计介绍使用CH643简单模拟一个键盘设备,并通过USB_FS全速接口与PC主机通信,用端点1上传键盘键值。
USB_FS全速接口初始化
USBFS_RCC_Init( ); // 开启USB时钟
USBFS_Device_Init( ENABLE , PWR_VDD_SupplyVoltage()); // USB设备初始化
USB设备端口初始化
void USBFS_Device_Endp_Init( void )
{
USBFSD->UEP4_1_MOD = USBFS_UEP1_TX_EN; // 使能端点1的发送
USBFSD->UEP0_DMA = (uint32_t)USBFS_EP0_Buf; // 端点缓冲区的起始地址
USBFSD->UEP1_DMA = (uint32_t)USBFS_EP1_Buf;
USBFSD->UEP0_CTRL_H = USBFS_UEP_R_RES_ACK | USBFS_UEP_T_RES_NAK;
USBFSD->UEP1_CTRL_H = USBFS_UEP_T_RES_NAK;
}
描述符的实现
设备描述符
const uint8_t MyDevDescr[ ] =
{
0x12, // bLength 描述符长度,18字节
0x01, // bDescriptorType 描述符类型编码,设备描述符0x01
0x00, 0x02, // bcdUSB 协议类型
0x00, // bDeviceClass 设备类型,此处为0,在接口描述符中描述
0x00, // bDeviceSubClass 设备子类型
0x00, // bDeviceProtocol 子类型协议
0x40, // bMaxPacketSize0 端点0最大包长64字节
0x01, 0x00, // idVendor VID
0x02, 0x00, // idProduct PID
0x00, 0x01, // bcdDevice 设备版本号
0x01, // iManufacturer 厂商字符串索引
0x02, // iProduct 产品字符串索引
0x03, // iSerialNumber 设备序列号字符串索引
0x01, // bNumConfigurations 表示设备有多少种配置
};
配置描述符集合
const uint8_t MyCfgDescr[ ] =
{
/* Configuration Descriptor */
0x09, // bLength 描述符长度,9字节
0x02, // bDescriptorType 描述符类型,配置描述符
0x22, 0x00, // wTotalLength 配置集合总长度
0x01, // bNumInterfaces 接口数量
0x01, // bConfigurationValue 配置的值
0x00, // iConfiguration 该配置的字符串索引
0xA0, // bmAttributes: Bus Powered; Remote Wakeup 设备的一些特性,如支持远程唤醒
0x32, // MaxPower: 100mA 从总线获取最大100mA电流
/* Interface Descriptor (Keyboard) */
0x09, // bLength 描述符长度,9字节
0x04, // bDescriptorType 描述符类型,接口描述符
0x00, // bInterfaceNumber 接口0
0x00, // bAlternateSetting 接口备用编号
0x01, // bNumEndpoints 端点数量,1
0x03, // bInterfaceClass 接口类型,HID接口类
0x01, // bInterfaceSubClass 接口子类,BIOS子类(键鼠属于此类)
0x01, // bInterfaceProtocol: Keyboard 接口子类协议,键盘
0x00, // iInterface 接口字符串索引
/* HID Descriptor (Keyboard) */
0x09, // bLength 描述符长度,9字节
0x21, // bDescriptorType 描述符类型,HID描述符
0x11, 0x01, // bcdHID 协议版本
0x00, // bCountryCode 设备适用国家
0x01, // bNumDescriptors 下级描述符数量
0x22, // bDescriptorType 下级描述符类型,0x22为报告描述符
0x3E, 0x00, // wDescriptorLength 下级描述符长度
/* Endpoint Descriptor (Keyboard) */
0x07, // bLength 描述符长度,7字节
0x05, // bDescriptorType 描述符类型,端点描述符
0x81, // bEndpointAddress: IN Endpoint 1 端点1,输入端点
0x03, // bmAttributes 端点类型,中断端点
0x10, 0x00, // wMaxPacketSize 端点最大包长
0x01, // bInterval: 1mS 端点查询时间,1ms
};
报告描述符
/* Keyboard Report Descriptor 报告描述符(键盘)*/
const uint8_t KeyRepDesc[ ] =
{
/*用途为通用桌面键盘*/
0x05, 0x01, // 用途页(通用桌面),0x01表示后面跟1字节数据
0x09, 0x06, // 0x06表示接下来的集合用途(键盘)
0xA1, 0x01, // 0x01表示该集合是一个应用集合(应用程序)
/*用途为8个特殊按键*/
0x05, 0x07, // 用途页(密钥代码),0x07表示用途为键盘
0x19, 0xE0, // 最小使用值(224),实际上是键盘Ctrl键
0x29, 0xE7, // 最大使用值(231),实际上是键盘右GUI(WIN)键
0x15, 0x00, // 逻辑最小值(0),就是返回数据域的值最小为0
0x25, 0x01, // 逻辑最大值(1)
0x75, 0x01, // 报告大小(1),每个数据域的长度为1个位
0x95, 0x08, // 报告数量(8),数据域的数量为8个
0x81, 0x02, // 输入(数据、变量、绝对值)
/*保留字节(保留给OEM使用)*/
0x95, 0x01, // 报告数量(1),数据域数量为1个
0x75, 0x08, // 报告大小(8),每个数据域长度为8位
0x81, 0x01, // 输入(常量,即返回的数据一直为0)
/*用途为LED*/
0x95, 0x03, // 报告数量(3),数据域数量为3
0x75, 0x01, // 报告大小(1),每个数据域长度为1位
0x05, 0x08, // 用途页(LED)
0x19, 0x01, // 最小使用值(1)
0x29, 0x03, // 最大使用值(3)
0x91, 0x02, // 输出(数据、变量、绝对值)
0x95, 0x05, // 报告数量(5)
0x75, 0x01, // 报告大小(1)
0x91, 0x01, // 输出(常量、数组、绝对值)
/*用途为普通按键*/
0x95, 0x06, // 报告数量(6)
0x75, 0x08, // 报告大小(8)
0x26, 0xFF, 0x00, // 逻辑最大值(255)
0x05, 0x07, // 用途页(密钥代码),键盘
0x19, 0x00, // 最小使用值(0)
0x29, 0x91, // 最大使用值(145)
0x81, 0x00, // 输入(数据、数组、绝对值)
0xC0 // 结束
};
键盘识别结果
程序参考
完整程序和CH643手册均可从南京沁恒官网下载参考;https://www.wch.cn/downloads/CH643EVT_ZIP.html
https://www.wch.cn/downloads/CH643RM_PDF.html
https://www.wch.cn/downloads/CH643DS0_PDF.html