USB HID通信记录

最近在封装一个使用HT42B564-x作为通信芯片的模块。
在之前的客户端中进行适配添加。

 

首先HT42B564-x具有全双工的异步串行通信接口,内置了UART功能。默认采用9600波特率进行通信。

如果需要改变波特率,需要采用接口进行修改。客户端底层通信使用的微软的HIDSDI的通信模块(HIDSDI.h)。提供了基础的配置接口

https://docs.microsoft.com/zh-cn/windows-hardware/drivers/ddi/_hid/

此处可以通过下面两个接口获取和设置波特率等相关的通信参数

BOOLEAN __stdcall
HidD_GetInputReport (
   IN    HANDLE   HidDeviceObject,//通信句柄
   OUT   PVOID    ReportBuffer,//接收数据对象的地址
   IN    ULONG    ReportBufferLength//数据长度
   );
BOOLEAN __stdcall
HidD_SetFeature (
IN HANDLE HidDeviceObject,//通信句柄
IN PVOID ReportBuffer,//设定的参数地址
IN ULONG ReportBufferLength//参数长度
);

  //设置波特率 需要根据具体的通信协议设定值
 BYTE buf[9] = { 0x50, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x03, 0x00 };
 HidD_SetFeature(_hdev, buf, sizeof(buf));

建议先用GetFeature读出来,然后在修改对应的波特率部分的参数。一般是数组第2位到第5位

例如:

可以通过下面两个接口获取和设置通信缓存区的大小(一般来说都是默认32个字节)

BOOLEAN __stdcall
HidD_GetNumInputBuffers (
    IN  HANDLE  HidDeviceObject,//通信句柄
    OUT PULONG  NumberBuffers//接收缓存区大小的对象地址
    );
BOOLEAN __stdcall
HidD_SetNumInputBuffers (
    IN  HANDLE HidDeviceObject,//通信句柄
    OUT ULONG  NumberBuffers//写入的具体缓存区大小
    );
//配置缓存区
HidD_SetNumInputBuffers(_hdev, 64);

 

在查找后创建设备通信句柄时使用CreateFile,非UNICODE编码下实际就是CreateFileA,需要注意dwFlagsAndAttributes这个值的设定,用于控制异步通信模式:

 CreateFileA(
  __in LPCSTR lpFileName,
  __in DWORD dwDesiredAccess,
  __in DWORD dwShareMode,
  __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  __in DWORD dwCreationDisposition,
  __in DWORD dwFlagsAndAttributes,
  __in_opt HANDLE hTemplateFile
  );


devHandle = CreateFile(SPDeviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, m_dwFlagsAndAttributes,//异步通信,定义:m_dwFlagsAndAttributes(FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED) 0);

发送数据使用WriteFile进行写入

//同样定义一个m_dwFlagsAndAttributes
//同步方式
if ((m_dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED) != FILE_FLAG_OVERLAPPED)
    return WriteFile(_dev, _buf, _buf_len, &nWrite, nullptr) ? nWrite : UErr::Failed;

//异步 需要个一个OVERLAPPED的对象
OVERLAPPED overlap;
memset(&overlap, 0, sizeof(overlap));
//overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //如果出现错误码87 可以试试打开
auto r = WriteFile(_dev, _buf, _buf_len, &nWrite, &overlap);

读取数据使用

//目前我们使用下面这个接口获取数据
//return AsynchReadThreadProc(_dev, _buf, _buf_len, _timeout);

DWORD nRead = 0;
chr::timer<int> tt(_timeout);

//同步方式
if ((m_dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED) != FILE_FLAG_OVERLAPPED)
    return ReadFile(_dev, _buf, _buf_len, &nRead, nullptr) ? nRead : UErr::Failed;

//异步方式
OVERLAPPED overlap;
memset(&overlap, 0, sizeof(overlap));
overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

auto r = ReadFile(_dev, _buf, _buf_len, &nRead, &overlap);

 

posted @ 2022-03-09 17:41  蓦然而然  阅读(267)  评论(0编辑  收藏  举报