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

Iscochronous IN transfer using DMA Mode (LPC1769)

Hi,
We have decided to use EP3 of the LPC1769 USB module to realize Isochrnous IN transfers to the host. I am currently using the LPCXpresso IDE and LPCXpresso LPC1769 dev kit. The function USB_Reset initializes the DMA.

#define USB_DMA_EP 0x00000080

LPC_USB->EpIntClr = 0xFFFFFFFF;

LPC_USB->EpIntEn = 0xFFFFFFFF ^ USB_DMA_EP; <----- Enable the DMA mode

LPC_USB->DevIntClr = 0xFFFFFFFF;

LPC_USB->DevIntEn = DEV_STAT_INT | EP_SLOW_INT | (USB_SOF_EVENT ? FRAME_INT : 0) | (USB_ERROR_EVENT ? ERR_INT : 0);

#if USB_DMA

LPC_USB->UDCAH = USB_RAM_ADR;

LPC_USB->DMARClr = 0xFFFFFFFF;

LPC_USB->EpDMADis = 0xFFFFFFFF;

LPC_USB->EpDMAEn = USB_DMA_EP; <---- Enable the EP for DMA

LPC_USB->EoTIntClr = 0xFFFFFFFF;

LPC_USB->NDDRIntClr = 0xFFFFFFFF;

LPC_USB->SysErrIntClr = 0xFFFFFFFF;

LPC_USB->DMAIntEn = 0x00000007;

The DMA mode is enabled in the statement LPC_USB->EpIntEn = 0xFFFFFFFF ^ USB_DMA_EP; shown above for the EP7 (IN Isochronous). After execution of this statement the USBDMARSt register changes state to 0x00000080 immediately. Is this normal. I expected the register to change state in the event of an interrupt on the corresponding EP.
Executing the statement LPC_USB->EpDMAEn = USB_DMA_EP; should enable the DMA for EP3 and thereby change the state of the register USBEpDMAEn to 0x00000080 and correspondingly change the value of USBEpDMASt to 0x00000080, however, the values in these register continue to be 0.
Please can you let me know if my understanding is correct. Would anybody happen to know of a tool using which I could send setup packets or IN/OUT requests to my device connected to a PC?
Also, one last question. When using DMA Descriptors, if the UDCA space contains a valid pointer to a descriptor and there is an IN request on the corresponding EP, the transfer should begin without the generation of any interrupts, am I right? An interrupt will be generated after the transfer is complete. Please can you confirm my understanding?
Thanks very much.

Regards,
Shaunak

  • > I am currently using the LPCXpresso IDE and LPCXpresso LPC1769 dev kit.

    You may be better to post it to LPCXpresso Forum, because your setup has nothing to do with Keil ;-)
    " href= "http://www.nxp.com/documents/user_manual/UM10360.pdf">www.nxp.com/.../UM10360.pdf )

    11.15.6.2 Finding the DMA Descriptor p262
    A DMA request will be placed for DMA-enabled isochronous endpoints on every FRAME
    interrupt
    .

    This behavior is reasonable on isoc endpoint, counting in transaction drop. On isoc transfer, endpoint should be refresshed at every frame, regardless of transaction completion at a frame. When a transaction drop occurs at an isoc IN endpoint, the current data on the endpoint buffer should be discarded, and the data for the next frame is loaded. For such a SIE that generates transaction completion interrupt on isoc, we have to code this endpoint refresh process on transaction drop, explicitly. LPC SIE does it automatically. Excellent SIE design.

    Tsuneo

  • > Would anybody happen to know of a tool using which I could send setup packets or IN/OUT requests to my device connected to a PC?

    libusb-Win32 supports isoc
    sourceforge.net/.../libusbwin32_documentation

    Tsuneo

  • Hi Tsuneo,
    Thank you for your reply.
    Please can you confirm my understanding?
    1. Once an IN Isochronous endpoint has been enabled for DMA mode and has been realized using the Set Interface command from the host, it is ready for transfer. The FRAME interrupt has been enabled on the device.
    2. The FRAME interrupt occurs once every 1ms and hence the irq will be called every 1ms.
    3. The transfer will not begin until there is an Isochronous IN request on the corresponding endpoint. Upon a request the DD (if present) will be fetched only when the FRAME interrupt occurs. If there is no DD present then an NDDR interrupt will be recorded.

    We are using a USB host present on a board running WinCE to make above requests. Even after enabling the FRAME request there seems to be no data transfer or NDDR interrupt being generated on the device side. Please can you advise upon the course of action? We are using the same ISR as mentioned in the Keil examples.

    Thanks very much.

    Regards,
    Shaunak

  • > 1. .. The FRAME interrupt has been enabled on the device.

    FRAME interrupt doesn't need to be enabled.
    The data sheet writes "on every FRAME interrupt", but more precisely, USBDMARSt is set "on every SOF timing."

    > 3. The transfer will not begin until there is an Isochronous IN request on the corresponding endpoint.

    Surely, IN transactions don't occur until host starts isoc transfer. But the SIE raises DMA request (USBDMARSt) at every SOF timing, regardless of IN transaction. It's because the endpoint buffer should be loaded and refreshed before isoc transfer starts. Until isoc transfer starts, data on the endpoint buffer is overwritten.

    After Set_Interface, there are delay frames until isoc transactions actually starts. This delay interval depends on host applications. On USB audio, 20 - 30 frames delay is seen. In this delay period, data on the endpoint buffer is discarded by overwrite.

    At the timing when USBDMARSt raises (ie. at a SOF timing), the SIE checks a DMA Descriptor (DD). If the DD is invalid, SIE doesn't put any response. USBDMARSt stays in '1' on this failure. To re-trigger DMA (edge trigger) at next SOF timing, USBDMARSt should be cleared once manually, by USBDMARClr.

    I have an impression that USBDMARSt is triggered, before the firmware prepares a valid DD. Clear USBDMARSt by USBDMARClr once after DMA registers are set up, to get next chance.

    Better implementation is, don't enable DMA at the endpoint (USBEpIntEn), until the endpoint is "realized", AND, until the firmware finishes DMA register set up.

    Tsuneo

  • Hi Tsuneo,

    Thank you for the explanation. I understand now. I will adopt your implementation strategy.
    I have one question regarding the FRAME interrupt though.
    If we do not enable the FRAME interrupt on the device using

    USBDevIntEn |= 0x01;
    

    will USBDMARSt still be set? I noticed that enabling the FRAME interrupt causing execution to vector to the USB irq every 1ms. That is,

    USBDevIntSt = 0x01;
    

    every 1ms. This happens even when the host has been disconnected.

    > If the DD is invalid, SIE doesn't put any response
    Will the SIE raise a NDDR (New DMA Descriptor Request) interrupt here, since there is no valid descriptor avialable yet? I could also clear USBDMARSt here if the interrupt will actually be generated, in addition to when I furnish the DD.

    Thank you again for all your help.

    Regards,
    Shaunak

  • > If we do not enable the FRAME interrupt on the device using
    > USBDevIntEn |= 0x01;
    > will USBDMARSt still be set?

    Yes.

    > I noticed that enabling the FRAME interrupt causing execution to vector to the USB irq every 1ms.

    It's a SIE function, so-called "SOF recovery"
    On the SIE, an interval timer tracks SOF timing.
    Even when SOF packet drops by noise, this timer keeps SOF timing.
    Well-designed SIE has this feature, to supports isoc transfer seriously,
    because the process of isoc endpoints heavily depends on stable SOF interval.
    This option is seen on these SIEs; NXP LPC, STM32 OTG_FS/HS, Cypress EX-USB, SiLabs 'F32x/34x, etc.

    >> If the DD is invalid, SIE doesn't put any response
    > Will the SIE raise a NDDR (New DMA Descriptor Request) interrupt here, since there is no valid descriptor avialable yet?

    Ah, this "invalid" means "not-prepared".
    As we see, recovered SOF starts just after the SIE is enabled.
    When DMA request is enabled at USBEpIntEn, DMA request starts to fire at evey SOF timing. Therefore, if the firmware would enable USBEpIntEn in early stage, DMA request could accidentally jump in while the firmware sets up DMA registers.

    Tsuneo

  • Hi Tsuneo,

    All is clear. Thank you very much for your help. I have made changes as per your suggestions and the transfer is working well now.

    Thanks very much.

    Regards,
    Shaunak