|
|
  |
USB Device на AT91SAM7, Насколько сложно и что нужно |
|
|
|
Nov 13 2006, 17:57
|

фанат Linux'а
    
Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008

|
Цитата(Kitsok @ Nov 13 2006, 12:47)  Направьте, пожалуйста, где понятно описан обмен между хостом и устройством, а то никак не въеду. Как мне показалось, тут http://www.mqp.com/ums_3.htm довольно понятно всё описано (возможно потому что всё очень сжато, без воды). Цитата(Kitsok @ Nov 13 2006, 12:47)  Поставил IAR, который до 32 кб, виглер есть, а вот как прицепить виглер к ИАРу? В самом начале установки IARа есть пункт "install drivers", открыть папку Macraigor и установить содержимое. Если нет такого пункта, то нужное можно скачать тут: http://www.macraigor.com/downloads/ocd_dbgr.exe
--------------------
|
|
|
|
|
Nov 13 2006, 22:12
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Спасибо за наводку, через виглер напрямую не получилось, зато получилось через H-JTAG. Правда, все равно - бесполезно, т.к. тайминги уезжают и винда отрубает USB-устройство. Сейчас впоролся - вроде и осознание процесса пришло, а все равно, не получается. Итак, беру демо-проект из FreeRTOS с джойстиком на три оси. Дескриптор репорта там выглядит следующим образом: Код const portCHAR pxReportDescriptor[] = { 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ 0x09, 0x04, /* USAGE (Joystick) */ 0xa1, 0x01, /* COLLECTION (Application) */ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ 0x09, 0x01, /* USAGE (Pointer) */ 0xa1, 0x00, /* COLLECTION (Physical) */ 0x09, 0x30, /* USAGE (X) */ 0x09, 0x31, /* USAGE (Y) */ 0x09, 0x32, /* USAGE (Z) */ // 0x09, 0x33, /* USAGE (T) */ 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */ 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */ 0x75, 0x08, /* REPORT_SIZE (8) */ // 0x95, 0x04, /* REPORT_COUNT (4) */ 0x95, 0x03, /* REPORT_COUNT (3) */ 0x81, 0x02, /* INPUT (Data,Var,Abs) */ 0xc0, /* END_COLLECTION */ 0xc0 /* END_COLLECTION */ }; То, что закоментарено - мое, т.е. я добавил 0x09, 0x33 и подправил REPORT_COUNT. Плюс к этому подправлено вот что: Код /* Endpoint 1 descriptor */ 0x07, /* bLength */ 0x05, /* bDescriptorType */ 0x81, /* bEndpointAddress, Endpoint 01 - IN */ 0x03, /* bmAttributes INT */ //0x04, 0x00, /* wMaxPacketSize: 4 bytes (x, y, z, t) */ 0x03, 0x00, /* wMaxPacketSize: 3 bytes (x, y, z) */ 0x0A /* bInterval т.е. я по наитию расширил максимальный размер пакета. Плюс к этому в функции, которая собственно шлет данные, добавил посылку еще одной оси: Код /* Write our sample data to the fifo. */ AT91C_BASE_UDP->UDP_FDR[ usbEND_POINT_1 ] = x; AT91C_BASE_UDP->UDP_FDR[ usbEND_POINT_1 ] = y; AT91C_BASE_UDP->UDP_FDR[ usbEND_POINT_1 ] = z; //AT91C_BASE_UDP->UDP_FDR[ usbEND_POINT_1 ] = t; В итоге, судя по обмену, винду вроде все устраивает, но устройство не отвечает на BULK_OR_INTERRUPT TRANSFER, после чего винда его отваливает через какое-то время.... Где еще копать - не пойму.. Помогите, люди добрые
|
|
|
|
|
Nov 13 2006, 22:49
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Чудны дела темных сил электричества. В общем, в подозрениях на глюки с размером дескриптора репорта (в оригинале - 30 байт, после изменений - 32), я добавил еще одну ось, подправил соответствующим образом размеры и вывод в шину. Трафик на шине я смотрю при помощи SnoopyPro. Так вот если я смотрю на трафик, то трафика не видно, и устройство в девайс-менеджере висит с ошибкой. Если выключаю снупи, то все работает как задумано И че теперь делать-то?  Пробовал USBTrace, но мне нужно захватить процедуру инициализации, а он при рестарте девайса выключает захват.
|
|
|
|
|
Nov 13 2006, 22:57
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861

|
Цитата(Kitsok @ Nov 14 2006, 01:49)  Чудны дела темных сил электричества. В общем, в подозрениях на глюки с размером дескриптора репорта (в оригинале - 30 байт, после изменений - 32), я добавил еще одну ось, подправил соответствующим образом размеры и вывод в шину. ... И че теперь делать-то?  Пробовал USBTrace, но мне нужно захватить процедуру инициализации, а он при рестарте девайса выключает захват. Очень похоже на грабли, на которые я наступал. Если размер дескриптора кратен макс размеру пакета для нулевой конечной точки, то надо посылать замыкающий пакет нулевой длинны. Пример, который переделывал я, этого не делал и я убил на это много времени. Вот http://electronix.ru/forum/index.php?showtopic=22614&hl=
--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
|
|
|
|
|
Nov 14 2006, 07:03
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(Dron_Gus @ Nov 14 2006, 01:57)  Да, видимо, так и есть... А вот еще вопрос. Допустим, мне надо через EP1 передать больше 8 байт, поскольку я вроде как в Full Speed, то максимум - 64 байта. А вот какой размер FIFO в SAM7S256? В даташите написано Цитата The maximum number of bytes to write is fixed by the Max Packet Size in the Standard Endpoint Descriptor. It can not be more than the physical memory size associated to the endpoint. Refer to the Universal Serial Bus Specification, Rev. 2.0 for more information. Получается, что размер FIFO - 64 байта? А что за physical memory size associated?
|
|
|
|
|
Nov 14 2006, 08:17
|
Местный
  
Группа: Свой
Сообщений: 459
Регистрация: 30-03-06
Из: Москва
Пользователь №: 15 600

|
Цитата(Kitsok @ Nov 14 2006, 10:03)  Получается, что размер FIFO - 64 байта? А что за physical memory size associated? А FIFO, это что такое по-твоему? ;)
|
|
|
|
|
Nov 14 2006, 12:01
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(Tahoe @ Nov 14 2006, 11:17)  А FIFO, это что такое по-твоему?  Насколько я понял, FIFO - это вполне себе аппаратный кусок UDP, и соответственно, влиять на его размер я не могу. Так? Вот еще вопрос. Пытаюсь разобрать дескриптор репорта некого устройства. DT в этом не помогает ну ни разу. Пытаюсь в ручном режиме добавить запись, ввожу 15 (base 16), а получается 0x55.... Есть какие-нибудь тулы повменяемей?
|
|
|
|
|
Nov 15 2006, 06:59
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(Dron_Gus @ Nov 15 2006, 01:33)  В доке на AT91SAM7S раздел USB Device Port с этого начинается. Первая конечная точка 8 байт. Если надо 64, то либо 8 пакетов, либо другую EP используйте. Все-таки, нулевая, а не первая. Первая - 64 байта. Вчера поставил выстраданный Report Descriptor и пихаю без проверок и остановок 16 байт подряд, все доходит. Спасибо всем, разобрался.
|
|
|
|
|
Jul 22 2007, 19:46
|
Участник

Группа: Участник
Сообщений: 31
Регистрация: 5-12-06
Пользователь №: 23 156

|
Помогите пожалуйста передать данные на комп или, кажите куда мне копать, если ли такие готовые проги для PC или надо разбираться и писать самому. вот код Код uint32_t A[ARRAY_SIZE]; ..... AT91F_USB_Open(); // Init USB device // Wait for the end of enumeration for(i=0;i<ARRAY_SIZE;i++) { while (!pCDC.IsConfigured(&pCDC)); pCDC.Write(&pCDC, (const char *)&A[i], 4); } на стороне компа это все надо получить и сохранить в текстовый файл, или что то вроде того сейчас пытался прошить пример AT91SAM7S256-BasicUSART_USB-IAR4_30A-1_21 и загрузить BasicUSB_6124.exe но с драйвером atm6124.Inf пишет нет устройства, а со вторым atm6124ser.inf, который как раз и эмулирует виртуальный ком порт вообще сразу вылетает. Форум я почитал тут в принципе много на эту тему, но многие сами пишут драйвер, что мне не по силам.
|
|
|
|
|
Jul 23 2007, 07:15
|

Местный
  
Группа: Свой
Сообщений: 387
Регистрация: 20-12-06
Из: Obninsk
Пользователь №: 23 719

|
Цитата(Handler @ Jul 22 2007, 23:46)  Форум я почитал тут в принципе много на эту тему, но многие сами пишут драйвер, что мне не по силам. Можно прикинуться девайсом, под который уже есть написаные дрова. Я сделал прикид под FTDI и спокойно работаю через ft2xx.dll
|
|
|
|
|
Aug 11 2007, 15:18
|

Частый гость
 
Группа: Свой
Сообщений: 154
Регистрация: 6-11-05
Из: Москва
Пользователь №: 10 515

|
А как реализовать обработку UDP через прерывания? Сделал как в примере USBWorkframe, который вместе с новым ИАРом еще (5.10) вместе идет. Пишу вот так: Код // Настраиваем вызов прерываний AT91F_AIC_ConfigureIt( AT91C_BASE_AIC, AT91C_ID_UDP, USB_INTERRUPT_PRIORITY, 0, USB_InterruptHandler); // Включаем прерывание AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_UDP);
// На какие прерывания реагировать AT91C_BASE_UDP->UDP_IER |= AT91C_UDP_ENDBUSRES | AT91C_UDP_EPINT0; Ничего не работает. Винда ждет свой таймаут и говорит, что неизвестное устройство. А когда пишу вот так, то все работает Код int main() { ................. .................
USB_Open(&usb); USB_SetPullUp(1);
while(1) { USB_InterruptHandler(); } } Что не так с прерываниями? Вот реализация самой функции USB_InterruptHandler: Код // Функция для обработки прерываний USB контроллера void USB_InterruptHandler() { // Считываем значение регистра статуса преривания AT91_REG ISR = AT91C_BASE_UDP->UDP_ISR; // Маски прерываний, которые нужно удалить AT91_REG CSR = 0;
// Обрабатываем все прерывания while(1) { // Маски прерываний, которые нужно удалить CSR = 0;
// Если завершился сброс USB контроллера if (ISR & AT91C_UDP_ENDBUSRES) { // Очищаем маску этого прерывания CSR |= AT91C_UDP_ENDBUSRES; // Reset all endpoints AT91C_BASE_UDP->UDP_RSTEP = (unsigned int)-1; AT91C_BASE_UDP->UDP_RSTEP = 0; // Enable the function AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN; // Включаем EndPoint 0 и устанавливаем режим // передачи данных Control AT91C_BASE_UDP->UDP_CSR[0] = AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL; } // Прерывание от EndPoint 0 // Several signals can generate this interrupt. // The reason can be found by reading UDP_CSR[0]: // RXSETUP set to 1 // RX_DATA_BK0 set to 1 // RX_DATA_BK1 set to 1 // TXCOMP set to 1 // STALLSENT set to 1 else if (ISR & AT91C_UDP_EPINT0) { // Очищаем маску этого прерывания CSR |= AT91C_UDP_EPINT0; // Если хост отправил Setup пакет и он доступен // в FIFO буфере EndPoint'а 0, то if((AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RXSETUP)) { // Отвечаем на запрос от хоста USB_RequestHandler(); } }
// Очищаем маску всех обработанных прерываний if(CSR) { AT91C_BASE_UDP->UDP_ICR = CSR; }
// Если больше не обработали никаких прерываний, то if(CSR == 0) { // Все прерывания обработаны break; } // Опять считываем значение регистра статуса преривания AT91_REG ISR = AT91C_BASE_UDP->UDP_ISR; } } P.S. Если чего, то код в функции USB_InterruptHandler не зависает: пробовал нажимать break во время выполнения - вылетал в бесконечный цикл, который в main().
Сообщение отредактировал Pasha 111 - Aug 11 2007, 15:19
|
|
|
|
|
Aug 20 2007, 13:38
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(Pasha 111 @ Aug 11 2007, 19:18)  Вот реализация самой функции USB_InterruptHandler: Код // Функция для обработки прерываний USB контроллера void USB_InterruptHandler() { // Считываем значение регистра статуса преривания AT91_REG ISR = AT91C_BASE_UDP->UDP_ISR; // Маски прерываний, которые нужно удалить AT91_REG CSR = 0;
// Обрабатываем все прерывания while(1) { <skipped> // Отвечаем на запрос от хоста USB_RequestHandler();
<skipped> Я что-то не понял. Вы в обработчик прерывания воткнули while(1)????? Да еще и по прерыванию от USB что-то через USB шлете? Хм...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|