Hi,
I modified USB memory example from Keil and I can enumerate. But I was trying to trace back how are the USB_Endpoint() functions called. For example usbuser.c file has EndPoint definitions that look like this:
/* * USB Endpoint 1 Event Callback * Called automatically on USB Endpoint 1 Event * Parameter: event */ void USB_EndPoint1 (u32 event) { // BulkIn } /* * USB Endpoint 2 Event Callback * Called automatically on USB Endpoint 2 Event * Parameter: event */ void USB_EndPoint2 (u32 event) { USB_EP_Bulkout(); // Handle data that arrived on this Endpoint }
I use Endpoint 1(IN) and Endpoint 2(OUT). But when I tried to search for these functions to see where they are called I came up empty. Is this done in a interrupt routine someplace? IS this function name assembled someplace? I assumed that as soon as the host sends data to the device it goes to the OUT endpoint and my device executes my function USB_EP_Bulkout(). But I couldn't find out where this UEB_EndPoint2() is called.
Any help is appreciated. Thanks
Have you taked a look at all the defines for the USB descriptions? You have a lot of "magic" there.
wario, you will find a reference to these functions in a sructure that contains pointers to functions (don't remember in which c file...). these pointers are used upon the occurance of a usb interrupt.
"I modified USB memory example from Keil"
Which one? We can see these MSD (Mass Storage Device) examples on Keil web site.
"ARM Download Files" http://www.keil.com/download/list/arm.htm
1) LPC2148 USB Mass Storage Device Example 2) LPC2368 / LPC2378 USB Mass Storage Device Example 3) STM32 USB Mass Storage Device Example 4) STR750 / STR751 USB Mass Storage Device Example
These examples derive from single code base, but the details are, of course, depending on the chip and the board. "But when I tried to search for these functions to see where they are called I came up empty."
In addition to Tamir,
On the LPC2148 (MCB2140) example, USB_EndPointN() routines (N=0..15) are called through this function-pointer table.
usbcfg.h #define USB_EP_EVENT 0x0005 usbuser.c #define P_EP(n) ((USB_EP_EVENT & (1 << (n))) ? USB_EndPoint##n : NULL) /* USB Endpoint Events Callback Pointers */ void (* const USB_P_EP[16]) (DWORD event) = { P_EP(0), P_EP(1), P_EP(2), P_EP(3), P_EP(4), P_EP(5), P_EP(6), P_EP(7), P_EP(8), P_EP(9), P_EP(10), P_EP(11), P_EP(12), P_EP(13), P_EP(14), P_EP(15), };
Maybe you missed what the P_EP(n) macro does. The preprocessor operator '##' concatenates 'USB_EndPoint' string and the number N, it makes up a single token, like USB_EndPoint1 or USB_EndPoint2. Then, each P_EP(N) on the table is replaced with USB_EndPointN or NULL, depending on the bit of USB_EP_EVENT.
The function-pointer table, USB_P_EP is referred in the USB ISR. Then, USB_EndPointN routines are called from the USB ISR, if it is enabled by the bit on USB_EP_EVENT, and when the endpoint puts an interrupt.
usbhw.c /* * USB Interrupt Service Routine */ void USB_ISR (void) __irq { ... ... /* Endpoint's Slow Interrupt */ if (disr & EP_SLOW_INT) { while (EP_INT_STAT) { /* Endpoint Interrupt Status */ for (n = 0; n < USB_EP_NUM; n++) { /* Check All Endpoints */ if (EP_INT_STAT & (1 << n)) { m = n >> 1; EP_INT_CLR = 1 << n; while ((DEV_INT_STAT & CDFULL_INT) == 0); val = CMD_DATA; if ((n & 1) == 0) { /* OUT Endpoint */ if (n == 0) { /* Control OUT Endpoint */ if (val & EP_SEL_STP) { /* Setup Packet */ if (USB_P_EP[0]) { USB_P_EP[0](USB_EVT_SETUP); continue; } } } if (USB_P_EP[m]) { USB_P_EP[m](USB_EVT_OUT); } } else { /* IN Endpoint */ if (USB_P_EP[m]) { USB_P_EP[m](USB_EVT_IN); } } } } } } ...
Tsuneo
Tamir, oh yeah I just saw these. I'll need to take a look at them more closely. There are some preprocessor directives it seems like and they are doing bunch of things with it I believe.
Thanks
Thanks Tsuneo, I should have said that I am using AT91SAM7X256,sorry for the confusion. IT came with my Keil compiler software. I think the code should for the most part be the same except few differences depending on the chip, am I right? I saw these directives but didn't really caught my eye what it was doing but now it makes sense. I'll have to spend some time trying to figure it out, you've explained most of it it seems like, now I just have to understand it.
Thanks again.