This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Mailbox send & receive sync

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

Parents
  • 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)

Reply
  • 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)

Children