Bulat
Участник-
Постов
206 -
Зарегистрирован
-
Посещение
Репутация
0 ОбычныйИнформация о Bulat
-
Звание
Местный
- День рождения 13.06.1984
Информация
-
Город
Array
-
Ошибку нашел. Заработало.
-
Решил воспользоваться стандартным WDF-драйвером Winusb.sys из WDK 7600. Все делал согласно инструкции. Настроив inf-файл под свое устройство, удалось успешно установить драйвер, открыть устройство с помощью createfile. Далее при попытке записи 1-го байта в драйвер с использованием функции WinUsb_WritePipe из библиотеки winusb.lib, не смотря на то, что функция записи WinUsb_WritePipe возвращает TRUE, программа USBTrace показала, что было отправлено 0 байт, хотя пытался отправить 1 байт. Проверил адреса конечных точек для записи и чтения, в моем устройстве они следующие: 0x81, // bEndpointAddress, Endpoint 01 - IN 0x02, // bEndpointAddress, Endpoint 02 - OUT, то есть, направления точек заданы верны, если адреса поменять местами, то WinUsb_WritePipe возвращает FALSE, отсюда сделал вывод, что, видимо, направления и адреса задал правильно. Атрибуты обеих конечных точек BULK. Может быть я еще что-то не учел в дескрипторах конечных точек на устройстве? Со стороны приложения хоста вроде никаких изменений по сравнению с кодом из msdn не вносил. Почему WinUsb_WritePipe возвращает TRUE, но при этом ничего не отправляет?
-
Спасибо! Он мне подходит)
-
чем меньше, тем лучше. хорошо бы меньше, чем 1210 (smd)
-
Не могу найти высокочастотный (1 МГц и выше) повышающий преобразователь с 3,3 до +\- 12В, 50 мА. Нашел max743, но у него частота 200 кГц, отчего огромные индуктивности и емкости. Заранее благодарен.
-
Вопрос по работе SSC-модуля at91sam7s
Bulat ответил Bulat тема в ARM, 32bit
и еще PIO запретить. спасибо) -
Вопрос по работе SSC-модуля at91sam7s
Bulat опубликовал тема в ARM, 32bit
Почему после выполнения команды AT91C_BASE_SSC->SSC_CR = AT91C_SSC_TXDIS синхросигнал на вывод TK всеравно продолжает поступать. Как отключать тактовый сигнал у SSC? Заранее благодарен. -
Так ведь индексы каждого из 3-х строковых дескрипторов (iManufacturer, iProduct, SerialNumber) прописываются в дескрипторе устройства и затем запрашиваются при нумерации отдельными запросами: wValue = 301, 302, 303, соответственно. А ваш дескриптор как отправлять? по каждому запросу по частям?
-
Исправил, но тогда для отправки строквых дескрипторов надо использовать другую функцию SendData, которая отправляет данные типа wchar_t static void AT91F_USB_SendData_w(AT91PS_UDP pUdp, wchar_t *pData, uint txlen) { uint cpt = 0; AT91_REG csr; do { cpt = MIN(txlen, 8); txlen -= cpt; while(cpt--) pUdp->UDP_FDR[0] = *pData++; if(pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) Udp_ep_clr_flag(pUdp, 0, AT91C_UDP_TXCOMP); pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY; do { csr = pUdp->UDP_CSR[0]; // Data IN stage has been stopped by a status OUT if(csr & AT91C_UDP_RX_DATA_BK0) { pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0); return; } } while(!(csr & AT91C_UDP_TXCOMP)); }while(txlen); if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) Udp_ep_clr_flag(pUdp, 0, AT91C_UDP_TXCOMP); }//AT91F_USB_SendData_w но строковые дескрипторы всеравно не приходят и теперь нумерация идет гораздо дольше - несколько секунд. Как правильно отправлять структуры типа wchar_t?
-
Не удается передать строковые дескрипторы при нумерации
Bulat опубликовал тема в ARM, 32bit
Сами дескрипторы в usb.h const char devDescriptor[] = { 0x12, // bLength // Device descriptor 0x01, // bDescriptorType 0x10, // bcdUSBL 0x01, // 0xFF, // bDeviceClass: CDC class code 0x00, // bDeviceSubclass: CDC class sub code 0x00, // bDeviceProtocol: CDC Device protocol 0x08, // bMaxPacketSize0 0xEB, // idVendorL 0x03, // 0x55, // idProductL 0x03, // 0x01, // bcdDeviceL 0x00, // 0x01, // iManufacturer // 0x01 0x02, // iProduct 0x03, // SerialNumber 0x01 // bNumConfigs }; const char strDescriptor_IDL[]={ /* String_IDLanguages Descriptor */ 0x04, // bLength 0x03, // bDescriptorType 0x09, // wLANGID[0] 0x04 }; const char strDescriptor_IMan[]={ /* String_IManufacturer Descriptor */ 0x02+0x02*12, // bLength 0x03, // bDescriptorType 'O'<<8, 'r'<<8, 'g'<<8, 'a'<<8, 'n'<<8, 'i'<<8, 'z'<<8, 'a'<<8, 't'<<8, 'i'<<8, 'o'<<8, 'n'<<8 // bString }; const char strDescriptor_IPro[]={ /* String_IProduct Descriptor */ 0x02+0x02*9, // bLength 0x03, // bDescriptorType 'I'<<8, 'n'<<8, 't'<<8, 'e'<<8, 'r'<<8, 'f'<<8, 'a'<<8, 'c'<<8, 'e'<<8 //bString }; const char strDescriptor_ISer[]={ /* String_ISerialNumber Descriptor */ 0x02+0x02*11, // bLength 0x03, // bDescriptorType '1'<<8,'2'<<8,'3'<<8,'-'<<8,'4'<<8,'5'<<8,'6'<<8,'-'<<8,'7'<<8,'8'<<8,'9'<<8 //bString }; static char devDescriptor_ram[sizeof(devDescriptor)]; static char cfgDescriptor_ram[sizeof(cfgDescriptor)]; static char strDescriptor_IDL_ram[sizeof(strDescriptor_IDL)]; static char strDescriptor_IMan_ram[sizeof(strDescriptor_IMan)]; static char strDescriptor_IPro_ram[sizeof(strDescriptor_IPro)]; static char strDescriptor_ISer_ram[sizeof(strDescriptor_ISer)]; Обработка запроса GET_DESCRIPTOR в usb.c ... if(!(pUDP->UDP_CSR[0] & AT91C_UDP_RXSETUP))return; bmRequestType = pUDP->UDP_FDR[0]; bRequest = pUDP->UDP_FDR[0]; wValue = (pUDP->UDP_FDR[0] & 0xFF); wValue |= (pUDP->UDP_FDR[0] << 8); wIndex = (pUDP->UDP_FDR[0] & 0xFF); wIndex |= (pUDP->UDP_FDR[0] << 8); wLength = (pUDP->UDP_FDR[0] & 0xFF); wLength |= (pUDP->UDP_FDR[0] << 8); if(bmRequestType & 0x80) { while(!(pUDP->UDP_CSR[0] & AT91C_UDP_DIR)) pUDP->UDP_CSR[0] |= AT91C_UDP_DIR; } while((pUDP->UDP_CSR[0] & AT91C_UDP_RXSETUP)) pUDP->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP; switch ((bRequest << 8) | bmRequestType) // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1 { case STD_GET_DESCRIPTOR: switch (wValue) { case 0x100: AT91F_USB_SendData(pUDP, devDescriptor_ram, MIN(sizeof(devDescriptor_ram), wLength)); break; case 0x200: AT91F_USB_SendData(pUDP, cfgDescriptor_ram, MIN(sizeof(cfgDescriptor_ram), wLength)); break; case 0x300: AT91F_USB_SendData(pUDP, strDescriptor_IDL_ram, MIN(sizeof(strDescriptor_IDL_ram), wLength)); break; case 0x301: AT91F_USB_SendData(pUDP, strDescriptor_IMan_ram, MIN(sizeof(strDescriptor_IMan_ram), wLength)); break; case 0x302: AT91F_USB_SendData(pUDP, strDescriptor_IPro_ram, MIN(sizeof(strDescriptor_IPro_ram), wLength)); break; case 0x303: AT91F_USB_SendData(pUDP, strDescriptor_ISer_ram, MIN(sizeof(strDescriptor_ISer_ram), wLength)); break; default: AT91F_USB_SendStall(pUDP); break; } break; ... Индексы в дескрипторе устройства прописал, все запросы строковых дескрипторов обрабатываю, но при этом ни один из строковых дескрипторов не приходит. Не подскажите, в чем тут может быть проблема. Заранее благодарен. -
Необходимо из приложения изменять значение констатнты (например, серийный номер устройства), чтобы это константа сохранялась после отключения питания. Как лучше реализовать эту функцию. Если с помощью перезаписи страницы флеш-памяти, то где можно найти примеры?
-
Дело в том, что в документации есть предупреждение о том, что нельзя делать слишком большую паузу между установкой бита TXCOMP и установкой бита TXPKTRDY: If the delay between receiving TX_COMP is set and TX_PKTRDY is set is too long, some Data IN packets may be NACKed, reducing the bandwidth. У меня видимо что-то подобное и происходит?
-
Если я в этом коде вместо условия: 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 условия: 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 опрашивался и соответственно сбрасывался только после заполнения второго банка).
-
Да, я это исправил, просто забыл в ответ написать. Я использовал функцию #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); Код, который я привел в предыдущем сообщении уже с этими функциями. Всеравно больше одного банка не передается.
-
Ниже приведен код работы с 2-мя банками. Первые 60 байт нормально передаются на Хост, а потом передача затыкается. Вроде все сделал, как в документации. Почему так происходит? 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)