Hi all,
I'm trying to use uDMA to control UART6 data transmit and receive. Eventually, I plan to use UART4 as well in the same manner.
UART6 is configured as 115200 8N1 standard UART and I want to use the uDMA to transfer up to 128 bytes at a time without processor intervention.
I am using a TM4C123GH6PM on custom hardware.
This currently seems to initiate a transfer but the first byte is repeated 32 times, and sizes above 32 bytes just seem to be "clipped" so to speak. No bytes beyond 32 are ever transferred (I do not see start or stop bits in the UART waveform.)
Here is my code, some of which is based off the working example (udma_demo)
uint8_t test_data[128];
uint32_t testn = 0;
/**
* Prepare the UART and DMA peripherals for fast transmit mode.
*
* The UART modules will be configured for the correct baud rate.
*/
void init_uart_dma()
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART6);
uDMAEnable();
uDMAControlBaseSet(udma_controltbl);
UARTConfigSetExpClk(UART6_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
UARTFIFOLevelSet(UART6_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
UARTEnable(UART6_BASE);
UARTDMAEnable(UART6_BASE, UART_DMA_RX | UART_DMA_TX);
uDMAChannelAssign(UDMA_CH11_UART6TX);
uDMAChannelAttributeDisable(UDMA_CH11_UART6TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
uDMAChannelAttributeEnable(UDMA_CH11_UART6TX, UDMA_ATTR_USEBURST);
uDMAChannelControlSet(UDMA_CH11_UART6TX, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4);
GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5);
GPIOPinConfigure(GPIO_PD4_U6RX);
GPIOPinConfigure(GPIO_PD5_U6TX);
DBG_PRINTF("uDMA for UART initialised\r\n", 0);
}
/**
* Transfer data over UART TX via uDMA.
*
* A maximum of 1023 bytes can be transferred in a single packet.
*
* Blocks while relevant uDMA transfer is in use.
*
* @param port UART_CH_BLE or UART_CH_RASPI
* @param nbytes number of bytes to transfer (0-1023)
* @param data pointer to data structure to read from
*/
void uart_dma_tx(uint32_t port, uint32_t nbytes, uint8_t *data)
{
strcpy(test_data, "TestDataPacket");
test_data[0] = testn;
// wait for uDMA channel to be free
while(uDMAChannelIsEnabled(UDMA_CH11_UART6TX));
uDMAChannelTransferSet(UDMA_CH11_UART6TX, UDMA_MODE_BASIC, &test_data, (void *)(UART6_BASE + UART_O_DR), testn);
uDMAChannelEnable(UDMA_CH11_UART6TX);
testn++;
testn %= 64;
}
Thanks for any help that can be offered
Oscilloscope screenshot showing repeated byte:
Waveform showing maximum packet size and lack of any transfer past 32 bytes or so:

