Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: USB своими руками для sam7x256
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
shrek
А у меня наоборот проблема с отправкой пакета размером больше конечной точки rolleyes.gif.
А вот прием идет шустро) посылаю 1023 байта все за кадр приходят)
Не забывайте что хост когда отправляет пакеты чередует данные DATA0 и DATA1 это разные прерывания RX_DATA_BK1 и RX_DATA_BK0 от одного источника (и разные буферы).
мой кусок обработки прерывания:
CODE
//---Обработка прерываний от конечной точки-------------------------------------
void USB_EP_INT()
{
switch ((AT91C_BASE_UDP -> UDP_CSR[POINT]) & UDP_CSR_STATUS)
{
case AT91C_UDP_RXSETUP:
{
send_byte(0xF1);//для отладки по RS-232
USB_READ_FIFO_EP((unsigned char *) pSetup_Packet, POINT);//переход на функцию сохранения байтов в память
RXSETUP_CLEAR(POINT);//Сброс бита RXSetup (данные из буфера прочитал)
switch ((pSetup_Packet -> bmRequestType) & USB_TYPE_REQUEST)
{
case USB_TYPE_STANDARD:
{
switch (pSetup_Packet -> bRequest) //че комп от меня хочет?
{
case GET_DESCRIPTOR:
{USB_GET_DESCRIPTOR(); break;}//запрос дескриптора
case SET_ADRESS:
{USB_SET_ADRESS(); break;}//установка адреса
case SET_CONFIGURATION:
{USB_SET_CONFIGURATION(); break;}
case CLEAR_FEATURE:
{USB_CLEAR_FEATURE(); break;}
default:
{USB_STALL(); break;}
//если запрос не известен то выход из оператора switch
}
break;
}
case USB_TYPE_CLASS:
{
switch (pSetup_Packet -> bRequest)//че комп от меня хочет?
{
case SET_LINE_CODING:
{k = 1; break;}
case GET_LINE_CODING:
{pData[POINT] = (unsigned char *) pLine_Control;
dLenght[POINT] = 7;
USB_WRITE_FIFO_EP(POINT); break;}
case SET_CONTROL_LINE_STATE:
{ZERO_PACKET(); break;}
default:
{USB_STALL();
break;}
//если запрос не известен то выход из оператора switch
}
break;
}
default: {USB_STALL(); break;}
}
break;
}
//------------------------------------------------------------------------------
case AT91C_UDP_TXCOMP:
{
send_byte(0xF2);
TXCOMP_CLEAR(POINT);//сбрасываем бит TXCOMP
if (pStatus[POINT])
{
USB_WRITE_FIFO_EP(POINT);
}
break;
}
//------------------------------------------------------------------------------
case AT91C_UDP_ISOERROR:
{
send_byte(0xF3);
STALL_CLEAR(POINT);
FORCESTALL_CLEAR(POINT);
break;
}
//------------------------------------------------------------------------------
case AT91C_UDP_RX_DATA_BK0:
case AT91C_UDP_RX_DATA_BK1:
{
send_byte(0xF4);
if (k) {k = 0; USB_READ_FIFO_EP((unsigned char *) pLine_Control, POINT); RX_DATA_BK_CLEAR(POINT); ZERO_PACKET();}
else {USB_READ_FIFO_EP(DATA, POINT); RX_DATA_BK_CLEAR(POINT);}
break;
}
default: break;
}
}
//==============================================================================

Этот обработчик написан для CDC конфигурации USB устройства (находится в стадии оптимизации).
Проблемы с приемом не возникали, но... Возникали проблемы с открытием порта. Открывался некорректно! Подвисал програмки для работы с COM портом. Потом разобрался сейчас не вспомню в чем проблема была.

Вспомнил в чем проблема. Проблема в корректной обработки запроса SET_LINE_CODING. Я с начала отправлял пустой пакет подтверждения после приема запроса, но потом оказалось пустой пакет надо отправлять после приема данных по запросу SET_LINE_CODING
Код
if (k) {k = 0; USB_READ_FIFO_EP((unsigned char *) pLine_Control, POINT); RX_DATA_BK_CLEAR(POINT); ZERO_PACKET();}

При этом бит DIR контрольной точки менять не нужно...
e0000
Хм....
если у нас прилетает пакет равный размеру конечной точки, прилетит ли после этого нулевой пакет?
shrek
нулевой по идее прилетит последним в кадре если размер пакета кратен конечной точке. Так жеж и с отправкой. Если отправляешь пакет кратный размеру конечной точки то последним надо отправлять пустой байт. Вот в принципе поэтому 1023 байта можно отправить через bulk точку, чтобы не отправлять нулевой байт (видать не хватает времени устройству чтобы отправить все за кадр).
e0000
но у меня не прилетает "нулевой пакет" если я принимаю 64 байта sad.gif
(размер конечной точки 64 байта)
shrek
хотя в принципе в моем обработчике прерываний как то все равно придет или не придет нулевой байт) rolleyes.gif
Вам этот нулевой байт сильно нужен?)
Нулевой байт по идее в конце кадра должен приходить. Кадр 1 мс. В течении 1 мс можно принять 1023 байта для FS устройств. Вот нулевой байт по идее должен прийти если число байт в кадре кратно размеру конечной точки. Вот 1023 байта пакет. Нулевой не прилетит. А вот 960 байт по идее должен.
e0000
Ситуация какова...
Я не знаю сколько мне прилетит данных и вычисляю их по ходу в первом пакете
Но если ко мне летит


Обработчик следующий:
Код
void BulkOut (void) {
U32 i;
U8 temp;

  BulkLen = USB_ReadEP(EP_OUT_L, &BulkBuf[0]); //смотрим длинну пакета

  switch (BulkStage_OUT){  //проверяем на каком мы свете
    case BS_CBW: {Get_CMD(); break;}
    case BS_DATA_OUT: {GoonGet_CMD(); break;}  
            }
}


так вот в состояние BS_DATA_OUT он не попадает, хотя длины пакетов вычисляются правильно - проверил дебагером
shrek
Вообще для того чтобы узнать сколько байт прилетело к какой-то конечной точке достаточно прочитать поле RXBYTECNT регистра UDP_CSRx. Я обычно это поле читаю перед тем как прочитать данные из буфера. А перед этим смотрятся флаги которые вызвали прерывание.
За что отвечает BulkStage_OUT?
e0000
Обнаружил следующее:
1. Если пакет меньше 64 байта - все ок!
2. Если пакет кратен 64 байта - все ok!
3. Если пакет не кратен 64 байта и при этом больше чем 64 (например 255 байт) то первые 3 по 64 прилетают и я их вижу, а последние 63 не прилетают..
shrek
а если 65 байт?)
у некоторых программ для работы с com портом (тест типа netweak) могут быть ограничения в размере буфера...

Если 65 байт или например 129 принимает то в принципе то ваше устройство работоспособно)))
e0000
при 65 принимаю только 64, а последний не вызывает прерывание...
shrek
Странно...
А вы прерывания сбрасываете?
А попутно другого прерывания не возникает?
e0000
Нет не возникает...
Переделали протокол. Сделали его кратным 64. Пока работает.

Теперь с передатчиком. Надо ли отправлять нулевой пакет в конце каждой посылки в ПК? Или надо отправлять только если размер данных кратен конечной точке?
shrek
Цитата
Теперь с передатчиком. Надо ли отправлять нулевой пакет в конце каждой посылки в ПК? Или надо отправлять только если размер данных кратен конечной точке?


Надо если размер данных кратен конечной точке, но не больше 1023 байта за раз!
Отправлять надо нулевой пакет через ту же что и отправляете данные, но не через контрольную точку!
shrek
Недавно кит вернули AT91SAM7A3-EK я на нем запустил USB_CDC все порты корректно открываются. Передаю данные в устройство (транзакция IN), принимает (смотрю в "отладчике"). Отладчик это прога netweak для работы с com портами. Заметил одну вещь... Нулевой байт хост мне отправляет когда пакет кратен конечной точке, если пакет больше размера конечной точки и еще когда пакет равен 8, 16, 24, 32, 40, 48 ну и 64 байт!!!
Мой проект в IAR ARM 4.22 Нажмите для просмотра прикрепленного файла
Проект "рабочий" biggrin.gif , т.е. устройство определяется (нужно только дрова поставить Нажмите для просмотра прикрепленного файла), порт открывается на любой скорости biggrin.gif (поверяли), данные бегают только в устройство biggrin.gif , девайс работает минут 20 ниче не отваливается)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.