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

 
 
 
Reply to this topicStart new topic
> Usbser.sys и AT91SAM7x256
antoxa1
сообщение Jan 9 2008, 09:29
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 15
Регистрация: 6-04-06
Пользователь №: 15 889



Есть плата(самоделка) на основе AT91SAM7x256. Из примеров, поставляемых с Keil, из папки Boards\Atmel\AT91SAM7S взят пример для HID устройства. Данный пример, переработан с целью исполнения CDC устройства(изменены дискрипторы и т.д. и т.п).
При подключении к шине USB устройство определяется нормально. В качестве драйвера виртуального COM порта установлен usbser.sys.
Ситуация такая: через HyperTerminal на устройство отправляется байт данных, в ответ на это устройством должен отправляется байт "подтверждения", HyperTerminal принимает этот байт в первый раз нормально..при отправке следующего байта в устройство должно произойти тоже самое, но терминал не получает никаких данных в ответ. Отправка байт в устройство проходит нормально. При этом если работать с устройством через программу BusHound(монитор шины USB) то отправка и последующий приём выполняются корректно.
Вопрос: почему терминал не принимает второй и, соответственно, последующие байты "подтверждения"? Если кто может объяснить как работать с usbser.sys(или виртуальными COMпортами), откликнитесь, пожалуйста.
P.S. мой поиск по данной теме не дал видимых результатов
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jan 9 2008, 11:07
Сообщение #2


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

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



Если CDC устройство реализовано правильно, HyperTerminal (и другие терминальные программы) нормально работают через usbser.sys до тех пор, пока не произошел disconect с USB устройством (программный или физический). Эта проблема не решена по сей день в usbser.sys.

Думаю, проблемы в твоей реализации CDC.
Go to the top of the page
 
+Quote Post
Alechek
сообщение Jan 9 2008, 13:23
Сообщение #3


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

Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882



Возможно, все-таки ошибка не в usbser.sys, а в hands.dll
Советую еще раз просмотреть процедуру приема и отправки байта в устройстве, посмотреть настройки ГИперТерминала.
У меня тоже были похожие ошибки. Когда не досылался хвост данных. Оказалось что я поздно сбрасывал флаг прерывания, в итоге события, возникшие во время прерывания обрабатывались только в следующий раз. Правда то был LPC...
Go to the top of the page
 
+Quote Post
antoxa1
сообщение Jan 9 2008, 17:23
Сообщение #4


Участник
*

Группа: Новичок
Сообщений: 15
Регистрация: 6-04-06
Пользователь №: 15 889



Ошибочен ли следующий алгоритм: от хоста отправить данные--->в обработчике прерывания конечной точки типа OUT выполнить над принятыми данными необходимые действия--->в этом же обработчике записать нужные данные в буфер конечной точки типа IN --->ждать очередного пакета данных от хоста и повторить весь алгоритм

Драйвер usbser.sys отправляет запрос на чтение данных с устройства периодически или сразу же за запросом на запись в устройство?
Go to the top of the page
 
+Quote Post
Dron_Gus
сообщение Jan 9 2008, 17:51
Сообщение #5


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

Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861



Данные в конечную точку записывать после примерно такой проверки:

Код
while ( !(pUdp->UDP_CSR[EP_IN] & AT91C_UDP_TXCOMP) );
pUdp->UDP_CSR[EP_IN] &= ~(AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[EP_IN] & AT91C_UDP_TXCOMP);


Первая строчка - дожидаемся отправки предыдущих данных.

Вторая строчка - сбрасываем флаг отправки

Третья строчка - дожидаемся сброса этого флага (USB и проц работают на разных частотах, поэтому флаг сбрасывается "не сразу")



Ну или полный код отправки пакета (пакет может быть и больше размера конечной точки):

Код
uint AT91F_UDP_Write(AT91PS_HID pHid, const char *pData, uint length)
{
AT91PS_UDP pUdp = pHid->pUdp;
uint cpt = 0;

// Send the first packet
cpt = MIN(length, EP_IN_SIZE);
length -= cpt;
while (cpt--) pUdp->UDP_FDR[EP_IN] = *pData++;
pUdp->UDP_CSR[EP_IN] |= AT91C_UDP_TXPKTRDY;

while (length) {
  // Fill the second bank
  cpt = MIN(length, EP_IN_SIZE);
  length -= cpt;
  while (cpt--) pUdp->UDP_FDR[EP_IN] = *pData++;
  // Wait for the the first bank to be sent
                //while ( !(AT91S_UDP_EP[EP_IN].CSR & AT91C_UDP_TXCOMP))
  while ( !(pUdp->UDP_CSR[EP_IN] & AT91C_UDP_TXCOMP) )
   if ( !AT91F_UDP_IsConfigured(pHid) ) return length;
  pUdp->UDP_CSR[EP_IN] &= ~(AT91C_UDP_TXCOMP);
                //AT91S_UDP_EP[EP_IN].CSR &= ~(AT91C_UDP_TXCOMP);
  while (pUdp->UDP_CSR[EP_IN] & AT91C_UDP_TXCOMP);
                //while (AT91S_UDP_EP[EP_IN].CSR & AT91C_UDP_TXCOMP);
  pUdp->UDP_CSR[EP_IN] |= AT91C_UDP_TXPKTRDY;
}
// Wait for the end of transfer
return length;
}




З.Ы. Выдрано откуда-то из примеров Atmel.


--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
Go to the top of the page
 
+Quote Post
Alechek
сообщение Jan 9 2008, 18:17
Сообщение #6


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

Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882



Цитата(antoxa1 @ Jan 9 2008, 23:23) *
Ошибочен ли следующий алгоритм: от хоста отправить данные--->в обработчике прерывания конечной точки типа OUT выполнить над принятыми данными необходимые действия--->в этом же обработчике записать нужные данные в буфер конечной точки типа IN --->ждать очередного пакета данных от хоста и повторить весь алгоритм

Смотря какой размер входных данных, помещаются ли они в одной Endpoint, идут ли они одной Булкой, посылаются ли с HT какие-то служебные символы (\r\n etc). Как ведет себя точка IN при поступлении запроса на посылку данных, но попылать нечего? И тп.. Ньюансов больше чем кажется. Самый простой вариант - не очищается буфер приема после принятия данных.

Цитата
Драйвер usbser.sys отправляет запрос на чтение данных с устройства периодически или сразу же за запросом на запись в устройство?

Драйвер ничего не запрашивает с устройства, он общается только с хост-контроллером. а вот хост уже запрашивает данные с устройств. Периодически, с максимальным периодом
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jan 9 2008, 19:03
Сообщение #7


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

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



Уж не знаю сколько раз здесь на форуме говорилось и в куче умных книжек написано - время нахождения в прерывании должно быть минимальным. К чему городить все эти навороты с перепосылом чего-то обратно прямо тут-же в прерывании? Получается какай-то каша из квитирования сигналов и собственно прерываний. Хочется самому все программно раскручивать - не используй прерывания вообще.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 3rd July 2025 - 03:18
Рейтинг@Mail.ru


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