Trouble with USB without LUFA on at90USB162

I have a task transmit stream ~4MBit from device to PC. LUFA use ‘superloop’, because i think it can be slow.

Most application use CDC/HID/Masstorgae - I can’t use it. Board is ok - I have tested it with LUFA demos.

The Truble is that MCU dont’ interrupt when it recieved SETUP packet. Source should be UEINTX.RXSTPI, UEIENX.RXSTPE, , sei() enabled.

I made ‘debugger’ -output info on UART. What I see?

MCU caught USB General Interrupt as source bus reset and USB Endpoint Interrupt only with UEINTX.TXINI.

I connected logic analiser - it showed that host sended DeviceDescriptor, but MCU didn’t catch it.

I read datashet lot of times, + USB NutShell + particulary USB specification.

One more moment - I mean, MCU shoul recive ‘body’ DevDecsr request, but where It should be? UEBCLX always is 0.

I haven’t any ideas.

“debugger” sends: R 08: 21 00 00: 00 18 00: 00 18 00: 00 18 00: 00 18 00: 00 18 00

R 08 - isn’t wrong, you can find comented line.

R - reset, USB not initialized .

08 - reg. UEIENX before sei()

: 21 00 00 - UECONX and, copied from interrupt UDINT and UEINTX. UECONX.STALLRQ - Cleared by hardware when a new SETUP is received.(my small test)

: 00 18 00 - the same next times.

    • didn’t print, ENDPOINT interrupt not called

Source code - bellow. Then - analiser report.

/*
* 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);
}

LOG:

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

I have done one more experiment - in interrupts I count times of call only. And it is iteresting - channel level interrupt overflov 8 bit counter some times!

PS: How can I use spoiler here?

ISR(USB_COM_vect, ISR_BLOCK)
{
   // Endpoint events
   //LED_ON;
   cntCOM++;
   if (UEINT & (1<<TXINI))
   {
      UEINT &= ~(1<<TXINI);
   }
}
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

I have one more think. Can somebody, who have time ant have interes, chek initializations? :cry: I use crystal 8 MHz. CPU clock should be OK, bu I am not sure. (UART is working).

Earlier I disbled all UE* interrupt’s source, exlude RXSTPI - but MCU haven’t catch it. :shifty:

I reversed part of LUFA. Possible, RXSTPI alone can’t be routed. Now I catch (UEINTX & (1<<RXSTPI)) first time. routines now is

ISR(USB_COM_vect, ISR_BLOCK)
{
	// Endpoint events
	if (UEINTX & (1<<RXSTPI)) {
		LED_ON;
		tmpreg2 = UEINTX; // show it in main loop over UART
	}
	waitTXR;UDR1 = '*';
}

and second

ISR(USB_GEN_vect, ISR_BLOCK)
{
	// Hardware Interface
	tmpreg1 = UDINT;
	
	if (UDINT & (1<<EORSTI)) {
		UDINT &= ~(1<<EORSTI);
		UDINT &= ~(1<<SUSPI);
		UDIEN &= ~(1<<SUSPE);
		UDIEN |= 1<<WAKEUPE;
		init_EP(0, 0, 0);	// re-init EP0
			UEIENX |= 1<<RXSTPE;
	}
	
	if (UDINT & (1<<WAKEUPI)) {
		PLLCSR |= 1<<PLLE;
		while (!(PLLCSR & (1<<PLOCK))); // wait PLL LOCK
		USBCON &= ~(1<<FRZCLK);
		UDINT &= ~(1<<WAKEUPI);
		UDIEN &= ~(1<<WAKEUPE);
		UDIEN |= 1<<SUSPE;
	}
	
}

UART ‘debug’ types:

18 49***