Перейти к публикации

Рекомендованные сообщения

Опубликовано:

Неспешно копаюсь в теме.

 

1. Для ATmega32u4 я нашел такое: https://github.com/NicoHood/HID/wiki .

Сделать свой джойстик с этим - занятие порядка примерно той же сложности, что помигать светодиодиком. Проверяем в цикле датчики и сообщаем объекту, ну, а работать с shif registers и потенциометрами тоже проблем не составляет. С TLE5010 я тоже работал...

 

Есть надежда, что для других контроллеров тоже найдётся что-то подобное, но всерьёз не копался.

 

2. Но есть проблема с тем кодом - почему-то шесть осей, причём две почему-то восьмибитные. И автор всерьёз считает, что поддерживаются только 32 кнопки. Разобраться с этими ограничениями задача уже посложнее, чем помигать светодиодиками. И я пока в этом самом месте.

 

На горизонте маячат другие пункты:

 

3. Настройки. Включая калибровку и что к каким контактам подключено. Требуется писать какую-то программу, которая будет как-то с джойстиком общаться. Очевидно, можно работать по последовательному порту. Можно, но не очень удобно. Надо понимать, какому джойстику какой порт соответствует, и, возможно, настраивать параметры (скорость-чётность...). Есть ещё некий RawHID. Судя по описанию в wiki, автор с ним не справился (пишет про какие-то проблемы при совместном использовании gamepad и rawhid); если он не справился, то справлюсь ли я.

 

Другие контроллеры (BlackPill. STM32f411CEU6, STM32F401CCu6.)

4. У BluePill, кроме всего прочего, есть ещё некая особенность (по сравнению с Ардуиной) - по крайней мере, первую прошивку по USB просто так не сделать. https://github.com/FreeJoy-Team/FreeJoyConfiguratorQt способен выполнить вторую, но это тоже дополнительная сложность. Нужно ли это повторять это для BlackPill?

 

5. Про BlackPill пишут так:

https://hackaday.com/2021/01/20/blue-pill-vs-black-pill-transitioning-from-stm32f103-to-stm32f411/

It has a much better DMA design, so it can actually run at full bus speed. It also has more memory for USB packets, and it uses the memory more efficiently.
---
Better seems to be relative, it’s also more complex to program and has fewer endpoints available in device mode.
On the upside it supports host mode…
---
This depends on what you consider “better”.

The F401/F411 only support 3 endpoints per direction, which limits the number of CDC-ACM (serial) interfaces to 1. The L4xx e.g. support 6 EPs per direction, the F103 allows up to 16 Endpoints (any direction), so this is a significant step backwards.

 

Учитывая, что написано в https://github.com/NicoHood/HID/wiki/API-Documentation , всего 3 эндпойнта сейчас у меня вызывают беспокойство.

 

4. Платы на rp2040 дешёвые, эндпойнтов 16. Процесс прошивки очень удобен. Есть ещё интересный вариант плат с BT и WiFi. Интересно, насколько годится для джойстика Питон?

 

5. Платы на rp2350 сейчас дороговаты.

 

 

Опубликовано: (изменено)

"640к One endpoint ought to be enough for anybody" (С)

Учтите разные типы репортов  - с их помощью через одну точку можно делать почти всё.

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

 

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

В волшебных пузырьках рипортах - вся магия.

Изменено пользователем Alex_Oz
Опубликовано:
11.11.2024 в 14:11, vvm13ru сказал:

Неспешно копаюсь в теме.

ахах, ну добро пожаловать в клуб.

  • Нравится 1
  • Поддерживаю! 1
Опубликовано:

Пункт 2 я практически преодолел, т.е., ту библиотеку я слегка подправил и джойстик с восемью осями, четырьмя dPad'ами и больше чем 32 кнопками я теперь могу изобразить, но в целом тема (USB-программирование) - жуть. Хорошо, что мне не приходится заниматься этим по работе...

Опубликовано:

Про кнопки наврал. 8 16-битных осек и четыре dPad'а работают, но вот это изменение

	/* 32 Buttons */
	0x05, 0x09,							/*   USAGE_PAGE (Button) */
	0x19, 0x01,							/*   USAGE_MINIMUM (Button 1) */
//	0x29, 0x20,							/*   USAGE_MAXIMUM (Button 32) */
	0x29, 0x40,							/*   USAGE_MAXIMUM (Button 64) */
	0x15, 0x00,							/*   LOGICAL_MINIMUM (0) */
	0x25, 0x01,							/*   LOGICAL_MAXIMUM (1) */
	0x75, 0x01,							/*   REPORT_SIZE (1) */
//	0x95, 0x20,							/*   REPORT_COUNT (32) */
	0x95, 0x40,							/*   REPORT_COUNT (64) */
	0x81, 0x02,							/*   INPUT (Data,Var,Abs) */

оказалось плачевным. Хотя всё по той же логике менял.

Опубликовано:

Забавно, что моя прошивка-псевдоджойстик заработала на той подделке "STM32F103C8T6", что прислал мне MYCYJIbMAHUH.

(Она изображает из себя джойстик и мигает светодиодиком).

Freejoy на ней не работает.

 

Наверное, я сделал что-то не так ;-).

Например, на данный момент я не понимаю, как у знатоков положено делать Clock Configuration. По виду. у меня контроллер работает на 48 мегагерц вместо 72, и разница может быть в этом.

 

 

image.thumb.png.df53690f341d3857df1f55facbb6a81f.png

Опубликовано:
15 часов назад, vvm13ru сказал:

Freejoy на ней не работает.

мелкие проекты с парой функций будут работать на подделках, как и версия FJ 1.5 и меньше, а как попытаешь больше возможностей контроллера использовать, то окажется, что половина не работает 

 image.thumb.png.49e5ffd5eb47c70da4195b748fa6aeb0.png

 

Опубликовано:

Забабацал такой дескриптор:

/** Usb HID report descriptor. */
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
  /* USER CODE BEGIN 0 */
	
/* 
	Данные с нашей панели обновляются не быстро. Чтобы было быстро, 
	в файлах usbd_customhid.h нужно поменять 
	#define CUSTOM_HID_EPIN_SIZE на максимальное значение 0x40, 
	#define CUSTOM_HID_EPOUT_SIZE тоже поставить 0x40. 
	В файле usbd_customhid.c найти комментарии в дескрипторе эндпойнтов "/ * bInterval: Polling Interval (20 ms) * /" 
	и поменять байт дескриптора на 0x01 для каждого эндпойнта, всего два раза. Что будет соответствовать 1 мс обмена данными.
*/	
	
/* Gamepad with 126 buttons and 8 axis*/
      0x05, 0x01,                         /* USAGE_PAGE (Generic Desktop) */
      0x09, 0x04,                         /* USAGE (Joystick) */
      0xa1, 0x01,                         /* COLLECTION (Application) */
      0x85, HID_REPORTID_GAMEPAD,         /*   REPORT_ID */
      // 8

      /* 128 Buttons */
      0x05, 0x09,                         /*   USAGE_PAGE (Button) */
      0x19, 0x01,                         /*   USAGE_MINIMUM (Button 1) */
      0x29, 0x80,                         /*   USAGE_MAXIMUM (Button 128) */
      0x15, 0x00,                         /*   LOGICAL_MINIMUM (0) */
      0x25, 0x01,                         /*   LOGICAL_MAXIMUM (1) */
      0x75, 0x01,                         /*   REPORT_SIZE (1) */
      0x95, 0x80,                         /*   REPORT_COUNT (128) */
      0x81, 0x02,                         /*   INPUT (Data,Var,Abs) */
      // 8 + 16 = 24
      
      /* 8 16bit Axis */
      0x05, 0x01,                         /*   USAGE_PAGE (Generic Desktop) */
      0xa1, 0x00,                         /*   COLLECTION (Physical) */
      0x09, 0x30,                         /*     USAGE (X) */
      0x09, 0x31,                         /*     USAGE (Y) */
      0x09, 0x32,                         /*     USAGE (Z) */
      0x09, 0x33,                         /*     USAGE (Rx) */
      0x09, 0x34,                         /*     USAGE (Ry) */
      0x09, 0x35,                         /*     USAGE (Rz) */
      0x09, 0x36,                         /*     USAGE (Slider) */
      0x09, 0x37,                         /*     USAGE (Dial) */
      0x16, 0x00, 0x80,                   /*     LOGICAL_MINIMUM (-32768) */
      0x26, 0xFF, 0x7F,                   /*     LOGICAL_MAXIMUM (32767) */
      0x75, 0x10,                         /*     REPORT_SIZE (16) */
      0x95, 0x08,                         /*     REPORT_COUNT (8) */
      0x81, 0x02,                         /*     INPUT (Data,Var,Abs) */
      0xc0,                               /*   END_COLLECTION */
      // 33 + 24 = 57

      /* 4 Hat Switches */
      0x05, 0x01,                         /*   USAGE_PAGE (Generic Desktop) */
      0x09, 0x39,                         /*   USAGE (Hat switch) */
      0x09, 0x39,                         /*   USAGE (Hat switch) */
      0x09, 0x39,                         /*   USAGE (Hat switch) */
      0x09, 0x39,                         /*   USAGE (Hat switch) */
      0x15, 0x01,                         /*   LOGICAL_MINIMUM (1) */
      0x25, 0x08,                         /*   LOGICAL_MAXIMUM (8) */
      0x95, 0x04,                         /*   REPORT_COUNT (4) */
      0x75, 0x08,                         /*   REPORT_SIZE (8) */
      0x81, 0x02,                         /*   INPUT (Data,Var,Abs) */
      // 57 + 20 = 77

      0x85, HID_REPORTID_LED_OUT,	   // REPORT_ID (2)
      //0x05, 0x08,                          // USAGE_PAGE (LEDs)
      //0x09, 0x4B,                          // USAGE (Generic Indicator)
      0x05, 0x01,                         /*   USAGE_PAGE (Generic Desktop) */
      0x09, 0x3B,                         /*   USAGE ( 3B ByteCount) */

      0x15, 0x01,                         /*   LOGICAL_MINIMUM (1) */
      0x25, 0xFF,                         /*   LOGICAL_MAXIMUM (255) */

      0x75, 0x08,                          /* REPORT_SIZE (8) */
      0x95, 0x01,                          // REPORT_COUNT (1)
      0x91, 0x02,                          // OUTPUT (Data,Var,Abs)
			// 77 + 16 = 93

      0x85, HID_REPORTID_LED_IN,	   // REPORT_ID (3)
      //0x05, 0x08,                          // USAGE_PAGE (LEDs)
      //0x09, 0x4B,                          // USAGE (Generic Indicator)
      0x05, 0x01,                         /*   USAGE_PAGE (Generic Desktop) */
      0x09, 0x3B,                         /*   USAGE ( 3B ByteCount) */

      0x15, 0x01,                         /*   LOGICAL_MINIMUM (1) */
      0x25, 0xFF,                         /*   LOGICAL_MAXIMUM (255) */

      0x75, 0x08,                          /* REPORT_SIZE (8) */
      0x95, 0x01,                          // REPORT_COUNT (1)
      0x81, 0x02,                          /* INPUT (Data,Var,Abs) */
			// 93 + 16 = 109

  /* USER CODE END 0 */
  0xC0    /*     END_COLLECTION	             */
};

То есть, первый репорт - джойстик, второй - включить/выключить LED, третий - узнать состояние LED'а.
Оно как бы работает (квазиджойстик как бы работает, а когда я пересылаю байт во 2-м report'е, то получаю его обратно в 3-м), но со странностями. Клиентский код у меня написан на hid4java ( https://github.com/gary-rowe/hid4java ), и

hd.getReportDescriptor(bytes) возвращает 106 (хотя дескриптор длиной 110), а

hd.read(bytes,timeoutMillis) возвращает 37 как для 1-го, так и для 3-го report'а, тогда как длина 3-го должна быть 2.

 

И утилитой UsbHidDemonstrator.exe воспользоваться для отправки данных не могу. Java-библиотеку обвинить легко, но не упустил ли я что-то в дескрипторе? Честно говоря, я логики его написания  почти не понимаю. Тут есть коллекция, там нет, тут джойстик, а тут не джойстик... Для создания структуры report'ов это наверняка всё игнорируется, но как бедный клиентский софт общего назначения разбирается...

 

 

Опубликовано:

Давно занимался дескриптором и мало помню. Ничего критического в глаза не бросается, но logical maximum вроде должен быть так, если 255image.png.a8984af530e83a9df0e16a71b5f70ec1.png

Для проверки HID использую USBlyzer

Опубликовано:

Увидел занятное различие между тем кодом, что я вижу во FreeJoy, и тем, что я вижу нагенерённым STM32CubeMX. У первого в главном цикле (нет/не видно явно) отправки report'ов. Просто чтение с разнообразных датчиков (плюс работа с LED). Похоже, что работа идёт по прерываниям. Есть

void (*pEpInt_OUT[7])(void) =
  {
    EP1_OUT_Callback,
    EP2_OUT_Callback,
    EP3_OUT_Callback,
    EP4_OUT_Callback,
    EP5_OUT_Callback,
    EP6_OUT_Callback,
    EP7_OUT_Callback,
  };

EP - эндпойнт. Отчёт от джойстика, видимо, отправляет функция USB_CUSTOM_HID_SendReport. Она вызывается из EP2_OUT_Callback(void). Ссылка на эту EP2_OUT_Callback, как видно выше, находится в  pEpInt_OUT, которая используется в CTR_LP(void), которая используется в void USB_Istr(void), которая используется в void USB_LP_CAN1_RX0_IRQHandler(void).

 

А у второго я такого не вижу. Люди просто USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, report, len) (обёрнутую во что-нибудь) в главном цикле вызывают. Тут мне было немного неприятно, потому что, похоже, между вызовами USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, report, len) должен быть какой-то временной промежуток, два репорта разом не получилось отправить.

 

-----

Для Logical Maximum (из hid1_11.pdf😞

Цитата

The Logical Minimum and Logical Maximum values identify the range of values that will be found in a report. If Logical Minimum and Logical Maximum are both positive values then a sign bit is unnecessary in the report field and the contents of a field can be assumed to be an unsigned value. Otherwise, all integer values are signed values represented in 2’s complement format.

Исходя из того, что тут написано, я не ошибся.

...А может, и ошибся... Вы можете сказать, что 0 не positive, но это факт для математиков, но не факт, что это факт для писателей спецификации.

Опубликовано:

Ну да.

Цитата

If both the Logical Minimum and Logical Maximum extents are defined as positive values (0 or greater) then the report field can be assumed to be an unsigned value. Otherwise, all integer values are signed values represented in 2’s complement format.

 

Опубликовано:

 

Занятную штуку нашёл в документации VJoy


One Continuous POV Hat:

  USAGE (Hat switch)		09 39
  LOGICAL_MINIMUM (0)		15 00 
  LOGICAL_MAXIMUM (35900)	27 3C 8C 00 00 
  UNIT (Eng Rot:Angular Pos)	65 14 
  REPORT_SIZE (16)		75 10 
  REPORT_COUNT (1)		95 01 
  INPUT (Data,Var,Abs)		81 02

 

Опубликовано: (изменено)

Есть небольшая проблема в том, что некоторые игрушки спотыкаются на хайрез хатках - но юзеры считают что виноват именно девайс( ведь у других девайсов 3-х битные хатки работают!)

 

Изменено пользователем Alex_Oz
Опубликовано:

У ВКБ я видел пример решения - на джойстике нажимной миниджойстик (физически - миниджойстик, под ним кнопка), по нажатию кнопки происходит переключение из режима миниджойстика в режим 8-позиционного POV и обратно.

Так что (теоретически) можно было бы и третий режим туда добавить - миниджойстик, POV 8-позиционный, POV hi res.

Опубликовано: (изменено)

Так все равно все игры видят только 45-градусные положения хатки - хоть 3 битной, хоть хайрез 15-битной.

И переводят их тупо в 8 кнопок. Никто из игроделов в этом разбираться не собирается и не будет.

Смысл в хайрез хатках - дополнительные 4 оси директинпута на девайс.

Ну или если хатка в девайсе к элемент POV присутствует - то 3. В процентах к 8 основным осям ДИ - неплохая прибавка к пенсии от M$.

Для девайсов начального уровня министик также мог бы быть средством плавного обзора при использование хайрез. - без задействования основных осей ДИ в любом симе.

Но это надо ходить и биться любом в стенки - а нах?

смотрите дату

image.thumb.png.5b62586ae746517d95bd2dfd0e45c679.png

Изменено пользователем Alex_Oz
  • Нравится 1
Опубликовано:

> hd.getReportDescriptor(bytes) возвращает 106 (хотя дескриптор длиной 110), а

Дескриптор возвращается не точно такой, какой я написал, а слегка переписанный. Почему-то там мои репорты 2 и 3 поменяны местами, несколько байтов прибавлено и несколько убавлено. Хотя, в принципе, структура та же.

 

> hd.read(bytes,timeoutMillis) возвращает 37 как для 1-го, так и для 3-го report'а, тогда как длина 3-го должна быть 2.

А тут Wireshark показывает, что лишнее не передаётся. То есть, проблема, скорее всего, либо в Java-коде hid4java, либо в DLL-ках, что она вызывает.

Довольно неприятно, хотя пользоваться не невозможно.

Опубликовано:

полная длина репортов in-out описывается раньше в ЕP, в хидрипорт -  это как бы "действующая' -  но пакет обмена  все равно полный

Возможно и есть смысл разбрасывать рипорты с разной длиной по разным EP в случае с FFB или управления светодиодами.

Но разницы без миллиона тестов не заметите.

Опубликовано: (изменено)

Меня занимало и беспокоило, что будет, если, скажем, третий отчёт будет длиной больше 37. Будет ли read по-прежнему возвращать 37, по длине первого отчёта.

Увеличил. Сделал третий отчёт с данными длиной в 0x34 (52). OK. read теперь стал для обоих отчётов возвращать 53. так что хорошо.

По дороге одна из платок как-то непонятно подпортилась, что подпортило и настроение. ST-Link к ней не коннектится, если не переставить перемычку на boot. Я попеременке заливаю прошивку на "оригинальную" и поддельную, так подпортилась "оригинальная".

Изменено пользователем vvm13ru
Опубликовано:

Ещё одна занятная тема - ESP32. Для беспроводных игровых устройств, в частности. В том числе, можно было бы даже телефон превратить в джойстик, не очень напрягаясь.

 

Насколько я вижу, вариации S2 и S3 поддерживают USB OTG. Но нас интересует USB HID. Наверное, если USB OTG поддерживается, то USB HID тоже. Но если USB OTG не поддерживается, то не факт, что USB HID не поддерживается...

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас
×
×
  • Создать...