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.

CCS/EK-TM4C1294XL: TM4C1294NCPDT used UART3 sent DMA, the DMA is sent to complete the interrupt, But after the sent is completed,program into the interruption All the time.

Part Number: EK-TM4C1294XL
Other Parts Discussed in Thread: TM4C1294NCPDT

Tool/software: Code Composer Studio

TM4C1294NCPDT used UART3 sent DMA, the DMA is sent to complete the interrupt, But after the sent is completed,program into the interruption All the time.

void InitUART3Transfer(void)
{
	uint_fast16_t ui16Idx;

	//
	// Fill the TX buffer with a simple data pattern.
	//
	for(ui16Idx = 0; ui16Idx < UART_TXBUF_SIZE; ui16Idx++)
	{
		g_ui8TxBuf[ui16Idx] = ui16Idx;
	}
	//
	// Enable the GPIO Peripheral used by the UART.
	//
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
	//
	// Enable the UART peripheral, and configure it to operate even if the CPU
	// is in sleep.
	//
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);
	ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART3);
	//
	// Configure GPIO Pins for UART mode.
	//
	ROM_GPIOPinConfigure(GPIO_PA4_U3RX);
	ROM_GPIOPinConfigure(GPIO_PA5_U3TX);
	ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_4 | GPIO_PIN_5); 
	//
	// Configure the UART communication parameters.
	//
	ROM_UARTConfigSetExpClk(UART3_BASE, g_ui32SysClock, 115200,
	UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
	UART_CONFIG_PAR_NONE);

	//
	// Set both the TX and RX trigger thresholds to 4. This will be used by
	// the uDMA controller to signal when more data should be transferred. The
	// uDMA TX and RX channels will be configured so that it can transfer 4
	// bytes in a burst when the UART is ready to transfer more data.
	//
	ROM_UARTFIFOLevelSet(UART3_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);

	//
	// Enable the UART for operation, and enable the uDMA interface for both TX
	// and RX channels.
	//
	ROM_UARTEnable(UART3_BASE);
	ROM_UARTDMAEnable(UART3_BASE, UART_DMA_RX | UART_DMA_TX);

	ROM_uDMAChannelAssign(UDMA_CH16_UART3RX);
	ROM_uDMAChannelAssign(UDMA_CH17_UART3TX);

	//
	// Put the attributes in a known state for the uDMA UART3RX channel. These
	// should already be disabled by default.
	//
	ROM_uDMAChannelAttributeDisable(UDMA_SEC_CHANNEL_UART3RX,
	UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
	UDMA_ATTR_HIGH_PRIORITY |
	UDMA_ATTR_REQMASK);

	//
	// Configure the control parameters for the primary control structure for
	// the UART RX channel. The primary contol structure is used for the "A"
	// part of the ping-pong receive. The transfer data size is 8 bits, the
	// source address does not increment since it will be reading from a
	// register. The destination address increment is byte 8-bit bytes. The
	// arbitration size is set to 4 to match the RX FIFO trigger threshold.
	// The uDMA controller will use a 4 byte burst transfer if possible. This
	// will be somewhat more effecient that single byte transfers.
	//
	ROM_uDMAChannelControlSet(UDMA_SEC_CHANNEL_UART3RX | UDMA_PRI_SELECT,
	UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
	UDMA_ARB_4);

	//
	// Configure the control parameters for the alternate control structure for
	// the UART RX channel. The alternate contol structure is used for the "B"
	// part of the ping-pong receive. The configuration is identical to the
	// primary/A control structure.
	//
	ROM_uDMAChannelControlSet(UDMA_SEC_CHANNEL_UART3RX | UDMA_ALT_SELECT,
	UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
	UDMA_ARB_4);

	//
	// Set up the transfer parameters for the UART RX primary control
	// structure. The mode is set to ping-pong, the transfer source is the
	// UART data register, and the destination is the receive "A" buffer. The
	// transfer size is set to match the size of the buffer.
	//
	ROM_uDMAChannelTransferSet(UDMA_SEC_CHANNEL_UART3RX | UDMA_PRI_SELECT,
	UDMA_MODE_PINGPONG,
	(void *)(UART3_BASE + UART_O_DR),
	g_ui8RxBufA, sizeof(g_ui8RxBufA));

	//
	// Set up the transfer parameters for the UART RX alternate control
	// structure. The mode is set to ping-pong, the transfer source is the
	// UART data register, and the destination is the receive "B" buffer. The
	// transfer size is set to match the size of the buffer.
	//
	ROM_uDMAChannelTransferSet(UDMA_SEC_CHANNEL_UART3RX | UDMA_ALT_SELECT,
	UDMA_MODE_PINGPONG,
	(void *)(UART3_BASE + UART_O_DR),
	g_ui8RxBufB, sizeof(g_ui8RxBufB));

	//
	// Put the attributes in a known state for the uDMA UART1TX channel. These
	// should already be disabled by default.
	//
	ROM_uDMAChannelAttributeDisable(UDMA_SEC_CHANNEL_UART3TX,
	UDMA_ATTR_ALTSELECT |
	UDMA_ATTR_HIGH_PRIORITY |
	UDMA_ATTR_USEBURST |
	UDMA_ATTR_REQMASK);

	//
	// Set the USEBURST attribute for the uDMA UART TX channel. This will
	// force the controller to always use a burst when transferring data from
	// the TX buffer to the UART. This is somewhat more effecient bus usage
	// than the default which allows single or burst transfers.
	//
	// ROM_uDMAChannelAttributeEnable(UDMA_SEC_CHANNEL_UART3TX, UDMA_ATTR_USEBURST);

	//
	// Configure the control parameters for the UART TX. The uDMA UART TX
	// channel is used to transfer a block of data from a buffer to the UART.
	// The data size is 8 bits. The source address increment is 8-bit bytes
	// since the data is coming from a buffer. The destination increment is
	// none since the data is to be written to the UART data register. The
	// arbitration size is set to 4, which matches the UART TX FIFO trigger
	// threshold.
	//
	ROM_uDMAChannelControlSet(UDMA_SEC_CHANNEL_UART3TX | UDMA_PRI_SELECT,
	UDMA_SIZE_8 | UDMA_SRC_INC_8 |
	UDMA_DST_INC_NONE |
	UDMA_ARB_4);

	//
	// Set up the transfer parameters for the uDMA UART TX channel. This will
	// configure the transfer source and destination and the transfer size.
	// Basic mode is used because the peripheral is making the uDMA transfer
	// request. The source is the TX buffer and the destination is the UART
	// data register.
	//
	ROM_uDMAChannelTransferSet(UDMA_SEC_CHANNEL_UART3TX | UDMA_PRI_SELECT,
	UDMA_MODE_BASIC, g_ui8TxBuf,
	(void *)(UART3_BASE + UART_O_DR),
	sizeof(g_ui8TxBuf));

	//
	// Now both the uDMA UART TX and RX channels are primed to start a
	// transfer. As soon as the channels are enabled, the peripheral will
	// issue a transfer request and the data transfers will begin.
	//
	ROM_uDMAChannelEnable(UDMA_SEC_CHANNEL_UART3RX);
	ROM_uDMAChannelEnable(UDMA_SEC_CHANNEL_UART3TX);

	//
	// Enable the UART DMA TX/RX interrupts.
	//
	ROM_UARTIntEnable(UART3_BASE, UART_INT_DMARX | UART_INT_DMATX );//UART_INT_DMATX

	//
	// Enable the UART peripheral interrupts.
	//
	ROM_IntEnable(INT_UART3);
}

void UART3IntHandler(void)
{
	uint32_t ui32Status;
	uint32_t ui32Mode;

	//
	// Read the interrupt status of the UART.
	//
	ui32Status = ROM_UARTIntStatus(UART3_BASE, 1);

	//
	// Clear any pending status, even though there should be none since no UART
	// interrupts were enabled. If UART error interrupts were enabled, then
	// those interrupts could occur here and should be handled. Since uDMA is
	// used for both the RX and TX, then neither of those interrupts should be
	// enabled.
	//
	ROM_UARTIntClear(UART3_BASE, ui32Status);

	//
	// Check the DMA control table to see if the ping-pong "A" transfer is
	// complete. The "A" transfer uses receive buffer "A", and the primary
	// control structure.
	//
	ui32Mode = ROM_uDMAChannelModeGet(UDMA_SEC_CHANNEL_UART3RX | UDMA_PRI_SELECT);

	//
	// If the primary control structure indicates stop, that means the "A"
	// receive buffer is done. The uDMA controller should still be receiving
	// data into the "B" buffer.
	//
	if(ui32Mode == UDMA_MODE_STOP)
	{
		//
		// Increment a counter to indicate data was received into buffer A. In
		// a real application this would be used to signal the main thread that
		// data was received so the main thread can process the data.
		//
		g_ui32RxBufACount++;

		//
		// Set up the next transfer for the "A" buffer, using the primary
		// control structure. When the ongoing receive into the "B" buffer is
		// done, the uDMA controller will switch back to this one. This
		// example re-uses buffer A, but a more sophisticated application could
		// use a rotating set of buffers to increase the amount of time that
		// the main thread has to process the data in the buffer before it is
		// reused.
		//
		ROM_uDMAChannelTransferSet(UDMA_SEC_CHANNEL_UART3RX | UDMA_PRI_SELECT,
		UDMA_MODE_PINGPONG,
		(void *)(UART3_BASE + UART_O_DR),
		g_ui8RxBufA, sizeof(g_ui8RxBufA));
	}

	//
	// Check the DMA control table to see if the ping-pong "B" transfer is
	// complete. The "B" transfer uses receive buffer "B", and the alternate
	// control structure.
	//
	ui32Mode = ROM_uDMAChannelModeGet(UDMA_SEC_CHANNEL_UART3RX | UDMA_ALT_SELECT);

	//
	// If the alternate control structure indicates stop, that means the "B"
	// receive buffer is done. The uDMA controller should still be receiving
	// data into the "A" buffer.
	//
	if(ui32Mode == UDMA_MODE_STOP)
	{
		//
		// Increment a counter to indicate data was received into buffer A. In
		// a real application this would be used to signal the main thread that
		// data was received so the main thread can process the data.
		//
		g_ui32RxBufBCount++;

		//
		// Set up the next transfer for the "B" buffer, using the alternate
		// control structure. When the ongoing receive into the "A" buffer is
		// done, the uDMA controller will switch back to this one. This
		// example re-uses buffer B, but a more sophisticated application could
		// use a rotating set of buffers to increase the amount of time that
		// the main thread has to process the data in the buffer before it is
		// reused.
		//
		ROM_uDMAChannelTransferSet(UDMA_SEC_CHANNEL_UART3RX | UDMA_ALT_SELECT,
		UDMA_MODE_PINGPONG,
		(void *)(UART3_BASE + UART_O_DR),
		g_ui8RxBufB, sizeof(g_ui8RxBufB));
	}

	//
	// If the UART1 DMA TX channel is disabled, that means the TX DMA transfer
	// is done.
	//
	ui32Mode = ROM_uDMAIntStatus();
	if(ui32Mode & (1 << UDMA_SEC_CHANNEL_UART3TX))
	{
		ROM_uDMAIntClear(1 << UDMA_SEC_CHANNEL_UART3TX);
	}

}