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

How to enable and use DMA for USB bulk IN endpoints

Hi,

I'm using uVision 4 with the MCB2300 development board. I'm developing a software that periodically transmits data (status information) from the device to the host (as first step, the data are sent without being explicitly requested by the host as soon as a connection has been established). Thereto I've modified the USBCDC example included with uVision. The software transmits 20 bytes periodically, using USB_WriteEP (in usbhw.c, which uses the register interface). This works fine so far. Now I would like to use the DMA engine to avoid copying the bytes word by word into the register. I've enabled DMA in the USB configuration for logical IN endpoint 2 (physical endpoint 5 which is called CDC_DEP_IN in the example), and I have managed to set up DMA descriptors. But how do I trigger a DMA transfer?
I've tried several combinations of USB_DMA_Setup and USB_DMA_Enable. Manually setting the appropriate bit in DMA_REQ_SET to trigger the interrupt results in an error state. What am I doing wrong?
Could anyone please give me some hints concerning USB DMA? Thanks a lot.
I'll be back in January, after my Christmas vacation. I wish everybody a merry Christmas and a happy new year!

CC

Parents
  • here's the whole code from the usb_reset() - I didn't change anyhting in this function...

    void USB_Reset (void) {
    #if USB_DMA
      uint32_t n;
    #endif
    
      LPC_USB->USBEpInd = 0;
      LPC_USB->USBMaxPSize = USB_MAX_PACKET0;
      LPC_USB->USBEpInd = 1;
      LPC_USB->USBMaxPSize = USB_MAX_PACKET0;
      while ((LPC_USB->USBDevIntSt & EP_RLZED_INT) == 0);
    
      LPC_USB->USBEpIntClr  = 0xFFFFFFFF;
      LPC_USB->USBEpIntEn   = 0xFFFFFFFF ^ USB_DMA_EP;
      LPC_USB->USBDevIntClr = 0xFFFFFFFF;
      LPC_USB->USBDevIntEn  = DEV_STAT_INT    | EP_SLOW_INT    |
                   (USB_SOF_EVENT   ? FRAME_INT : 0) |
                   (USB_ERROR_EVENT ? ERR_INT   : 0);
    
    #if USB_DMA
      LPC_USB->USBUDCAH   = USB_RAM_ADR;
      LPC_USB->USBDMARClr = 0xFFFFFFFF;
      LPC_USB->USBEpDMADis  = 0xFFFFFFFF;
      LPC_USB->USBEpDMAEn   = USB_DMA_EP;
      LPC_USB->USBEoTIntClr = 0xFFFFFFFF;
      LPC_USB->USBNDDRIntClr = 0xFFFFFFFF;
      LPC_USB->USBSysErrIntClr = 0xFFFFFFFF;
      LPC_USB->USBDMAIntEn  = 0x00000007;
      DDMemMap[0] = 0x00000000;
      DDMemMap[1] = 0x00000000;
      for (n = 0; n < USB_EP_NUM; n++) {
        udca[n] = 0;
        UDCA[n] = 0;
      }
    #endif
    }
    

Reply
  • here's the whole code from the usb_reset() - I didn't change anyhting in this function...

    void USB_Reset (void) {
    #if USB_DMA
      uint32_t n;
    #endif
    
      LPC_USB->USBEpInd = 0;
      LPC_USB->USBMaxPSize = USB_MAX_PACKET0;
      LPC_USB->USBEpInd = 1;
      LPC_USB->USBMaxPSize = USB_MAX_PACKET0;
      while ((LPC_USB->USBDevIntSt & EP_RLZED_INT) == 0);
    
      LPC_USB->USBEpIntClr  = 0xFFFFFFFF;
      LPC_USB->USBEpIntEn   = 0xFFFFFFFF ^ USB_DMA_EP;
      LPC_USB->USBDevIntClr = 0xFFFFFFFF;
      LPC_USB->USBDevIntEn  = DEV_STAT_INT    | EP_SLOW_INT    |
                   (USB_SOF_EVENT   ? FRAME_INT : 0) |
                   (USB_ERROR_EVENT ? ERR_INT   : 0);
    
    #if USB_DMA
      LPC_USB->USBUDCAH   = USB_RAM_ADR;
      LPC_USB->USBDMARClr = 0xFFFFFFFF;
      LPC_USB->USBEpDMADis  = 0xFFFFFFFF;
      LPC_USB->USBEpDMAEn   = USB_DMA_EP;
      LPC_USB->USBEoTIntClr = 0xFFFFFFFF;
      LPC_USB->USBNDDRIntClr = 0xFFFFFFFF;
      LPC_USB->USBSysErrIntClr = 0xFFFFFFFF;
      LPC_USB->USBDMAIntEn  = 0x00000007;
      DDMemMap[0] = 0x00000000;
      DDMemMap[1] = 0x00000000;
      for (n = 0; n < USB_EP_NUM; n++) {
        udca[n] = 0;
        UDCA[n] = 0;
      }
    #endif
    }
    

Children
  • The interrupt which occured after setting up the dma descriptor in the SendDataToHost method, is a "New DD Request Interrupt"... but after that nothing happens.

    if (LPC_USB->USBDMAIntSt & 0x00000002) {          /* New DD Request Interrupt */
    {
    }
    

    I hope you could give me some hints to get in working...