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 };
The '.inf' file I use is:
[Version] Signature="$Windows NT$" Class=Ports ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%XXXX% LayoutFile=layout.inf DriverVer=08/04/2004,5.1.2699.2180
[Manufacturer] %XXXX%=XXXX
[XXXX] %AXXv100%= AXXv100,USB\VID_0B6A&PID_5346
;[AXXv100_Install.NTx86] ;Copy from Windows system ;include=mdmcpq.inf ;CopyFiles=DriverCopyFiles ;CopyFiles=FakeModemCopyFileSection
[DestinationDirs] DefaultDestDir=12 AXXv100.NT.Copy=12, System32\Drivers
[AXXv100.NT] include=mdmcpq.inf AddReg=LowerFilterAddReg CopyFiles=AXXv100.NT.Copy AddReg= AXXv100.NT.AddReg
[AXXv100.NT.Copy] usbser.sys
[AXXv100.NT.AddReg] HKR,,DevLoader,,*ntkern HKR,,NTMPDriver,,usbser.sys HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[AXXv100.NT.Services] include=mdmcpq.inf AddService=usbser, 0x00000002, Service_Inst
[Service_Inst] DisplayName = %Serial.SvcDesc% ServiceType = 1 ; SERVICE_KERNEL_DRIVER StartType = 3 ; SERVICE_DEMAND_START ErrorControl = 1 ; SERVICE_ERROR_NORMAL ServiceBinary = %12%\usbser.sys
[Strings] XXXX = "xxxx xxxxxxxxxxx" ; Your company name AXXv100 = "XXX XXXXX" ; Device description Serial.SvcDesc = "AXX - Virtual Serial Comm Port" ; Device driver description
Sound like the problem of INF file
Since Win2k, usbser.sys doesn't exist in the driver folder as the default Windows installation. It is copied from the installation archive, like C:\I386, when the INF file requests.
Is there usbser.sys in this folder of your XP box? C:\Windows\System32\drivers
Revise the AXXv100.NT section of INF as follows. Then, usbser.sys is copied from the installation archive to the driver folder.
[AXXv100.NT] include=mdmcpq.inf CopyFiles=FakeModemCopyFileSection AddReg= AXXv100.NT.AddReg
And delete entire AXXv100.NT.Copy section
This MS KB tells this solution. "How to use or to reference the Usbser.sys driver from universal serial bus (USB) modem .inf files" support.microsoft.com/.../en-us "I'm using a MAX3420E in order to comm a PCB with Atmel microcontroller"
Anyway, what is related to this Keil forum? :-)
Tsuneo
Hello Tsuneo,
Thank you for your reply. Yes...isn't the correct forum to ask about, but I see some questions related with USB answered, and I try to get some information... Sorry for the inconveniences.
I write messages in other forums and don't get a solution, and it's impossible to registry in the USB forum from (http://www.usb.org)! I attempted some months ago and now, but nothing...
Anyway, I try to change the .inf file many times, and nothing, including your suggestions. Yes the file usbser.sys exists in the directory...when I debug the enumeration process, ask three times for the initial frames: 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... ... repeat 2 more times...
It's possible that Vista recognizes the USB descriptors, and XP don't do ??
In Windows Vista, the initial frames are: 128 6 0 1 0 0 64 0 (Set address) 128 6 0 1 0 0 18 0 128 6 0 2 0 0 255 0 ->Length is different! 128 6 3 3 9 4 255 0 ->From here continue with all other descriptor frames...
"when I debug the enumeration process, ask three times for the initial frames:"
OK,OK A new fact appears :-) Then, the INF has surely above problem, but it doesn't the direct cause of the trouble of your XP box.
I can't understand the table of figures you shown above. "0 5 12 0 0 0 0 0" seems to mean the setup packet of Set_Address, but what for other figures? But, maybe, it doesn't matter.
What occurs here is, that the device fails to return ACK to Set_Address request, and the host repeats the request three times, before giving up the request. As your device works on a Vista box, it is a timing problem.
There are two cases of timing problems, a) Power-up timing of bus-powered device b) Accelerated Control transfer on OHCI or over hub
a) Power-up timing Is your device a bus-powered one - supplied power just from USB VBUS? Then, try this test.
Power-up timing test 1) Plug in a hub to the XP box. 2) Open Device Manager on the XP, find the hub under the USB controller tree. 3) Right-click on the hub, select "Disable" once. 4) Plug in the device to the hub. 5) After a couple of seconds, in Device Manager, right-click on the hub again and "Enable" it.
Just after enabling the hub, enumeration starts. This time, is the device enumerated successfully? If so, the device suffers Power-up timing trouble.
Please confirm that the VBUS power is supplied to the device throughout in this sequence. If not, you may need to connect a power supply to the hub.
b) Accelerated Control transfer - Did you use a hub between the device and the XP box, when the device fails? Or, laptop may have an internal hub in a docking station. Check the connection tree on USBView
MS USBView on FTDI site www.ftdichip.com/.../usbview.zip
- Does the XP USB port equips OHCI host controller? HCList tells which host controller is.
HCList from Jan Axelson's USB Central www.lvr.com/.../HCList.zip
If you use a hub, or if the XP USB port is OHCI, the control transfer timing is accelerated. It may cause the timing error. Apply these tests, and find which case is applied to your trouble. When another new fact comes up with these tests, we move to solution of the trouble.
I tried the power-up timing test, but nothing...I think it's related with OHCI, all the USB uses OHCI host controller, and there appear EHCI host controller too, but it's inaccessible physically...I don't know what can I do, to solve timming problems, or how to change the controller...
Piru
You don't need to change the PC host controller. Modify the firmware of your device, to satisfy the timing.
For more confirmation, Does the Vista box, the working one, equip UHCI host controller? What does HCList tell about this PC?
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 :-)
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
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.
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