I want to develop mass storage device using LPC2148.I am just referring code from Keil for USBMem. My problem is - I get Get_descriptor command from PC to which I respond with device descriptor. On receiving 8th byte it generates Reset. Then I get Set_address command. On response to it, I execute Set Address command in protocol engine. Then again I get Get_descriptor command (It should actually have index field of 18 but I receive with 64). Again after 8th byte it generates Reset and again gives Set_address command instead of Get_descriptor command for Configuration descriptor. What can be the problem?
> When initially I get Get_descriptor command, if i set TxPLen=18, then I don't get Reset generated by host after reception of 8th byte because when reset occurs I am in ISR only, busy writing 9th to 18th bytes.
1) How many bytes does the host request in the wLength field of the SETUP data of the Get_Descriptor request ? 2) How many bytes do you return in the bMaxPacketSize0 field of the device descriptor ? Post your device descriptor.
Tsuneo
> How many bytes does the host request in the wLength field of the SETUP data of the Get_Descriptor request? 0x40. > How many bytes do you return in the bMaxPacketSize0 field of the device descriptor ? 0x40. Here is my device descriptor -
const unsigned char USB_DeviceDescriptor[] = { 0x12, /* bLength */ 0x01, /* bDescriptorType */ 0x00,0x02, /* 2.0 */ /* bcdUSB */ 0x00, /* bDeviceClass */ 0x00, /* bDeviceSubClass */ 0x00, /* bDeviceProtocol */ 0x40, /* bMaxPacketSize0 */ 0x51,0xc2, /* idVendor */ 0x03,0x13, /* idProduct */ 0x00,0x02, /* 2.0 */ /* bcdDevice */ 0x00, /* iManufacturer */ 0x00, /* iProduct */ 0x00, /* iSerialNumber */ 0x01, /* bNumConfigurations */ };
Your descriptor is fine.
Did you set up this bMaxPacketSize0 (0x40) to the USB engine?
usbhw.c void USB_Reset (void) { EP_INDEX = 0; // <------ setup bMaxPacketSize0 to EP0 IN/OUT of USB engine MAXPACKET_SIZE = USB_MAX_PACKET0; EP_INDEX = 1; MAXPACKET_SIZE = USB_MAX_PACKET0; while ((DEV_INT_STAT & EP_RLZED_INT) == 0);
Maybe, you have trouble on the handling of USB protocol engine commands.
While your firmware is writing to the descriptor to the default IN EP, host never reads it, because the data is not validated yet. When your firmware puts Validate Buffer command, the data is passed to the endpoint. As your writing process to the endpoint is disturbed, you miss some sequence to the USB protocol engine.
I recommend you to examine the successful implementations, like KEIL and LPCUSB, for the usage details of protocol engine commands. Compare these routines with your code.
KEIL - usbhw.c: USB_Reset(), USB_ReadEP(), USB_WriteEP(), USB_ISR()
The USB engine (SIE) of LPC family is a little difficult for USB starters to write low-level USB stack. You have to synchronize to the USB protocol engine everywhere, not just fiddle the USB registers.
Isn't it better to start with easier USB engine? Like SiLabs C8051F32x/34x, Atmel AT90USB, ST Micro STM32, etc. But I don't recommend EZ-USB for USB study, because it's too easy :-)
Tsuneo,
Sorry....Out of topic:
You should write a book about USB specifically in MCUs.
I know there are some good books about General USB, like: "USB Complete". But I think that your knowledge and excellent communication skills could produce a really good book.
Didn't you think about it?
Tsuneo, I agree! Bradford
http://www.keil.com/forum/docs/thread16320.asp
I recommend you to examine the successful implementations. KEIL - usbhw.c: USB_Reset(), USB_ReadEP(), USB_WriteEP(), USB_ISR() Actually i have referred them and understood them. I checked my routines too. They are same only. That's why i am getting confused because I am not getting where the problem is. I will let you know as soon as I get anything.
For last two weeks, stuck at the same position. I think the problem occurs during handling Set_address command only. Tried by implementing all ways for setting address. But still trying to find the bug.
Is it your custom board, or one of dev board made by some manufacturer?
Run above KEIL example on your board first, to rule out any hardware problem of the board. KEIL example is written for their MCB2140 board. You may apply minor changes to the example code, because of the hardware difference.
MCB2140 schematic http://www.keil.com/mcb2140/mcb2140-schematics.pdf
The check points are,
1) Crystal frequency and PLL setting MCB2140 mounts 12MHz crystal. For other frequency, modify PLL setting. usbhw.c USB_Init() OTG_CLK_CTRL
2) CONNECT control and VBUS detection pins MCB2140 apply a fixed D+ pull-up resistor (R35, 1.5k) without CONNECT pin (P0.31) control. VBUS detection on P0.23 is optional (J15) If your board has these feature, modify PINSEL setting. usbhw.c USB_Init() PINSEL3/4
With these short modifications, KEIL example should work on your board. If it doesn't work, check your hardware.
Anyway, having a working example on your board will encourage you so much ;-) And then, it also works as a good reference for your original USB stack.
Got finally!!! Thanks for your constant support! By implementing Bettrick's method, I got the Get_descriptor command with length field 18. Challenge - Still not getting Get_descriptor for configuration descriptor. Can it be problem of Vendor id or product id? I am not using Keil board. It's board designed by local company.
Actually I am using LPC2148 CPU module designed by local company. Can I use vendor id and product id by Keil?
> Can I use vendor id and product id by Keil?
Unless the Vendor/Product ID (VID/PID) conflict with other devices connected to your PC, you can use any VID/PID on your PC for development. Unique official VID/PID is required when you release your product, so that it doesn't conflict with others on your customer's PC. I often use VID = 0xFFF0 - 0xFFFF for development. USB.org has not assigned these range of VID yet, then it should not conflict with existing USB devices.
This is given in USB in a nutshell. Normally when something is wrong with a descriptor or how it is being sent, the host will attempt to read it three times with long pauses in between requests. After the third attempt, the host gives up reporting an error with your device. I am getting Get_descriptor 3 times and then nothing happens. But if I can send 8 bytes successfully then I think 18 bytes also would have gone succesfully. And I have already shown my device descriptor before. And t seems to be fine. What else can be the problem?
Still not getting Get_descriptor command for configuration descriptor. But getting it for device descriptor three times. What can be the problem?
Most of points have been discussed already. I don't think of any more. If you would have a hardware analyzer, you could get more detailed sign to focus on the firmware bug...
Do you have any account on a server to share your code? Post your code to the sharing server so that we can look into it. If it can, I'll run your code on my LPC2148 board (IAR or Olimex), and monitor it with a hardware analyzer.
If it can, I'll run your code on my LPC2148 board (IAR or Olimex), and monitor it with a hardware analyzer.
you have a good soul!
I have sent my code on your yahoo account which I got from LPC2000 group. Problem still continues......