This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

USB CDC enumeration problem with XP

Hello,

I'm using a MAX3420E in order to comm a PCB with Atmel microcontroller, with a PC using USB. In windows vista, the PC recognizes a Serial (Virtual) Port and works right, but when I try it in Windows XP, it seems that PC doesn't recognizes the device.

It appears in the device manager as "unknown device" with VID_0000&PID_0000...

I've been searching for a similar post, and found one that had the same problem VID_0000, but the last message does't give any solution...

Any clue? Thank you very much in advance.

The descriptors I use are list below:

// DESCRIPTORS
const unsigned char DD[]=
// DEVICE Descriptor
{0x12, // bLength = 18d
0x01, // bDescriptorType = Device (1)
0x10,0x01, // bcdUSB(L/H) USB spec rev (BCD)
0x02,0x00,0x00, // bDeviceClass, bDeviceSubClass, bDeviceProtocol (descrito en Interface Descriptor)
0x40, // bMaxPacketSize0 EP0 is 64 bytes
0x6A,0x0B, // idVendor(L/H)--Maxim is 0B6A (2922 en decimal)
0x46,0x53, // idProduct(L/H)--5346 (21318 en decimal)
0x00,0x01, // bcdDevice--1234
1,2,3, // iManufacturer, iProduct, iSerialNumber
1}; // bNumConfigurations

const unsigned char CD[]=
// CONFIGURATION Descriptor
{0x09, // bLength
0x02, // bDescriptorType = Config
67,0x00, // wTotalLength(L/H) = Nº Bytes (67[0x43}) (Sin cabeceras 48[0x30]) 0x4300
0x02, // bNumInterfaces = 2
0x01, // bConfigValue
0x00, // iConfiguration
0xA0, // bmAttributes. b7=1 b6=NO self-powered b5=RWU supported (1 1 1 0 0 0 0 0)
0xFA, // MaxPower is 200 ma

// INTERFACE Descriptor
0x09, // length = 9
0x04, // type = IF
0x00, // InterFace Number = 0
0x00, // bAlternate Setting
0x01, // bNum Endpoints = 1 IN
0x02, // bInterfaceClass = 2 Communication
0x02, // bInterfaceSubClass = 2
0x01, // bInterfaceProtocol =1 (SubClass ACM=Abstract Control Mode, InterfaceProtocol=V.25ter, common AT commands)
0x00, // iInterface

// Header Functional Descriptor (marks beginning of the concatenated set of Functional Descriptors)
0x05, // bFunctionLength, Descriptor size in bytes --[18] --[48]
0x24, // bDescriptorType, CS_INTERFACE
0x00, // bDescriptorSubtype, Header Functional Descriptor
0x10,0x01, // bcdCDC, CDC specification release number in BCD format ([0x10, 0x01])

// Call Management Functional Descriptor
0x05, // bFunctionLength, Descriptor size in bytes
0x24, // bDescriptorType, CS_INTERFACE
0x01, // bDescriptorSubtype, Call Management Functional Descriptor
0x03, // bmCapabilities, Device doesn't call management itself (0->3)
0x01, // bDataInterface, Interface used for call management

// Abstract Control Management Functional Descriptor
0x04, // bDescriptorLength, Descriptor size in bytes
0x24, // bDescriptorType, CS_INTERFACE
0x02, // bDescriptorSubtype, Abstract Control Management Functional Descriptor
0x06, // bmCapabilities, Support for the GET/SET_LINE_CODING, BREAK & SET_CONTROL_LINE_STATE

// Union Functional Descriptor
0x05, // bFunctionLength, Descriptor size in bytes
0x24, // bDescriptorType, CS_INTERFACE
0x06, // bDescriptorSubtype, Union Functional Descriptor
0x00, // bMasterInterface, The controlling interface for the union (bInterfaceNumber of a Communication or Data Class interface in this configuration)
0x01, // bSlaveInterface0, The controlled interace in the union (bInterfaceNumber of an interface in this configuration)

Functional Descriptor*****************
// Endpoint Descriptor EP3-IN
0x07, // bLength
0x05, // bDescriptorType (Endpoint)
0x83, // bEndpointAddress (EP3 IN)
0x03, // bmAttributes (interrupt = 3)
0x40,0x00, // wMaxPacketSize (64[0x0040])
0x02, // bInterval, Maximum latency (0x02)

// INTERFACE Descriptor
0x09, // length = 9 --[44]
0x04, // type = IF
0x01, // InterFace Number = 1
0x00, // bAlternate Setting
0x02, // bNum Endpoints = 2 (IN&OUT)
0x0A, // bInterfaceClass = A (Data)
0x00,0x00, // bInterfaceSubClass, bInterfaceProtocol (SubClass ACM=Abstract Control Mode, InterfaceProtocol=V.25ter, common AT commands)
0x00, // iInterface

// Endpoint Descriptor EP1-OUT
0x07, // bLength
0x05, // bDescriptorType (Endpoint)
0x01, // bEndpointAddress (EP1-OUT)
0x02, // bmAttributes (bulk = 2)
0x40,0x00, // wMaxPacketSize (64[0x40])
0x00, // bInterval (0x00)

// Endpoint Descriptor EP2-IN
0x07, // bLength
0x05, // bDescriptorType (Endpoint)
0x82, // bEndpointAddress (EP2-IN)
0x02, // bmAttributes (bulk = 2)
0x40,0x00, // wMaxPacketSize (64[0x40])
0x00, // bInterval (0x00)
};

// STRING descriptors. An array of string arrays

const unsigned char strDesc[][64]= {
// STRING descriptor 0--Language string
{ 0x04, // bLength
0x03, // bDescriptorType = string
0x09,0x04 // wLANGID(L/H) = English-United Sates
},
// STRING descriptor 1--Manufacturer ID
{ 34, // bLength (0x2C para 23 (incluyendo tamaño y tipo??)
0x03, // bDescriptorType = string
'x',0,
'x',0,
'x',0,
'x',0,
' ',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,// text in Unicode
},
// STRING descriptor 2 - Product ID
{ 8, // bLength
0x03, // bDescriptorType = string
'X',0,
'X',0,
'X',0,
},

// STRING descriptor 3 - Serial Number ID
{ 8, // bLength
0x03, // bDescriptorType = string
'X',0,
'X',0,
'X',0,
}};

const unsigned char SerialConf[]=
{ 0x00,0xE8,0x03,0x00, // dwDTFRate. Baudrate (9600hex->38400 baud)
0, // bCharFormat. 1 Stop bit
0, // bParityType: none
8, // Number of data bits: 8
};

Parents Reply Children
  • Yes, in HCList tells me that there are UHCI and EHCI...

  • Now that the problem lands on the typical one - timing issue on OHCI host controller.

    OHCI and UHCI are host controllers for full-speed device, like MAX3420E. EHCI is for hi-speed. When full-speed device is plugged in to a PC USB port directly, the PC assigns OHCI/UHCI controller to the port. For plug in of hi-speed device, EHCI is assigned.

    OHCI is faster than UHCI for control transfer, like Set_Address request.
    When the XP box with OHCI puts Set_Address, your firmware is not prepared for the request yet. As this sequence shows, Bus reset occurs just before Set_Address. Then, the firmware takes too much time to handle Bus reset.

    CDC-ACM (port) enumeration sequence
    
    WinXP SP2, SP3
                            wValue  wIndex   wLen
    Bus Reset
    Get_Descriptor(DEVICE)  0x0100  0x0000  0x0040
    Bus Reset
    Set_Address               0002    0000    0000
    Get_Descriptor(DEVICE)    0100    0000    0012
    Get_Descriptor(CONFIG)    0200    0000    0009
    Get_Descriptor(STRING)    0300    0000    00FF
    Get_Descriptor(STRING)    0303    0409    00FF
    Get_Descriptor(CONFIG)    0200    0000    00FF
    Get_Descriptor(STRING)    0300    0000    00FF
    Get_Descriptor(STRING)    0302    0409    00FF
    Get_Descriptor(STRING)    0300    0000    00FF
    Get_Descriptor(STRING)    0302    0409    00FF
    Get_Descriptor(DEVICE)    0100    0000    0012
    Get_Descriptor(CONFIG)    0200    0000    00FF
    Set_Configuration         0001    0000    0000
    Get_Line_Coding           0000    0000    0007
    Set_Control_Line_State    0000    0000    0000
    IN transaction to the Interrupt IN EP
    
    
    Vista SP1
                            wValue  wIndex   wLen
    Bus Reset
    Get_Descriptor(DEVICE)  0x0100  0x0000  0x0040
    Bus Reset
    Set_Address               0002    0000    0000
    Get_Descriptor(DEVICE)    0100    0000    0012
    Get_Descriptor(CONFIG)    0200    0000    00FF
    Get_Descriptor(STRING)    0303    0409    00FF
    Get_Descriptor(STRING)    0300    0000    00FF
    Get_Descriptor(STRING)    0302    0409    00FF
    Get_Descriptor(DEVICE)    0100    0000    0012
    Get_Descriptor(CONFIG)    0200    0000    00FF
    Set_Configuration         0001    0000    0000
    Get_Line_Coding           0000    0000    0007
    Set_Control_Line_State    0000    0000    0000
    IN transaction to the Interrupt IN EP
    

    We have enough information to examine the firmware source code.
    I want to see your firmware.

    Is your firmware based on any existing example on the web?
    If so, show the link to the example.

    Or, if it is your original, post it somewhere I can reach.



    Ah, I remember...
    The device is putting debug outputs for enumeration, like above post.
    Deleting the debug output routine may solve the timing issue.
    I've seen this solution twice in another cases :-)

    Tsuneo

  • Hello Tsuneo,

    I'm not sure to understand debug outputs for enumeration"...What does this mean? I don't use variables for debugging, just the program to enumerate the device....

    The program is too extensive to copy here without write too much posts, if you want, I can send you to email. I did it from a example for a HID device from maxim web, www.maxim-ic.com/.../3690 , but fitted it to my application...

    Greetings, Piru

  • "I'm not sure to understand debug outputs for enumeration"...What does this mean?"

    I thought this debug output comes from the device, don't it?

    128 6 0 1 0 0 64 0 0 5 12 0 0 0 0 0 ->Set address
    128 6 0 1 0 0 18 0
    128 6 0 1 0 0 9 0
    128 6 0 1 0 0 64 0 ->Again first...
    





    This code is the bus reset handler, excerpted from the Maxim example.
    www.maxim-ic.com/.../3690
    - Did you insert any heavy routine here ?

    EnumAppNote_BF1.C
    
    void service_irqs(void)
    {
    ...
    if(rreg(rUSBIRQ)& bmURESIRQ)
        {
        L1_ON                         // turn the BUS RESET light on
        L2_OFF                        // Suspend light off (if on)
        wreg(rUSBIRQ,bmURESIRQ);      // clear the IRQ
        }
    if(rreg(rUSBIRQ) & bmURESDNIRQ)
        {
        L1_OFF                        // turn the BUS RESET light off
        wreg(rUSBIRQ,bmURESDNIRQ);    // clear the IRQ bit
        Suspended=0;                  // in case we were suspended
        ENABLE_IRQS                   // ...because a bus reset clears the IE bits
        }
    

    This excerpt shows the main (super) loop of the Maxim example.
    While the user task is a light one like this example, it works well.
    But when the user tasks grow and become heavy, the service to the USB tasks delays. And the timing issue occurs, as you are seeing now. To solve this problem, handle the service_irqs() in an interrupt.

    Connect MAX3420E INT pin to the external interrupt pin (INT0 or INT1) of your MCU.
    In the ISR (Interrupt Service Routine) of the external INT, call service_irqs().

    EnumAppNote_BF1.C
    
    void main(void)
    {
    initialize_MAX();
    while(1)                // endless loop
      {
                                // ------------------- USB tasks
      if(Suspended)
        check_for_resume();
      if (MAX_Int_Pending())    //   <--- polling MAX3420E interrupt pin.
        service_irqs();
                                // ------------------- user task(s)
      msec_timer++;
      if(msec_timer==TWENTY_MSEC)
        {
        msec_timer=0;
        if((rreg(rGPIO) & 0x10) == 0) // Check the pushbutton on GPI-0
            {
            inhibit_send = 0x00;      // Tell the "do_IN3" function to send the text string
            L0_ON                     // Turn on the SEND light
            }
        blinktimer++;                 // blink the loop active light every half second
        if(blinktimer==BLINKTIME)
            {
            blinktimer=0;
            L3_BLINK
            }
        }// msec_timer==ONE_MSEC
    
      } // while(1)
    }// main
    

    Tsuneo

  • I get to simplify the code text to fit in just a couple of posts...

    BYTE SUD[9];
    BYTE ep3stall=0, ep2stall=0, ep1stall=0;
    BYTE RWU_enabled;
    bool USB_ini()
    {
            USB_IO();
            SPI_ini(0);
            // software flags
            configval=0; // No configured
            PC_DTR=0;
            Suspended=1;                                    // USB suspended
            RWU_enabled=0; // Set by host Set_Feature(enable RWU) request
            USB_rcv_length=0;
            USB_command_EOF=0;
            USB_send_length=0;
            USB_CSE;
                    wreg(rPINCTL,(bmFDUPSPI+gpxOPERATE)); // MAX3420: SPI=full-duplex, INT=Edge Mode, POSINT=0(neg.edge xa menor consumo), GPX=OPERATE
                    wreg(rUSBCTL,0);
                    wreg(rCPUCTL,bmIE);         // Enables the INT pin
                    ENABLE_IRQS;
            USB_CSD;
            return TRUE;
    }
    
    void check_for_resume(void)
    {
            SPI_ini(0);
            USB_CSE;
            if(rreg(rUSBIRQ) & bmBUSACTIRQ)     // THE HOST RESUMED BUS TRAFFIC
                    Suspended=0;                    // no longer suspended
            USB_CSD;
    }
    
    
    void service_irqs(void)
    {
            if(SPI_mode==1){SPI_CLOSE;}if(SPI_init==0){SPI_ini(0);}
            USB_CSE;
            BYTE itest1,itest2;
            itest1 = rreg(rEPIRQ);          // Check the EPIRQ bits
            itest2 = rreg(rUSBIRQ);         // Check the USBIRQ bits
    
            if(itest1 & bmSUDAVIRQ)
            {
                    wreg(rEPIRQ,bmSUDAVIRQ);    // clear the SUDAV IRQ
                    do_SETUP();
            }
    
            if(itest1 & bmOUT1DAVIRQ) // Rcved EP1 (Bulk)
                    TOS_post(USB_Rcv_Data);
    
    
            if((configval != 0) && (itest2&bmSUSPIRQ))   // HOST suspended bus for 3 msec
            {
                    wreg(rUSBIRQ,(bmSUSPIRQ+bmBUSACTIRQ));  // clear the IRQ and bus activity IRQ
                    Suspended=1;                // signal the main loop
            }
            if(rreg(rUSBIRQ)& bmURESIRQ)
                    wreg(rUSBIRQ,bmURESIRQ);    // clear IRQ
    
            if(rreg(rUSBIRQ) & bmURESDNIRQ)
            {
                    wreg(rUSBIRQ,bmURESDNIRQ);  // clear IRQ bit
                    Suspended=0;                // in case were suspended
                    ENABLE_IRQS;
            }
            USB_CSD;
    }
    
    
    
    void do_SETUP(void)
    {
            readbytes(rSUDFIFO,8,SUD);          // got a SETUP packet
            switch(SUD[bmRequestType]&0x60)     // Parse the SETUP packet
            {
                    case 0x00:      std_request();          break;
                    case 0x20:      class_request();        break;
                    default:        STALL_EP0 // unrecognized
            }
    }
    
    
    void std_request(void)
    {
            switch(SUD[bRequest])
            {
                    case    SR_GET_DESCRIPTOR:      send_descriptor();    break;
                    case    SR_SET_INTERFACE:       set_interface();      break;
                    case    SR_GET_INTERFACE:       get_interface();      break;
                    case    SR_GET_CONFIGURATION:   get_configuration();  break;
                    case    SR_SET_CONFIGURATION:   set_configuration();  break;
                    case    SR_SET_ADDRESS:         rregAS(rFNADDR);      break;  // discard return value
                    default:  STALL_EP0
            }
    }
    
    void set_configuration(void)
    {
            configval=SUD[wValueL];
            if(SUD[wValueL]!=0)
            {
                    wreg(rCLRTOGS,bmCTGEP3IN);              // Clear toggle data EP3 IN (Interrupt)
                    wreg(rCLRTOGS,bmCTGEP1OUT);             // Clear toggle data EP1 OUT (Bulk)
                    SETBIT(rUSBIEN, bmSUSPIE);              // start looking for SUSPEND interrupts
                    rregAS(rFNADDR); // dummy read to set the ACKSTAT bit
            }
    }
    
    void get_configuration(void)
    {
            wreg(rEP0FIFO,configval);         // Send the config value
            wregAS(rEP0BC,1);
    }
    
    void set_interface(void)        // All we accept are Interface=0 and AlternateSetting=0, otherwise send STALL
    {
            if((SUD[wValueL]==0)            // wValueL=Alternate Setting index
            &&(SUD[wIndexL]==0))            // wIndexL=Interface index
                            rregAS(rFNADDR);        // dummy read to set the ACKSTAT bit
            else STALL_EP0
    }
    
    
    void get_interface(void)        // Check for Interface=0, always report AlternateSetting=0
    {
            if(SUD[wIndexL]==0)             // wIndexL=Interface index
            {
                    wreg(rEP0FIFO,0);               // AS=0
                    wregAS(rEP0BC,1);               // send one byte, ACKSTAT
            }
            else STALL_EP0
    }
    

  • I add thesecond part...
    First...I should have commented you that the program runs over API based on tinyOS (meshnetics), and the main bucle (my aplication) is called every Xms, I say 'X', because I can configures it with '0 ms' to make it runs 'as fast as possible'...but don't know the exact time.
    About the debug outputs, I just copy the variable's values meanwhile I debug.

    void send_descriptor(void)
    {
            WORD sendlen,desclen;
            BYTE *pDdata=NULL;                                      // pointer to ROM Descriptor data to send
            bool send_ZLP=FALSE;
            desclen = 0; // check for zero as error condition (no statements satisfied)
            switch (SUD[wValueH])                           // wValueH is descriptor type
            {
            case  GD_DEVICE:
                  desclen = DD[0];  // descriptor length
                  pDdata = (BYTE *) DD;
                  break;
            case  GD_CONFIGURATION:
                  desclen = CD[2];  // Config descriptor includes interface, header and ep descriptors (67 Bytes [0x0043])
                              pDdata = (BYTE *) CD;
                  break;
            case  GD_STRING:
                  desclen = strDesc[SUD[wValueL]][0];   // wValueL=string index, array[0] is the length
                  pDdata = (BYTE *) strDesc[SUD[wValueL]];       // point to first array element
                  break;
            case CS_INTERFACE:
                             if(SUD[wIndexL]==0)    // Interface Number=0. Del EndPoint 2 (interrupción), Communication
                             {
                                    desclen = CD[9];
                                    pDdata = (BYTE *) &CD[9];
                             }
                             else if (SUD[wIndexL]==1)      // Interface Number=1. Del EndPoint 1 (bulk), Datos
                             {
                                    desclen = CD[44];
                                    pDdata = (BYTE *) &CD[44];
                             }
                                    break;
            }       // end switch on descriptor type
    //
            if (desclen!=0)                          // one of the case statements above filled in a value
            {
                    sendlen = desclen;                      // Send Lower data
                    if((desclen % 64) == 0) send_ZLP=TRUE;  // Flag to send ZLP
                    while(desclen>0)
                    {
                            if(desclen>64) sendlen=64;   // if packet>64 bytes
                            else sendlen=desclen;           // if packet<=64 bytes
                            while(!(rreg(rEPIRQ) & bmIN0BAVIRQ));// While out buff. isn't free
                            writebytes(rEP0FIFO,sendlen,pDdata);// Write data in FIFO (EP_CONTROL)
                            pDdata=(pDdata+sendlen);
                            if(desclen<64) wregAS(rEP0BC,sendlen);       // load EP0BC to arm the EP0-IN transfer & ACKSTAT
                            else wreg(rEP0BC,sendlen);      // load EP0BC to arm the EP0-IN transfer & ACKSTAT
                            desclen-=sendlen;                       // Resta los datos ya enviados
                    }
                    if(send_ZLP)
                            wregAS(rEP0BC,0);                       // load EP0BC to arm the EP0-IN transfer & ACKSTAT
            }
            else STALL_EP0;  // none of the descriptor types match
    }
    
    
    void class_request(void)
    {
            switch (SUD[bRequest])
            {
            case SEND_ENCAPSULATED_COMMAND: wregAS(rEP0BC, 0);      break; // send_encapsulated_command();  break;
            case GET_ENCAPSULATED_RESPONSE: wregAS(rEP0BC, 0);      break; // send_encapsulated_command();  break; // get_encapsulated_response();  break;
    
            case SET_COMM_FEATURE:  break;
            case GET_COMM_FEATURE:  break;
            case CLEAR_COMM_FEATURE:break;
            case SET_LINE_CONDING:
            {
                    wregAS(rEP0BC, 0);                              // Envía un paquete de longitud 0 para la etapa de 'STATUS' (?)
                    if(SUD[wLengthL]>0)
                    {
                            while(!(rreg(rEPIRQ) & bmOUT0DAVIRQ) && SUD[7]<=5) SUD[7]++;
            readbytes(rEP0FIFO,SUD[wLengthL],(uint8_t *)&SUD[0]);               // Lee la configuración serie por el EP0 (hay que cambiar algo para que lea?)
                    }
            } break;
            case GET_LINE_CODING:
            {
                    wregAS(rEP0BC, 0);                              // Envía un paquete de longitud 0 para la etapa de 'STATUS' (?)
    writebytes(rEP0FIFO,SUD[wLengthL],(uint8_t *)&SerialConf[0]);
                    wreg(rEP0BC, SUD[wLengthL]);
            } break;
            case SET_CONTROL_LINE_STATE:
            {
                    if(configval)
                    {
                            USB_init=1;                                     // Si llega a este punto, el dispositivo ha terminado de inicializarse
                            if((SUD[wValueL]&0x01)==0x01)// PC listo para aceptar tramas del AZC
                                    PC_DTR=1;
                            if(SUD[wValueL]==0x00)          // Se ha cortado la comunicación con el PC
                                    PC_DTR=0;
                    }
                    wregAS(rEP3INBC, 0);
            } break;
            case SEND_BREAK:        break;
            default: STALL_EP0;                                     // none of the descriptor types match
            }
    }
    
    
    void wreg(BYTE reg, BYTE dat)
    {
            uint8_t data[2];
            USB_CSE;
                    data[0]=reg+2;
                    data[1]=dat;
                    spi_readWrite(data, 2);
            USB_CSD;
    }
    
    
    // Write a MAX3410E register with the "ACK STATUS" bit set in the command byte
    void wregAS(BYTE reg, BYTE dat)
    {
            uint8_t data[2];
            USB_CSE;
                    data[0]=reg+3;
                    data[1]=dat;
                    spi_readWrite(data, 2);
            USB_CSD;
    }
    
    
    // Read a register, return its value.
    uint8_t rreg(BYTE reg)
    {
            uint8_t dat[2];
            dat[0]=reg;
            USB_CSE;
                    spi_readWrite(&dat[0], 2);
            USB_CSD;
            return(dat[1]);
    }
    
    // Read a byte (as rreg), but also set the AckStat bit in the command byte.
    BYTE rregAS(BYTE reg)
    {
            uint8_t dat[2];
            dat[0]=reg+1;;
            USB_CSE;
                    spi_readWrite(&dat[0], 2);
            USB_CSD;
            return(dat[1]);
    }
    
    
    void readbytes(BYTE reg, BYTE N, uint8_t *p)
    {
    //      uint8_t ind_read=0;
            p[0]=reg;
            USB_CSE;
                    spi_readWrite(&p[0], N+1);
            USB_CSD
            *(uint64_t*)p=*(uint64_t*)(p+1);
    //      for(ind_read=0;ind_read<N;ind_read++)
            //      p[ind_read] = rreg(reg);
    }
    
    
    void writebytes(BYTE reg, BYTE N, uint8_t *p)
    {
            uint8_t ind_write=0;
            for(ind_write=0;ind_write<N;ind_write++)
                    wreg(reg, p[ind_write]);
    }
    

  • "About the debug outputs, I just copy the variable's values meanwhile I debug."

    I see.

    As of your above code,
    - Bus reset handler is fine. No problem.
    - Unfortunately, you didn't include the super loop which calls service_irqs()
    The problem lies in the way how service_irqs() is called.

    "I should have commented you that the program runs over API based on tinyOS (meshnetics),
    and the main bucle (my aplication) is called every Xms, I say 'X', because I can configures
    it with '0 ms' to make it runs 'as fast as possible'...but don't know the exact time."

    I suppose service_irqs() is called from your "main bucle" using polling, like Maxim example.
    Is your tinyOS support interrupt?
    Then, move service_irqs() call to external INT pin ISR, which is connected to MAX3420E INT pin.

    Tsuneo

  • Hi,
    do you debug while plugging it in?
    I have the problem, that USB enumeration does not work while debugging (even without any breakpoint).
    The device sends vendor and device ID 0000. When I do not debug (load/start the app out of DataFlash) the enumeration works fine on Windows XP.

  • "I have the problem, that USB enumeration does not work while debugging (even without any breakpoint)."

    This problem often occurs on the board which has a fixed USB D+ (or D-) pull-up resistor, like
    MCB2140 - R35
    MCBSTR7 - D+ resistor is included in USBUF01W6 - fixed

    When the pull-up resistor is controlled by MCU, the problem doesn't occur (as long as the firmware handles it properly).

    These boards are fine at this point.
    MCB2300 - R3
    MCB2460 - OTG - controlled by ISP1301
    MCBSTR750 - R29
    MCBSTR9 - R29
    MCBSTM32(E) - R29

    Tsuneo

  • Yes, I try to run it without debuging of course, but don't work anyway...

    ----

    About the interrupts, yes it's supported (as far as I know). 'service_irqs()' is called every time that MAXIM3420 actives interrupt, is not inside a (super) loop...directly...Maybe it's inside a superloop because it is (more than) possible that API has a task manager (that is the reason I have to define a 'user loop call time').
    Now I don't use interrupts, put 'service_irqs()' into 'user entry' function where I have to define the time that the main loop is called. Just a while loop calling 'service_irqs()', nothing more to do...in Vista it works, but in XP it don't work yet...

  • Hello,

    I spent some time looking for a solution without results, but I found other things, that maybe gives any clue to anybody that have suffered the same problem...

    It seems that it works in a laptop with Vista, many USB controller OHCI, and a EHCI (PCI to USB Enhanced Host Controller). It has the same resources than the PC, but the controller is OpenHCD, and the PC uses "SiS 7001".

    I found many forums where peoples have many problems with this controller "SiS 7001", I don't know if somebody knows something about this...

    I try to disable the Enhanced controller, but nothing, only says that memory pen can works faster because is USb 2.0...

    The USBView utility tells me that my device has a Low Bus Speed (this application can read PID and VID also)...any clue...?

    thank you in advance, and sorry for the insistence...

  • I reviewed this problem, and another possibility.
    It may relate to suspend after connection, before bus reset.
    To confirm it, disable suspend temporarily.

    bool USB_ini()
    {
       ...
       // Suspended=1;      // USB suspended <---- disable suspend temporarily
    

    Tsuneo

  • Finally I found the error!! Now I hace an initialization error, but it recognizes the device.

    Looking for the differences between descriptors requeriments of Vista and XP, I found that in XP you should return the exact number of Bytes of the descriptors requested, but if the request is higher, you have to truncate the number to the exact number of descriptor types...
    I neglected this...

    Sorry for the inconveniences, and than you very much for your time!

    I hope this error be useful to more people...

    Greetings!

  • Well, now the device works all right.

    I would like to explain exactly the problem to help to anyone who needs it.

    When PC ask me for a configuration device, I returned the length of the descriptor, but sometimes the machine just ask for a part of the descriptor...

    when ask for 255 bytes, return 67 bytes that I defined...when ask for 9 I also returned 67...but it's wrong, you have to return the bytes for the descriptor part that PC ask you, it could be 9 or 67, depending of the request... well, I think it's no necessary that I explain the full real example ...

  • Hello,

    I seem to be having very similar problems and I can't get the hardware working with the instructions in the last post. Would you mind posting your send_descriptor function so I can track down whats going wrong.

    Thanks