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

 
 
> AT91SAM7S128 вопрос по UDP, биты AT91C_UDP_TXPKTRDY и AT91C_UDP_TXCOMP
misyachniy
сообщение Dec 2 2009, 16:31
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 716
Регистрация: 27-05-05
Из: Kyiv
Пользователь №: 5 454



С sam7S работаю давно.
Несколько программ работают успешно.
Осуществлял обмен по USB как короткими посылками размером в endpoint так и в мегабайты длиной.

Для удобства запросы и ответы были кратными 64-ем байтам.

Сейчас нужно принимать с устройства пакетами по 224 байта.
Я данные складываю по два пакета и получаю 448 байт, что составляет 448/64=7 размеров конечной точки.

То есть передача может начатся с банка 0 или 1.
В этом наверное и причина проблемы.

Для приема ответов на команды и приема указанных данных использую одну и ту же функцию.
После многочисленных вариаций получилась такая
Код
//---------------------------------------------------------
// Отослать пакет из 64 байт
void SendPack64 (char *bufer)
{
  int TXcount;

if (pCDC.currentTXBank == 0)
{
  while (AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXPKTRDY);  //Точка зависания 2
}  
  
// пересылаем данные в буфер endpoint  
TXcount=64;  
while (TXcount--) AT91C_BASE_UDP->UDP_FDR[2] = *bufer++;


if (pCDC.currentTXBank == 1)
{
  while (!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP));  //Точка зависания 1
}

// даем команду передавать
  AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;    // передаем

//if (pCDC.currentTXBank == 1)
//{
   AT91C_BASE_UDP->UDP_CSR[2] &= ~(AT91C_UDP_TXCOMP); // обязательно сбрасываем
//}
  
//else
//{
//  if (AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP)
//   AT91C_BASE_UDP->UDP_CSR[2] &= ~(AT91C_UDP_TXCOMP);  
//}

if (pCDC.currentTXBank == 0) pCDC.currentTXBank = 1;
else pCDC.currentTXBank = 0;

}



Я могу посылать команду и получать ответ размером в конечную точку множество раз без зависаний.

Передавать пакет данных у меня получается только один раз.

Если передавать в штатном режиме две посылки команда/ответ то происходит зависание программы в "Точка зависания 1"
Если вставить 3-ю пустую посылку команда/ответ то программа останавливается в "Точка зависания 2"

Перечитал последнюю версию документации на серию "6175I–ATARM–24-Dec-08"
На 503 странице нарисованы графики и расписано как правильно работать с двумя банками.
Вроде бы все правильно делаю.

Есть только одна претензия к документации. В самом низу страницы:

Warning: TX_COMP must be cleared after TX_PKTRDY has been set.

На графике видно что после первой установки TX_PKTRDY флаг TX_COMP не взводится и естественно не сбрасывается.

Я вводил специальную переменную не сбрасивать AT91C_UDP_TXCOMP при первов вызове SendPack64(), но это не помогло.

На сколько я понял взведенный флаг TX_PKTRDY указывает, что идет пересылка данных и в endpoint нельзя писать.
Но в случае 2-х буферов можно писать анализирую флаг TX_COMP при этом UDP переключает банки.

У меня получается накладка, после записи 7-го пакета и возврата в основную программу у меня взводится TX_COMP.

Не понятно почему при обмене комманда/ответ он не влияет?
А при посылке команда/ответ/данные влияет.

Пока я могу сформулировать только такие вопросы

1)Я взвел флаг TX_PKTRDY и очистил TX_COMP, при этом у меня оба банка заняты.
После отправки обеих банков хосту, UDP 2 раза взведет флаг TX_COMP или они наложатся друг на друга, если не опросить/сбросить вовремя?

По какому принципу UDP переключает банки?

Ну а если у кого есть решение проблемы, то не откажусь :-)
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
aaarrr
сообщение Dec 2 2009, 16:48
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(misyachniy @ Dec 2 2009, 19:31) *
Есть только одна претензия к документации. В самом низу страницы:

Warning: TX_COMP must be cleared after TX_PKTRDY has been set.

На графике видно что после первой установки TX_PKTRDY флаг TX_COMP не взводится и естественно не сбрасывается.

Ставится, естественно. И на каком графике это не так?

Код
  AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;    // передаем

   AT91C_BASE_UDP->UDP_CSR[2] &= ~(AT91C_UDP_TXCOMP); // обязательно сбрасываем

Так делать нельзя - нужно в обязательном порядке дождаться установки TXPKTRDY, иначе он будет сброшен вместе с TXCOMP.

И зачем вводить какие-то программные счетчики банков?

Работа с двумя банками на передачу предельно проста:
1. Загружаем в FIFO самый первый пакет, ставим TXPKTRDY, переходим к п.2
2. Загружаем в FIFO следующий пакет, переходим к п.3
3. Ждем установки TXCOMP, ставим TXPKTRDY, снимаем TXCOMP, переходим к п.2
И все.
Go to the top of the page
 
+Quote Post
misyachniy
сообщение Dec 3 2009, 09:42
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 716
Регистрация: 27-05-05
Из: Kyiv
Пользователь №: 5 454



Цитата(aaarrr @ Dec 2 2009, 18:48) *
Ставится, естественно. И на каком графике это не так?


6175I–ATARM–24-Dec-08
Figure 35-8. Data IN Transfer for Ping-pong Endpoint
Картинку прикладываю.

Наверное корректнее было фразу сформулировать так:

На графике видно что после первой установки TX_PKTRDY флаг TX_COMP взводится когда TX_PKTRDY уже сброшен и очистить этот флаг
нельзя.


Цитата(aaarrr @ Dec 2 2009, 18:48) *
Код
  AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;    // передаем
AT91C_BASE_UDP->UDP_CSR[2] &= ~(AT91C_UDP_TXCOMP); // обязательно сбрасываем

Так делать нельзя - нужно в обязательном порядке дождаться установки TXPKTRDY, иначе он будет сброшен вместе с TXCOMP.


Я пробовал и такой вариант:

Код
  while (AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXPKTRDY);

TXcount=64;  
while (TXcount--) AT91C_BASE_UDP->UDP_FDR[2] = *bufer++;

  AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;  
  while (!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXPKTRDY));

  while (!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP));
  AT91C_BASE_UDP->UDP_CSR[2] &= ~(AT91C_UDP_TXCOMP);
  while (AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP);


Одиночные пересылки проходят успешно.
Пересылка 7 пакетов проходит только один раз.
Из алгоритма явно видно что при первом вызове функции сброс TXCOMP произойдет при низком уровне TXPKTRDY.

Цитата(aaarrr @ Dec 2 2009, 18:48) *
И зачем вводить какие-то программные счетчики банков?

Работа с двумя банками на передачу предельно проста:
1. Загружаем в FIFO самый первый пакет, ставим TXPKTRDY, переходим к п.2
2. Загружаем в FIFO следующий пакет, переходим к п.3
3. Ждем установки TXCOMP, ставим TXPKTRDY, снимаем TXCOMP, переходим к п.2
И все.


Во первых вы нарисовали бесконечный цикл. ;-)
Что в реальных проектах бывает очень редко.

В указаном алгоритме при выходе из цикла в UDP остается не переданные данные.
После передачи которых будет взведен флаг TXCOMP.

При повторном вызове в пункте 3 получается неоднозначность:
TXCOMP это оставшийся от прошлой передачи или "свежий"?

---------------------
P.S.
Может я не там копаю?
http://www.embeddedrelated.com/groups/AT91SAM/show/3815.php


Вопрос

I have usbsniffers and can view my bulk out endpoint working
correctly. When i transmit a character out of the hyperterm I can
view it using a breakpoint at my bulk out int handler. I then put
this character into UDPRegisters->UDP_FDR[AT91C_EP_IN] and set
AT91C_UDP_TXPKTRDY. It works once then stops transmitting. TXPKTRDY
never clears TXCOMP interrupt never fires.



Решение

Yes, you do. smile.gif
> // Endpoint 1 descriptor
> 0x07, // bLength
> 0x05, // bDescriptorType
> 0x83, // bEndpointAddress, Endpoint 01 - IN 333333
> 0x03, // bmAttributes INT
> 0x0a, // wMaxPacketSize
> 0x00,
> 0x00, // bInterval

The comment is wrong, this is an Endpoint 3 (the 4th endpoint)
descriptor, and it's being configured as an interrupt in. I believe
the interrupt in is required for the serial class driver whether you
use it or not (I'm not 100% sure about that).

Now make sure you have something like this in the init code:

pUDP->UDP_CSR[3] = AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN;

That was the line that got me. I believe it was originally
indicating that endpoint 3 was an ISO endpoint.

У меня объявлены в дескрипторе только две конечные точки в режиме bulk.
Их я и инициализирую и управляю.
Я пробовал вставлять в код инициализации pUDP->UDP_CSR[3] = AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN
Но безрезультатно.
Может конечную точку нужно "заглушить" по другому?
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post



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

 


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


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