#include #include #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_uart.h" #include "driverlib/fpu.h" #include "driverlib/gpio.h" #include "driverlib/interrupt.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/sysctl.h" #include "driverlib/systick.h" #include "driverlib/uart.h" #include "driverlib/udma.h" #include "utils/cpu_usage.h" #include "utils/uartstdio.h" #include "utils/ustdlib.h" //***************************************************************************** //***************************************************************************** #if defined(ewarm) #pragma data_alignment=1024 uint8_t ui8ControlTable[1024]; #elif defined(ccs) #pragma DATA_ALIGN(ui8ControlTable, 1024) uint8_t ui8ControlTable[1024]; #else uint8_t ui8ControlTable[1024] __attribute__ ((aligned(1024))); #endif #define UART_TXBUF_SIZE 16 #define UART_RXBUF_SIZE 16 static uint8_t g_pui8TxBuf[UART_TXBUF_SIZE]; static uint8_t g_pui8RxPing[UART_RXBUF_SIZE]; static uint8_t g_pui8RxPong[UART_RXBUF_SIZE]; // Error counter static uint32_t g_ui32DMAErrCount = 0; // Transfer counters static uint32_t g_ui32RxPingCount = 0; static uint32_t g_ui32RxPongCount = 0; volatile int UARTIntHitsCounter = 0; // uDMA control table aligned to 1024-byte boundary #pragma DATA_ALIGN(ucControlTable, 64) uint8_t ucControlTable[64]; void uDMAErrorHandler(void) { uint32_t ui32Status; ui32Status = ROM_uDMAErrorStatusGet(); if(ui32Status) { ROM_uDMAErrorStatusClear(); g_ui32DMAErrCount++; } } // UART interrupt handler. Called on completion of uDMA transfer void UART0IntHandler(void) { uint32_t ui32Status; uint32_t ui32Mode; ui32Status = ROM_UARTIntStatus(UART0_BASE, 1); ROM_UARTIntClear(UART0_BASE, ui32Status); UARTIntHitsCounter++; ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT); if(ui32Mode == UDMA_MODE_STOP) { g_ui32RxPingCount++; ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(UART0_BASE + UART_O_DR), g_pui8RxPing, sizeof(g_pui8RxPing)); } ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | UDMA_ALT_SELECT); if(ui32Mode == UDMA_MODE_STOP) { g_ui32RxPongCount++; ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(UART0_BASE + UART_O_DR), g_pui8RxPong, sizeof(g_pui8RxPong)); } if(!ROM_uDMAChannelIsEnabled(UDMA_CHANNEL_UART0TX)) { ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, g_pui8TxBuf, (void *)(UART0_BASE + UART_O_DR), sizeof(g_pui8TxBuf)); ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0TX); } } // Initialize UART uDMA transfer void InitUART1Enable(void) { ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // Enable UART1 and make sure it can run while the CPU sleeps ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART0); ROM_GPIOPinConfigure(GPIO_PA0_U0RX); ROM_GPIOPinConfigure(GPIO_PA1_U0TX); // Configure and enable the UART with DMA ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE); ROM_UARTFIFOLevelSet(UART0_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8); ROM_UARTEnable(UART0_BASE); ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX); ROM_IntEnable(INT_UART0); // Receive channel setup for ping and pong ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0RX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); ROM_uDMAChannelAttributeEnable(UDMA_CHANNEL_UART0RX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4); ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0RX | UDMA_ALT_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4); ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(UART0_BASE + UART_O_DR), g_pui8RxPing, sizeof(g_pui8RxPing)); ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(UART0_BASE + UART_O_DR), g_pui8RxPong, sizeof(g_pui8RxPong)); // Enable both channels ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0RX); } int main(void) { volatile uint32_t ui32Loop; ROM_FPULazyStackingEnable(); ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); ROM_SysCtlPeripheralClockGating(true); // GPIO setup for LEDs ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2); // Enable uDMA ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA); //ROM_IntEnable(INT_UDMAERR); ROM_uDMAEnable(); ROM_uDMAControlBaseSet(ucControlTable); // Initialize the uDMA/UART InitUART1Enable(); while(1) { if(UARTIntHitsCounter > 0) { GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2); SysCtlDelay(SysCtlClockGet() / 20 / 3); GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0); SysCtlDelay(SysCtlClockGet() / 20 / 3); } } }