|
как обработать установочный пакет usb |
|
|
|
Feb 10 2009, 16:20
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
понятно , будем разбирать.  Есть простой вопрос наверно по си, не хочется темы размножать с простыми вопросами, напишу здесь. вот объявляем новый тип SetPacked который состоит из 8 байт: Код typedef struct{ BYTE bmReqestType; BYTE bReqest; DWORD wValue; DWORD wIndex; DWORD wLenght; }SetPacked; Вот еще объявляем? что то, как это будет работать не пойму, пример из книги Агурова. Код typedef union{ SetPacked setup; BYTE b[8]; WORD wREqest; }usbSetPacked; объясните если не затруднит.
|
|
|
|
|
Feb 10 2009, 16:33
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Feb 10 2009, 19:20)  вот объявляем новый тип SetPacked который состоит из 8 байт: А DWORD у Вас - это short? Как-то нестандартно очень. Цитата(sergey sva @ Feb 10 2009, 19:20)  Вот еще объявляем? что то, как это будет работать не пойму, пример из книги Агурова. Я бы не стал вообще заморачиваться структурами и юнионами для setup-пакета. Зачем?
|
|
|
|
|
Feb 10 2009, 16:37
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Какой-то немного странный union, вы wREqest [4] может быть хотели написать? Но раз так написали, то в памяти переменные будут расположены следующим образом (если принять порядок следования как у "больших индейцев") Код 1-й байт, смещение 0: bmReqestType - b[0] - мл. байт wREqest 2-й байт, смещение 1: bReqest - b[1] - ст. байт wREqest 3-й байт, смещение 2: мл.байт wValue - b[2] - ничего 4-й байт, смещение 3: ст.байт wValue - b[3] - ничего 5-й байт, смещение 4: мл.байт wIndex - b[4] - ничего 6-й байт, смещение 5: ст.байт wIndex - b[5] - ничего 7-й байт, смещение 6: мл.байт wLenght - b[6] - ничего 8-й байт, смещение 7: ст.байт wLenght - b[7] - ничего
|
|
|
|
|
Feb 10 2009, 19:48
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Цитата Ну, это пока еще не разборщик smile.gif Будем потихоньку разбираться с этими разборщиками.  Вот наваял для разборки запроса от хоста Get_stat_dev, может что тоже нужно подправить, может в обращениях к регистрам что подправить? CODE //------------------------------------------------------------------------------- void end_point_read(DWORD EP, BYTE *dat){ DWORD LenByt, n; /* */ EP &=0x0F; LenByt = (AT91C_BASE_UDP->UDP_CSR[EP] >> 16) & 0x07FF; for (n = 0; n < LenByt; n++) { *dat++ = (BYTE) AT91C_BASE_UDP->UDP_FDR[EP]; }//end for /* */ }//end //------------------------------------------------------------------------------- DWORD end_point_write(DWORD EP, BYTE dat[], DWORD len) { DWORD n; /* */ EP &= 0x0F; /* */ if (AT91C_BASE_UDP->UDP_CSR[EP] & AT91C_UDP_TXPKTRDY) { if ((DualBankEP & (1 << EP)) && (TxDataBank[EP] == 0)) { TxDataBank[EP] = 1; } else { return 0; } }//end if AT91C_UDP_TXPKTRDY
for (n = 0; n < len; n++){ AT91C_BASE_UDP->UDP_FDR[EP] = dat[n]; } AT91C_BASE_UDP->UDP_CSR[EP] |= AT91C_UDP_TXPKTRDY; while(!(AT91C_BASE_UDP->UDP_CSR[EP] & AT91C_UDP_TXCOMP)); AT91C_BASE_UDP->UDP_CSR[EP] &= ~AT91C_UDP_TXCOMP; return len; } //------------------------------------------------------------------------------- void Get_stat_dev(DWORD EP){ BYTE OPT[2]; EP &=0x0F; /* */ OPT[0] = (POW_BUS | IGNOR_SIG); OPT[1] = 0; AT91C_BASE_UDP->UDP_CSR[EP] |= AT91C_UDP_DIR;
end_point_write(EP,OPT,2);
while(!(AT91C_BASE_UDP->UDP_CSR[EP] & AT91C_UDP_RXSETUP)); AT91C_BASE_UDP->UDP_CSR[EP] &= ~AT91C_UDP_RXSETUP; AT91C_BASE_UDP->UDP_CSR[EP] &= ~AT91C_UDP_DIR; }//end void Get_stat_dev(void) //-------------------------------------------------------------------------------
|
|
|
|
|
Feb 10 2009, 20:36
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Feb 10 2009, 22:48)  Вот наваял для разборки запроса от хоста Get_stat_dev, Логичнее было бы начинать с GET_DESCRIPTOR. Цитата(sergey sva @ Feb 10 2009, 22:48)  может что тоже нужно подправить, может в обращениях к регистрам что подправить? Обратите внимание на методику и последовательность установки/снятия битов регистра UDP_CSR в датшите. В частности, DIR нужно ставить до снятия RXSETUP и т.п.
|
|
|
|
|
Feb 11 2009, 19:32
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Вот функция которая записывает в конечную точку байты.: CODE //------------------------------------------------------------------------------- DWORD end_point_write(DWORD EP, BYTE dat[], DWORD len) { DWORD n; /* */ EP &= 0x0F; /* */ if (AT91C_BASE_UDP->UDP_CSR[EP] & AT91C_UDP_TXPKTRDY) { if ((DualBankEP & (1 << EP)) && (TxDataBank[EP] == 0)) { TxDataBank[EP] = 1; } else { return 0; } }//end if AT91C_UDP_TXPKTRDY
for (n = 0; n < len; n++){ AT91C_BASE_UDP->UDP_FDR[EP] = dat[n]; } AT91C_BASE_UDP->UDP_CSR[EP] |= AT91C_UDP_TXPKTRDY; while(!(AT91C_BASE_UDP->UDP_CSR[EP] & AT91C_UDP_TXCOMP)); AT91C_BASE_UDP->UDP_CSR[EP] &= ~AT91C_UDP_TXCOMP; return len; } //------------------------------------------------------------------------------- сначала здесь записываются в буфер конечной точки байты , после устанавливается флаг окончания записи, далеше в цикле while ожидаю когда хост подтвердит получение байт, установкой флага AT91C_UDP_TXCOMP, а если этого не произойдет, то программа зависнет в этом месте. Как получше это обработать, может еще какие флаги проверять, или таймаут добавить ?
Причина редактирования: Уменьшение видимого размера исходника.
|
|
|
|
|
Feb 11 2009, 20:32
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Feb 11 2009, 22:32)  Лучше сделать здесь реальную проверку, или не делать вообще. Цитата(sergey sva @ Feb 11 2009, 22:32)  А где это сбрасывается? Цитата(sergey sva @ Feb 11 2009, 22:32)  Код AT91C_BASE_UDP->UDP_CSR[EP] |= AT91C_UDP_TXPKTRDY; Обратите внимание на Warning в описании UDP_CSR. В данном случае он важен. Цитата(sergey sva @ Feb 11 2009, 22:32)  Код while(!(AT91C_BASE_UDP->UDP_CSR[EP] & AT91C_UDP_TXCOMP)); Простым ожиданием TXCOMP убиваются все преимущества двойной буферизации. Совет: не пытайтесь написать универсальные процедуры обслуживания конечных точек - ничего, кроме лишнего геморроя, это не принесет.
|
|
|
|
|
Feb 12 2009, 19:05
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
решил немного с готовыми примерами разобраться, а то сложновато сразу разобраться. В сети нашел пример usb hid, смотрю код, огромное количество структур объединений, и прочей.., некоторый код даже не совсем понимаю как работает, вот например Код /* USB Common Descriptor */ typedef struct _USB_COMMON_DESCRIPTOR { BYTE bLength; BYTE bDescriptorType; }__attribute__ ((packed)) USB_COMMON_DESCRIPTOR; эта структура описана в h файле. этот код встречается в функции Код USB_COMMON_DESCRIPTOR * pD; (BYTE *) pD += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; при компиляции вылетает ошибка Description Resource Path Location Type lvalue required as left operand of assignment И как этот оператор выполняется, что с чем складывается .?
|
|
|
|
|
Feb 12 2009, 20:57
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Цитата А компилятор какой? yagarto(GCC) эта строчка тоже вызывает такую же ошибу lvalue required as left operand of assignment Требуется какой то левый оператор (BYTE *)pD += pD->bLength;
|
|
|
|
|
Feb 14 2009, 15:52
|
Участник

Группа: Участник
Сообщений: 70
Регистрация: 22-04-07
Из: Poltava/Kharkov
Пользователь №: 27 243

|
Цитата(sergey sva @ Feb 14 2009, 17:36)  .. Код AT91C_BASE_UDP->UDP_CSR[EP] |= AT91C_UDP_TXPKTRDY; while(!(AT91C_BASE_UDP->UDP_CSR[EP] & AT91C_UDP_TXCOMP)); AT91C_BASE_UDP->UDP_CSR[EP] &= ~AT91C_UDP_TXCOMP; .. Хочу обратить внимание, что при доступе к регистру UDP_CSR Atmel рекомендует использовать следующие макросы, хотя в своих же примерах их не использует  doc6175.pdf (35.6.10 UDP Endpoint Control and Status Register) Цитата WARNING: Due to synchronization between MCK and UDPCK, the software application must wait for the end of the write operation before executing another write by polling the bits which must be set/cleared. //! Clear flags of UDP UDP_CSR register and waits for synchronization #define Udp_ep_clr_flag(pInterface, endpoint, flags) { \ pInterface->UDP_CSR[endpoint] &= ~(flags); \ while ( (pInterface->UDP_CSR[endpoint] & (flags)) == (flags) ); \ } //! Set flags of UDP UDP_CSR register and waits for synchronization #define Udp_ep_set_flag(pInterface, endpoint, flags) { \ pInterface->UDP_CSR[endpoint] |= (flags); \ while ( (pInterface->UDP_CSR[endpoint] & (flags)) != (flags) ); \ } Note: In a preemptive environment, set or clear the flag and wait for a time of 1 UDPCK clock cycle and 1peripheral clock cycle. However, RX_DATA_BLK0, TXPKTRDY, RX_DATA_BK1 require wait times of 3 UDPCK clock cycles and 3 peripheral clock cycles before accessin DPR.
|
|
|
|
|
Feb 17 2009, 08:13
|
Местный
  
Группа: Свой
Сообщений: 207
Регистрация: 26-01-06
Из: СПб
Пользователь №: 13 659

|
Цитата(sergey sva @ Feb 14 2009, 18:36)  Пытался отправит полностью весь дескриптор конфигурации, но хост принимает(установкой TXCOMP) только первые 8 байт после, завивает в ожидание, может заметите что то неправильное. Это уже винда, она сначала считывает первые 8 байт дескриптора с размерами, потом у себя в кишках готовит буфер а на устройство выдает END_BUS_RES, после этого вычитывает дескриптор полностью. Ну и естественно все виснет по тому что не тот флаг ожидается. Сам долго с этим бился пока доку не прочитал :-)
Сообщение отредактировал Sagittarius - Feb 17 2009, 08:15
|
|
|
|
|
Feb 18 2009, 10:19
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Про END_BUS_RES не знал, добавил но ситуация такая же. 1 получаю установочный пакет, разбираю его, хост просит девайс дескриптор. 2 проверяю бит AT91C_UDP_TXPKTRDY и AT91C_UDP_RXSUSP Код while(AT91C_BASE_UDP->UDP_CSR[EP] & AT91C_UDP_TXPKTRDY){if( AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_RXSUSP ) return;} 3 заполняю буфер , проверяю бит AT91C_UDP_TXCOMP , сбрасываю если надо. Код if (AT91C_BASE_UDP->UDP_CSR[EP] & AT91C_UDP_TXCOMP) { AT91C_BASE_UDP->UDP_CSR[EP] &= ~(AT91C_UDP_TXCOMP); while (AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP); }//end if 4 устанавливаю AT91C_UDP_TXPKTRDY Код AT91C_BASE_UDP->UDP_CSR[EP] |= AT91C_UDP_TXPKTRDY; 5 жду подтверждения получения хостом данных, или сброс, если сброс то вызываю функцию сброса. Код while(!(AT91C_BASE_UDP->UDP_CSR[EP] & AT91C_UDP_TXCOMP)){ if (AT91C_BASE_UDP->UDP_CSR[EP] & AT91C_UDP_RX_DATA_BK0) { AT91C_BASE_UDP->UDP_CSR[EP] &= ~(AT91C_UDP_RX_DATA_BK0); return; }//end if if (AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES){ reset_status = 1; return; }//end bus reset }//end while Ситуации в итоге такая: размер дескриптора конфигурации 18 байт, первые 8 он забирает с подтверждением, следующие 8 байт не берет (подтверждения на них нет AT91C_UDP_TXCOMP) иногда присылает _ENDBUSRES, но после сброса ситуация не меняется, берет первые 8 байт а вторую посылку нет подтверждения. Работа с usb, что то вроде кота в мешке, что там происходит, установил монитор но он позволяет наблюдать только после успешной конфигурации, может есть программы которые позволяет просмотреть что там происходит?
|
|
|
|
|
Feb 20 2009, 12:16
|
Знающий
   
Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847

|
Цитата(sergey sva @ Feb 12 2009, 21:05)  Код USB_COMMON_DESCRIPTOR * pD; (BYTE *) pD += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; при компиляции вылетает ошибка Description Resource Path Location Type lvalue required as left operand of assignment И как этот оператор выполняется, что с чем складывается .? В gcc-4.x так уже нельзя делать. Нужно Код USB_COMMON_DESCRIPTOR * pD; /* Кстати чему pD равен в этом месте? */ BYTE *p = (BYTE *) pD; p += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; pD = (USB_COMMON_DESCRIPTOR *)p;
--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть. © Lewis Carroll. Alice's adventures in wonderland.
|
|
|
|
|
Feb 22 2009, 13:59
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Цитата /* Кстати чему pD равен в этом месте? */ pD = (BYTE *) USB_ConfigDescriptor->bLength; На нулевой элемент дескриптора конфигурации. Атрибут __packed выравнивает адресс по байтам?Этот пример из rw , а какой атрибут использовать в gcc? Код typedef __packed struct _USB_CONFIGURATION_DESCRIPTOR { BYTE bLength; BYTE bDescriptorType; WORD wTotalLength; BYTE bNumInterfaces; BYTE bConfigurationValue; BYTE iConfiguration; BYTE bmAttributes; BYTE MaxPower; } USB_CONFIGURATION_DESCRIPTOR;
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|