USB джойстик с уклоном в файтинги на RP2040

Здравствуйте.
Я бы хотел создать USB джойстик для телефона на платформе Андроид с уклоном в файтинги (достаточно 3 аналоговых оси). Да Я знаю, что можно купить готовый (Commander Octa), но это не так интересно, и чуточку дороговато. К тому же мне подарили logitech f710 без usb приемника, и он удобен тем, что микропроцессор там на плате напоминающей ЕСП32 и легко отпаивается от основной платы… прозвонка выявила конфигурацию матрицы кнопок 15*1 (в будущем хочу попробовать другой корпус с вклеенными кнопками от компьютерной мыши)

RP2040 выбрал из за наличия ее у меня и готового примера - PicoGamepad на гитхабе.

Так же у меня есть референстный джойстик logitech f310

дальше пошли грабли
по библиотеке

  1. ошибки в дескрипторе (по мнению перехватчика USBlyzer)
  2. пакет на 32 байта и отправляется 4 пакетами по 8байт (вместо 8байт и одного пакета как у logitech f310 )
  3. автору чесалось сделать более 100 кнопок на джойстике
  4. автору чесалось сделать диапазон аналоговых осей -32767 +32767
    (вместо от 0 минимум, центр на 127 и максимум 255 как у logitech f310 )
  5. учитывая пункты 1-4 телефон не видит кнопок от RP2040 (зато видит logitech f710)
  6. использовано только 1 ядро и на опрос и на юсб (хотелось бы опрос отдать одному ядру, а обмен другому)
  7. нет калибровки (хотелось бы нажать на кнопку калибровки, покрутить аналоговые оси, нажать еще раз мк считает нулевое положение осей, а потом натянет значение с АЦП на 0 минимум, центр на 127 и максимум 255 )

Зачем создал тему? и что мне не хватает для понимания вопроса

  1. я не уверен что идея сделать пересчет с дробными числами оптимальна по производительности… А как сделать калибровку через умножение и сдвиг?

  2. я не знаю как на RP2040 сделать максимально быстро. На Ардуино Нано В3 я бы не читал каждый бит в отдельности, я бы считал весь порт в переменную и далее делил бы ее на биты. А на RP2040 как?

  3. Я не уверен в адекватности функций АЦП блока. На той же ЕСП32 было быстрее через adcAttachPin, adcStart, adcBusy, resultadcEnd заюзать 2 АЦП в параллель. Чем пытаться юзать штатный analogRead. А на RP2040 как?

Сейчас я попробую прикрутить дескриптор от logitech f310 к RP2040 и после разобраться 2х поточностью.

есть ESP32C3 двух типов, в том числе с USB CDC, платка с CDC даже дешевле, 150 рублей

  1. Причем тут CDC или CH340 или вообще RS232 ?
  2. У ЕСП32 нелинейное АЦП, и мне его калибровать лень
  3. у меня из плат с ЕСП32 нет плат с юсб слейвом, а покупать новую мне доставка в 300р выйдет… не говоря о том, что нормальная двухядерная есп с дма (ESP32s3) на плате стоит под 1000р и никаких не 150р (а у ESP32c3 = одно ядро и нет дма)
  4. у ЕСП32 пинов свободных мало (то не трогай, это подтянуто и т.д.)

Как же так сделать джойстик без дма и пяти ядер
Это ж до безумия высокопроизводительная задача.

Ага, для файтингов ДА
Отсюда же и провод, а не блютуз, который удобнее на ЕСП32
(вот только блютуз по быстродействию не проходит)
Отсюда же и механические кнопки (а не резиновые)
как итог и цена в несколько раз больше китайских
недо джоев и реплик плойки и Хбокса у готового решения (Commander Octa).

Если бы меня реплика устраивала бы, я бы ее взял и не парился.
У меня уже есть logitech f310, который лучше китайских реплик ,
но я все же хочу под себя, удобный по хвату мне и максимально производительный.

видимо файтинги теперь разгоняют частоту пакетов usb сверх стандарта

В том то и проблема, что с текущим вызовом функций от Ардуино ИДЕ получается МЕНЬШЕ стандарта. А хотелось бы 100 пакетов в секунду с реальными данными.

Производительности при грамотном написании кода должно хватить.
Поэтому и вопрос, а как написать правильно?

Научиться программировать? Если ты 100Гц из опроса кнопок выжать не можешь, то это печально.

Вот и спросил, как исправить этот печальный недостаток.
НА ЭТОЙ платформе и НА ЭТОМ МК.

И я не автор - PicoGamepad
которая из коробки тормозит.
я ттолько предпологаю, в чем причина ее тормозов и как это править.

но там не только опрос в 100 Гц.

Там опрос кнопок
Опрос 3х АЦП портов
Применение результата калибровки.
драйвер USB

Если Вы такой знающий и по вашему все должны писать юсб с нуля для данного применения, то прошу в студию ссылку на ВАШ гит хаб, где ВЫ грамотно и корректно написали СВОЙ USB стек и стек работы с 2мя ядрами, ну и свою библу под опрос АЦП.

Хоть под какую то платформу. не обязательно под эту.

А то закрадывается подозрение, что собеседник в теме НОЛЬ.
И сам ни разу USВ стек не писал (я писал, на ассемблере под AT90USB162)

Повторяю, тут задача не сделать красиво - тут задача микроскопом забить гвоздь, через ТОРМОЗНУТУЮ ардуино ИДЕ с минимаными правками кода криворуких библостроителей, которые 100Гц с нормальным функционалом и без глюков выжать не смогли.

а если разогнать, на 350 мегагерцах температура ядра поднималась всего на 2 градуса

Нафиг?

когда есть 2 ядро… можно заюзать… к томуже подозреваю что функции юсб блокирующие и пока все не отправится С ФИКСИРОВАННОЙ СКОРОСТЬЮ управление не вернется…
Можно в 4 раза уменьшить обмен по юсб…
И я надеюсь можно как минимум 17 раз подряд не спрашивать состояние бита.
через тормознутую обертку ардуино ИДЕ, а считать весь порт и пилить на биты?

не знаю, мне не надо было, сомнительно, что напрямую возможно

я на прямую не просил на асме писать (как предлагал rkit ) все сам и с нуля

вопрос можно ли считать порт? и есть ли он тут вообще
как на атмегах PinC (PortC) целиком

Или как в STM32
#define GPIO_ReadInputData LL_GPIO_ReadInputPort

Сам сформулировал вопрос, сам же и натравил поиск по файлам

А это случаем не оно?

// ----------------------------------------------------------------------------
// Input
// ----------------------------------------------------------------------------

/*! \brief Get state of a single specified GPIO
*  \ingroup hardware_gpio
*
* \param gpio GPIO number
* \return Current state of the GPIO. 0 for low, non-zero for high
*/
static inline bool gpio_get(uint gpio) {
   return !!((1ul << gpio) & sio_hw->gpio_in);
}

/*! \brief Get raw value of all GPIOs
*  \ingroup hardware_gpio
*
* \return Bitmask of raw GPIO values, as bits 0-29
*/
static inline uint32_t gpio_get_all(void) {
   return sio_hw->gpio_in;
}

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

ложь

Мной озвучено 4 самых крупных

  1. не прямое чтение (1 раз), а через ардуину ИДЕ 17 раз по биту за раз.
  2. не использование второго ядра, в то время как первое блокировано отправкой данных по юсб (советами добрых людей переписать юсб стек на не блокирующую отправку = тем самым “исправив” проблему умеючи программировать = пренебрежем )
  3. кривой дескриптор и отправка 32х байт вместо 8 байт
  4. не быстрая конвертация данных с АЦП

на звание ГУРУ я не претендовал.
А тут спросил, может у кого опыта больше и кто нибудь видит решение?

Или может тут есть не блокирующая функция чтения АЦП?
что бы на время чтения заняться чем то полезным?

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

А может не по Сеньке шапка ?
Не рано вам с такими познаниями стучаться в USB ?

Не рано. Это уже примерно 40 девайс с юсб в котором я дескриптор под себя переписываю. Первым был MJoy в далеком 2006. Я к нему китайцами доработанный юсб стек от IgorPlug прикручивал. Для меня не знакомы подводные камни использования RP2040

Тогда откуда этот бред по завешиванию МК при передаче через USB при измерении АЦП ???

Бредите к сожалению ВЫ, я такого не писал.
(одно второе не “вешает”)

До окончания передачи функция управления не возвращает.
так же и АЦП не возвращает управления до завершения измерений

может вам погуглить немного по словам = adcAttachPin, adcStart, adcBusy, resultadcEnd

может и приедт понимание что может быть и по другому (на той же ESP32 и работе 2х АЦП в параллель)

А с пониманием и виденье, как ускорить систему используя не блокирующие функции.

А это тогда что ?