I have been through the USB sample code downloaded from the keil website and i have a few questions regarding how the endpoints are used
1) they have used a macro in the code to convert from logical endpoint number to endpoint address
#define IDX2EP(idx) ((((idx)<<7)&0x80)|(((idx)>>1)&0xF))
on working this out , i got a pattern of 0x00,0x80,0x01,0x81...0x0f,0x8f. How was this macro derived? There is nothing in the user manual about the actual addresses of endpoints.
2) Each of these addresses correspond to a memory location of 1 byte . Where do the incoming and outgoing packets go? there are variable packet sizes possible so i was under the assumption that the individual buffers for endpoints are of variable size . Where are these individual buffers located?
3) The code enables endpoints at 0x05 and 0x82 which correspond to logical endpoints 5 and 10. Why not 4 and 5 both of which correspond to logical endpoint 3 (4 is out and 5 is in) ? Does it make a difference which endpoint is enabled as long as it if of the required type (bulk/interrupt etc)?
4) I came across this macro
#define LE_WORD(x) ((x)&0xFF),((x)>>8)
I am not able to understand what it does. what does the comma mean? It was used at multiple locations. to get product and vendor ids, to get max packet size for an endpoint and also to get bcd USB value in device descriptor
thanks for your time.
It takes a 16-bit number and splits into two bytes - little endian style. It will emit this as two numbers with a comma in between. So it is part of a much bigger output of lots byte values for an array declaration.
uint8_t my_array[] = { LE_WORD(0x1234),LE_WORD(0x5678), ... };
Above would emit
uint8_t my_array[] = { 0x34,0x12,0x78,0x56, ... };
But it would just emit numbers in decimal form - I selected to show them in hexadecimal to make it easier to see low byte, high byte, low byte, high byte.
Thank you . That part is clear now. Can you please help me with the rest ?
www.beyondlogic.org/.../usb5.shtml
USB Descriptors
Endpoint Descriptors
Endpoint descriptors are used to describe endpoints other than endpoint zero. Endpoint zero is always assumed to be a control endpoint and is configured before any descriptors are even requested. The host will use the information returned from these descriptors to determine the bandwidth requirements of the bus.
Field: bEndpointAddress Description: Endpoint Address Bits 0..3b Endpoint Number. Bits 4..6b Reserved. Set to Zero Bits 7 Direction 0 = Out, 1 = In (Ignored for Control Endpoints)
NXP Semiconductors UM10211 Chapter 13: LPC23XX USB device controller Table 249. Fixed endpoint configuration
logical endpoints 5 : Bulk (Supposed to be Data Transfer) logical endpoints 10: Interrupt (Supposed to be Control) (I believe you need both Data Transfer and Control)
logical endpoint 3: Isochronous (Not enough, maybe not appropriate either)
http://www.keil.com/forum/16477/
Tsuneo Chinzei, 3-Mar-2010 12:10 GMT
The USB SIEs on NXP LPC family MCU classify each endpoint into interrupt/bulk/isoc (and default control) transfer type. Actually, these bulk and interrupt endpoints can be exchanged, because there is no difference on the handling of bulk and interrupt transaction of the device side. NXP calls double buffered endpoints as bulk, single buffer ones as interrupt.
NXP Semiconductors UM10211 Chapter 13: LPC23XX USB device controller
6.3 Endpoint RAM (EP_RAM) Each endpoint buffer is implemented as an SRAM based FIFO. The SRAM dedicated for this purpose is called the EP_RAM. Each realized endpoint has a reserved space in the EP_RAM. The total EP_RAM space required depends on the number of realized endpoints, the maximum packet size of the endpoint, and whether the endpoint supports double buffering.
2) Each of these addresses correspond to a memory location of 1 byte I don't understand this question.
-- Tired and frustrated. I will try to find a new job, I hope it is a position in Kaohsiung, Southern Taiwan.
> 2) Each of these addresses correspond to a memory location of 1 byte . Where do the incoming and outgoing packets go? there are variable packet sizes possible so i was under the assumption that the individual buffers for endpoints are of variable size . Where are these individual buffers located?
Endpoint buffers are "realized" using USBReEp register in EP_RAM on the USB engine (SIE). The buffer size matches to the wMaxPacketSize field of each endpoint descriptor. (For the default endpoint, wMaxPacketSize0 of the device descriptor.) When a transfer size goes over wMaxPacketSize, it is split into multiple transactions.
> 3) The code enables endpoints at 0x05 and 0x82 which correspond to logical endpoints 5 and 10. Why not 4 and 5 both of which correspond to logical endpoint 3 (4 is out and 5 is in) ? Does it make a difference which endpoint is enabled as long as it if of the required type (bulk/interrupt etc)?
On the LPC214x SIE, the transfer type of each endpoint is fixed. Refer to this chapter of the user manual. ics.nxp.com/.../user.manual.lpc2141.lpc2142.lpc2144.lpc2146.lpc2148.pdf 9.3 Fixed endpoint configuration (p95)
I recommend you to refer to user manual of LPC23xx (or LPC24xx) for USB device controller chapter, too. The USB device engine is (almost) same on these MCUs, and the manuals explain more in details.
Tsuneo
Firstly, i would like to apologize because i have made some fundamental mistakes while asking my question . i discovered these errors only yesterday when i went through the user manual and referred to "usb complete'.
1) Thank you for your post Mr John . I was under the impression that the endpoint address was a memory location on the device and was the place where incoming packets are stored.
3) I was confused between logical and physical endpoints To clarify , (apart from control ep) The endpoints enabled in the code are -
addr | physical ep | ( logical ep , dir ) | type |
[ 0x05 | 10 | (5 ,out ) | bulk ] [ 0x82 | 5 | (2 , in ) | bulk ] [ 0x8A | 21 | (10 , in) | interrupt ]
suppose instead of logical ep (5,out) i i change the address in the descriptor to (2, out) will it make a difference? {i don't have access to the machine as of now which is why i cannot try it myself}
Also, since bulk and interrupt are handled the same way on the device, suppose i replace (10,in) with (8,in) type -bulk im guessing it wont make a difference. am i right?
Thank you.
Ok, quick update. I managed to get my hands on the device and tried changing the endpoint address to 0x85 (logical 5, in) instead of 0x82 (2,in) . It did not work :(
> I managed to get my hands on the device and tried changing the endpoint address to 0x85 (logical 5, in) instead of 0x82 (2,in) . It did not work :(
Did you change the endpoint address in the subroutines, not just on the endpoint descriptor?
For example of USBMem
mscuser.h /* MSC In/Out Endpoint Address */ #define MSC_EP_IN 0x82 #define MSC_EP_OUT 0x02
For example of USBHID,
usbuser.c /* * USB Set Configuration Event Callback * Called automatically on USB Set Configuration Request */ #if USB_CONFIGURE_EVENT void USB_Configure_Event (void) { if (USB_Configuration) { /* Check if USB is configured */ GetInReport(); USB_WriteEP(0x81, &InReport, sizeof(InReport)); } } #endif /* * USB Endpoint 1 Event Callback * Called automatically on USB Endpoint 1 Event * Parameter: event */ void USB_EndPoint1 (DWORD event) { switch (event) { case USB_EVT_IN: GetInReport(); USB_WriteEP(0x81, &InReport, sizeof(InReport)); break; } }