Создание USB дескрипторов для класса Custom HID.

STM32Cube USB

Доброго дня всем посетителям и читателям нашего сайта! Наконец-то, после длительного летнего перерыва, возобновляется работа над новыми статьями 🙂 Тем накопилось очень много, темы абсолютно разные, так что в ближайшее время, надеюсь каждый найдет что-то интересное для себя. И сегодня мы начнем обсуждать реализацию класса USB HID для наших любимых микроконтроллеров STM32. Почему начнем? Просто я решил, что для одной статьи тут будет многовато всего, поэтому их будет две или три, так что давайте приступать!

Итак, по старой доброй традиции разберемся с инструментарием… Я буду использовать отладочную плату с микроконтроллером STM32F103VET6, а для создания проекта мы задействуем набирающий все большую популярность STM32CubeMx.

Запускаем Cube, создаем новый проект (на этих шагах я не останавливаюсь, все уже разобрано в мини-цикле статей, посвященных этой теме на нашем сайте – их можно найти в рубрике STM32CubeMx). Включаем только то, что нам понадобится для решения непосредственно сегодняшней задачи, ничего лишнего:

Работа с USB HID в STM32CubeMx.

Кроме того, на моей плате есть вот такая фишка:

Подключение отладочной платы по USB

Поэтому для того, чтобы подключение по USB в принципе могло работать мне надо подать на PC13 напряжение низкого уровня, чтобы открыть транзистор.

В настройках тактирования нам необходимо обеспечить 48 МГц для работы USB. Тут ничего сложного, просто подбираем нужные значения умножителей и делителей частоты и не забываем активировать внешний кварц, который мы уже подключили в предыдущем окне:

Настройки тактирования STM32

Переходим на вкладку Configuration, но там все оставляем в первозданном виде. Разве что можно зайти в настройки USB_Device и посмотреть значения PID и VID, они могут нам пригодиться впоследствии для того, чтобы проверить, действительно ли наше устройство успешно подключилось к компьютеру. Но не будем забегать вперед, а просто запомним или запишем эти значения. По умолчанию они такие:

  • PID – 22352 (0x5750)
  • VID – 1155 (0x483)

USB дескрипторы устройства.

Работу в Cube на этом заканчиваем, генерируем файлы проекта и переходим в IAR (ну или Keil, у каждого своя IDE 🙂 ). Мы можем прошить полученную программу в микроконтроллер, но, к сожалению, это нам ничего не даст – устройство определится в системе, но работать не будет, а в диспетчере устройств мы увидим ошибку – “Сбой запроса дескриптора устройства”. И эта ситуация как ни парадоксально абсолютно правильна и логична. Дело в том, что дескриптор для нашего Custom HID устройства мы должны создать самостоятельно и добавить в наш сгенерированный проект. Этим мы сейчас и займемся.

Всего есть три USB дескриптора, которые отвечают за подключение к ПК:

  • дескриптор устройства
  • дескриптор конфигурации
  • дескриптор репорта

Дескриптор устройства описан в файле usbd_desc.c и выглядит следующим образом:

/* USB Standard Device Descriptor */
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
	0x12,                       /*bLength */
	USB_DESC_TYPE_DEVICE,       /*bDescriptorType*/
	0x00,                       /*bcdUSB */
	0x02,
	0x00,                       /*bDeviceClass*/
	0x00,                       /*bDeviceSubClass*/
	0x00,                       /*bDeviceProtocol*/
	USB_MAX_EP0_SIZE,           /*bMaxPacketSize*/
	LOBYTE(USBD_VID),           /*idVendor*/
	HIBYTE(USBD_VID),           /*idVendor*/
	LOBYTE(USBD_PID_FS),         /*idVendor*/
	HIBYTE(USBD_PID_FS),         /*idVendor*/
	0x00,                        /*bcdDevice rel. 2.00*/
	0x02,
	USBD_IDX_MFC_STR,            /*Index of manufacturer  string*/
	USBD_IDX_PRODUCT_STR,        /*Index of product string*/
	USBD_IDX_SERIAL_STR,         /*Index of serial number string*/
	USBD_MAX_NUM_CONFIGURATION   /*bNumConfigurations*/
}; /* USB_DeviceDescriptor */

В принципе здесь все снабжено комментариями, все значения стандартные, ну и мы собственно, здесь ничего трогать сейчас не будем, а двинемся дальше. Дескриптор конфигурации мы можем найти в файле usbd_customhid.c:

/* USB CUSTOM_HID device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
	0x09,                        /* bLength: Configuration Descriptor size */
	USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
	USB_CUSTOM_HID_CONFIG_DESC_SIZ,
	/* wTotalLength: Bytes returned */
	0x00,
	0x01,                        /* bNumInterfaces: 1 interface */
	0x01,                        /* bConfigurationValue: Configuration value */
	0x00,                        /* iConfiguration: Index of string descriptor describing
	                                the configuration */
	0xC0,                        /* bmAttributes: bus powered */
	0x32,                        /* MaxPower 100 mA: this current is used for detecting Vbus */

	/************** Descriptor of CUSTOM HID interface ****************/
	/* 09 */
	0x09,                        /*bLength: Interface Descriptor size*/
	USB_DESC_TYPE_INTERFACE,     /*bDescriptorType: Interface descriptor type*/
	0x00,                        /*bInterfaceNumber: Number of Interface*/
	0x00,                        /*bAlternateSetting: Alternate setting*/
	0x02,                        /*bNumEndpoints*/
	0x03,                        /*bInterfaceClass: CUSTOM_HID*/
	0x00,                        /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
	0x00,                        /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
	0,                           /*iInterface: Index of string descriptor*/
	/******************** Descriptor of CUSTOM_HID *************************/
	/* 18 */
	0x09,                        /*bLength: CUSTOM_HID Descriptor size*/
	CUSTOM_HID_DESCRIPTOR_TYPE,  /*bDescriptorType: CUSTOM_HID*/
	0x11,                        /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/
	0x01,
	0x00,                        /*bCountryCode: Hardware target country*/
	0x01,                        /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/
	0x22,                        /*bDescriptorType*/
	USBD_CUSTOM_HID_REPORT_DESC_SIZE, /*wItemLength: Total length of Report descriptor*/
	0x00,
	/******************** Descriptor of Custom HID endpoints ********************/
	/* 27 */
	0x07,                        /*bLength: Endpoint Descriptor size*/
	USB_DESC_TYPE_ENDPOINT,      /*bDescriptorType:*/
	CUSTOM_HID_EPIN_ADDR,        /*bEndpointAddress: Endpoint Address (IN)*/
	0x03,                        /*bmAttributes: Interrupt endpoint*/
	CUSTOM_HID_EPIN_SIZE,        /*wMaxPacketSize: 2 Byte max */
	0x00,
	0x20,                        /*bInterval: Polling Interval (20 ms)*/
	/* 34 */

	0x07,                        /* bLength: Endpoint Descriptor size */
	USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: */
	CUSTOM_HID_EPOUT_ADDR,       /*bEndpointAddress: Endpoint Address (OUT)*/
	0x03,                        /* bmAttributes: Interrupt endpoint */
	CUSTOM_HID_EPOUT_SIZE,       /* wMaxPacketSize: 2 Bytes max  */
	0x00,
	0x20,                        /* bInterval: Polling Interval (20 ms) */
	/* 41 */
};

В общем-то здесь тоже инженеры и программисты ST позаботились о том, чтобы хорошенько все прокомментировать, поэтому я не буду останавливаться на каждом поле (если возникнут вопросы или что-то не будет работать, пишите в комментариях, обязательно помогу 🙂 ). Отдельно стоит обратить внимание на CUSTOM_HID_EPOUT_SIZE. В файле usbd_customhid.h находим:

define CUSTOM_HID_EPOUT_SIZE                                    0x02

Эта константа определяет максимальный размер пакетов, которые будут использоваться при обмене данными с ПК. Давайте поставим 4 байта. Но не забывайте, что по стандарту максимальный размер пакета составляет 64 байта (0x40), больше ставить не рекомендую 🙂

С двумя из упомянутых USB дескрипторов разобрались, теперь настала очередь третьего. Он определен в файле usbd_custom_hid_if.c:

__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
	/* USER CODE BEGIN 0 */
	0x00,
	/* USER CODE END 0 */
	0xC0 /* END_COLLECTION */
};

Как видите он абсолютно пуст, поэтому наше устройство и не смогло определиться в системе как положено. Так что давайте разберемся и реализуем дескриптор репорта.

Что такое в принципе репорт?

Все дело в том, что ПК и наше устройство не просто кидают друг другу байты данных, а обмениваются пакетами, имеющими четко определенную структуру. Идентификация пакета происходит по первому байту, который представляет из себя ID репорта. Перед нами стоит задача отправлять данные хосту, а также принимать данные, передающиеся в обратном направлении. Поэтому мы определим два репорта – на прием и на передачу. Пусть на передачу у нас будет репорт с ID = 1, а на прием репорт с ID = 2:

__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
	/* USER CODE BEGIN 0 */ 
	0x06, 0x00, 0xff,            // USAGE_PAGE (Generic Desktop)
	0x09, 0x01,                  // USAGE (Vendor Usage 1)
	
	// System Parameters
	0xa1, 0x01,                  // COLLECTION (Application)
	0x85, 0x01,                  // REPORT_ID (1)
	0x09, 0x01,                  // USAGE (Vendor Usage 1)
	0x15, 0x00,                  // LOGICAL_MINIMUM (0)
	0x25, 0x01,                  // LOGICAL_MAXIMUM (1)
	0x75, 0x08,                  // REPORT_SIZE (8)
	0x95, 4,                     // REPORT_COUNT (4)
	0xb1, 0x82,                  // FEATURE (Data,Var,Abs,Vol)
	0x85, 0x01,                  // REPORT_ID (1)
	0x09, 0x01,                  // USAGE (Vendor Usage 1)
	0x91, 0x82,                  // OUTPUT (Data,Var,Abs,Vol)

	0x85, 0x02,                  // REPORT_ID (4)
	0x09, 0x02,                  // USAGE (Vendor Usage 4)
	0x75, 0x08,                  // REPORT_SIZE (8)
	0x95, 4,                     // REPORT_COUNT (4)
	0x81, 0x82,                  // INPUT (Data,Var,Abs,Vol)
	/* USER CODE END 0 */
	0xC0 /* END_COLLECTION */
};

Не забываем изменить размер массива дескриптора – USBD_CUSTOM_HID_REPORT_DESC_SIZE, а заодно и USBD_CUSTOMHID_OUTREPORT_BUF_SIZE:

#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE                        4
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE                         38

Ну и в файле usbd_customhid.h также устанавливаем значения, соответствующие нашему режиму передачи и приема (а именно передача и прием по 4 байта):

#define CUSTOM_HID_EPIN_ADDR                                     0x81
#define CUSTOM_HID_EPIN_SIZE                                     4

#define CUSTOM_HID_EPOUT_ADDR                                    0x01
#define CUSTOM_HID_EPOUT_SIZE                                    4

И вот теперь уже мы можем попробовать собрать проект и запрограммировать микроконтроллер. В результате устройство должно успешно определиться в диспетчере устройств:

USB Custom HID

Соответственно, значения PID и VID у этого устройства соответствуют тем, которые мы задали в STM32CubeMx при создании и настройке проекта.

Таким образом, на сегодня мы на этом заканчиваем. Сразу расскажу, чем мы будем заниматься в следующей статье 🙂 Во второй части, посвященной USB Custom HID мы разберемся как принимать и передавать данные, а в третьей части мы напишем программку для ПК, которая собственно и будет осуществлять подключение и обмен данными с нашим устройством. До скорой встречи!

Поделиться!

Подписаться
Уведомление о
guest
70 Комментарий
старее
новее большинство голосов
Inline Feedbacks
View all comments
Николай
Николай
4 лет назад

Спасибо большое! Отличная статья!

Alexey
Alexey
4 лет назад

Спасибо, будем ждать! Программа для ПК будет на QT?

Haamu
Haamu
4 лет назад

Еще б не помешало поподробнее рассказать про дескриптор репорта, как его формировать и какие поля за что отвечают.

Паша
Паша
4 лет назад

USBD_CUSTOM_HID_REPORT_DESC_SIZE, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE я нашел только в файле usbd_conf.h, т.к. в статье не указывалось в каком файле они именно. И после компиляции vid pid почему то поменялись хотя размещение STM32 Custom Human interface
За статью большое спасибо!

Сергей
Сергей
4 лет назад

А где продолжение?

Sasha95
Sasha95
4 лет назад

Вы неправильно написали , у вас написано
” ubd_desc.c ” , а нужно “usbd_desc.c”

Sergey
Sergey
4 лет назад

С удовольствием прочитал и повторил все манипуляции с файлами для для платы STM32F4291-DISCO, запрограммировал контроллер, результат нулевой. Устройство совсем не определяется. Может быть на плате тоже есть какая-либо фишка. Подскажите.
Буду очень благодарен.
Сергей

Sergey
Sergey
4 лет назад

Вы оказались правы. На плате свободен только USB_OTG_HS, а я пытался задействовать USB_OTG_FS, потому ничего и не получалось.
Спасибо.

Egor
Egor
4 лет назад

Использую stm32f4discovery. У Вас написано, что для Вашей платы необходимо подать небольшое напряжение на PC13. Вопрос как его подать? И второй вопрос, для моей платы куда надо подать напряжение. Я поискал в интернете, нашел вот такую схему вроде как моей платы: http://www.micromouseonline.com/wp/wp-content/uploads/2013/05/stm32f4discovery-usb-schematic.png , получается мне на PD5 надо будет подавать напряжение? Так же при компиляции полученного проекта в IAR ругается на добавленный в дискриптор репорта код вот такими обидными словами «Error[Pe146]: too many initializer values»

Алексей
Алексей
4 лет назад

Скажите пожалуйста. Что нужно добавить в ваш репорт (который выложен в статье) чтобы расширить размер передаваемых данных?

Алексей
Алексей
4 лет назад

Через ваш репорт нельзя передать в одном байте 0xff.

Alex
4 лет назад

Но вот хочу я передать текст “ABCDE” А репорт позволяет передавать в одном байте только 1 или 0.
Buffer[0] = d; // передаваемый байт
d может быть 1 или 0. А если я захочу d сделать больше 1 то репорт не передаст его. Я пока не очень разобрался с репортами но вроде как нужно репорт дополнить LOGICAL_MINIMUM и LOGICAL_MAXIMUM.

Антон
Антон
4 лет назад

я сделал как написано в статье . у меня stm32f417 . можете подсказать где моя ошибка ?
Буду очень благодарен.

Антон
Антон
4 лет назад

не устанавливается драйвера Custom HID , отказ выдает . десять раз перепробовал , все равно результат нулевой . (сделал все как по статьи). схему посмотрел, нечего лишного не подключен к USB. (вот моя плата http://starterkit.ru/html/index.php?name=shop&op=view&id=68) спасибо что выделили время и ответили на мой вчерашний вопрос. Буду благодарен.

LEV
LEV
4 лет назад

Возникла проблема при компиляции проекта:

__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
/* USER CODE BEGIN 0 */
0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Vendor Usage 1)
// System Parameters
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x01, // REPORT_ID (1)
0x09, 0x01, // USAGE (Vendor Usage 1)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 4, // REPORT_COUNT (4)
0xb1, 0x82, // FEATURE (Data,Var,Abs,Vol)
0x85, 0x01, // REPORT_ID (1)
0x09, 0x01, // USAGE (Vendor Usage 1)
0x91, 0x82, // OUTPUT (Data,Var,Abs,Vol)

0x85, 0x02, // REPORT_ID (4)
0x09, 0x02, // USAGE (Vendor Usage 4)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 4, // REPORT_COUNT (4)
0x81, 0x82, // INPUT (Data,Var,Abs,Vol)
/* USER CODE END 0 */
0xC0 /* END_COLLECTION */

};

ошибка: ..\Src\usbd_custom_hid_if.c(45): error: #146: too many initializer values

Подскажите пожалуйста. Использую CubeMX 4.10 и Keil 5.16a.

LEV
LEV
4 лет назад

Разобрался, надо было сначала значения поменять #define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 4
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 38.

LEV
LEV
4 лет назад

Разобрался, надо было сначала значения поменять #define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE

Albertas
Albertas
4 лет назад

Spasibo bolshoe!

Lutshee chto nashol v seti pro custom hid i STM32CubeMX !

Вася
Вася
4 лет назад

спасибо. Информативно и доступно. от души

Aleksey
Aleksey
4 лет назад

Уважаемый Aveal. Вот такой вопрос.
Есть 2 платы stm324x9I и stm3220G. На одной реализовал HID Device (просто HID, не Custom HID), на второй Host Supporting ALL Classes. Все понятно, все работает. А вот когда реализую Custom HID, Host не определяет тип HID устройства: Device not supporting HID class.

Что делать? как это исправит?

Aleksey
Aleksey
Reply to  Aveal
4 лет назад

Да

UtuG
4 лет назад

где можно исходники можно посмотреть? не отображается в диспетчере устройств. работаю с coocox. Ошибок не выдает, но и не работает. Спасибо!

Дмитрий
Дмитрий
4 лет назад

Приветствую. Есть пара вопросов по режимам работы USB
1) В чем разница междцу HID и custom HID? Где какой нужен?
2) Что такое режим DFU? В сети по нему мало информации

Евгений
Евгений
4 лет назад

Уважаемый Aveal! Если можно, то прошу дать пару-другую примеров, как через дескриптор репорта задавать размер передаваемых данных, например, 8, 12, 16, 24, 32 и 64 байта, и заодно прошу поподробнее расписать поля этого дескриптора. Буду очень благодарен, если Вы это сделаете…

Олег
Олег
3 лет назад

Здравствуйте, подскажите пжл.
Если с этим понятно,
CUSTOM_HID_EPIN_SIZE 4
CUSTOM_HID_EPOUT_SIZE 4
Это wMaxPacketSize, хотим гонять маленькие пачки – ставим поменьше, большие – ставим побольне, например 0x40

То с этой константой USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 4
всё мутно и в голове каша.
Везде пишут “определяет размер буфера приема данных из компьютера”, или Maximum report buffer size (OUT ENDPOINT).

И какой его нужно ставить? Если я собираюсь гонять пачки по 64 байта, мне обязательно увеличивать этот буфер, или может там какая то хитрая схема?
Если не сложно, поделитесь мыслями и направьте на путь истинный))
Заранее спасибо!

Ilya
Ilya
3 лет назад

Здравствуйте. Создал проект в CubeMX однако в сгенерированном проекте отсутствую файлы usbd_hustomhid.c и usbd_custom_hid_if.c. Подскажите что можно сделать. И будет ли статься про HID на SPL. Спасибо.

Ilya
Ilya
Reply to  Aveal
3 лет назад

спасибо)

Николай
Reply to  Ilya
4 месяцев назад

У Cube нет недоброй особенности. Есть невнимательность пользователей. Вы вместо USB Custom HID выбрали USB HID в настройках Middleware. Вот файлы Custom и не были включены. Вот, если вопрос еще актуален.

Ultrasat
3 лет назад

Большое спасибо за статью. НЕ подскажете где почитать описание протокола USB (на русском либо англ), чтобы понять назначение многочисленных значений параметров допустим функции – CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] ??

И может подскажете что в языке Си обозначает это __ALIGN_BEGIN перед типом значения этой функции?

Спасибо. С этого сайта началось мое знакомство с STM32))

Ultrasat
Reply to  Aveal
3 лет назад

Спасибо за ответ.
Нашел.
http://www.usb.org/developers/docs/
Но это капец….столько читать.

Илья
Илья
3 лет назад

Здравствуйте, спасибо за статью, очень интересная, не могу разобраться, как изменить имя устройства, подскажите пожалуйста. Заранее спасибо.

GLoo,
GLoo,
3 лет назад

Приветствую. Подскажите, что может быть не так. Использовал SW4STM32.
Сделал все как описано, определяется. HID REPORT использовал из своего проекта на PIC18
Пытаюсь слать данные
(CreateFile, WriteFile), но внутри static int8_t CUSTOM_HID_OutEvent_FS (uint8_t event_idx, uint8_t state) ничего не происходит, также пробовал HID Terminal от MikroC, также никакой реакции, иногда происходит зависание.

Вадим
Вадим
2 лет назад

Уважаемый Aveal, спасибо за статью. Очень информативно и доступно.
Не доводилось ли реализовывать какой-либо кастомный класс USB? STM в своей документации поясняет, что это возможно: http://www.st.com/content/ccc/resource/technical/document/user_manual/cf/38/e5/b5/dd/1d/4c/09/DM00108129.pdf/files/DM00108129.pdf/jcr:content/translations/en.DM00108129.pdf
Но как-то вскользь. Пытаюсь реализовать кастомный класс на STM32F407. Пока есть затруднения, как отредактировать шаблон.

Cahes
Cahes
2 лет назад

Ошибка:
…рации мы можем найти в файле usbd_Hustomhid.c:…

Правильно:
…usbd_Customhid.h…

Сергей
Сергей
2 лет назад

Мы правим define
CUSTOM_HID_EPIN_SIZE 4
CUSTOM_HID_EPOUT_SIZE 4

Но после следующей генерации куба они затруться на другие значения. Как этого можно избежать? Может есть эти настройки в кубе где-то?

Владимир
Владимир
2 лет назад

Здравствуйте.
У меня в “кубе” раздел USB_DEVICE не активен.
Пробовал для разных чипов.
Что надо сделать?

И скажите ещё, для платы stm32f4 disco много ли переделывать надо будет?

Владимир
Владимир
2 лет назад

Большое спасибо.
Включил. Также включил опцию Activate_VBUS.
Это правильно?
И ещё вопрос имеется.
Вы писали “нам необходимо обеспечить 48 МГц для работы USB”
Я на вкладке “clock conf” такого поля (USB FS Clock) не вижу.
Тоже что-то включить надо?

Andrius
1 год назад

Спасибо за статю!

Александр
Александр
1 год назад

Добрый день Aveal. Спасибо за сведения.
Не подскажете такой вопрос: После нескольких, иногда удачных, попыток подключить USB HID на STM32F7 последние разы получаю сообщение: Система Windows остановила это устройство, так как оно сообщило о возникновении неполадок. (Код 43). И во вкладке События показана дата последнего успешного определения устройства 21.03.2019. Дескрипторы менялись после этого для приведения к собственным нуждам.

Сергей
Сергей
1 год назад

Здравствуйте!
А почему надо прописывать
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 38
а не 39?
Последний байт 0xC0 /* END_COLLECTION */ не учитывается что ли?

Сергей
Сергей
Reply to  Aveal
1 год назад

Пересчитал, стало действительно получаться 38 байт. Прощу прощения(((

Сергей
Сергей
1 год назад

Пересчитал, стало действительно получаться 38 байт. Прощу прощения(((

Присоединяйтесь!

Profile Profile Profile Profile Profile
Vkontakte
Twitter

Язык сайта

Сентябрь 2020
Пн Вт Ср Чт Пт Сб Вс
 123456
78910111213
14151617181920
21222324252627
282930  

© 2013-2020 MicroTechnics.ru