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.