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 };
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 ...
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
I just copy send descriptor function and try to change tabulations...but it's not very 'readable', but if you copy the code to an empty text file, you could read it clear. I Hope this will be useful ;)
Greetings.
void send_descriptor(void) { static WORD sendlen,desclen; BYTE *pDdata=NULL; // pointer to ROM Descriptor data to send bool send_ZLP=FALSE; // Zero Length packet Flag desclen = 0; // check for zero as error condition (no case statements satisfied) switch (SUD[wValueH]) // wValueH is descriptor type { case GD_DEVICE: /*if(SUD[wLengthL]>DD[0])*/ desclen = DD[0]; // descriptor length //else desclen = SUD[wLengthL]; pDdata = (BYTE *) DD; break; case GD_CONFIGURATION: if(SUD[wLengthL]>CD[2]) desclen = CD[2]; // Config descriptor includes interface, header and ep descriptors (67 Bytes [0x0043]) else desclen = SUD[wLengthL]; if(SUD[wLengthH]!=0) desclen = CD[2]; // wLengthH=1 (last byte) 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 { /*if(SUD[wLengthL]>CD[9]) */desclen = CD[9]; //else desclen = SUD[wLengthL]; pDdata = (BYTE *) &CD[9]; } else if (SUD[wIndexL]==1) // Interface Number=1. Del EndPoint 1 (bulk), Datos { /*if(SUD[wLengthL]>CD[44])*/ desclen = CD[44]; //else desclen = SUD[wLengthL]; 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 size of data if((desclen % 64) == 0) send_ZLP=TRUE; // Send zero length packet Flag Flag para enviar paquete de tamaño 0 while(desclen>0) // Meanwhile there are data to be sent { if(desclen>64) sendlen=64; // If there are more than 64 bytes in the packet else sendlen=desclen; // If there are less than 64 bytes in the packet while(!(rreg(rEPIRQ) & bmIN0BAVIRQ));// Meanwhile output buffer isn't free writebytes(rEP0FIFO,sendlen,pDdata);// Write data to EP_CONTROL FIFO pDdata=(pDdata+sendlen); // Increments data pointer !! ********(VERY IMPORTANT)******* 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; // Substract sent data } if(send_ZLP) wregAS(rEP0BC,0); // load EP0BC to arm the EP0-IN transfer & ACKSTAT } else STALL_EP0; // none of the descriptor types match }