|
|
  |
Не получается работать с 2 банками при передаче на хост через UDP (at91sam7s) |
|
|
|
Aug 19 2010, 10:58
|
Местный
  
Группа: Участник
Сообщений: 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. Такие задержки допустимы?
|
|
|
|
|
Aug 21 2010, 20:48
|
Гуру
     
Группа: Свой
Сообщений: 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 и передача просто зависнет.
|
|
|
|
|
Aug 23 2010, 12:01
|
Местный
  
Группа: Участник
Сообщений: 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)
|
|
|
|
|
Aug 23 2010, 13:55
|
Местный
  
Группа: Участник
Сообщений: 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); Код, который я привел в предыдущем сообщении уже с этими функциями. Всеравно больше одного банка не передается.
|
|
|
|
|
Aug 24 2010, 08:09
|
Местный
  
Группа: Участник
Сообщений: 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
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|