Other Parts Discussed in Thread: TM4C129ENCPDT
Our UART ISR is triggered but when we call:
// Find out why interrupt was triggered uint32_t Status = MAP_UARTIntStatus(UART6_BASE, 1);
The debugger is showing that Status is 0.
Why is the interrupt triggered?
We are doing UART communication with DMA and trying to receive a block of 8 bytes. We are expecting the interrupt to trigger with UART_INT_DMARX and to set a flag indicating DMA has completed. Instead Status is 0 and we never act upon the received data.
UART and DMA initialization:
#if defined (ewarm)
#pragma data_alignment=1024
uint8_t DmaControlTable[1024];
#elif defined (ccs)
#pragma DATA_ALIGN(DmaControlTable, 1024)
uint8_t DmaControlTable[1024];
#else
uint8_t DmaControlTable[1024] __attribute__ ((aligned(1024)));
#endif
MAP_SysCtlPeripheralDisable(SYSCTL_PERIPH_UDMA);
MAP_SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
while (MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA) != true) {
}
// Enable uDMA error interrupt to catch bus errors during transfers
MAP_IntEnable(INT_UDMAERR);
// Enable the uDMA controller
MAP_uDMAEnable();
// Point at the control table to use for channel control structures
MAP_uDMAControlBaseSet(DmaControlTable);
MAP_SysCtlPeripheralDisable(SYSCTL_PERIPH_UART6);
MAP_SysCtlPeripheralReset(SYSCTL_PERIPH_UART6);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART6);
while (MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_UART6) != true) {
}
// Setup GPIO port pin muxing and UART function
MAP_GPIOPinConfigure(GPIO_PD4_U6RX);
MAP_GPIOPinConfigure(GPIO_PD5_U6TX);
MAP_GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5);
MAP_UARTConfigSetExpClk(UART6_BASE, Global.SysClockFreqHz, u->Baud, (UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE | UART_CONFIG_WLEN_8));
// Set UART Tx and Rx FIFO trigger thresholds to 4
MAP_UARTFIFOEnable(UART6_BASE);
MAP_UARTFIFOLevelSet(UART6_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
// Enable UART and enable DMA for Tx and Rx
MAP_UARTEnable(UART6_BASE);
// Connect appropriate DMA channels to the selected UARTs
MAP_uDMAChannelAssign(UDMA_CH10_UART6RX);
MAP_uDMAChannelAssign(UDMA_CH11_UART6TX);
// Make sure unneeded Rx channel DMA attributes are off
MAP_uDMAChannelAttributeDisable(UDMA_CH10_UART6RX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
// Set Rx DMA primary control structure:
// - Data size 8 bits
// - Source address does not increment; always points to UART Rx data register
// - Destination address increment is byte (8-bit)
// - Arbitration size is 4 to match UART Rx FIFO trigger threshold
// - DMA will use 4 byte burst transfer if possible for efficiency
MAP_uDMAChannelControlSet(
UDMA_CH10_UART6RX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4
);
// Make sure unneeded Tx channel DMA attributes are off
MAP_uDMAChannelAttributeDisable(UDMA_CH11_UART6TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
// Enable USEBURST to force Tx channel DMA to always use burst when
// transferring from Tx buffer to UART.
MAP_uDMAChannelAttributeEnable(UDMA_CH11_UART6TX, UDMA_ATTR_USEBURST);
// Set Tx DMA primary control structure:
// - Data size 8 bits
// - Source address increment is byte (8-bit)
// - Destination address does not increment; always points to UART Tx data register
// - Arbitration size is 4 to match UART Tx FIFO trigger threshold
MAP_uDMAChannelControlSet(
UDMA_CH11_UART6TX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4
);
// Enable master interrupt for this UART
MAP_IntEnable(INT_UART6);
Begin receiving data block:
// Set Rx DMA primary control structure transfer parameters: // - Mode set to basic (not ping-pong). // - Source is UART data register // - Destination is receive memory buffer // - Transfer size is set to match the size of the buffer // MAP_uDMAChannelTransferSet( UDMA_CH10_UART6RX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)(UART6_BASE + UART_O_DR), RxBuf, SizeOfRxBuf ); // Enable channel because it is disabled at completion of each transfer MAP_uDMAChannelEnable(UDMA_CH10_UART6RX); // Enable DMA Rx interrupt MAP_UARTDMAEnable(UART6_BASE, UART_DMA_RX); MAP_UARTIntEnable(UART6_BASE, UART_INT_DMARX);
Interrupt:
void IsrUart6Handler(void)
{
uint32_t Status;
// Find out why interrupt was triggered
Status = MAP_UARTIntStatus(UART6_BASE, true);
// Clear pending status
MAP_UARTIntClear(UART6_BASE, Status);
if (Status & UART_INT_DMARX) {
RxDone = true;
MAP_UARTDMADisable(UART6_BASE, UART_DMA_RX);
MAP_UARTIntDisable(UART6_BASE, UART_INT_DMARX);
}
}
When we examined unmasked UART interrupt status in the debugger, it was 0xf; three of those set bits are reserved and one was CTSRIS which we are not using. Masked interrupt status is 0.