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

 
 
 
Reply to this topicStart new topic
> 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
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
aaarrr
сообщение Dec 3 2009, 09:53
Сообщение #4


Гуру
******

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



Цитата(misyachniy @ Dec 3 2009, 12:42) *
На графике видно что после первой установки TX_PKTRDY флаг TX_COMP взводится когда TX_PKTRDY уже сброшен и очистить этот флаг
нельзя.

И не надо.

Цитата(misyachniy @ Dec 3 2009, 12:42) *
Я пробовал и такой вариант:

Прерывания не забыли запретить?

Цитата(misyachniy @ Dec 3 2009, 12:42) *
Во первых вы нарисовали бесконечный цикл. ;-)
Что в реальных проектах бывает очень редко.

Я нарисовал последовательность действий, где Вы цикл увидели - не представляю.

Цитата(misyachniy @ Dec 3 2009, 12:42) *
При повторном вызове в пункте 3 получается неоднозначность:
TXCOMP это оставшийся от прошлой передачи или "свежий"?

Повторном вызове чего? У меня нет вызовов.
TXCOMP "несвежим" там быть не может по определению - он сбрасывается регулярно.
Go to the top of the page
 
+Quote Post
misyachniy
сообщение Dec 3 2009, 12:09
Сообщение #5


Знающий
****

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



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


Может вы и правы но в документации сказано четко
Warning: TX_COMP must be cleared after TX_PKTRDY has been set.

И если производить отсылку данных только проверяя TX_PKTRDY, то обмен останавливается.


Цитата
Прерывания не забыли запретить?

USB обслуживается без прерываний.


Цитата
Я нарисовал последовательность действий, где Вы цикл увидели - не представляю.


На сколько я понимаю, из пункта 2 идет переход на пункт 3 а с пункта 3 на пункт 2 и так до бесконечности.

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


Я хочу чтобы моя функция отсылала один пакет.
С паузой между пакетами, когда TXPKTRDY успеет опустится в 0.
И при повторном вызове функции когда TXPKTRDY от предыдущего вызова еще активен.

Цитата
Повторном вызове чего? У меня нет вызовов.
TXCOMP "несвежим" там быть не может по определению - он сбрасывается регулярно.


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

При первом вызове функции реализующем ваш алгоритм
TXPKTRDY будет взведет 2 раза а TXCOMP сброшен один раз.

При втором вызове функции TXCOMP будет уже взведен.
При выполнении 3-го пункта алгоритма, не сброшеный TXCOMP от первого вызова куда денется?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 3 2009, 13:03
Сообщение #6


Гуру
******

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



Цитата(misyachniy @ Dec 3 2009, 15:09) *
И если производить отсылку данных только проверяя TX_PKTRDY, то обмен останавливается.

Если честно, я не понимаю о чем вы. Что TXCOMP нельзя сбросить, если нет данных, и, соответственно, нет возможности взвести перед этим TXPKTRDY?

Цитата(misyachniy @ Dec 3 2009, 15:09) *
USB обслуживается без прерываний.

А что, других прерываний в системе нет?

Цитата(misyachniy @ Dec 3 2009, 15:09) *
На сколько я понимаю, из пункта 2 идет переход на пункт 3 а с пункта 3 на пункт 2 и так до бесконечности.

Это состояния, как будет осуществляться переключение между ними - дело конкретной программной реализации.

Цитата(misyachniy @ Dec 3 2009, 15:09) *
Посмотрите на приведенный вами алгоритм.

Давайте посмотрим вместе:

1. Загружаем в FIFO самый первый пакет, ставим TXPKTRDY, переходим к п.2
После выполнения этого пункта в FIFO загружен один пакет, TXPKTRDY взведен.

2. Загружаем в FIFO следующий пакет, переходим к п.3
На момент перехода к выполнению этого пункта UDP может находиться в одном из двух состояний:
- FIFO пуст, TXCOMP = 1
- В FIFO один пакет, TXCOMP = 0

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

Покажите, где здесь что-то теряется. Только без "вызовов функций" - это только алгоритм, никаких функций тут нет.
В жизни это замечательно реализуется при помощи конечного автомата.

P.S. Да-да, одной функцией типа "послать буфер" обойтись не получится из-за п.3
Go to the top of the page
 
+Quote Post
misyachniy
сообщение Dec 8 2009, 08:33
Сообщение #7


Знающий
****

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



Вернулся к предыдущему проекту.
По частям привел к "новому".
Поганял 2 дня - зависаний нету.
Очевидно при первой переделке где-то накосячил.

Резюме
"Warning: TX_COMP must be cleared after TX_PKTRDY has been set."
Нужно для того чтобы не попасть в ситуацию, когда перед установкой флага TX_PKTRDY уже установлен флаг TX_COMP.
И анализ состояния флага TX_COMP будет ошибочным.

Тему считаю исчерпаной.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 04:36
Рейтинг@Mail.ru


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