//***************************************************************************** // // The interrupt handler for UART0. This interrupt will occur when a DMA // transfer is complete using the UART0 uDMA channel. It will also be // triggered if the peripheral signals an error. This interrupt handler will // switch between receive ping-pong buffers A and B. It will also restart a TX // uDMA transfer if the prior transfer is complete. This will keep the UART // running continuously (looping TX data back to RX). // //***************************************************************************** void UART0IntHandler(void) { unsigned long ulStatus; unsigned long ulMode; // // Read the interrupt status of the UART. // ulStatus = ROM_UARTIntStatus(UART0_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(UART0_BASE, ulStatus); // // 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. // ulMode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | 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(ulMode == 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_ulRxBufACount++; // // 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_CHANNEL_UART0RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(UART0_BASE + UART_O_DR), g_ucRxBufA, sizeof(g_ucRxBufA)); } // // 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. // ulMode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | 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(ulMode == 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_ulRxBufBCount++; // // 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_CHANNEL_UART0RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(UART0_BASE + UART_O_DR), g_ucRxBufB, sizeof(g_ucRxBufB)); } // // If the UART0 DMA TX channel is disabled, that means the TX DMA transfer // is done. // if(!ROM_uDMAChannelIsEnabled(UDMA_CHANNEL_UART0TX)) { // // Start another DMA transfer to UART0 TX. // ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, g_ucTxBuf, (void *)(UART0_BASE + UART_O_DR), sizeof(g_ucTxBuf)); // // The uDMA TX channel must be re-enabled. // ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0TX); } }
//***************************************************************************** // // Process data to produce a CRC-32 checksum. // //***************************************************************************** uint32_t CRC32DataProcess(uint32_t *pui32Data, uint32_t ui32Length, uint32_t ui32Seed, bool bUseDMA) { uint32_t ui32Result; // // Perform a soft reset. // ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_CCM0); while(!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_CCM0)) { } // // Configure the CRC engine. // ROM_CRCConfigSet(CCM0_BASE, (CRC_CFG_INIT_SEED | CRC_CFG_TYPE_P4C11DB7 | CRC_CFG_SIZE_32BIT)); // // Write the seed. // ROM_CRCSeedSet(CCM0_BASE, ui32Seed); // // Generate CRC using uDMA to copy data. // if(bUseDMA) { // // Setup the DMA module to copy data in. // ROM_uDMAChannelAssign(UDMA_CH30_SW); ROM_uDMAChannelAttributeDisable(UDMA_CH30_SW, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); ROM_uDMAChannelControlSet(UDMA_CH30_SW | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE | UDMA_ARB_1 | UDMA_DST_PROT_PRIV); ROM_uDMAChannelTransferSet(UDMA_CH30_SW | UDMA_PRI_SELECT, UDMA_MODE_AUTO, (void *)g_pui32RandomData, (void *)(CCM0_BASE + CCM_O_CRCDIN), ui32Length); ROM_uDMAChannelEnable(UDMA_CH30_SW); UARTprintf(" Data in DMA request enabled.\n"); // // Start the uDMA. // ROM_uDMAChannelRequest(UDMA_CH30_SW | UDMA_PRI_SELECT); // // Wait for the transfer to finish. // while(ROM_uDMAChannelIsEnabled(UDMA_CH30_SW)) { } // // Read the result. // ui32Result = ROM_CRCResultRead(CCM0_BASE, false); } // // Generate CRC using CPU to copy data. // else { ui32Result = ROM_CRCDataProcess(CCM0_BASE, g_pui32RandomData, ui32Length, false); } return(ui32Result); }