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

 
 
> Непонятки с UDP у SAM7S64
sgrig
сообщение May 24 2007, 07:35
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 4-11-05
Из: Tomsk
Пользователь №: 10 464



Зашел в тупик, бьюсь не первый день. Может, что подскажете?

Делаю HID-устройство на SAM7S64.
Обслуживаю прерывание от EP0 стандартно: получаю запрос, разгребаю его и отправляю в ответ дескриптор или репорт. Для справки: размер EP0 равен 8 байтам, а дескрипторы и репорты могут быть больше.

Суть проблемы:
Если перед загрузкой в FIFO очередной порции данных флаг TXCOMP опрашиваю поллингом в цикле (так сделано в примере HID mouse от Atmel) - все работает как надо, вопросов нет. Но крутиться в прерывании как-то некрасиво.
Если же я начинаю делать "подкачку" данных в прерывании по TXCOMP, то, почему-то, не отправляется уже вторая порция данных.

Например, обрабатывается запрос хоста GET_DESCRIPTOR_DEVICE:
1) по прерыванию от EP0 выгребаю запрос из FIFO
2) формирую дескриптор устройства
3) первые 8 байт дескриптора загружаю в FIFO и поднимаю TXPKTRDY
4) жду прерывания от TXCOMP - и оно приходит
5) сбрасываю TXCOMP
6) очередную порцию дескриптора загружаю в FIFO и поднимаю TXPKTRDY
и ничего не передается, хост ждет некоторое время и обрывает транзакцию IN.

Про необходимость правильной реакции на обрыв транзакции знаю.
Где могут быть грабли? Любые соображения приму с багодарностью.

PS. Обратите внимание, что в случае поллинга флага TXCOMP все работает как часы, поэтому обсуждать правильность реализации протокола, видимо, не имеет смысла.
Go to the top of the page
 
+Quote Post
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 14)
KAlex
сообщение May 24 2007, 08:24
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 387
Регистрация: 20-12-06
Из: Obninsk
Пользователь №: 23 719



Цитата(sgrig @ May 24 2007, 11:35) *
5) сбрасываю TXCOMP

Попробуй так
if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
}
Go to the top of the page
 
+Quote Post
sgrig
сообщение May 24 2007, 08:35
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 4-11-05
Из: Tomsk
Пользователь №: 10 464



Цитата(KAlex @ May 24 2007, 15:24) *
Попробуй так
if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
}


Так и делаю, примеры я разобрал по "косточкам" и все попробовал. Похоже, я чего-то не понимаю.
Кстати, такая же "подкачка" для TWI работает без проблем.
Go to the top of the page
 
+Quote Post
KAlex
сообщение May 24 2007, 09:32
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 387
Регистрация: 20-12-06
Из: Obninsk
Пользователь №: 23 719



Вот кусок рабочего кода. Никаких прерываний. AT91F_UDP_IsConfigured вызывается постоянно из основного цикла.
__arm static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, u_int length){
u_int cpt = 0;
AT91_REG csr;
do { cpt = MIN(length, 8);
length -= cpt;
while (pUdp->UDP_CSR[0] & AT91C_UDP_TXPKTRDY)
if ( pUdp->UDP_ISR & AT91C_UDP_RXSUSP ) return;
while (cpt--) pUdp->UDP_FDR[0] = *pData++;
if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
}
pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
do {
csr = pUdp->UDP_CSR[0];
// Data IN stage has been stopped by a status OUT
if (csr & AT91C_UDP_RX_DATA_BK0) {
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);
return;
}
} while ( !(csr & AT91C_UDP_TXCOMP) );
} while (length);
if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
}
}

__arm void AT91F_USB_SendStall(AT91PS_UDP pUdp)
{
pUdp->UDP_CSR[0] |= AT91C_UDP_FORCESTALL;
while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_ISOERROR) );
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);
AT91F_UDP_ResetEp ( pUdp, 1);
while (pUdp->UDP_CSR[0] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR));
}

__arm static void AT91F_HID_Enumerate(AT91PS_HID pHid)
{
AT91PS_UDP pUDP = pHid->pUdp;
uc08 bmRequestType, bRequest;
ushort wValue, wIndex, wLength, wStatus;

if ( !(pUDP->UDP_CSR[0] & AT91C_UDP_RXSETUP) ) return;

bmRequestType = pUDP->UDP_FDR[0];
bRequest = pUDP->UDP_FDR[0];
wValue = (pUDP->UDP_FDR[0] & 0xFF);
wValue |= (pUDP->UDP_FDR[0] << 8);
wIndex = (pUDP->UDP_FDR[0] & 0xFF);
wIndex |= (pUDP->UDP_FDR[0] << 8);
wLength = (pUDP->UDP_FDR[0] & 0xFF);
wLength |= (pUDP->UDP_FDR[0] << 8);

if (bmRequestType & 0x80) {
pUDP->UDP_CSR[0] |= AT91C_UDP_DIR;
while ( !(pUDP->UDP_CSR[0] & AT91C_UDP_DIR) );
}
pUDP->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;
while ( (pUDP->UDP_CSR[0] & AT91C_UDP_RXSETUP) );

// Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1
switch ((bRequest << 8) | bmRequestType) {
case STD_GET_DESCRIPTOR:
run = 0;
if (wValue == 0x100) // Return Device Descriptor
AT91F_USB_SendData(pUDP, devDescriptor, MIN(sizeof(devDescriptor), wLength));
else if (wValue == 0x200) // Return Configuration Descriptor
AT91F_USB_SendData(pUDP, cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));
else if (wValue == 0x300) // Return Configuration Descriptor
AT91F_USB_SendData(pUDP, String0, MIN(sizeof(String0), wLength));
else if (wValue == 0x302) // Return Configuration Descriptor
AT91F_USB_SendData(pUDP, String1, MIN(sizeof(String1), wLength));
else if (wValue == 0x303) // Return Configuration Descriptor
AT91F_USB_SendData(pUDP, String1, MIN(sizeof(String1), wLength));
else
AT91F_USB_SendStall(pUDP);
break;
... поскипано
__arm static uc08 AT91F_UDP_IsConfigured(AT91PS_HID pHid)
{
AT91PS_UDP pUDP = pHid->pUdp;
AT91_REG isr = pUDP->UDP_ISR;

if (isr & AT91C_UDP_ENDBUSRES) {
pUDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
// reset all endpoints
pUDP->UDP_RSTEP = (unsigned int) -1;
pUDP->UDP_RSTEP = 0;
// Enable the function
pUDP->UDP_FADDR = AT91C_UDP_FEN;
// Configure endpoint 0
pUDP->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
}
else if (isr & AT91C_UDP_EPINT0) {
pUDP->UDP_ICR = AT91C_UDP_EPINT0;
AT91F_HID_Enumerate(pHid);
}
...поскипано
Go to the top of the page
 
+Quote Post
sgrig
сообщение May 24 2007, 12:45
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 4-11-05
Из: Tomsk
Пользователь №: 10 464



Цитата(KAlex @ May 24 2007, 16:32) *
Вот кусок рабочего кода. Никаких прерываний. AT91F_UDP_IsConfigured вызывается постоянно из основного цикла.
...................................


Вопрос как раз и состоял в том, как это все заставить работать ПО ПРЕРЫВАНИЯМ.
Без прерываний проблем нет, но это же вариант совсем пионерский.
Go to the top of the page
 
+Quote Post
KAlex
сообщение May 24 2007, 13:17
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 387
Регистрация: 20-12-06
Из: Obninsk
Пользователь №: 23 719



Цитата(sgrig @ May 24 2007, 11:35) *
Например, обрабатывается запрос хоста GET_DESCRIPTOR_DEVICE:
1) по прерыванию от EP0 выгребаю запрос из FIFO
2) формирую дескриптор устройства
3) первые 8 байт дескриптора загружаю в FIFO и поднимаю TXPKTRDY
4) жду прерывания от TXCOMP - и оно приходит
5) сбрасываю TXCOMP
6) очередную порцию дескриптора загружаю в FIFO и поднимаю TXPKTRDY
и ничего не передается, хост ждет некоторое время и обрывает транзакцию IN.

О! А проверка TXPKTRDY где?
Go to the top of the page
 
+Quote Post
sgrig
сообщение May 24 2007, 14:40
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 4-11-05
Из: Tomsk
Пользователь №: 10 464



Цитата(KAlex @ May 24 2007, 20:17) *
О! А проверка TXPKTRDY где?

А вот с этого места, пожалуйста, подробнее. Зачем его проверять? Ведь TXCOMP устанавливается после падения TXPKTRDY.
Go to the top of the page
 
+Quote Post
KAlex
сообщение May 25 2007, 07:41
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 387
Регистрация: 20-12-06
Из: Obninsk
Пользователь №: 23 719



Цитата(sgrig @ May 24 2007, 18:40) *
Ведь TXCOMP устанавливается после падения TXPKTRDY.

По лигике вещей, так оно и должно быть. Но в даташите об этом ни слова:
>>Данный флаг используется для генерации транзакции "Ввод данных" (в направлении устройство->>хост). Программа устройства проверяет возможность записи данных в FIFO путем оценки состояния >>TXPKTRDY, который должен быть равен нулю. Передача в FIFO выполняется путем записи в регистр >>UDP_ FDRx. Сразу после передачи данных в FIFO программа должна уведомить об этом USB->>устройство путем установки бита TXPKTRDY. После этого можно начинать транзакцию USB. TXCOMP >>устанавливается сразу после приема данных хостом.
И по cкольку у нас поток "управление", в котором при детекции ошибки повторение автоматическое,
то ХЗ, что первым падает и устанавливается.
Go to the top of the page
 
+Quote Post
sgrig
сообщение May 25 2007, 09:52
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 4-11-05
Из: Tomsk
Пользователь №: 10 464



Попробовал и это. Не помогло. Пойду напьюсь, может просветление наступит
Go to the top of the page
 
+Quote Post
KAlex
сообщение May 25 2007, 10:15
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 387
Регистрация: 20-12-06
Из: Obninsk
Пользователь №: 23 719



Цитата(sgrig @ May 25 2007, 13:52) *
Попробовал и это. Не помогло. Пойду напьюсь, может просветление наступит

beer.gif
Тоже иногда надо. А то smile3046.gif

Цитата(sgrig @ May 24 2007, 11:35) *
Например, обрабатывается запрос хоста GET_DESCRIPTOR_DEVICE:
1) по прерыванию от EP0 выгребаю запрос из FIFO
2) формирую дескриптор устройства
3) первые 8 байт дескриптора загружаю в FIFO и поднимаю TXPKTRDY
4) жду прерывания от TXCOMP - и оно приходит
5) сбрасываю TXCOMP
6) очередную порцию дескриптора загружаю в FIFO и поднимаю TXPKTRDY
и ничего не передается, хост ждет некоторое время и обрывает транзакцию IN.

Про RXSETUP не забыл?
Go to the top of the page
 
+Quote Post
sgrig
сообщение May 25 2007, 10:28
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 4-11-05
Из: Tomsk
Пользователь №: 10 464



Цитата(KAlex @ May 25 2007, 17:15) *
beer.gif
Тоже иногда надо. А то smile3046.gif
Про RXSETUP не забыл?

Конечно нет. Я же говорю, если TXCOMP ждать в цикле, то все работает. Если в прерывании, то кирдык. crying.gif
Go to the top of the page
 
+Quote Post
Calculator
сообщение May 28 2007, 05:26
Сообщение #12


Участник
*

Группа: Свой
Сообщений: 45
Регистрация: 19-04-07
Пользователь №: 27 172



Цитата(sgrig @ May 25 2007, 16:28) *
Например, обрабатывается запрос хоста GET_DESCRIPTOR_DEVICE:
1) по прерыванию от EP0 выгребаю запрос из FIFO
2) формирую дескриптор устройства
3) первые 8 байт дескриптора загружаю в FIFO и поднимаю TXPKTRDY
4) жду прерывания от TXCOMP - и оно приходит
5) сбрасываю TXCOMP
6) очередную порцию дескриптора загружаю в FIFO и поднимаю TXPKTRDY
и ничего не передается, хост ждет некоторое время и обрывает транзакцию IN.


Насколько я помню, сначала нужно поднять TXPKTRDY, а уже потом сбросить TXCOMP
Go to the top of the page
 
+Quote Post
sgrig
сообщение May 28 2007, 09:10
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 4-11-05
Из: Tomsk
Пользователь №: 10 464



Цитата(Calculator @ May 28 2007, 12:26) *
Насколько я помню, сначала нужно поднять TXPKTRDY, а уже потом сбросить TXCOMP

Делал и так, те же balls, side view. Похоже, косяк в кристалле: биты TXCOMP и STALLSENT не вызывают прерывание EP0INT, при этом RXSETUP и RX_DATA_BK работают, как описано в DS.
Go to the top of the page
 
+Quote Post
YKonstantin
сообщение May 28 2007, 17:38
Сообщение #14


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 7-11-06
Пользователь №: 22 038



Цитата(sgrig @ May 24 2007, 10:35) *
3) первые 8 байт дескриптора загружаю в FIFO и поднимаю TXPKTRDY
6) очередную порцию дескриптора загружаю в FIFO и поднимаю TXPKTRDY


А какой размер второго пакета?
Случайно не 8, и к тому же это последний пакет?
Go to the top of the page
 
+Quote Post
sgrig
сообщение May 29 2007, 03:36
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 4-11-05
Из: Tomsk
Пользователь №: 10 464



Цитата(YKonstantin @ May 29 2007, 00:38) *
А какой размер второго пакета?
Случайно не 8, и к тому же это последний пакет?

Нет, эту фишку я тоже знаю. Там действительно косяк с прерыванием.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 11:59
Рейтинг@Mail.ru


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