|
AT91RM9200 USB Host OHCI , HID Mouse., Как прочитать репорт мыши через канал управления? |
|
|
|
Oct 17 2012, 14:32
|

Местный
  
Группа: Свой
Сообщений: 421
Регистрация: 27-05-05
Из: Энергодар
Пользователь №: 5 480

|
Есть железо на базе AT91RM9200 в котором OHCI USB host. На выходе UHP AT91RM9200 припаян Хаб TUSB2046B. На данный момент реализованы управляющие (Control) запросы через OHCI, которыми читаю дескрипторы и управляю портами на выходе хаба. На первом этапе стоит задача подключить мышь. При подключении мыши определяем факт подключения, настраиваем поты хаба, делаем сброс порта ну и так далее… Читаю дескрипторы мыши и ее отчетный дескриптор все получается. После чего 1) Устанавливаю новый адрес мыши 2) Устанавливаю ее конфигурацию (Set_Configuration) 3) Для проверки читаю конфигурацию все ОК (Get_Configuration) 4) Устанавливаю отчетный протокол (пробовал и загрузочный) (Set_Protocol) 5) Тоже его читаю (Get_Protocol) 6) После чего пытаюсь прочитать отчет, через канал управления мыши и тут ничего не получается Отчет читаю через специфический запрос HID Get_Report Сам запрос Код bmRequestType = 0xA1 bRequest = 0x01 //GET_REPORT wValue = 0x0100 //Тип отчета Report ID wIndex = 0x0000 //интерфейс если установить в 1 то ошибка wLength = 0x0005 // Length [/code] {0xA1,0x01,0x00,0x01,0x00,0x00,0x05,0x00} В ответ приходит мой Setup пакет и никаких ошибок передачи. 0xA1,0x01,0x00,0x01,0x00 что послал то и вернулось. Функции для чтения дескрипторов и для отчета одни и те же. Дескрипторы читаются правильно проверял снифером на ПК, а вот с отчетами не понятно. Тот порядок настроек, который под цифрами 1-6 это последняя вариация пробовал по разному, как и по разному формировал запрос HID Get_Report. В результате либо ошибка, а если нет ошибки, то возвращается сам запрос. Также игрался с настройками периода передачи Set_Idle, но ничего не помогает. По стандарту данные c устройства HID нужно читать через канал Interrupt IN, но так же можно через канал Control ENDP0. Подскажите, что я делаю не так?
|
|
|
|
|
 |
Ответов
|
Nov 6 2012, 09:07
|

Местный
  
Группа: Свой
Сообщений: 421
Регистрация: 27-05-05
Из: Энергодар
Пользователь №: 5 480

|
Не получается ни так ни этак. Что-то совсем запутался, уже не знаю, что и делать. Пытаюсь организовать канал прерывания для чтения репорта мыши. Подскажите, как правильно сформировать список TD для запроса данных IN прерывания? Один из моих вариантов. Код // |Формируем структуру дескриптора конечной точки ED AT91F_CreateEd( (unsigned int) &pCtrlED, // ED Address 8, // Max packet size 0, // TD format 1, // Skip 1, // Speed = "Low" ("0" <=> "Full", "1" <=> "Low") 0x0, // Direction (брать из поля PID Td) 0x1, // Endpoint Address FuncAddress, // Func Address (unsigned int) &pCtrlTD[2], // TDQTailPointer (unsigned int) &pCtrlTD[0], // TDQHeadPointer 0, // ToggleCarry 0x0); // NextED
//Data IN AT91F_CreateGenTd( (unsigned int) &pCtrlTD[0], // TD Address 3, // Data Toggle (First data packet <=> всегда DATA1) 0x00, // DelayInterrupt 0x2, // Direction ("2" <=> In) 1, // Buffer Rounding (unsigned int) buffer, // Current Buffer Pointer (сюда принимаем данные) (unsigned int) &pCtrlTD[1], // Next TD 5); // Buffer Length
//Status OUT AT91F_CreateGenTd( (unsigned int) &pCtrlTD[1], // TD Address 3, // Data Toggle (Status packet <=> всегда DATA1) 0x00, // DelayInterrupt 0x01, // Direction ("1" <=> Out) 1, // Buffer Rounding 0x0, // Current Buffer Pointer (unsigned int) &pCtrlTD[2], // Next TD 0x0); // Buffer Length
// Этот TD хостом никогда не обрабатывается AT91F_CreateGenTd( (unsigned int) &pCtrlTD[2], // TD Address 3, // Data Toggle 0x00, // DelayInterrupt 0x01, // Direction ("1" <=> Out) 1, // Buffer Rounding 0x0, // Current Buffer Pointer (unsigned int) 0, // Next TD 0x0); // Buffer Length После я подсоединяю ED к HCCA. HccaInterrruptTable[0] и установив бит PLE в HcControl. Ждем события мыши, так как предварительно было установлено Idle = 0. Нажав на кнопку мыши, я принимаю первый пакет данных, в buffer записываются прочитанные данные и они вроде правильные. Но в pCtrlTD[1].control в поле CC = 5 ошибка DEVICENOTRESPONDING Device did not respond to token (IN) or did not provide a handshake (OUT) И все от мыши больше ничего принять нельзя. Перечитал кучу литературы с нулевым результатов. Передача прерывания состоит из трех пакетов Token Packet Data Packet H/S Packet pCtrlTD[0] – это Data Packet pCtrlTD[1] – должен быть H/S Packet (но он передается с ошибкой) Кто формирует Token Packet. Думаю, что его формирует OHCI из ED, но может его нужно указывать явно через дополнительный TD (так тоже пробовал, но ничего не получилось). Подскажите хотя бы правильное направление, а то три недели стою на месте уже не знаю что и делать.
|
|
|
|
|
Nov 7 2012, 09:06
|

Местный
  
Группа: Свой
Сообщений: 421
Регистрация: 27-05-05
Из: Энергодар
Пользователь №: 5 480

|
Нашел два файла, где есть пример чтения репортов мыши через канал прерывания. Правда у меня вызывает сомнение реализация функции заполнения дескриптора конечной точки. Код void OHCI_Create_ed (tED **ed, tTD **td, u32 FA, u32 EN, u32 D, u32 S, u32 K, u32 F, u32 MPS) { if (((*ed) != NULL) || ((*td) != NULL)) rExit("OHCI_Create_ed failed."); (*ed) = rmalloc16B ("HC_ENDPOINT_DESCRIPTOR"); (*ed)->Control = 0; (*ed)->Control |= (FA << 0); //7-bit (*ed)->Control |= (EN << 7); //2-bit (*ed)->Control |= (D << 9); //2-bit (*ed)->Control |= (S << 11); //1-bit (*ed)->Control |= (K << 12); //1-bit (*ed)->Control |= (F << 13); //1-bit (*ed)->Control |= (MPS<< 14); (*td) = rmalloc16B ("HC_TRANSFER_DESCRIPTOR"); (*td)->Control = 0; (*td)->CBP = NULL; (*td)->NextTD = NULL; (*td)->BE = NULL; (*ed)->TailP = (*td); (*ed)->HeadP = (*td); (*ed)->NextED = NULL; } Не сходятся со стандартом биты которые устанавливаются в Control Код (D << 9),(S << 11),(K << 12),(F << 13),(MPS<< 14); Должно быть так Код (D << 11),(S << 13),(K << 14),(F << 15),(MPS<< 16); В исходниках по тексту видно, что при, заполнении ED программист подбирал значения, но не везде. Поэтому не понятно работоспособен ли данный пример. Сделал ED, TD как в примере. Код // Формируем структуру дескриптора конечной точки ED AT91F_CreateEd( (unsigned int) &pED, // ED Address 8, // Max packet size 0, // TD format 1, // Skip 1, // Speed = "Low" ("0" <=> "Full", "1" <=> "Low") 0x0, // Direction (брать из поля PID Td) 0x1, // Endpoint Address FuncAddress, // Func Address (unsigned int) &pTD[1], // TDQTailPointer (unsigned int) &pTD[0], // TDQHeadPointer 0, // ToggleCarry 0x0); // NextED
// Формируем структуры дескрипторов передачи ТD //Data IN AT91F_CreateGenTd( (unsigned int) &pTD[0], // TD Address 3, // Data Toggle (First data packet <=> всегда DATA1) 0x00, // DelayInterrupt 0x2, // Direction ("2" <=> In) 1, // Buffer Rounding (unsigned int) buffer, // Current Buffer Pointer (сюда принимаем данные) (unsigned int) &pTD[1], // Next TD 4); // Buffer Length
// Этот TD хостом не должен обрабатывается AT91F_CreateGenTd( (unsigned int) &pTD[1], // TD Address 0, // Data Toggle 0, // DelayInterrupt 0, // Direction ("1" <=> Out) 0, // Buffer Rounding 0, // Current Buffer Pointer (unsigned int) 0, // Next TD 0); // Buffer Length Пропали ошибки. Стал отлавливать события от мыши. Вот только в приемном буфере одни нули. Ладно будем разбираться дальше. Файлы примера прикладываю.
|
|
|
|
|
Nov 8 2012, 07:04
|

Местный
  
Группа: Свой
Сообщений: 421
Регистрация: 27-05-05
Из: Энергодар
Пользователь №: 5 480

|
Наметился прогресс. Только странно это как то.
В спецификации сказано что ED и TD должны быть выровнены по границе 16 бит, что и делаю. Должен ли быть выровнен приемный буфер (который указываем в регистре CBP дескриптора передачи TD) ничего не сказано (или не нашел где указано). Выровнял приемный буфер по границе диапазона и начал принимать данные, но через раз.
В данный момент у меня настроена только одна конечная точка прерываний, другими словами читаю данные один раз в 32 мсек. В дескрипторе конечной точки мыши читаем, что значение интервала опроса должно быть 10 мсек. получается надо настраивать опрос конечной точки один раз в 8 мсек. Думаю, что в этом заключается проблема потери данных или…. (см. ниже)
Не понятно, что делать с DATA TOGLE (DT). 1 Переключение (DT) происходит в процессе передачи пакетов данных, которые больше чем максимальный пакет, разрешенный для устройства? (В пределах одной транзакции) 2 Данные должны переключаются каждый раз при приеме очередного пакета? (В каждой отдельной транзакции).
Сейчас, я читаю данные каждый раз с DT=1 предполагая, что процесс проходит по типу вопроса 1.
Вечером буду проверять.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|