Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Usbser.sys и AT91SAM7x256
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
antoxa1
Есть плата(самоделка) на основе AT91SAM7x256. Из примеров, поставляемых с Keil, из папки Boards\Atmel\AT91SAM7S взят пример для HID устройства. Данный пример, переработан с целью исполнения CDC устройства(изменены дискрипторы и т.д. и т.п).
При подключении к шине USB устройство определяется нормально. В качестве драйвера виртуального COM порта установлен usbser.sys.
Ситуация такая: через HyperTerminal на устройство отправляется байт данных, в ответ на это устройством должен отправляется байт "подтверждения", HyperTerminal принимает этот байт в первый раз нормально..при отправке следующего байта в устройство должно произойти тоже самое, но терминал не получает никаких данных в ответ. Отправка байт в устройство проходит нормально. При этом если работать с устройством через программу BusHound(монитор шины USB) то отправка и последующий приём выполняются корректно.
Вопрос: почему терминал не принимает второй и, соответственно, последующие байты "подтверждения"? Если кто может объяснить как работать с usbser.sys(или виртуальными COMпортами), откликнитесь, пожалуйста.
P.S. мой поиск по данной теме не дал видимых результатов
sergeeff
Если CDC устройство реализовано правильно, HyperTerminal (и другие терминальные программы) нормально работают через usbser.sys до тех пор, пока не произошел disconect с USB устройством (программный или физический). Эта проблема не решена по сей день в usbser.sys.

Думаю, проблемы в твоей реализации CDC.
Alechek
Возможно, все-таки ошибка не в usbser.sys, а в hands.dll
Советую еще раз просмотреть процедуру приема и отправки байта в устройстве, посмотреть настройки ГИперТерминала.
У меня тоже были похожие ошибки. Когда не досылался хвост данных. Оказалось что я поздно сбрасывал флаг прерывания, в итоге события, возникшие во время прерывания обрабатывались только в следующий раз. Правда то был LPC...
antoxa1
Ошибочен ли следующий алгоритм: от хоста отправить данные--->в обработчике прерывания конечной точки типа OUT выполнить над принятыми данными необходимые действия--->в этом же обработчике записать нужные данные в буфер конечной точки типа IN --->ждать очередного пакета данных от хоста и повторить весь алгоритм

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

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

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

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

Драйвер ничего не запрашивает с устройства, он общается только с хост-контроллером. а вот хост уже запрашивает данные с устройств. Периодически, с максимальным периодом
sergeeff
Уж не знаю сколько раз здесь на форуме говорилось и в куче умных книжек написано - время нахождения в прерывании должно быть минимальным. К чему городить все эти навороты с перепосылом чего-то обратно прямо тут-же в прерывании? Получается какай-то каша из квитирования сигналов и собственно прерываний. Хочется самому все программно раскручивать - не используй прерывания вообще.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.