Hi,
I have a code for USB mass storage device on atmel AT91SAM7SE512 target. The code is based on Keil\ARM\Boards\Atmel\AT91SAM7X-EK\RL\USB\RTX_Memory .
When connecting my device to a PC and saving a file - I see that at some point, messages are sent to endpoint task from ISR (isr_mbx_send...) but not received by the endpoint task (os_mbx_wait...). Some save sessions are passed successfully, but most sessions behave as described above...
Any idea what may be the problem...?
Thanks
Can you post the code of the ISR and the receiving function?
The ISR code:
/* Endpoint Interrupts */ for (n = 0; n < USB_EP_NUM; n++) { if (isr & (1 << n)) { csr = pUDP->UDP_CSR[n]; /* Setup Packet Received Interrupt */ if (csr & AT91C_UDP_RXSETUP) { pEpEvent = _alloc_box (USB_MsgPool); /* allocate memory */ if (pEpEvent){ pEpEvent->bCnt = USB_ReadEP(n, pEpEvent->bData); /* read the setup packet */ pEpEvent->wEvent = USB_EVT_SETUP; /* set event */ if (isr_mbx_check (USB_EPMbx[n]) == 0) _free_box (USB_MsgPool, pEpEvent); else isr_mbx_send (USB_EPMbx[n], pEpEvent); } Udp_ep_clr_flag(pUDP,n,AT91C_UDP_RXSETUP); } /* Data Packet Received Interrupt */ bkm = RX_DATA_BK[RxDataBank[n]]; if (csr & bkm) { pEpEvent = _alloc_box (USB_MsgPool); /* allocate memory */ if (pEpEvent){ pEpEvent->bCnt = USB_ReadEP(n, pEpEvent->bData); /* read the data packet */ pEpEvent->wEvent = USB_EVT_OUT; /* set event */ // Save isr_mbx_check result for debug mbxCheck = isr_mbx_check (USB_EPMbx[n]); if (mbxCheck == 0){ _free_box (USB_MsgPool, pEpEvent); mbxErr++; // Debug } else { isr_mbx_send (USB_EPMbx[n], pEpEvent); // Debug- count the bulk out (EP 2) data messages if ((pEpEvent->bCnt == 64) && (n==2)) EP_2_Count_Sent++; } } Udp_ep_clr_flag(pUDP,n ,bkm); if (DualBankEP & (1 << n)) { RxDataBank[n] ^= 1; } } /* Data Packet Sent Interrupt */ if (csr & AT91C_UDP_TXCOMP) { Udp_ep_clr_flag(pUDP,n ,AT91C_UDP_TXCOMP); if (TxDataBank[n]) { //pUDP->UDP_CSR[n] |= AT91C_UDP_TXPKTRDY; Udp_ep_set_flag(pUDP,n,AT91C_UDP_TXPKTRDY); TxDataBank[n] = 0; } pEpEvent = _alloc_box (USB_MsgPool); if (pEpEvent){ pEpEvent->wEvent = USB_EVT_IN; if (isr_mbx_check (USB_EPMbx[n]) == 0) _free_box (USB_MsgPool, pEpEvent); else isr_mbx_send (USB_EPMbx[n], pEpEvent); } } /* STALL Packet Sent Interrupt */ if (csr & AT91C_UDP_STALLSENT) { if ((csr & AT91C_UDP_EPTYPE) == AT91C_UDP_EPTYPE_CTRL) { pEpEvent = _alloc_box (USB_MsgPool); if (pEpEvent){ pEpEvent->wEvent = USB_EVT_IN_STALL; if (isr_mbx_check (USB_EPMbx[n]) == 0) _free_box (USB_MsgPool, pEpEvent); else isr_mbx_send (USB_EPMbx[n], pEpEvent); } } Udp_ep_clr_flag(pUDP,n ,AT91C_UDP_STALLSENT); } } }
The receiver task code:
void USB_EndPoint2 (void) __task { T_USB_EP_EVENT *pEpEvent; USB_EPMbx[2] = USB_EP2Mbx; /* store Mbx in array */ os_mbx_init (USB_EP2Mbx, sizeof(USB_EP2Mbx)); /* initialize the mailbox */ for (;;) { os_mbx_wait (USB_EP2Mbx, (void **)&pEpEvent, 0xFFFF); /* Wait for an Event */ memcpy (BulkBuf, pEpEvent->bData, pEpEvent->bCnt); /* store received data from mailbox */ BulkLen = pEpEvent->bCnt; // Debug - update counters if ((BulkBuf[15] == 0x2A) && (BulkLen == 31)) { printf("\n --> BulkOut zero counter %d (writeCount = %d) ", bufOutCount, writeCount); bufOutCount = 0; writeCount = 0; } else if (BulkLen == 64) bufOutCount++; MSC_BulkOut(); _free_box (USB_MsgPool, pEpEvent); /* free memory allocated for message */ } }
In the error case - I eventually receive Bus reset from host and then I print the session counters: CBW.dDataLength = 29184, - Length of data that was sent (/64 = 456) EP_2_Count_Sent = 420, - Number of bulks sent by ISR bufOutCount = 388, - Number of bulks received by receiver task writeCount = 388, - Number of bulks handled by SW mbxErr = 0 , - No mailbox request errors mbxCheck = 28 - Number of available mailbox entries
(Each Bulk is 64 bytes)
May it be possible, that
pEpEvent = _alloc_box (USB_MsgPool);
fails and therefore the message is not even created. There is no error checking for this case, as far as I see.
The next line checks that aloccation was successfull ( if (pEpEvent){...). If allocation failes - the mailbox send code is not activated... See that my counter is promoted only after successfull allocations and when mailbox is available