Hi, I am currently using IN EP3 of the LPC1769 to realize Isochronous transactions to the Host. I have configured the this endpoint in the DMA mode
LPC_USB->EpDMAEn = 0x80;
I enable the DMA on the EP when I receive the Set Interface command from the Host. However, I see that the EpDMAEn does not change its value to 0x80 as desired (this could probably be because the register is Write Only, but I am not sure). Please can someone let me know the conditions under which the DMA mode for the EP would get disabled?
In order to get around this problem I write to the above register everytime I create a DMA Descriptor. Is this a good method? Many time we end up loosing bytes of information on the host but I am not sure if it is actually because of this.
Any help in this regard would be much appreciated.
Thanks very much.
Regards, Shaunak
> I see that the EpDMAEn does not change its value to 0x80 as desired (this could probably be because the register is Write Only, but I am not sure).
Ya, USBEpDMAEn register is write-only. Reading from this register does't have any meaning. USBEpDMASt holds the result of write to USBEpDMAEn. Once enabled by USBEpDMAEn, the status (enabled/disabled) doesn't change until your firmware disables it by writing to USBEpDMADis.
> I enable the DMA on the EP when I receive the Set Interface command from the Host.
Here is the bus traffic of a USB microphone, running on Windows XP At the end of enumeration, two Set_Interface( alternate:0 ) are seen.
// enumeration - last part [6.393,395] FS: Control Transfer Addr:07 Endp:0 - Set Configuration (0x01) [6.464,475] FS: Control Transfer Addr:07 Endp:0 - Set Interface 1 to 0 // <------ [6.475,128] FS: Control Transfer Addr:07 Endp:0 - Get String Descriptor 0 [6.478,213] FS: Control Transfer Addr:07 Endp:0 - Get String Descriptor 2 [6.481,535] FS: Control Transfer Addr:07 Endp:0 - Get String Descriptor 0 [6.485,039] FS: Control Transfer Addr:07 Endp:0 - Get String Descriptor 2 [6.492,961] FS: Control Transfer Addr:07 Endp:0 - Get String Descriptor 0 [6.495,275] FS: Control Transfer Addr:07 Endp:0 - Get String Descriptor 2 [6.497,541] FS: Control Transfer Addr:07 Endp:0 - Set Interface 1 to 0 // <------
When Audacity, an audio recording application, starts up, this app issues two pairs of Set_Interface( alternate:1/0 )
// Audacity starts up [12.089,038] FS: Control Transfer Addr:07 Endp:0 - Set Interface 1 to 1 // <------ [12.138,837] FS: Control Transfer Addr:07 Endp:0 - Set Interface 1 to 0 // <------ [13.383,604] FS: Control Transfer Addr:07 Endp:0 - Set Interface 1 to 1 // <------ [13.411,127] FS: Control Transfer Addr:07 Endp:0 - Set Interface 1 to 0 // <------
At "Start Monitoring", Set_Interface( alternate:1 ) is issued, and isoc transactions start
// Start Monitoring [22.678,272] FS: Control Transfer Addr:07 Endp:0 - Set Interface 1 to 1 // <------ [22.718,957] FS: Data Transfer (Isochronous-IN) Addr:07 Endp:1 - Audio Stream [22.719,957] FS: Data Transfer (Isochronous-IN) Addr:07 Endp:1 - Audio Stream ... Isoc INs continue ...
At "Stop Monitoring", isoc transactions stop, and Set_Interface( alternate:0 ) is issued.
// Stop Monitoring [27.268,106] FS: Data Transfer (Isochronous-IN) Addr:07 Endp:1 - Audio Stream [27.269,106] FS: Data Transfer (Isochronous-IN) Addr:07 Endp:1 - Audio Stream [27.277,759] FS: Control Transfer Addr:07 Endp:0 - Set Interface 1 to 0 // <------
In this way, Set_Interface() is issued many times, before isoc transfer actually starts. We have to count in this fact on coding.
Tsuneo
HI Tsuneo,
Thank you for your reply.
So if have enabled an EP for DMA transfer then it should remain enabled. If I do not want to wait for the FRAME (1ms) trigger could I use
LPC_USB->DMARSet = 0x80
to manually initiate a DMA transfer? Also, writing to the USBDMARSet register would trigger only 1 DMA transfer, am I right? If I needed to trigger another transfer then I would either have to wait for the FRAME trigger or write to USBDMARSet again. Please correct me if I'm wrong.
> If I do not want to wait for the FRAME (1ms) trigger could I use > LPC_USB->DMARSet = 0x80 > to manually initiate a DMA transfer?
You may. But is it really required? As above bus trace shows, it takes 40 ms (22.678,272 - 22.718,957 second) from Set_Interface( alternate:1 ) to the first isoc IN transaction. You'll get enough number of SOF (FRAME) triggers in this interval.
> Also, writing to the USBDMARSet register would trigger only 1 DMA transfer, am I right? If I needed to trigger another transfer then I would either have to wait for the FRAME trigger or write to USBDMARSet again.
Yes. Writing '1' to USBDMARSet register gives a trigger to the DMA logic, like SOF (FRAME) trigger.
> Many time we end up loosing bytes of information on the host but I am not sure if it is actually because of this.
Are you nervous on the packet drops in the period from Set_Interface( alternate:1 ) to the first isoc IN transaction? It is the way how USB audio works. Just the audio data on time is worth being transferred. The packets before the first isoc IN should be discarded, because they are behind the time line.
Hi Tsuneo,
We are implementing a video class device using LPC1769. The data loss occurs during normal operation much after the Set Interface command. The Set interface command on our custom video class driver is being sent only once from the Host.
I have also understood your post regarding USBDMARSet. Thank you very much for the explanation.
> We are implementing a video class device using LPC1769.
Either on USB audio or on UVC (USB Video Class), the "isochronous" concept is the same; Just the data [b]on time[/b] is worth being transferred.
> The data loss occurs during normal operation much after the Set Interface command.
Monitor the bus traffic using both of hardware and software sniffer. The data loss may occur on the PC side.
Thanks for your reply. We are actually using Win CE Development board as the Host. We do not have a sniffer to view packets transferred over USB for Win CE.
However, I had a few more questions.
I have created a DMA decriptor for the Isochronous endpoint. We intend to transfer 1284 bytes of data over the IN Isochronous Endpoint via 2 burst of 642 each. The descriptor is as follows
Next_DD = 0x00000000 DMA_mode = 0x00 Next_DD_valid = 0 Isochronous_endpoint = 1 Max_packet_size = 0 DMA_buffer_length = 2 DMA_buffer_start_addr = Start address of Data buffer to be transferred DD_retired = 0 DD_status = 0 Packet_valid = 0 LS_byte_extracted = 0 MS_byte_extracted = 0 Message_length_position = 0 Present_DMA_count = 0 Isochronous_packetsize_memory_address = pointer to the address containing the following data 0x00000282; There are 2 locations at consecutive word boundaries having the same value;
Please could you let me know following? 1. The DMA transfer for a burst of 642 bytes will begin after teh corresponding bit in USBDMARSt is set (FRAME 1ms trigger). Will the second transfer soon follow this transfer or will the second burst trasfer take place only after the bit in the USBDMARSt register is set again (FRAME 1ms trigger)? 2. If the first DMA transfer to the EP RAM has completed but hasn't been read by the host through an in transaction, will the next DMA transfer over-write the data transferred during the first burst? 3. If the Host is in the process of reading the data from the IN Isochronous EP, and the 2nd DMA burst is initiated will the data being transfer to the host get corrupted?
Please see the following post. The message is too long to be completed in a single post. Thanks very much
View all questions in Keil forum