We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I have the lpc3131 embedded artists board and I am working on a USB driver. I first converted the Keil example code to IAR code and got the USB working. I then tried to port it over to a different syntax and for some reason the following code does not reset the ep_QH (end point queue head) to make dQH (device queue head) values zero:
DQH_T* const ep_QH = (DQH_T*)DQH_BASE;
//memset fills the first n bytes of the memory area //pointed to by s with the constant byte c. //void *memset(void *s, int c, size_t n);
/* Zero out the Endpoint queue heads */ memset((void*)ep_QH, 0, EP_NUM_MAX * sizeof(DQH_T));
/* dQH Queue Head */ typedef volatile struct { Int32U cap; Int32U curr_dTD; Int32U next_dTD; Int32U total_bytes; Int32U buffer0; Int32U buffer1; Int32U buffer2; Int32U buffer3; Int32U buffer4; Int32U reserved; Int32U setup[2]; Int32U gap[4]; } DQH_T;
//Here's the memset function: #define _DLIB_STRING_SKIP_INLINE_MEMSET #pragma inline void * memset(void * _D, int _C, size_t _N) { __aeabi_memset(_D, _N, _C); return _D; }
It goes into the function and passes the correct parameters but it doesn't seem to change the value of dQH to zero. Anyone know why this is happening or a work around.
It always pays to read the instructions carefully before you post - it's quite clear really: www.danlhenry.com/.../keil_code.png
Isn't it?
Are you sure that ep_QH points to the start of the array at the very specific time when you try to zero a full array of EP_NUM_MAX entries?
If you do want to clear the array, shouldn't you use DQH_BASE as the pointer instead?
And are you sure that clearing the array will really mean anything? Shouldn't the ep_QH (queue header pointer) be modified to point to the first entry of the array?
I should have added this code in my post. EP_NUM_MAX is a constant
/* Total physical enpoints*/ #define EP_NUM_MAX 8 #define DQH_BASE (EXT_SDRAM_BASE) #define EXT_SDRAM_BASE 0x30000000
I want to test if I can change the value of anything in the ep_QH structure to whatever value. I tried this:
ep_QH->cap = 0;
and that didn't change the value of 'cap'.
Simply put, why does the following code not work:
memset((void*)ep_QH, 0, 16);
That would of course require that you read the datasheet for the chip.
It seems a bit strange of the queue header pointer always points to the first element of an array. If ep_QH is regularly stepped between elements in the array, then the read may not access the same element as the assign modified.
The next thing is of course if you have set up the external SDRAM correctly, so that you can correctly read and write to it directly.
Another thing is that you say that the queue starts at the start of your external RAM. But have you configured the project so that the linker doesn't make use of the same RAM range for normal variables or the stack?
And finaly - exactly how does this queue work? By rewriting pointers in the individual entries, or by stepping the ep_QH pointer and treating the buffer as a ring buffer?
I have never worked with your chip and not with these specific features on any similar NXP chip and I don't have the time to look through sample code and datasheets to figure out exactly what is expected by the hardware and/or the driver software.
Just more thing - any reason for memset() of 16 bytes? Is that the only part of the *ep_QH entry you want cleared?
It will only clear the fields cap, curr_dTD, next_dTD and total_bytes. Not to many queues, lists etc would like some outsider to clear private fields. The next_dTD field might possibly chain the entries in the queue in which case a clear of it would break the queue.
Thank you so much for all the help. I realized the problem was that another programmer had commented out my SDRAM initialization function and so I was trying to read an address that was not memory mapped. My solution was to just change the address I was selecting to an internal onchip SRAM memory location instead.
Thanks again.