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

 
 
 
Reply to this topicStart new topic
> Не получается работать с 2 банками при передаче на хост через UDP (at91sam7s)
Bulat
сообщение Aug 19 2010, 10:58
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Я пытаюсь использовать 2 банка при передачи данных на хост, но при этом прерывания от конечной точки отключены. Поэтому я в цикле опрашиваю бит TXCOMP. Переменную iby ввел, чтобы при первой записи различить банк 0 и 1 и затем уже не производить запись в FIFO UDP c проверкой бита TXPKTRDY.
CODE

while(1)
{
//Запись первого пакета в буфер FIFO с проверкой бита TXPKTRDY
if(iby==0)
{
if(!(regUDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY))
{

regUDP->UDP_FDR[AT91C_EP_IN] = 11;
regUDP->UDP_FDR[AT91C_EP_IN] = rec&0xff;
unsigned int m_stat = rec>>8;
regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff;
m_stat = rec>>16;
regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff;
m_stat = rec>>24;
regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff;
kA++;

}//if(!(regUDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY))

//Если сформирован пакет размером 12*5=60 байт, то можно отправлять
if(kA==12)
{
regUDP->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;
kA=0;
iby = 1;
}

} //if(ib==0)


//Запись в банк 1 и далее по очереди без проверки бита TXPKTRDY
if(iby==1)
{

regUDP->UDP_FDR[AT91C_EP_IN] = 11;
regUDP->UDP_FDR[AT91C_EP_IN] = rec&0xff;
unsigned int m_stat = rec>>8;
regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff;
m_stat = rec>>16;
regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff;
m_stat = rec>>24;
regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff;
kA++;
}// if(rcrc1)


if(kA==12) {iby = 2;} //Если сформирован пакет 60 байт, то необходимо проверить TXCOMP и отправить второй банк


}//if(ib==1)


//Второй банк заполнен
if(iby == 2)
{
if(regUDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)
{
AT91F_disable_interrupt();
regUDP->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;
regUDP->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);
AT91F_enable_interrupt();
iby = 1; //возвращаемся к заполнению следующего банка без проверки бита TXCOMP
kA = 0;
}
}
}//while(1)


В документации сказано, что метод с переключающимися банками используется для изохронного типа передачи. А если у меня конечная точка работает в режиме bulk, то этот метод будет корректно работать? Дело в том, что хост считывает данные из моего девайса гораздо быстрее, чем мой девайс принимает эти данные от другого источника (200 кбит/с). Поэтому UDP успеет отправить содержимое первого банка раньше, чем заполнится второй банк, то есть возникнет ситуация, когда TXCOMP установится в 1, но я его не буду сбрасывать до тех пор, пока не заполню60-тью байтами второй банк и не перейду к условию iby=2. Такие задержки допустимы?
Go to the top of the page
 
+Quote Post
Bulat
сообщение Aug 21 2010, 07:29
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



никто не работал с 2-мя банками без прерывания, при передачи на хост?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 21 2010, 20:48
Сообщение #3


Гуру
******

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



Цитата(Bulat @ Aug 19 2010, 14:58) *
В документации сказано, что метод с переключающимися банками используется для изохронного типа передачи. А если у меня конечная точка работает в режиме bulk, то этот метод будет корректно работать?

Будет.

Цитата(Bulat @ Aug 19 2010, 14:58) *
Дело в том, что хост считывает данные из моего девайса гораздо быстрее, чем мой девайс принимает эти данные от другого источника (200 кбит/с). Поэтому UDP успеет отправить содержимое первого банка раньше, чем заполнится второй банк, то есть возникнет ситуация, когда TXCOMP установится в 1, но я его не буду сбрасывать до тех пор, пока не заполню60-тью байтами второй банк и не перейду к условию iby=2. Такие задержки допустимы?

Допустимы. Пока банк заполняется, хост будет получать NAK'и. Это просто один из механизмов управления скоростью.

После установки TXPKTRDY нужно в обязательном порядке дождаться действительного изменения состояния этого бита. Иначе возможна ситуация, когда он будет сброшен вместе с TXCOMP и передача просто зависнет.
Go to the top of the page
 
+Quote Post
Bulat
сообщение Aug 23 2010, 12:01
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(aaarrr @ Aug 22 2010, 02:48) *
После установки TXPKTRDY нужно в обязательном порядке дождаться действительного изменения состояния этого бита. Иначе возможна ситуация, когда он будет сброшен вместе с TXCOMP и передача просто зависнет.

Ниже приведен код работы с 2-мя банками. Первые 60 байт нормально передаются на Хост, а потом передача затыкается. Вроде все сделал, как в документации. Почему так происходит?
Цитата
Переменную iby ввел, чтобы при первой записи различить банк 0 и 1 и затем уже не производить запись в FIFO UDP c проверкой бита TXPKTRDY.

CODE

while(1)
{
//Запись первого пакета в буфер FIFO с проверкой бита TXPKTRDY
if(iby==0)
{
if(!(regUDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY))
{

regUDP->UDP_FDR[AT91C_EP_IN] = 11;
regUDP->UDP_FDR[AT91C_EP_IN] = rec&0xff;
unsigned int m_stat = rec>>8;
regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff;
m_stat = rec>>16;
regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff;
m_stat = rec>>24;
regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff;
kA++;

}//if(!(regUDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY))

//Если сформирован пакет размером 12*5=60 байт, то можно отправлять
if(kA==12)
{
Udp_ep_set_flag(regUDP, AT91C_EP_IN,AT91C_UDP_TXPKTRDY);
kA=0;
iby = 1;
}

} //if(ib==0)


//Запись в банк 1 и далее по очереди без проверки бита TXPKTRDY
if(iby==1)
{

regUDP->UDP_FDR[AT91C_EP_IN] = 11;
regUDP->UDP_FDR[AT91C_EP_IN] = rec&0xff;
unsigned int m_stat = rec>>8;
regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff;
m_stat = rec>>16;
regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff;
m_stat = rec>>24;
regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff;
kA++;
}// if(rcrc1)


if(kA==12) {iby = 2;} //Если сформирован пакет 60 байт, то необходимо проверить TXCOMP и отправить второй банк


}//if(ib==1)


//Второй банк заполнен
if(iby == 2)
{
if(regUDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)
{
AT91F_disable_interrupt();
Udp_ep_set_flag(regUDP, AT91C_EP_IN,AT91C_UDP_TXPKTRDY);
Udp_ep_clr_flag(regUDP, AT91C_EP_IN, AT91C_UDP_TXCOMP);
AT91F_enable_interrupt();
iby = 1; //возвращаемся к заполнению следующего банка без проверки бита TXCOMP
kA = 0;
}
}
}//while(1)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 23 2010, 13:13
Сообщение #5


Гуру
******

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



Цитата(Bulat @ Aug 23 2010, 16:01) *
Ниже приведен код работы с 2-мя банками...

Bulat, вы ответы вообще читаете? Уже неоднократно писал:
Цитата
После установки TXPKTRDY нужно в обязательном порядке дождаться действительного изменения состояния этого бита. Иначе возможна ситуация, когда он будет сброшен вместе с TXCOMP и передача просто зависнет.
Go to the top of the page
 
+Quote Post
Bulat
сообщение Aug 23 2010, 13:55
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(aaarrr @ Aug 23 2010, 19:13) *
Bulat, вы ответы вообще читаете? Уже неоднократно писал:

Да, я это исправил, просто забыл в ответ написать. Я использовал функцию
Код
#define Udp_ep_set_flag(pUDP, ep, flags) { pUDP->UDP_CSR[ep] |= (flags); while ( (pUDP->UDP_CSR[ep] & (flags)) != (flags) );}

То есть, так у меня устанавливается бит TXPKTRDY: Udp_ep_set_flag(regUDP, AT91C_EP_IN,AT91C_UDP_TXPKTRDY);
Код, который я привел в предыдущем сообщении уже с этими функциями. Всеравно больше одного банка не передается.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 23 2010, 14:13
Сообщение #7


Гуру
******

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



Цитата(Bulat @ Aug 23 2010, 17:55) *
Код, который я привел в предыдущем сообщении уже с этими функциями. Всеравно больше одного банка не передается.

Пардон, не заметил.

Код организован правильно, ошибок я не вижу. Точно так же делал передачу у себя в нескольких проектах.
Go to the top of the page
 
+Quote Post
Bulat
сообщение Aug 24 2010, 08:09
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(aaarrr @ Aug 23 2010, 20:13) *
Код организован правильно, ошибок я не вижу. Точно так же делал передачу у себя в нескольких проектах.

Если я в этом коде вместо условия:
Код
if(iby == 2)
        {
           if(regUDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)
           {            
              AT91F_disable_interrupt();
              Udp_ep_set_flag(regUDP, AT91C_EP_IN,AT91C_UDP_TXPKTRDY);
              Udp_ep_clr_flag(regUDP, AT91C_EP_IN, AT91C_UDP_TXCOMP);  
              AT91F_enable_interrupt();  
              iby = 1;
              kA = 0;
           }
        }

сделаю 2 условия:
CODE

if(regUDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)
{
AT91F_disable_interrupt();
Udp_ep_clr_flag(regUDP, AT91C_EP_IN, AT91C_UDP_TXCOMP);
AT91F_enable_interrupt();
}

if(iby == 2)
{
AT91F_disable_interrupt();
Udp_ep_set_flag(regUDP, AT91C_EP_IN,AT91C_UDP_TXPKTRDY);

AT91F_enable_interrupt();
iby = 1;
kA = 0;

}

То есть, вынесу опрос бита TXCOMP из под условия if(iby == 2), то есть разрешу сбрасывать TXCOMP как только будет отправлен первый банк, а не буду дожидаться, пока буде заполен второй банк, то девайс начинает передавать данные на Хост, но с заниженной скоростью, примерно, на 8 кбайт/с.
Это, конечно, же неправильно, так как в этом случае второй банк передается неполностью, но я его привел, чтобы показать, как влияет на работу задержка сброса TXCOMP. (В первом варианте кода TXCOMP опрашивался и соответственно сбрасывался только после заполнения второго банка).

Сообщение отредактировал Bulat - Aug 24 2010, 08:14
Go to the top of the page
 
+Quote Post
Bulat
сообщение Aug 25 2010, 08:55
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Дело в том, что в документации есть предупреждение о том, что нельзя делать слишком большую паузу между установкой бита TXCOMP и установкой бита TXPKTRDY: If the delay between receiving TX_COMP is set and TX_PKTRDY is set is too long, some Data IN packets may be NACKed, reducing the bandwidth.
У меня видимо что-то подобное и происходит?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 25 2010, 11:00
Сообщение #10


Гуру
******

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



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

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

 


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


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