Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: CDC класс на AT91SAM7X512
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
shrek
Добрый день. Суть проблемы вот в чем...
Есть КИТ AT91SAM7A3 на нем CDC класс работает без сучка и задоринки!
Переношу тот же код без изменения на AT91SAM7X512 (поменьял только параметры для ПЛЛ цепочки, ну и библиотеку для AT91SAM7X512)!
Дескрипторы устройства конфигурации конечных точек принимаются и обрабатываются, то есть устройство определяется компом и ставится драйвер с последующими спецефическими запросами для класса CDC.
Пытаюсь открыть порт любой прогой! Смотрю что ничего не приходит (в AT91SAM7A3 дескрипторы пачками шли в основном GET_LINE_CODING, SET_LINE_CODING и SET_CONTROL_LINE_STATE, причем у каждой проги для ком порта порядок и кол-во дескрипторов разные wacko.gif ).
Так вот не пойму в чем проблема...
shrek
опытным путем установленно путем закоментирования части обработки запроса SET_CONTROL_LINE_STATE (контроллер его отклоняет)
Код
/*case SET_CONTROL_LINE_STATE:
                                   {
                                   //AT91C_BASE_US0 -> US_CR = AT91C_US_RXDIS | AT91C_US_TXDIS;
                                   ZERO_PACKET();
                                   break;
                                   }*/

что какой то косяк в обработке этого запроса... по умолчанию отправлял нулевой пакет на AT91SAM7A3 это срабатывало...
После закомента пытался открыть порт... Посыпались спецефические запросы (в принципе это очень хорошо, так как раньше они при открытии порта запросы не сыпались)...

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

Еще кое что выяснилось... Косяк именно в точке BULK_IN!!! На этапе конфигурации конечную точку с этой конфигурацией закоментировал и порт начал корректно открываться!

Еще где бы я ни ставил дескриптор конечной точки BULK_IN, менял номера конечной точки BULK_IN и соответственно в дескрипторе менял все равно! Драйвер почему то не любит именно BULK_IN конечную точку... wacko.gif

Проблема оказалась в конечной точке с атрибутами BULK_IN. Комп упорно отказывался работать с этой конфигурацией. Поменял атрибут на ISO_IN все заработало!!!...
По спецификации CDC конечные точки могут быть либо изохорными либо BULK точки.

С изохорной точкой не работает прием (передача данных в хост).
Менял все булк точки на изохорные и передача в девайс отвалилась...
С изохорными точками нифига не работает, а с BULK_IN точкой порт не открывается. что за хрень...

Дескриптор устройства
CODE
static const USB_DEVICE_DESCRIPTOR Device_Descriptor =
{
sizeof(Device_Descriptor),
DEVICE_DESCRIPTOR,
DEVICE_USB1_1,
2,
0,
0,
8,
0x03EB,
0x0110,
0x0110,
INDEX_MANUFACTURE,
INDEX_PRODUCTID,
INDEX_SERIAL_NUMBER,
1,
};

Дескриптор конфигурации
CODE
static const USB_Configuration Configuration =
{
{
sizeof(USB_CONFIGURATION_DESCRIPTOR),
CONFIGURATION_DESCRIPTOR,
sizeof(Configuration),
2,
1,
0,
0x80,
0xFA,
},

{
sizeof(USB_INTERFACE_DESCRIPTOR),
INTERFACE_DESCRIPTOR,
2,
0,
1,
2,
2,
0,
0x00
},

{
0x05, 0x24, 0x00, 0x10, 0x01,
0x04, 0x24, 0x02, 0x00,
0x05, 0x24, 0x06, 0x00, 0x01,
0x05, 0x24, 0x01, 0x03, 0x01,
},

{
sizeof(USB_ENDPOINT_DESCRIPTOR),
ENDPOINT_DESCRIPTOR,
ENDPOINT_IN | 3,
ENDPOINT_INTERRUPT,
8,
10,
},

{
sizeof(USB_INTERFACE_DESCRIPTOR),
INTERFACE_DESCRIPTOR,
3,
0,
2,
0xA,
0,
0,
0x00
},

{
sizeof(USB_ENDPOINT_DESCRIPTOR),
ENDPOINT_DESCRIPTOR,
0x02,
0x02,
64,
0,
},

{
sizeof(USB_ENDPOINT_DESCRIPTOR),
ENDPOINT_DESCRIPTOR,
0x81,
0x02,
64,
0,
},

};

Все варианты исчерпал...

АААААААААААААА!!!! ПОБЕДИЛ!!!!!!
cheers.gif cheers.gif cheers.gif cheers.gif
Все на выходных надо напиться....
Вся соль была в...
CODE
#define AT91C_UDP_EP0 ((unsigned int) 0x1 << 0) // (UDP) Reset Endpoint 0
#define AT91C_UDP_EP1 ((unsigned int) 0x1 << 1) // (UDP) Reset Endpoint 1
#define AT91C_UDP_EP2 ((unsigned int) 0x1 << 2) // (UDP) Reset Endpoint 2
#define AT91C_UDP_EP3 ((unsigned int) 0x1 << 3) // (UDP) Reset Endpoint 3
#define AT91C_UDP_EP4 ((unsigned int) 0x1 << 4) // (UDP) Reset Endpoint 4
#define AT91C_UDP_EP5 ((unsigned int) 0x1 << 5) // (UDP) Reset Endpoint 5

#define AT91C_UDP_EP0 ((unsigned int) 0) // (UDP) Endpoint 0
#define AT91C_UDP_EP1 ((unsigned int) 1) // (UDP) Endpoint 1
#define AT91C_UDP_EP2 ((unsigned int) 2) // (UDP) Endpoint 2
#define AT91C_UDP_EP3 ((unsigned int) 3) // (UDP) Endpoint 3
#define AT91C_UDP_EP4 ((unsigned int) 4) // (UDP) Endpoint 4
#define AT91C_UDP_EP5 ((unsigned int) 5) // (UDP) Endpoint 5

Библиотеках на AT91SAM7A3 и AT91SAM7X512. Первую я собственно и подковырял немного)))
shrek
Сегодня тестил устройства на основе USB_CDC самопальной сборки)
Пытался с USARTом общаться) Так вот сделал по приему TIMEOUT, чтобы устройство могло принимать случайное число байт) Ну организовал весь обмен через PDC и прием и передачу. Даже сделал чтобы светодиодик моргал biggrin.gif еще прикрутил настройку USARTа к запросу SET_LINE_CODING. Так вот открываю порт любой прогой для работы с ком портом, закольцевал USART, закольцевал через приемопередатчики для RS422 (не помню название микросхемы), посылаю случайные байты и случайное их колво все супер работает!!! disco.gif !!!
Отдаю платку парню для его устройства) Он к вечеру разобрал все косяки с неработой своего девайса и моей платки с приемопередатчиками RS422))) Когда он пересылает с компа в свое устройство пакет все нормально без проишествий) Когда он дает команду на "сьемку" в мою платку летит пакет 4096 байт... Я думал что моя платка сможет переварить такой пакет... Однако не переварила)))) Переварила только 3000 с копейками байт))) Вот!!! Я думаю...
Надо подумать как этот пакет переварить...
shrek
Победил прием пакетов большого обьема. В процессе вылез один косяк...
Когда девайс пытается отправить из функции main, то есть под userом когда все прерывания разрешены (вложенных перываний нет я их не реализовывал), пакет размером больше 64 байт (больше конечной точки), то примерно после размера пакета 70 - 80 байт передача в хост отваливается... Долго думал и искал почему... Оказалось что контроллер не успевал работать с DUAL буфером BULK конечной точки. Когда контроллер начинал писать во второй буфер, еще не успев записать туда возникало прерывание TXCOMP по которому контроллер должен был записать данные размером с конечную точку в добавок к тому колву недозаписанных байт и передача в хост отваливалась. Решилось все запрещением прерываний на этапе первой записи данных в конечную точку.
Еще кое что... Для "универсальности", так как число байт которое может прийти в девайс величина случайная, организовал работу USART и PDC_USART по прерываниям ENDRX и TIMEOUT. По первому инициализировался NEXT буфер и NEXT счетчик (после того как регистр счетчик основного буфера заканчивается возникает прерывание ENDRX, а из регистров PDC_RNCR и PDC_RNPR (если не ошибаюсь) значения автоматом копируются в PDC_RCR и PDC_RPR. А когда возникало прерывание TIMEOUT необходимо было дослать оставшиеся байты в Host. Возникала ситуация при которой контроллер еще не успевал отослать 1023 байта в Host как возникало прерывание TIMEOUT и в довесок пыталось запустить новую передачу. Так как первый косяк обнаружился вместе со вторым не мог разрулить когда досылать оставшиеся байты)))
Днем пробовал на скорости 6 Мбит/с пересылать 16кбайт в Host за раз. Девайс без проблем переваривал)))
Теперь самая сложная проблема!!! Как мигать диодиком при приеме-передаче данных?))))
В атмеловских примерах нашел только макросы для включения, выключения и переключения диода, где, как и когда эти операции делаются не обнаружил)))
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.