реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> USB HID LPC1343
IgorAVR2
сообщение Feb 8 2011, 21:41
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 29-05-08
Пользователь №: 37 901



В LPC1343 есть встроенный драйвер USB HID устройства. Всё хорошо, всё работает, только есть вот одно но...

Процедура GetInReport, от которой идут данные в компьютер, вызывается с заданным интервалом по таймеру. То есть с определённым интервалом пакеты уходят в компьютер. Как сделать что бы репорты уходили не с определённым интервалом, а только тогда, когда мне это нужно, то есть тогда когда у меня есть данные на отправку? Так например работает мышка: двигаем - пошли пакеты, перестали двигать - пакеты не уходят. И как это организованно в других мк с USB при реализации HID?
Go to the top of the page
 
+Quote Post
kovigor
сообщение Feb 9 2011, 09:07
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(IgorAVR2 @ Feb 9 2011, 01:41) *
Как сделать что бы репорты уходили не с определённым интервалом, а только тогда, когда мне это нужно, то есть тогда когда у меня есть данные на отправку?


Именно так оно и работает. Если вы имеете данные для отправки, то вы загружаете их в буфер конечной точки, и при поступлении запроса от хоста эти данные уходят ему. Если же у вас нет данных, то вы ничего не загружаете в буфер конечной точки, и хост в ответ на свои запросы получает NAK. Вы можете только задать интенсивность прерываний (Interrupt In) от хоста в дескрипторе конечной точки прерывания, и все. Для мышей и клавиатур это значение всегда равно десяти. Аппаратный таймер внутри МК здесь не при чем. Хотя, конечно, вы можете по этому таймеру готовить очередные порции данных для отправки их хосту ...

Сообщение отредактировал kovigor - Feb 9 2011, 09:08
Go to the top of the page
 
+Quote Post
IgorAVR2
сообщение Feb 9 2011, 22:38
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 29-05-08
Пользователь №: 37 901



Да в том то и дело, что данные для отправки я кладу в массив, а не напрямую в буффер конечной точки. А если я даже туда ничео не положил то всё равно компьютеру отправляетя содержимое этого массива. То есть через фиксированный интервал всегда уходят данные. И никакого NAK видимо хосту не уходит... Как быть?
Go to the top of the page
 
+Quote Post
kovigor
сообщение Feb 10 2011, 07:22
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(IgorAVR2 @ Feb 10 2011, 01:38) *
Да в том то и дело, что данные для отправки я кладу в массив, а не напрямую в буффер конечной точки. А если я даже туда ничео не положил то всё равно компьютеру отправляетя содержимое этого массива. То есть через фиксированный интервал всегда уходят данные. И никакого NAK видимо хосту не уходит... Как быть?


Чудес не бывает. Если данные уходят хосту, то они были кем-то положены в буфер конечной точки. Кем ? Вопрос. Первый вариант - вами лично. Второй - подсистемой DMA. Возможно, в том проекте, который вы исследуете, используется DMA, и именно он перекладывает данные из вашего массива в буфер конечной точки. Одно я могу вам сказать совершенно точно. Досконально разобрать этот пример вам все же придется. А после его разбирания отпадут и подобные вопросы ...
Go to the top of the page
 
+Quote Post
IgorAVR2
сообщение Feb 10 2011, 07:30
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 29-05-08
Пользователь №: 37 901



Да я уже всё досканально разобрал, всё по сто раз перечитал, но про это там ни слова. Либо там по другому нельзя и аппаратный вшитый драйвер умеет только так, либо кто бы мне подсказал, знающий кокретно по этому вопросу...
Go to the top of the page
 
+Quote Post
kovigor
сообщение Feb 10 2011, 07:36
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(IgorAVR2 @ Feb 10 2011, 10:30) *
Да я уже всё досканально разобрал, всё по сто раз перечитал, но про это там ни слова. Либо там по другому нельзя и аппаратный вшитый драйвер умеет только так, либо кто бы мне подсказал, знающий кокретно по этому вопросу...


А откуда вы знаете, какие именно данные приходят хосту ? Чем вы это проверяли ?
Go to the top of the page
 
+Quote Post
IgorAVR2
сообщение Feb 10 2011, 20:13
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 29-05-08
Пользователь №: 37 901



Цитата(kovigor @ Feb 10 2011, 10:36) *
А откуда вы знаете, какие именно данные приходят хосту ? Чем вы это проверяли ?


Ну как откуда? Во первых есть прога "USB Port Monitor", а во вторых это же принимает моя прога для PC.
Go to the top of the page
 
+Quote Post
EXeGLuMATOR
сообщение Feb 21 2011, 22:57
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 182
Регистрация: 30-01-05
Из: Volgograd
Пользователь №: 2 305



Ковырялся тоже с этим камушком.
Тут дело в другом - если хосту не ответить на запрос - то он перестанет опрашивать ваш девайс.
И еще - почему-то при использовании встроенного аппаратного HID у меня не получилось завести ядро на частоте выше 12МГц. Если обычным образом - контроллер и софт, то все нормально.
Я поступил в данном случае проще - в обработчике, который вызывается по запросу хоста на Data_In - поставил условие, если не выставлен флажок что данные готовы - отправляется 1 байт с содержимым 0.
Если готовы - то весь буфер. Буфер используется отдельный, для подготовки данных. И в GetInReport - содержимое копируется в InReport.
Еще. В 1343 - буферы на прием и отправку, насколько помню - аппаратные, т.е. если Вы ими пользуетесь в коде где-то, то по вызову функций отправки/приема (также аппаратно) - содержимое уйдет автоматически.
Go to the top of the page
 
+Quote Post
IgorAVR2
сообщение Feb 27 2011, 21:40
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 29-05-08
Пользователь №: 37 901



Цитата(EXeGLuMATOR @ Feb 22 2011, 01:57) *
Ковырялся тоже с этим камушком.
Тут дело в другом - если хосту не ответить на запрос - то он перестанет опрашивать ваш девайс.
И еще - почему-то при использовании встроенного аппаратного HID у меня не получилось завести ядро на частоте выше 12МГц. Если обычным образом - контроллер и софт, то все нормально.
Я поступил в данном случае проще - в обработчике, который вызывается по запросу хоста на Data_In - поставил условие, если не выставлен флажок что данные готовы - отправляется 1 байт с содержимым 0.
Если готовы - то весь буфер. Буфер используется отдельный, для подготовки данных. И в GetInReport - содержимое копируется в InReport.
Еще. В 1343 - буферы на прием и отправку, насколько помню - аппаратные, т.е. если Вы ими пользуетесь в коде где-то, то по вызову функций отправки/приема (также аппаратно) - содержимое уйдет автоматически.


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

А как вы отправляете один байт с содержимым 0 ? У нас же размер репорта изначально описан и длинна его не может меняться? То есть мы не можем отправить или один байт или несколько за один раз?
Go to the top of the page
 
+Quote Post
kovigor
сообщение Feb 28 2011, 09:02
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(IgorAVR2 @ Feb 28 2011, 00:40) *
Насколько я понимаю это дело, то если у девайса нет данных для отправки хосту, то он должен ответить хосту что у него нет данных и всё и не слать данные. ... Так вот как так сделать?


Просто не кладите ничего в буфер конечной точки. Тогда хосту вместо блока данных будет отправлен NAK ...

Сообщение отредактировал kovigor - Feb 28 2011, 09:03
Go to the top of the page
 
+Quote Post
IgorAVR2
сообщение Feb 28 2011, 14:24
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 29-05-08
Пользователь №: 37 901



Цитата(kovigor @ Feb 28 2011, 12:02) *
Просто не кладите ничего в буфер конечной точки. Тогда хосту вместо блока данных будет отправлен NAK ...



Так у меня и нет там как такового буффера. У меня есть массив, и если я даже его не меняю он отправляет предыдущее его содержимое.
Go to the top of the page
 
+Quote Post
goodwin
сообщение Apr 22 2012, 07:42
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 481
Регистрация: 1-08-05
Пользователь №: 7 267



Подниму тему...

Писателям этого ROM HID драйвера оторвать бы причинное место sm.gif
Задумано хорошо, реализовано безбашенно.
Получилась игрушка. А жаль. Неплохое подспорье для экономии программной памяти и упрощения кода.

Проблема в том, что InReport постоянно шлет данные в комп. Когда надо и не надо... Соответственно, при при небольшом интервале поллинга и максимальном размере данных (64 байт) даже мой довольно шустрый комп грузит процессор под 6%. Т.е. отсутствует возможность ответить NAK при отсутствии данных. Что можно подкрутить? После инициализации ROM драйвера в программе доступен только обработчик прерывания USB (собственно, там все и крутится) и это единственная возможность подлезть, чтобы как то поправить ситуевину. В оригинале там просто вызывается подпрограмма обработчика из ROM. Есть мысль, что можно как то обработать прерываание InReport самостоятельно, заставить принудительно ответить NAK, если нет данных. Но "сала в голове", увы, не хватает wink.gif И неизвестно, что там наворотили в ROM драйверописцы (впрочем, имхо, там то же, что и в примерах HID от NXP, не использующих ROM драйвер и старадающей той же болячкой...) Может кто-либо решил эту проблему?

Go to the top of the page
 
+Quote Post
goodwin
сообщение Apr 24 2012, 07:14
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 481
Регистрация: 1-08-05
Пользователь №: 7 267



Попробовал подлезть и так, и эдак.
Код в ROM не похож на тот, что идет в примерах от NXP и кейла.
Махнул рукой.
Решил, что для HID загрузчика подойдет и ROM драйвер - сильно экономит место. Даже много лишнего остается wink.gif
Ибо все-равно одна 4 кб страница будет отдана под загрузчик. "Кривизна" там существенно не мешает...
Ну а "прямой " HID драйвер - в LR ARM... Там все пучком - есть правильная функция "usbd_hid_get_report_trigger(0, buf, len)". И прерывание постоянно не щелкает - только когда инициирована передача данных. Цена вопроса - ~6 кбайт, но оно того стОит...
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Apr 24 2012, 11:21
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



goodwin, подскажите, в RL-ARM стали исходники USB класть, или оно по-прежнему в виде бинарника и горки заголовков?

На бинарники закладываться как-то неинтересно, даже если там сам ARM свечку держал :-)


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
goodwin
сообщение Apr 24 2012, 12:03
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 481
Регистрация: 1-08-05
Пользователь №: 7 267



Да - все в библиотеках.

ЗЫ:
Несколько строчек - пара десятков байт кода и все становится гораздо кузявее wink.gif
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;
}
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th April 2024 - 06:31
Рейтинг@Mail.ru


Страница сгенерированна за 0.01511 секунд с 7
ELECTRONIX ©2004-2016