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 trying to write a very basic sanity test that uses two Vend Req (0xC2 and 0xC6) to output 4 bytes then read them back. (Using a FX2LP)
Using the framework... The vend request code is as follows :
switch (SETUPDAT[1]) { case VX_C2: // write { SYNCDELAY; keep[0] = EP0BUF[0]; SYNCDELAY; keep[1] = EP0BUF[1]; SYNCDELAY; keep[2] = EP0BUF[2]; SYNCDELAY; keep[3] = EP0BUF[3]; SYNCDELAY; EP0BCH = 0; EP0BCL = 0; EP0CS |= bmHSNAK; break; } case VX_C6: // read { EP0BUF[0] = keep[0]; EP0BUF[1] = keep[1]; EP0BUF[2] = keep[2]; EP0BUF[3] = keep[3]; SYNCDELAY; EP0BCH = 0; SYNCDELAY; EP0BCL = 4; EP0CS |= bmHSNAK; break; } default: return(TRUE); }
"keep" is defined a global (outside all functions):
BYTE keep[4];
From various debug it appears that the data on the "write" (OUT) vend reqs is not available in the EP0BUF and therefore is not being copied into keep[0-3]. If I hard wire various values (instead of reading EP0BUF) and see them propagate through to the "read" Vend request (IN) so I know that side is working.
I'm exercising the vend request with the standard CyConsole.
Any thoughts on what I might be missing to this basic flow working would be very much appreciated.
Where did you write this "switch" statement? Is it in DR_VendorCmnd() callback?
Then, at this point, the USB engine is NAKing to the DATA stage of Control Write transfer, until the firmware writes any value to EP0BCL. Writing to EP0BCL, the engine arms EP0 out. And then, at the transaction completion of each data packet, ISR_Ep0out() is called.
unsigned short vendor_wLength; DR_VendorCmnd( void ) { switch (SETUPDAT[1]) { case VX_C2: // write { vendor_wLength = (SETUPDAT[7] << 8) + SETUPDAT[6] EP0BCH = 0; EP0BCL = 0; // writing to EP0BCL arms EP0 OUT break; } ... ... void ISR_Ep0out( void ) interrupt 0 { // DATA stage greater than 64 bytes is split into multiple packets // // here, EP0BUF[] holds a packet on DATA stage // EP0BCL holds the size of the packet // process it // vendor_wLength -= EP0BCL; if ( vendor_wLength == 0 ) { EP0CS |= bmHSNAK; // STATUS stage } else { EP0BCH = 0; EP0BCL = 0; // next packet of DATA stage } }
Tsuneo
Thanks for the responce...
Yes, the code is in the DR_VendorCmnd routine.
Your suggestion makes sense (even though I can't find any documentation describing anything similar).
I reorganized the code as you suggested using the EP0out interrupt routine. However, interrupt isn't getting called. I can see the EP0BCL coming with 4 bytes in the vend req but the interrupt routine isn't getting called to extract the EP0BUF values.
Do I have to enable the interrupt somehow?
The interrupt jump table looks likes it correctly pointing to the function..
Suggestions?
> Do I have to enable the interrupt somehow?
Yes, Refer to this Cypress code example.
CE63210 - Endpoint Interrupts in EZ-USB® FX1 / FX2LP " href= "http://www.cypress.com/?docID=27501">www.cypress.com/
Umm, above ISR_Ep0out() drops EZUSB_IRQ_CLEAR() and EPIRQ = bmBIT1; After long blank, many things had dropped off from my memory.. or just aging?