PCCar.ru - Ваш автомобильный компьютер

PCCar.ru - Ваш автомобильный компьютер (http://pccar.ru/index.php)
-   Общение с машиной (http://pccar.ru/forumdisplay.php?f=14)
-   -   BMW IBUS to USB Keyboard (http://pccar.ru/showthread.php?t=18794)

iGeophysix 14.03.2013 15:54

в Ардуино есть библиотека Keyboard

и там есть просто метод: Keyboard.press(keyCode);

так вот какой keyCode я должен запихнуть?)))

128 для увеличения звука
129 для уменьшения
234 предыдущий трек
235 следующий трек
так?)

iGeophysix 14.03.2013 16:00

Цитата:

Сообщение от Alex_St (Сообщение 250632)
Коды для хида стандартны и известны. Я и Костя740 сделали такую штуку. Все работает как надо. Если что - можем помочь. Не стесняйся )

Спасибо! Сегодня пришел мой CANHacker) Буду отлавливать кнопочки.
На дня приедет планшет (EMS говорит, что он уже в Москве)

На выходных (на этих или следующих) будет большой разбор!)))

Alex_St 14.03.2013 16:17

Цитата:

Сообщение от iGeophysix (Сообщение 250650)
в Ардуино есть библиотека Keyboard

и там есть просто метод: Keyboard.press(keyCode);

так вот какой keyCode я должен запихнуть?)))

128 для увеличения звука
129 для уменьшения
234 предыдущий трек
235 следующий трек
так?)

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

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

Вот сканкоды для мультимедиа клавы:
Код:

// PAGE 00xC:
#define KEY_NEXT_TRACK        0x00B5  /*  Scan Next Track      0C    00B5 */
#define KEY_PREVIOUS_TRACK    0x00B6  /*  Scan Previous Track  0C    00B6 */
#define KEY_STOP              0x00B7  /*  Stop                0C    00B7 */
#define KEY_PLAY_PAUSE        0x00CD  /*  Play/ Pause          0C    00CD */
#define KEY_MUTE              0x00E2  /*  Mute                0C    00E2 */
#define KEY_BASS_BOOST        0x00E5  /*  Bass Boost          0C    00E5 */
#define KEY_LOUDNESS          0x00E7  /*  Loudness            0C    00E7 */
#define KEY_VOLUME_UP        0x00E9  /*  Volume Up            0C    00E9 */
#define KEY_VOLUME_DOWN      0x00EA  /*  Volume Down          0C    00EA */
#define KEY_BASS_UP          0x0152  /*  Bass Up              0C    0152 */
#define KEY_BASS_DOWN        0x0153  /*  Bass Down            0C    0153 */
#define KEY_TREBLE_UP        0x0154  /*  Treble Up            0C    0154 */
#define KEY_TREBLE_DOWN      0x0155  /*  Treble Down          0C    0155 */
#define KEY_MEDIA_SELECT      0x0183  /*  Media Select        0C    0183 */
#define KEY_MAIL              0x018A  /*  Mail                0C    018A */
#define KEY_CALCULATOR        0x0192  /*  Calculator          0C    0192 */
#define KEY_MY_COMPUTER      0x0194  /*  My Computer          0C    0194 */
#define KEY_WWW_SEARCH        0x0221  /*  WWW Search          0C    0221 */
#define KEY_WWW_HOME          0x0223  /*  WWW Home            0C    0223 */
#define KEY_WWW_BACK          0x0224  /*  WWW Back            0C    0224 */
#define KEY_WWW_FORWARD      0x0225  /*  WWW Forward          0C    0225 */
#define KEY_WWW_STOP          0x0226  /*  WWW Stop            0C    0226 */
#define KEY_WWW_REFRESH      0x0227  /*  WWW Refresh          0C    0227 */
#define KEY_WWW_FAVORITES    0x022A  /*  WWW Favorites        0C    022A */

Репорт должен быть настроен для Consumer Devices (PAGE 0x0C).

А для обычных кнопок репорт должен быть настроен на обычную клаву (0x07)
Я у себя сделал две коллекции в одном дескрипторе:
Код:

  0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
  0x09, 0x06,                    // USAGE (Keyboard)
  0xa1, 0x01,                    // COLLECTION (Application)
  0x85, 0x01,                    //  REPORT_ID (1)
  0x05, 0x07,                    //  USAGE_PAGE (Keyboard)
  0x19, 0xe0,                    //  USAGE_MINIMUM (Keyboard LeftControl)
  0x29, 0xe7,                    //  USAGE_MAXIMUM (Keyboard Right GUI)
  0x15, 0x00,                    //  LOGICAL_MINIMUM (0)
  0x25, 0x01,                    //  LOGICAL_MAXIMUM (1)
  0x75, 0x01,                    //  REPORT_SIZE (1)
  0x95, 0x08,                    //  REPORT_COUNT (8)
  0x81, 0x02,                    //  INPUT (Data,Var,Abs)
  0x05, 0x07,                    //  USAGE_PAGE (Keyboard)
  0x95, 0x01,                    //  REPORT_COUNT (1)
  0x75, 0x08,                    //  REPORT_SIZE (8)
  0x25, 0x65,                    //  LOGICAL_MAXIMUM (101)
  0x19, 0x00,                    //  USAGE_MINIMUM (Reserved (no event indicated))
  0x29, 0x65,                    //  USAGE_MAXIMUM (Keyboard Application)
  0x81, 0x00,                    //  INPUT (Data,Ary,Abs)
  0xc0,                          // END_COLLECTION
  0x05, 0x0c,                    // USAGE_PAGE (Consumer Devices)
  0x09, 0x01,                    // USAGE (Consumer Control)
  0xa1, 0x01,                    // COLLECTION (Application)
  0x85, 0x02,                    //  REPORT_ID (2)
  0x05, 0x0c,                    //  USAGE_PAGE (Consumer Devices)
  0x19, 0x00,                    //  USAGE_MINIMUM (Unassigned)
  0x2a, 0x08, 0x01,              //  USAGE_MAXIMUM (Police Alarm)
  0x15, 0x00,                    //  LOGICAL_MINIMUM (0)
  0x26, 0x08, 0x01,              //  LOGICAL_MAXIMUM (264)
  0x95, 0x02,                    //  REPORT_COUNT (2)
  0x75, 0x08,                    //  REPORT_SIZE (8)
  0x81, 0x00,                    //  INPUT (Data,Ary,Abs)
  0xc0,                          // END_COLLECTION

Первая - для обычных клавиш, вторая - для мультимедийных.

zyxel812 14.03.2013 16:30

Цитата:

Сообщение от Alex_St (Сообщение 250662)
Репорт должен быть настроен для Consumer Devices (PAGE 0x0C).

А для обычных кнопок репорт должен быть настроен на обычную клаву (0x07)

Вот, я про эти страницы (0x07, 0x0C) знаю, я взял за основу демо-пример клавиатуры из LUFA, у которого репорт настроен на страницу 7. Подскажи, что нужно добавить, чтобы можно было использовать страницу 0x0C? Я как раз с этим сейчас пытаюсь разобраться.

Alex_St 14.03.2013 17:17

дописать в ReportDecription вторую коллекцию с другим reportID. Я тебе привел пример репорта для двух коллекций. Первая - это обычная клава (страница 0х07), а вторая - это мультимедийная (страница 0х0С).
Потом вспоминаешь, что в репорте первый байт у тебя задан reportID, и в нем выбираешь что шлешь. 1 - обычная клавиша, 2 - мультимедия. И соответственно строишь тело пакета. Что где в теле лежит - смотришь из reportDescription.
Если что - стучись в аську: 307342375

zyxel812 14.03.2013 18:33

С ReportDecription разобрался кажется.
Теперь по поводу самого репорта, для страницы 7 структура такая:
uint8_t Modifier;
uint8_t Reserved;
uint8_t KeyCode[6]; (в моем случае размер указан именно 6)
Для страницы 0х0С такая же?
Только коды клавиш двух-байтные?
В репорт записывать сначала младший, потом старший байт?
Я правильно понял?

Alex_St 14.03.2013 19:44

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

Тут мы говорим, что будет новая коллекция (вариант репорта) под обычную клаву:
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)

РепортИД для этой коллекции - 1:
0x85, 0x01, // REPORT_ID (1)

Используем клавиатуру:
0x05, 0x07, // USAGE_PAGE (Keyboard)

Диапазон значений следующего поля - от 0хе0 до 0хе7)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)

Каждое значение может быть либо 0 либо 1:
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)

Размер поля - 1 бит. Кол-во полей - 8:
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)

То, что мы описали - вход для хоста, и данные идут как массив битов:
0x81, 0x02, // INPUT (Data,Var,Abs)

Это мы описали первый блок в репорте. Иными словами и по-русски - мы передаем 1 байт (8 бит), каждый бит в котором соответствует одной из клавиш от Keyboard LeftControl до Keyboard Right GUI.

Следующий блок передает опять данные клавы:
0x05, 0x07, // USAGE_PAGE (Keyboard)

Размер поля - 8 бит. Кол-во полей - 1шт:
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)

Диапазон значений - от 0до 0х65, транслируется 1:1 :
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)

Опять же - вход, но уже как значения:
0x81, 0x00, // INPUT (Data,Ary,Abs)
На этом первая коллекция закончилась. Больше в этом репорте мы ничего не шлем.
0xc0, // END_COLLECTION

Итого вышло три байта:
байт 1 - reportID = 1 (говорит о том, что дальше данные из первой коллекции)
байт 2 - массив для функциональных клавиш
байт 3 - одна из обычных.

Теперь вторая коллекция
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
0x09, 0x01, // USAGE (Consumer Control)
0xa1, 0x01, // COLLECTION (Application)

Именно такой репортид мы будем слать для нее:
0x85, 0x02, // REPORT_ID (2)

Страница - Сonsumer Devices (именно там у нас коды мультимедийных клавиш):
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)

Диапазон значений и его отображение. Обрати внимание, что он двухбайтный:
0x19, 0x00, // USAGE_MINIMUM (Unassigned)
0x2a, 0x08, 0x01, // USAGE_MAXIMUM (Police Alarm)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0x08, 0x01, // LOGICAL_MAXIMUM (264)

Слать будем два поля по 8 байт (те же два байта):
0x95, 0x02, // REPORT_COUNT (2)
0x75, 0x08, // REPORT_SIZE (8)

0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0, // END_COLLECTION

Иными словами:
байт 1 - репортид = 2
байты 2и3 - код клавиши в соответствии с таблицей, что я давал выше.
Все.

Теперь в общем.. Если мы хотим послать событие обычной кнопки - то шлем данные только для коллекции 1. Если для мультимедийной - то данные для коллекции 2. И там и там мы задали слать по 3 байта.

zyxel812 14.03.2013 20:07

До меня постепенно доходит суть и смысл.
Только я пользуюсь библиотекой lufa, поэтому у меня всё тоже самое, только другими словами.
Исходя из информации от тебя, я описал такой вот дескриптор:
Код:

                #define HID_DESCRIPTOR_KEYBOARD(MaxKeys)            \
                        HID_RI_USAGE_PAGE(8, 0x01),                    \
                        HID_RI_USAGE(8, 0x06),                          \
                        HID_RI_COLLECTION(8, 0x01),                    \
                            HID_RI_REPORT_ID(8, 0x01),                                        \
                                HID_RI_USAGE_PAGE(8, 0x07),                \
                                HID_RI_USAGE_MINIMUM(8, 0xE0),              \
                                HID_RI_USAGE_MAXIMUM(8, 0xE7),              \
                                HID_RI_LOGICAL_MINIMUM(8, 0x00),            \
                                HID_RI_LOGICAL_MAXIMUM(8, 0x01),            \
                                HID_RI_REPORT_SIZE(8, 0x01),                \
                                HID_RI_REPORT_COUNT(8, 0x08),              \
                                HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \
                                HID_RI_REPORT_COUNT(8, 0x01),              \
                                HID_RI_REPORT_SIZE(8, 0x08),                \
                                HID_RI_INPUT(8, HID_IOF_CONSTANT),          \
                                HID_RI_USAGE_PAGE(8, 0x08),                \
                                HID_RI_USAGE_MINIMUM(8, 0x01),              \
                                HID_RI_USAGE_MAXIMUM(8, 0x05),              \
                                HID_RI_REPORT_COUNT(8, 0x05),              \
                                HID_RI_REPORT_SIZE(8, 0x01),                \
                                HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), \
                                HID_RI_REPORT_COUNT(8, 0x01),              \
                                HID_RI_REPORT_SIZE(8, 0x03),                \
                                HID_RI_OUTPUT(8, HID_IOF_CONSTANT),        \
                                HID_RI_LOGICAL_MINIMUM(8, 0x00),            \
                                HID_RI_LOGICAL_MAXIMUM(8, 0xFF),            \
                                HID_RI_USAGE_PAGE(8, 0x07),                \
                                HID_RI_USAGE_MINIMUM(8, 0x00),              \
                                HID_RI_USAGE_MAXIMUM(8, 0xFF),              \
                                HID_RI_REPORT_COUNT(8, MaxKeys),            \
                                HID_RI_REPORT_SIZE(8, 0x08),                \
                                HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), \
                        HID_RI_END_COLLECTION(0), \  <-- на этом заканчивается то, что у меня было
                        HID_RI_USAGE_PAGE(8, 0x0C),                    \  <--это то, что я дописал для второй коллекции
                        HID_RI_USAGE(8, 0x01),                          \
                        HID_RI_COLLECTION(8, 0x01),                    \
                                HID_RI_REPORT_ID(8, 0x02),                                        \
                                HID_RI_USAGE_PAGE(8, 0x0C),                \
                                HID_RI_USAGE_MINIMUM(8, 0x00),              \
                                HID_RI_USAGE_MAXIMUM(16, 0x0108),          \
                                HID_RI_LOGICAL_MINIMUM(8, 0x00),            \
                                HID_RI_LOGICAL_MAXIMUM(16, 0x0108),        \
                                HID_RI_REPORT_COUNT(8, 0x02),              \
                                HID_RI_REPORT_SIZE(8, 0x08),                \
                                HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), \
                        HID_RI_END_COLLECTION(0)

его начало (до строки HID_RI_USAGE_PAGE(8, 0x0C)) это то, что у меня было, оставил как есть, только вставил строку HID_RI_REPORT_ID(8, 0x01) в начало, так как report_id небыло вообще.
Сам report у меня создается в функции
Код:

bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
                                        uint8_t* const ReportID,
                                        const uint8_t ReportType,
                                        void* ReportData,
                                        uint16_t* const ReportSize)

Я теперь разбираюсь, от куда вызывается эта функция, от куда берется ReportID, который в нее передается, чтобы внести изменения с учетом того, что у меня теперь две коллекции.

iGeophysix 14.03.2013 21:03

баааалин... да что все это значит вообще?)))))

m50b20 14.03.2013 21:25

Цитата:

Сообщение от iGeophysix (Сообщение 250723)
баааалин... да что все это значит вообще?)))))


+1 ))

жду готового продукта )


Часовой пояс GMT +4, время: 09:58.

Работает на vBulletin® версия 3.8.4.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot