Hi all,
I have to realize USB data transactions that are "split" automatically in multiple transfers.
Therefore I have been using linked lists which seemed the ideal mechanism for it.
However, depending on the number of links, the data size, the data itself, the behaviour I get is erroneous:
regularly some of the transactions are missing.
I did not find out yet the exact relationships and whether the problem comes from CSL, my environment, from the C5509A... But I'll have to solve this problem ASAP otherwise I'm blocked.
I use the C5509A and CSL. I use a hardware USB protocol analyzer (but a software version shows the same results).
For example, the following example code, executed from an infinite loop, should transmit 3 packets, each with 1 ms guaranteed transaction time, at each loop iteration.
But what I get on the bus is: packet 1, packet 2, packet 3, packet 1, packet 2, packet 1, packet 2, packet 3 etc.
The example code that fails:
#define REPORT_LEN (14)
#define REPORT_LEN_16 ((REPORT_LEN+1)/2)
Uint16 dat_0[REPORT_LEN_16+1];
Uint16 dat_1[REPORT_LEN_16+1];
Uint16 dat_2[REPORT_LEN_16+1];
USB_DataStruct lnk_0;
USB_DataStruct lnk_1;
USB_DataStruct lnk_2;
volatile Uint16 dbgcnt;
void usb_generate_report (void)
{
// reset buffers
memset(dat_0,0x0000,sizeof(dat_0));
memset(dat_1,0x0000,sizeof(dat_1));
memset(dat_2,0x0000,sizeof(dat_2));
memset(&lnk_0,0x0000,sizeof(lnk_0));
memset(&lnk_1,0x0000,sizeof(lnk_1));
memset(&lnk_2,0x0000,sizeof(lnk_2));
// generate links
lnk_0.Bytes = REPORT_LEN;
lnk_0.pBuffer = (Uint16*)&dat_0;
lnk_0.pNextBuffer = &lnk_1;
lnk_1.Bytes = REPORT_LEN;
lnk_1.pBuffer = (Uint16*)&dat_1;
lnk_1.pNextBuffer = &lnk_2;
lnk_2.Bytes = REPORT_LEN;
lnk_2.pBuffer = (Uint16*)&dat_2;
lnk_2.pNextBuffer = NULL;
// fill the data buffers with dummy values
{
Uint16 i;
// omit data 0 - rsvd for CSL API
dat_0[1] = 1; // set buffer ID for debug purpose
dat_1[1] = 2; // set buffer ID for debug purpose
dat_2[1] = 3; // set buffer ID for debug purpose
for (i=0; i<REPORT_LEN_16-1; i++)
{
dat_0[i+2] = dbgcnt+1*i;
dat_1[i+2] = dbgcnt+2*i;
dat_2[i+2] = dbgcnt+3*i;
}
}
dbgcnt++;
// wait until previous transaction has finished
while (! USB_isTransactionDone(&usbEpObjIn1) );
// transmit data
if (REPORT_LEN%64>0)
{
USB_postTransaction(&usbEpObjIn1, 0, &lnk_0, USB_IOFLAG_LNK|USB_IOFLAG_EOLL);
}
else
{
USB_postTransaction(&usbEpObjIn1, 0, &lnk_0, USB_IOFLAG_LNK|USB_IOFLAG_EOLL|USB_IOFLAG_NOSHORT);
}
}
For your reference: usbEpObjIn1 is a interrupt IN endpoint with bInterval = 1 and wMaxPacketSize = 64.
Could please someone help me or give me advise on this issue?
Thank you very much.
Andreas