Hoksmur 0 7 февраля, 2014 Опубликовано 7 февраля, 2014 (изменено) · Жалоба Есть задача запихать в комп поток порядка 4МБит, поэтому LUFA с её опросом по кольцу (superloop) не нравится. К тому же - _подавляющее_ большинство использовало так или иначе готовые примеры на HID/CDC/Massstorage, а потому подсказать ничего не могут. Не кварц или тактирование, потому что залитые демки работают. Главная проблема, с которой столкнулся - не ловлю прерывание по приёму пакета SETUP, источник UEINTX.RXSTPI, прерывание в UEIENX.RXSTPE разрешено, глобальные sei() - тоже. Сделал хоть какое-то подобие отладчика - вывод информации через UART. Но это не помогло найти проблему. По прерывания суммарно - попадаю в обработчик устройства USB General Interrupt при сбросе устройства хостом, в USB Endpoint Interrupt _только_ по UEINTX.TXINI. Логически анализатор показывает, что хост пытается передать запрос на дескриптор, но МК его не ощущает. То есть хост пытается запросить дескриптор. А где же, блин, пакет SETUP ? Раздел USB даташита скоро наизусть знать буду (две опечатки нашел), USB Nutshell+перевод весь излазил, спецификацию тоже читал. Ещё: должно, по идее, прилететь тело запроса дескриптора, но где его читать? Счётчик байт в буфере UESTA0X всегда 0. Номер конечной точки пока вообще не переключал. Дамы и господа - выручайте, уже никаких идей. Код (ниже) привожу весь. В самом низу - отчёт логического анализатора. "Отладчик" выдаёт следующее: R 08: 21 00 00: 00 18 00: 00 18 00: 00 18 00: 00 18 00: 00 18 00 Не пинайте за R 08 - рядом за комментарием строка со всеми разрешёнными прерываниями. R - сброс прошёл, USB не инициализировано. 08 - регистр UEIENX перед sei() : 21 00 00 - UECONX и, копируемые в прерывании UDINT и UEINTX. UECONX.STALLRQ - Cleared by hardware when a new SETUP is received. : 00 18 00 - то же самое. * - не печатается, в обработчик ENDPOINT-ов не попадаем. /* * USB_sample.c * * Created: 20.01.2014 10:31:24 * Author: t.oleg */ #include <avr/io.h> #include <avr/interrupt.h> #include <avr/cpufunc.h> #include <avr/wdt.h> #include <util/delay.h> #include <avr/power.h> #include <avr/sleep.h> #include <avr/pgmspace.h> #define waitTXR while(!( UCSR1A & (1<<UDRE1))){;} #define LED_ON PORTD &= ~(1<<4) #define LED_OFF PORTD |= 1<<4 volatile uint8_t tmpreg1=0; volatile uint8_t tmpreg2=0; static inline void init_EP( const uint8_t EPN, const uint8_t UECFG0, const uint8_t UECFG1 ); static inline void conf_int_EP(const uint8_t EPN, const uint8_t INTMASK); static void hexecho1 (uint8_t byte) { while (!( UCSR1A & (1<<UDRE1))) {;} UDR1 = ' '; while (!( UCSR1A & (1<<UDRE1))) {;} if ((byte >> 4) < 0x0A) { UDR1 = (byte >> 4) + 0x30; } else { UDR1 = (byte >> 4) + 0x37; } while (!( UCSR1A & (1<<UDRE1))) {;} if ((byte & 0x0F) < 0x0A) { UDR1 = (byte & 0x0F) + 0x30; } else { UDR1 = (byte & 0x0F) + 0x37; } } void USART_Init( const unsigned int baud ) { /* Set baud rate*/ UBRR1H = (unsigned char)(baud>>8); UBRR1L = (unsigned char)baud; #define USE_2X 1 #if USE_2X UCSR1A |= (1 << U2X1); #else UCSR1A &= ~(1 << U2X1); #endif /* Enable receiver and transmitter*/ UCSR1B = (1<<TXEN1); //|(1<<RXENn); /* Set frame format: 8data, 2stop bit*/ // use reset values for 8N1 // UCSRnC = (1<<USBSn)|(3<<UCSZn0); } void setupHW(void) { /* Disable watchdog if enabled by bootloader/fuses */ MCUSR &= ~(1 << WDRF); wdt_disable(); clock_prescale_set(clock_div_1); // так тактовая = частота кварца DDRD |= 1<< 4; DDRB |= 1<<PB7|1<<PB6|1<<PB5; USART_Init( 8 ); } void USBinit(void) { // USB_Init from LUFA REGCR &= ~(1 << REGDIS); // disable Vreg // USB_ResetInterface(); PLLCSR = ~(0<<PLLP0|0<<PLLP1|0<<PLLP2); PLLCSR |= 1<<PLLE; while (!(PLLCSR & (1<<PLOCK))); // wait PLL LOCK USBCON = 0x20; //~(1 << USBE )|(1<<FRZCLK); USBCON |= (1 << USBE); USBCON &= ~(1<<FRZCLK); init_EP(0, (uint8_t)~(1<<EPTYPE1|1<<EPTYPE0|1<<EPDIR), 0x00 ); // N0, control, 16 byte //conf_int_EP(0, 1<<FLERRE|1<<NAKINE|1<<NAKOUTE|1<<RXSTPE|1<<RXOUTE|1<<STALLEDE|1<<TXINE); conf_int_EP(0, 1<<RXSTPE); // UEIENX = 1<<FLERRE|1<<NAKINE|1<<NAKOUTE|1<<RXSTPE|1<<RXOUTE|1<<STALLEDE|1<<TXINE; // all EP Interrupts for test UDCON &= ~(1 << DETACH); // Init USB by steps, p. 194 // Configure PLL interface // Enable PLL // Check PLL lock // Enable USB interface // Configure USB interface (USB Endpoint 0 configuration) // Attach USB device //UDIEN = 1<<UPRSME|1<<EORSME|1<<WAKEUPE|1<<EORSTE|1<<SOFE|1<<SUSPE; // use all interrupt for start UDIEN = 1<<UPRSME|1<<EORSME|1<<EORSTE|1<<SOFE; // all, ex. WakeUP and SUSPEND } int main(void) { setupHW(); UDR1 = 'R'; USBinit(); hexecho1(UEIENX); sei(); LED_OFF; set_sleep_mode(SLEEP_MODE_IDLE); sleep_enable(); while(1) { //TODO:: Please write your application code waitTXR; UDR1 = ':'; hexecho1(UECONX); hexecho1(tmpreg1); tmpreg1 = 0; hexecho1(tmpreg2); tmpreg2 = 0; _NOP(); sleep_cpu(); LED_ON; } } ISR(USB_GEN_vect, ISR_BLOCK) { static uint8_t cntGEN=0; // Hardware Interface cntGEN++; tmpreg1 = UDINT; if (UDINT & (1<<EORSTI)) { // поймали сброс UDINT &= ~(1<<EORSTI); UERST |= 1 << 0|1<<1|1<<2|1<<3|1<<4; // reset EP 0 UDADDR = 0; UDADDR |= 1 << ADDEN; } } ISR(USB_COM_vect, ISR_BLOCK) { static uint8_t cntCOM=0; // Endpoint events cntCOM++; tmpreg2 = UEINTX; if (UEINTX & (1<<TXINI)) { UEINTX &= ~(1<<TXINI); } sei(); waitTXR; UDR1 = '*'; hexecho1(UECONX); hexecho1(UESTA0X); hexecho1(UESTA1X); } static void init_EP( const uint8_t EPN, const uint8_t UECFG0, const uint8_t UECFG1 ) { // Endpoint initialization // Endpoint activation, fig. 20-2 UENUM = EPN & 0x07; // last 3 bits // UECONX |= 1<<STALLRQ; UECONX |= 1<<EPEN|1<<STALLRQ; UECFG0X = UECFG0 & 0xC3; // [7:6]EPTYPE, [0] EPDIR UECFG1X = UECFG1 & 0x7E; // - [6:4]EPSIZE2:0, [3:2]EPBK1:0, [1] ALLOC UECFG1X = 1<<ALLOC; // 16 bytes, one bank, do ALLOCATE while (!(UESTA0X & (1<<CFGOK))); // wait ready } static void conf_int_EP(const uint8_t EPN, const uint8_t INTMASK) { // endpoint interrupt configure UENUM = EPN; UEIENX = INTMASK & ~(1<<5); } Лог (в спойлере становится чёрным): Please wait... USB RESET 11,31ms SOF 288 USB RESET 12,31ms SOF 289 13,31ms SOF 290 14,31ms SOF 291 15,31ms SOF 292 16,31ms SOF 293 17,31ms SOF 294 18,31ms SOF 295 19,31ms SOF 296 USB RESET 20,31ms SOF 297 21,31ms SOF 298 22,31ms SOF 299 23,31ms SOF 300 24,31ms SOF 301 25,31ms SOF 302 26,31ms SOF 303 27,31ms SOF 304 USB RESET 28,31ms SOF 305 29,31ms SOF 306 30,31ms SOF 307 31,31ms SOF 308 32,31ms SOF 309 33,31ms SOF 310 34,31ms SOF 311 35,31ms SOF 312 USB RESET 36,31ms SOF 313 37,31ms SOF 314 37,71ms SETUP Add: 0 EndPoint: 0 GET DESCRIPTOR DEVICE Length: 64 DATA0 80 06 00 01 00 00 40 00 37,73ms SETUP Add: 0 EndPoint: 0 GET DESCRIPTOR DEVICE Length: 64 DATA0 80 06 00 01 00 00 40 00 37,74ms SETUP Add: 0 EndPoint: 0 GET DESCRIPTOR DEVICE Length: 64 DATA0 80 06 00 01 00 00 40 00 38,31ms SOF 315 39,31ms SOF 316 40,31ms SOF 317 41,31ms SOF 318 42,31ms SOF 319 43,31ms SOF 320 USB RESET 44,31ms SOF 321 45,31ms SOF 322 46,31ms SOF 323 47,31ms SOF 324 48,31ms SOF 325 49,31ms SOF 326 50,31ms SOF 327 51,31ms SOF 328 No sync Found 51,32ms SOF 328 USB RESET ---.......----- 451,32ms SOF 728 USB RESET 452,32ms SOF 729 453,32ms SOF 730 454,32ms SOF 731 455,32ms SOF 732 456,32ms SOF 733 457,32ms SOF 734 458,32ms SOF 735 459,32ms SOF 736 USB RESET No sync Found Invalid Token No sync Found Invalid Token No sync Found Invalid Token No sync Found Invalid Token No sync Found Invalid Token No sync Found Invalid Token No sync Found Invalid Token No sync Found Invalid Token No sync Found Invalid Token 463,32ms SOF 740 464,32ms SOF 741 465,32ms SOF 742 466,32ms SOF 743 467,32ms SOF 744 USB RESET ---.......--- 539,32ms SOF 816 Invalid Token No sync Found Invalid Token USB RESET No sync Found Invalid Token No sync Found Invalid Token No sync Found Invalid Token No sync Found Invalid Token No sync Found Invalid Token No sync Found Invalid Token 542,32ms SOF 819 543,32ms SOF 820 544,32ms SOF 821 545,32ms SOF 822 546,32ms SOF 823 547,32ms SOF 824 USB RESET 548,32ms SOF 825 549,32ms SOF 826 550,32ms SOF 827 551,32ms SOF 828 552,32ms SOF 829 553,32ms SOF 830 USB RESET 565,32ms SOF 842 566,32ms SOF 843 567,32ms SOF 844 568,32ms SOF 845 569,32ms SOF 846 570,32ms SOF 847 571,32ms SOF 848 USB RESET 572,32ms SOF 849 573,32ms SOF 850 574,32ms SOF 851 575,32ms SOF 852 576,32ms SOF 853 577,32ms SOF 854 578,32ms SOF 855 579,32ms SOF 856 USB RESET 580,32ms SOF 857 581,32ms SOF 858 582,32ms SOF 859 583,32ms SOF 860 584,32ms SOF 861 585,32ms SOF 862 586,32ms SOF 863 587,32ms SOF 864 USB RESET 588,32ms SOF 865 589,32ms SOF 866 590,32ms SOF 867 591,32ms SOF 868 592,32ms SOF 869 593,32ms SOF 870 593,72ms SETUP Add: 0 EndPoint: 0 GET DESCRIPTOR DEVICE Length: 64 DATA0 80 06 00 01 00 00 40 00 593,74ms SETUP Add: 0 EndPoint: 0 GET DESCRIPTOR DEVICE Length: 64 DATA0 80 06 00 01 00 00 40 00 593,75ms SETUP Add: 0 EndPoint: 0 GET DESCRIPTOR DEVICE Length: 64 DATA0 80 06 00 01 00 00 40 00 594,32ms SOF 871 595,32ms SOF 872 USB RESET Изменено 7 февраля, 2014 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hoksmur 0 7 февраля, 2014 Опубликовано 7 февраля, 2014 (изменено) · Жалоба Поменял немного "логи". Теперь считаю в прерываниях количество вызовов, и в основной петле выплёвываю на экран. Тело переполняемого прерывания такое: ISR(USB_COM_vect, ISR_BLOCK) { // Endpoint events //LED_ON; cntCOM++; if (UEINT & (1<<TXINI)) { UEINT &= ~(1<<TXINI); } } "Логи" ниже. То есть вообще-то хот пытается достучаться, но потом надоедает, и пытается сбрасывать. В обработчике только сброс флага TXINI. Кстати, что это означает для случая Control ? R. > 00 5B > 00 D3 > 00 47 > 00 BF > 00 36 > 00 AB > 00 22 > 00 9A > 00 0F > 00 87 > 00 FC > 00 73 > 00 EB > 00 62 > 00 D7 > 00 4E > 00 C6 > 00 3A > 00 B2 > 00 29 > 00 9E > 00 16 > 00 8B > 00 03 > 00 7B > 00 F0 > 00 67 > 00 DC > 00 53 > 00 CB > 00 42 > 00 B7 > 00 2E > 00 A6 > 00 1A > 00 92 > 00 0A > 00 7F > 00 F7 > 00 6B > 00 E3 > 00 5A > 00 CF > 00 46 > 00 BE > 00 35 > 00 AA > 00 21 > 00 99 > 00 0E > 00 86 > 00 FB > 00 72 > 00 EA > 00 5E > 00 D6 > 00 4D > 00 C2 > 00 39 > 00 B1 > 00 28 > 00 9D > 00 15 > 00 8A > 00 02 > 00 77 > 00 EF > 00 66 > 00 DB > 00 52 > 00 CA > 00 41 > 00 B6 > 00 2D > 00 A2 > 00 19 > 00 91 > 00 06 > 00 7E > 00 F3 > 00 6A > 00 E2 > 00 59 > 00 CE > 00 45 > 00 BD > 00 34 > 00 A9 > 00 20 > 00 95 > 00 0D > 00 85 > 00 FA > 00 71 > 00 E6 > 00 5D > 00 D5 > 00 4C > 00 C1 > 00 38 > 00 B0 > 00 27 > 00 9C > 00 14 > 00 89 > 00 01 > 00 76 > 00 EE > 00 65 > 00 DA > 00 51 > 00 C9 > 00 3D > 00 B5 > 00 2C > 00 A1 > 00 18 > 00 90 > 00 05 > 00 7D > 00 F2 > 00 69 > 00 E1 > 00 58 > 00 CD > 00 44 > 00 BC > 00 30 > 00 A8 > 00 1F > 00 94 > 00 0C > 00 81 > 00 F9 > 00 70 > 00 E5 > 00 5C > 00 D4 > 00 4B > 00 C0 > 01 E2 > 02 E2 > 03 E2 > 04 E2 > 05 E2 Изменено 7 февраля, 2014 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hoksmur 0 9 февраля, 2014 Опубликовано 9 февраля, 2014 · Жалоба Мысль появилась. Можете посмотреть инициализацию, если у кого есть такая возможность и желание? Кварц 8 МГц. Тактирование CPU вроде правильно (иначе бы UART не работал нормально), но лучше тоже проверить. До этого запрещал все UE* прерывания, оставляя только RXSTPI - не ловил. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться