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
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.
> 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
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.