|
|
|
USB HID LPC1343 |
|
|
|
Feb 9 2011, 09:07
|
Гуру
Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295
|
Цитата(IgorAVR2 @ Feb 9 2011, 01:41) Как сделать что бы репорты уходили не с определённым интервалом, а только тогда, когда мне это нужно, то есть тогда когда у меня есть данные на отправку? Именно так оно и работает. Если вы имеете данные для отправки, то вы загружаете их в буфер конечной точки, и при поступлении запроса от хоста эти данные уходят ему. Если же у вас нет данных, то вы ничего не загружаете в буфер конечной точки, и хост в ответ на свои запросы получает NAK. Вы можете только задать интенсивность прерываний (Interrupt In) от хоста в дескрипторе конечной точки прерывания, и все. Для мышей и клавиатур это значение всегда равно десяти. Аппаратный таймер внутри МК здесь не при чем. Хотя, конечно, вы можете по этому таймеру готовить очередные порции данных для отправки их хосту ...
Сообщение отредактировал kovigor - Feb 9 2011, 09:08
|
|
|
|
|
Feb 10 2011, 20:13
|
Частый гость
Группа: Участник
Сообщений: 153
Регистрация: 29-05-08
Пользователь №: 37 901
|
Цитата(kovigor @ Feb 10 2011, 10:36) А откуда вы знаете, какие именно данные приходят хосту ? Чем вы это проверяли ? Ну как откуда? Во первых есть прога "USB Port Monitor", а во вторых это же принимает моя прога для PC.
|
|
|
|
|
Feb 27 2011, 21:40
|
Частый гость
Группа: Участник
Сообщений: 153
Регистрация: 29-05-08
Пользователь №: 37 901
|
Цитата(EXeGLuMATOR @ Feb 22 2011, 01:57) Ковырялся тоже с этим камушком. Тут дело в другом - если хосту не ответить на запрос - то он перестанет опрашивать ваш девайс. И еще - почему-то при использовании встроенного аппаратного HID у меня не получилось завести ядро на частоте выше 12МГц. Если обычным образом - контроллер и софт, то все нормально. Я поступил в данном случае проще - в обработчике, который вызывается по запросу хоста на Data_In - поставил условие, если не выставлен флажок что данные готовы - отправляется 1 байт с содержимым 0. Если готовы - то весь буфер. Буфер используется отдельный, для подготовки данных. И в GetInReport - содержимое копируется в InReport. Еще. В 1343 - буферы на прием и отправку, насколько помню - аппаратные, т.е. если Вы ими пользуетесь в коде где-то, то по вызову функций отправки/приема (также аппаратно) - содержимое уйдет автоматически. Насколько я понимаю это дело, то если у девайса нет данных для отправки хосту, то он должен ответить хосту что у него нет данных и всё и не слать данные. И поэтому хост не перестанет опрашивать девайс. Так работает мышка, как я писал выше. Так вот как так сделать? А как вы отправляете один байт с содержимым 0 ? У нас же размер репорта изначально описан и длинна его не может меняться? То есть мы не можем отправить или один байт или несколько за один раз?
|
|
|
|
|
Feb 28 2011, 14:24
|
Частый гость
Группа: Участник
Сообщений: 153
Регистрация: 29-05-08
Пользователь №: 37 901
|
Цитата(kovigor @ Feb 28 2011, 12:02) Просто не кладите ничего в буфер конечной точки. Тогда хосту вместо блока данных будет отправлен NAK ... Так у меня и нет там как такового буффера. У меня есть массив, и если я даже его не меняю он отправляет предыдущее его содержимое.
|
|
|
|
|
Apr 22 2012, 07:42
|
Местный
Группа: Свой
Сообщений: 481
Регистрация: 1-08-05
Пользователь №: 7 267
|
Подниму тему... Писателям этого ROM HID драйвера оторвать бы причинное место Задумано хорошо, реализовано безбашенно. Получилась игрушка. А жаль. Неплохое подспорье для экономии программной памяти и упрощения кода. Проблема в том, что InReport постоянно шлет данные в комп. Когда надо и не надо... Соответственно, при при небольшом интервале поллинга и максимальном размере данных (64 байт) даже мой довольно шустрый комп грузит процессор под 6%. Т.е. отсутствует возможность ответить NAK при отсутствии данных. Что можно подкрутить? После инициализации ROM драйвера в программе доступен только обработчик прерывания USB (собственно, там все и крутится) и это единственная возможность подлезть, чтобы как то поправить ситуевину. В оригинале там просто вызывается подпрограмма обработчика из ROM. Есть мысль, что можно как то обработать прерываание InReport самостоятельно, заставить принудительно ответить NAK, если нет данных. Но "сала в голове", увы, не хватает И неизвестно, что там наворотили в ROM драйверописцы (впрочем, имхо, там то же, что и в примерах HID от NXP, не использующих ROM драйвер и старадающей той же болячкой...) Может кто-либо решил эту проблему?
|
|
|
|
|
Apr 24 2012, 07:14
|
Местный
Группа: Свой
Сообщений: 481
Регистрация: 1-08-05
Пользователь №: 7 267
|
Попробовал подлезть и так, и эдак. Код в ROM не похож на тот, что идет в примерах от NXP и кейла. Махнул рукой. Решил, что для HID загрузчика подойдет и ROM драйвер - сильно экономит место. Даже много лишнего остается Ибо все-равно одна 4 кб страница будет отдана под загрузчик. "Кривизна" там существенно не мешает... Ну а "прямой " HID драйвер - в LR ARM... Там все пучком - есть правильная функция "usbd_hid_get_report_trigger(0, buf, len)". И прерывание постоянно не щелкает - только когда инициирована передача данных. Цена вопроса - ~6 кбайт, но оно того стОит...
|
|
|
|
|
Apr 24 2012, 12:03
|
Местный
Группа: Свой
Сообщений: 481
Регистрация: 1-08-05
Пользователь №: 7 267
|
Да - все в библиотеках. ЗЫ: Несколько строчек - пара десятков байт кода и все становится гораздо кузявее Program Size: Code=790 RO-data=426 RW-data=20 ZI-data=540 гораздо приятственнее чем 6 кБ кода RL. Магическая цифирька 0x10 простительна - вряд ли ROM изменится... Ну еще возможно надо проконтролировать в prepare_send () ушли ли предыдущие данные... Код #define INT_IN_EP 0x10 // это бит прерывания Input Report #define CCEMTY_INT (0x1<<10) #define CMD_SEL_EP_CLRI(x) (0x00400500 | ((x) << 16))
uint8_t fl_send=0; // флаг посылки данных
void WrCmd (uint32_t cmd) { LPC_USB->DevIntClr = CCEMTY_INT; LPC_USB->CmdCode = cmd; while ((LPC_USB->DevIntSt & CCEMTY_INT) == 0); }
USB_IRQHandler(void) { uint32_t disr; disr = LPC_USB->DevIntSt; /* Device Interrupt Status */ if ((disr & INT_IN_EP) && (!fl_send)) // тут проверим кинунуть гада или таки послать данные { LPC_USB->DevIntClr = disr & INT_IN_EP; // сбросим флаг прерывания WrCmd(CMD_SEL_EP_CLRI(INT_IN_EP>>1)); // в железе тоже } else (*rom)->pUSBD->isr();
} /* * Get HID Input Report -> InReport */ void GetInReport (uint8_t src[], uint32_t length) { fl_send=0; // сбросим флаг посылки данных // здесь делаем , что надо return; }
void prepare_send (void) { fl_send=1; // взведем флаг посылки двнных LPC_USB->DevIntSet|=INT_IN_EP; // взведем флаг прерывания GetInReport }
/* * Set HID Output Report <- OutReport */ void SetOutReport (uint8_t dst[], uint32_t length) { // здесь делаем , что надо... prepare_send(); // для примера тут инициируем посылку данных в ответ... return; }
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|