Динамический usb hid дискриптор

Тема в разделе "Arduino & Shields", создана пользователем Unicorn79, 9 мар 2022.

  1. Unicorn79

    Unicorn79 Нуб

    Добрый день всем, уважаемые! В данный момент работаю на базе Ардуино и возник такой нестандартный вопрос - возможна ли в принципе реализация Динамического USB HID дискриптора устройства на базе Arduino (например Leonardo)? Что натолкнуло на мысль - увидел в просторах интернета следующий код - выдержка из .cpp где вот так описывается HID дискриптор:
    Код (C++):
        0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
        0x09, 0x30,                    //     USAGE (X)
        0x09, 0x31,                    //     USAGE (Y)
        0x09, 0x38,                    //     USAGE (Wheel)
    #ifdef ABSOLUTE_MOUSE_MODE
        0x15, 0x01,                    //     LOGICAL_MINIMUM (1)       <<<< This allows us to talk to any display resolution
        0x25, 0x64,                    //     LOGICAL_MAXIMUM (100)     <<<<  as though it was 100x100 pixels
        0x75, 0x08,                    //     REPORT_SIZE (8)
        0x95, 0x03,                    //     REPORT_COUNT (3)
        0x81, 0x02,                    //     INPUT (Data,Var,Abs)      <<<< This allows us to moveTo absolute positions
    #else
        0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
        0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
        0x75, 0x08,                    //     REPORT_SIZE (8)
        0x95, 0x03,                    //     REPORT_COUNT (3)
        0x81, 0x06,                    //     INPUT (Data,Var,Rel)
    #endif
        0xc0,                          //   END_COLLECTION
        0xc0,                          // END_COLLECTION
    , где в зависимости от ABSOLUTE_MOUSE_MODE дискриптор будет разным. Однако, хотелось бы понять, каким образом из вне можно дать понять Ардуино, какую часть дискриптора грузить при следующем ребуте девайса. Самым простым решением было бы следить за каким-либо ПИНом и его замыканием и, в зависимости от этого, уже применять условие. Хотелось бы спросить у знающих людей, возможно ли такое реализовать в принципе. Также уточню, что триггером может выступать не обязательно ПИН платы, главное, чтоб это мог задать сам пользователь. Спасибо!
     
  2. parovoZZ

    parovoZZ Гуру

    в английской нотации слово звучит так:
    дескриптор надо грузить весь целиком. Иначе ОС не воспримет устройство.

    можно. Можно через ОЗУ - оно при ресете не сбрасывается. Если устройство обесточивается, то тогда через EEPROM.
     
  3. Unicorn79

    Unicorn79 Нуб

    Подскажите пож-та. интересует возможность опроса состояния ПИН-а на плате и, в зависимости от логического уровня на нём, как показано в примере выше при перезагрузке изменять именно часть дескриптора. Т.е., условно, могу ли я вне скетча в исходных файлах .cpp, где описывается дескриптор, предварительно опросить ПИН и уже в зависимости от результата выполнить тот или иной дескриптор (относительная система смещения указателя мыши или абсолютная, как в примере)? Я просто не совсем понимаю, как именно это сделать. Конфигурация ПИНов ввода вывода да и опрос обычно происходит уже в самом скетче , а вот каким образом провести опрос ПИН-а в исходнике .cpp, где описывается дескриптор? Я так понимаю, синтаксис опроса там будет уже отличный от IDE Arduino? (что-то похожнее на if ((PINC & (1 << PC3)) == 0)?). Спасибо
     
  4. parovoZZ

    parovoZZ Гуру

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

    А вот если взять чистую библиотеку LUFA (не та, что в дурине), то там всё прозрачно. Можно через глобальную переменную, можно непосредственно в файле, где происходит загрузка дескриптора.
     
  5. b707

    b707 Гуру

    а что это за файлы, "где описывается дескриптор"? это какая-то библиотека? Если библиотека - то она в любом случае из скетча будет вызываться
     
  6. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Попросту говоря, ТС хочет при ресете представлять Ардуино устройством по желанию - либо Ком-портом, либо Мышом, либо клавиатурой, и тд. Например Ардуино УНО R3 это гарантированно не может. Там дескриптор аппаратно вшит в микру УСБ-Сериал конвертора. Можно добиться желаемого, если использовать Ардуино с аппаратным УСБ портом, либо на бутлоадерах v-usb вроде микронуклеус (ардуины DigiSpark).
    ПС. Тут надо лезть на сайты ObDev.com, digistump.com.
     
    Последнее редактирование: 9 мар 2022
    arkadyf нравится это.
  7. b707

    b707 Гуру

    ТС написал, что у него леонардо
     
  8. Unicorn79

    Unicorn79 Нуб

    Платформа - Леонардо. Задача - реализовать, чтоб при замыкании джампера на пинах менялся USB HID дескриптор (или его часть). Т.е. чтоб по желанию юзера. без перепрошивки скетча, мышь при изменении джампера могла использовать относительную/абсолютную систему координат. В Леонардо исходники, где находится дескриптор, находятся отдельно в папке, куда установлена IDE, также могут быть добавлены в отдельных библиотеках. Заголовок Библиотеки, которая подгружает дескриптор, вызывается вначале скетча. У меня вопрос - каким образом можно опросить пины и этот опрос поместить в .cpp, где описан вышеуказанный дескриптор. Насколько я понимаю, команды IDE digitalRead() тут не сработают (могу ошибаться). Или я Вот так просто смогу прописывать конфигурацию пинов и чтение с них вне скетча (.ino)? Ведь насколько я помню - имеено там в секции setup производится конфигурация пинов и далее в voidloop() их уже можно читать... Мне нужно реализовать подобные операции с пинами в .cpp
     
  9. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Дескриптор превращает УСБ устройство в мышь, клаву, модем и тд. Если мышь остается мышью, зачем лезть в дескриптор ? Ваша задача опросить пин, опросить сенсор, и выбрать подпрограмму обработки данных с сенсора для передачи в виде данных "мыша". Что такое абсолютная / относительная система координат для мыша ?????
     
  10. Unicorn79

    Unicorn79 Нуб

    В моём примере мышь-то останется мышью, но вот какую систему координат (смещения) она использует, задается как раз в вышеуказанном кусочке коде дескриптора. Мне нужно при помощи ПИНа (наличия джампера на нем, а затем опроса состояния уровня) задать переменную ABSOLUTE_MOUSE_MODE, по значению которой выберется нужный мне кусочек дескриптора (код в первом посте топика). Следуя этой логике, в зависимости от условия - можно выбирать, какой дескриптор будет использоваться в девайсе при загрузке (клавиатура, мышь. джойстик и тд.).
     
    Последнее редактирование: 9 мар 2022
  11. akl

    akl Гуру

    ABSOLUTE_MOUSE_MODE это не переменная. нужно сделать два разных дескриптора с разными именами, найти в библиотеке функцию которая подцепляет этот дескриптор, внутри нее опросить пин и в зависимости от результата подставлять имя нужного дескриптора.
    Что за библиотека то? не похоже на стандартную ардуиновскую
     
  12. Unicorn79

    Unicorn79 Нуб

    https://github.com/NicoHood/HID
    Что касательно двух разных дескрипторов - позвольте вопрос - а как реализован механизм выбора в примере в моём первом посте? Раз есть if и возможность выбрать нужный кусочек дескриптора, то обязательно ли делать выбор из двух целых дескрипторов? И попутный вопрос - как в коде .cpp на Ардуино можно опросить ПИН?
     
  13. akl

    akl Гуру

    слишком сложная библиотека я не могу в ней разобраться
     
  14. Ariadna-on-Line

    Ariadna-on-Line Гуру

    А это не механизм выбора при работе процессора, это директива компилятора, который программу собирает. Дескриптор это - ответы. Не факт что они нужны для работы самого процессора. Процессор по запросам от хоста шлет ему байты из дескриптора. А хост по этим ответам опознает его как мышь, клаву или еще что. Возможно хост по этим байтам дескриптора как-то интерпретирует данные от мыша. Чтобы заставить проц слать разные ответы хосту при опознавании, придется в самом начале процедуры ответов ввести опрос пина. Надо копать исходники УСБ-шной части. До самой Ардуинной части тут далеко.
     
    Последнее редактирование: 10 мар 2022
  15. b707

    b707 Гуру

    так же, как в скетче - digitalRead()
    Только мне кажется, что если вы даже не знаете, что код ардуино - это и есть код на С++ - то вам эту задачу не осилить
     
  16. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Процедура идентификации - быстрая. Поэтому надо иметь два полноценных экземпляра дескрипторов, выбирать сразу, а не дергаться внутри процедуры. Иначе хост напишет про неопознанное устройство. Команда digitalRead() - слишком медленная и занимает много. Надо использовать работу с портами ассемблера или Си.
     
  17. akl

    akl Гуру

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

    parovoZZ Гуру

    ЛОЛ. Тему не читаешь? Что вообще такое дескриптор знаешь?
    пины можно читать вообще всегда. Нет никаких препятствий для этого. Если пин вход, то в какой-либо конфигурации он не требуется - сразу после ресета он и так вход.

    самым обычным (как это делают абсолютно все программисты) - путём чтения регистра IN необходимого порта.

    Почитай сперва про USB, потом пиши про небылицы. Инфы в тырнетах валом. На том же хабре или даже вот здесь:

    http://microsin.net/programming/arm-working-with-usb/index.html
     
  19. akl

    akl Гуру

    попробуй заменить файл src/SingleReport/SingleAbsoluteMouse.cpp
    на вот этот.
    но не факт что это как-то заработает.
    кнопку вешать на пин 12. нужна внешняя подтяжка к питанию или к земле.
     

    Вложения:

    Ariadna-on-Line нравится это.
  20. Unicorn79

    Unicorn79 Нуб

    То, что это C++ - я знал, но я был уверен, что именно IDE добавляет скажем так некоторые "свои" операторы для удобства, опять же могу ошибаться.


    Да, согласен с Вами, программист из меня слабый, но я пытаюсь анализировать имеющиеся алгоритмы, сопоставлять и компоновать их, чтоб этот агрегат работал исправно )
    Это занимает кучу времени, но и результат тоже есть.



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



    Спасибо. Вот это наиболее близкий ответ на вопрос. Буду пробовать читать ПИН непосредственно в исходном коде через digitalRead().