This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Using uDMA to send data to USB ('IN')



I'm working on the Stellaris Lauchpad, with the LM4F120XL processor.

Well, after quite an adventure, I got both ADCs working simultaneously, processed the measured data, and have the data ready to be transferred to the host. That initial part went quite well.

I tried simply pushing the data to the USB channel using USBEndpointDataPut(USB0_BASE, USB_EP_1,... and USBEndpointDataSend(), but that caused a lot of data loss, probably because of the unsynced data transfers.

Total transfer speed needs to be 400 kB/s (I'm now testing with 500 kB/s), which I suspect should be possible, as the USB channel bandwidth (at Full speed) is about 1.2MB/s, and no other traffic is on host port. I did find several posts on the 'net, indicating the speed is realizable (just not with the Stellaris).

Trying to combine the uDMA demo example with the usb_dev_bulk code caused a lot of confusion:

- I can't seem to find any example passing USB IN traffic through the uDMA controller.

- the Bulk Demo code uses USBDBulkInit() to initialize the USB device, but, as I understand it, I now need to pass other parameters to adjust for uDMA usage. Do I have to drop the use of the USBDBulkInit() code, and start defining everything myself, or edit USBDBulk.c code? Or is just changing the tables enough?

- At 64 bytes/packet at 1000 packets/second I think I actually need to use the uDMA controller to get around the 64kB/second limit. Is this correct?

  • Hello John,

    There are not any example in TivaWare for DMA enabled USB. However the forum threads would be useful

    e2e.ti.com/.../468467
    e2e.ti.com/.../1154618

    Regards
    Amit
  • Thanks Amit. The links were useful.
  • Well, back to the project - but I wasn't able to get uDMA working with the USB. I tried do follow as closely as possible the information in the driverlib and the USB lib references, but no luck... I hope someone can point out where the problem is.

    Here's the code I use to initialize uDMA, using ping-pong, with an IN endpoint (1):

        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
    
        // Enable the GPIO peripheral used for USB, and configure the USB
        // pins.
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
        ROM_GPIOPinTypeUSBAnalog(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    
    
        // Initialize the transmit and receive buffers.
    	USBBufferInit((tUSBBuffer *)&TxBuffer);
    	USBBufferInit((tUSBBuffer *)&RxBuffer);
    	USBBufferInfoGet(&TxBuffer, &TxRing);
    
    	USBStackModeSet(0, USB_MODE_FORCE_DEVICE, 0);
    
    	// Pass our device information to the USB library and place the device
    	// on the bus.
    	USBDBulkInit(0, &BulkDevice);
    
    	// Configure Endpoint 1.
    	USBDevEndpointConfigSet(USB0_BASE, USB_EP_1, 64,
    							DISABLE_NAK_LIMIT |
    							USB_EP_MODE_BULK |
    							USB_EP_DMA_MODE_0 |
    							USB_EP_AUTO_SET |
    							USB_EP_DEV_IN);
    
    	// Configure FIFO as a device IN endpoint FIFO starting at address 64
    	// and is 64 bytes in size.
    	USBFIFOConfigSet(USB0_BASE, USB_EP_1, 64, USB_FIFO_SZ_64, USB_EP_DEV_IN);
    
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    	ROM_uDMAEnable();
    
    	ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_USBEP1TX,
    	                                UDMA_ATTR_ALTSELECT |
    									UDMA_ATTR_USEBURST |
    	                                UDMA_ATTR_HIGH_PRIORITY |
    	                                UDMA_ATTR_REQMASK);
    
    	ROM_uDMAChannelControlSet(UDMA_CHANNEL_USBEP1TX | UDMA_PRI_SELECT,
    	                          UDMA_SIZE_32 |
    							  UDMA_SRC_INC_32 |
    							  UDMA_DST_INC_NONE |
    	                          UDMA_ARB_256);
    
    	ROM_uDMAChannelControlSet(UDMA_CHANNEL_USBEP1TX | UDMA_ALT_SELECT,
    	                          UDMA_SIZE_32 |
    							  UDMA_SRC_INC_32 |
    							  UDMA_DST_INC_NONE |
    	                          UDMA_ARB_256);
    
    	ROM_uDMAChannelTransferSet(UDMA_CHANNEL_USBEP1TX | UDMA_PRI_SELECT,
    	                           UDMA_MODE_PINGPONG,
    	                           TxData_A,
    							   (void *)ROM_USBFIFOAddrGet(USB0_BASE, USB_EP_1),
    							   sizeof(TxData_A));
    
    	ROM_uDMAChannelTransferSet(UDMA_CHANNEL_USBEP1TX | UDMA_ALT_SELECT,
    	                           UDMA_MODE_PINGPONG,
    							   TxData_B,
    							   (void *)ROM_USBFIFOAddrGet(USB0_BASE, USB_EP_1),
    							   sizeof(TxData_B));
    
    	// Enable uDMA burst mode.
    	ROM_uDMAChannelAttributeEnable(UDMA_CHANNEL_USBEP1TX,
    								   UDMA_ATTR_USEBURST);
    
    }
    

    Later, in the main program. I enable:

        ROM_IntEnable(INT_USB0);
    
        ROM_uDMAChannelEnable(UDMA_CHANNEL_USBEP1TX);
    

    The device enumerates correctly, but data is never sent. The TxHandler interrupt USB_EVENT_TX_COMPLETE is never called either.

    Am I forgetting something?

  • Hello John

    A CCS project zip and attached to the forum post would be more useful resource then code snippets!!!

    Regards
    Amit
  • My apologies for the delay. We had serious (and very strange) problems with a server yesterday.


    I've made a copy of the project, and removed most of the code I had already disabled (I hope).

    Notes:

    -The buffer I prepare to send does not contain initialized data - it was only for testing.

    -I know I should re-start when the end of transmission interrupt appears - but the interrupt is never generated.

    I hope this is the correct way to insert a file...

    usb_dev_bulk_copy.tar.gz

  • Hello John

    I believe, you have tested the scaled down version, to be not working with the same symptoms are earlier?

    Regards
    Amit
  • Correct - the USB interface is recognized (i.e. the host can connect and claim the USB interface), but the bulk transfer does not work. In the Launchpad, no interrupt is detected.
    This might be of help: On activating the board, enumeration seems normal - Manufacturer, Product, Serialnumber. Then there's the set configuration (Ok), and description string ('Bulk data configuration', and ...Interface). A STATUS request.
    At this moment, there is another descriptor request, but the board replies with a malformed packet, and all bus communication stops.
  • Hello John,

    Thanks for the confirmation

    Regards
    Amit