//***************************************************************************** // //! Sets up the Ping Pong mode of transfer //! //! \param ulChannel. DMA Channel to be used //! \param pvSrcBuf1.Pointer to the Source Buffer for Primary Control Structure //! \param pvDstBuf1.Pointer to the Destination Buffer for Primary Structure //! \param pvSrcBuf2.Pointer to the Source Buffer for alternate Control Structure //! \param pvDstBuf2. Pointer to the Destination Buffer for alternate Structure //! \param size. Total size to be transferred(should not exceed 1024). //! //! This function //! 1. Configures the uDMA channel //! //! \return None. // //***************************************************************************** void UDMASetupPingPongTransfer(unsigned long ulChannel, void *pvSrcBuf1, void *pvDstBuf1, void *pvSrcBuf2, void *pvDstBuf2, unsigned long size) { UDMASetupTransfer(ulChannel, UDMA_MODE_PINGPONG, size, UDMA_SIZE_8, UDMA_ARB_8, pvSrcBuf1, UDMA_SRC_INC_8, pvDstBuf1, UDMA_DST_INC_8); UDMASetupTransfer(ulChannel|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, size, UDMA_SIZE_8, UDMA_ARB_8, pvSrcBuf2, UDMA_SRC_INC_8, pvDstBuf2, UDMA_DST_INC_8); }
//***************************************************************************** // //! Sets up the Auto Memory transfer //! //! \param ulChannel. DMA Channel to be used //! \param pvSrcBuf. Pointer to the source buffer //! \param pvDstBuf. Pointer to the destination buffer //! \param size. Items to be transfered(should not exceed 1024). //! //! This function //! 1. Configures the uDMA channel //! //! \return None. // //***************************************************************************** void UDMASetupAutoMemTransfer(unsigned long ulChannel, void *pvSrcBuf, void *pvDstBuf, unsigned long size) { UDMASetupTransfer(ulChannel, UDMA_MODE_AUTO, size, UDMA_SIZE_8, UDMA_ARB_8, pvSrcBuf, UDMA_SRC_INC_8, pvDstBuf, UDMA_DST_INC_8); }
//***************************************************************************** //! //! Initializes the uDMA software channel to perform a memory to memory uDMA //! transfer. //! //! \param None //! //! \return None //***************************************************************************** void InitSWTransfer(void) { unsigned int uIdx; // // Fill the source memory buffer with a simple incrementing pattern. // for(uIdx = 0; uIdx < MEM_BUFFER_SIZE; uIdx++) { g_ulSrcBuf[uIdx] = uIdx; } // // Configure the control parameters for the SW channel. The SW channel // will be used to transfer between two memory buffers, 32 bits at a time. // Therefore the data size is 32 bits, and the address increment is 32 bits // for both source and destination. The arbitration size will be set to 8, // which causes the uDMA controller to rearbitrate after 8 items are // transferred. This keeps this channel from hogging the uDMA controller // once the transfer is started, and allows other channels cycles if they // are higher priority. // UDMASetupTransfer(UDMA_CH0_SW, UDMA_MODE_AUTO, MEM_BUFFER_SIZE, UDMA_SIZE_32, UDMA_ARB_8,g_ulSrcBuf, UDMA_SRC_INC_32, g_ulDstBuf, UDMA_DST_INC_32); if(StartAndCompleteSWTransfer(UDMA_CH0_SW)) { UART_PRINT("Memory to Memory Transfer Error \n\r"); } // // Verifying the transfered Data // for(uIdx = 0; uIdx < MEM_BUFFER_SIZE; uIdx++) { if(uIdx!=g_ulDstBuf[uIdx]) { UART_PRINT("Data transfered in Auto mode is Incorrect at %d th " "location \n\r\n\r",uIdx); Done=1; return; } } UART_PRINT("Data transfered in Auto mode is verified \n\r\n\r"); Done=1; }
//***************************************************************************** // //! Main function handling the UART and DMA configuration. It takes 8 //! characters from terminal without displaying them. The string of 8 //! caracters will be printed on the terminal as soon as 8th character is //! typed in. //! //! \param None //! //! \return None //! //***************************************************************************** void main() { // // Initailizing the board // BoardInit(); // // Initialize the RX done flash // bRxDone = false; // // Initialize uDMA // UDMAInit(); // // Muxing for Enabling UART_TX and UART_RX. // PinMuxConfig(); // // Register interrupt handler for UART // MAP_UARTIntRegister(UARTA0_BASE,UARTIntHandler); // // Enable DMA done interrupts for uart // MAP_UARTIntEnable(UARTA0_BASE,UART_INT_DMARX); // // Initialising the Terminal. // MAP_UARTConfigSetExpClk(CONSOLE,MAP_PRCMPeripheralClockGet(CONSOLE_PERIPH), UART_BAUD_RATE, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); // // Clear terminal // ClearTerm(); // // Display Banner // DisplayBanner(APP_NAME); Message("\t\t****************************************************\n\r"); Message("\t\t Type in a string of 8 characters, the characters \n\r"); Message("\t\t will not be displayed on the terminal until \n\r"); Message("\t\t 8th character is entered.\n\r") ; Message("\t\t****************************************************\n\r"); Message("\n\n\n\r"); // // Set the message // Message("Type in 8 characters:"); // // Configure the UART Tx and Rx FIFO level to 1/8 i.e 2 characters // UARTFIFOLevelSet(UARTA0_BASE,UART_FIFO_TX1_8,UART_FIFO_RX1_8); // // Setup DMA transfer for UART A0 // UDMASetupTransfer(UDMA_CH8_UARTA0_RX, UDMA_MODE_BASIC, 8, UDMA_SIZE_8, UDMA_ARB_2, (void *)(UARTA0_BASE+UART_O_DR), UDMA_SRC_INC_NONE, (void *)ucTextBuff, UDMA_DST_INC_8); // // Enable Rx DMA request from UART // MAP_UARTDMAEnable(UARTA0_BASE,UART_DMA_RX); // // Wait for RX to complete // while(!bRxDone) { } // // Setup DMA transfer for UART A0 // UDMASetupTransfer(UDMA_CH9_UARTA0_TX, UDMA_MODE_BASIC, 8, UDMA_SIZE_8, UDMA_ARB_2, (void *)ucTextBuff, UDMA_SRC_INC_8, (void *)(UARTA0_BASE+UART_O_DR), UDMA_DST_INC_NONE); // // Enable TX DMA request // MAP_UARTDMAEnable(UARTA0_BASE,UART_DMA_TX); while(1) { // // Inifite loop // } }
//***************************************************************************** // //! Initializes the UART0 peripheral and sets up the TX and RX uDMA channels. //! The UART is configured for loopback mode so that any data sent on TX will be //! received on RX. The uDMA channels are configured so that the TX channel //! will copy data from a buffer to the UART TX output. And the uDMA RX channel //! will receive any incoming data into a pair of buffers in ping-pong mode. //! //! \param None //! //! \return None //! //***************************************************************************** void InitUART0Transfer(void) { unsigned int uIdx; // // Fill the TX buffer with a simple data pattern. // for(uIdx = 0; uIdx < UART_TXBUF_SIZE; uIdx++) { g_ucTxBuf[uIdx] = 65; } MAP_PRCMPeripheralReset(PRCM_UARTA0); MAP_PRCMPeripheralClkEnable(PRCM_UARTA0,PRCM_RUN_MODE_CLK); MAP_UARTConfigSetExpClk(CONSOLE,SYSCLK, UART_BAUD_RATE, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); MAP_uDMAChannelAssign(UDMA_CH8_UARTA0_RX); MAP_uDMAChannelAssign(UDMA_CH9_UARTA0_TX); MAP_UARTIntRegister(UARTA0_BASE,UART0IntHandler); // // 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. // MAP_UARTFIFOLevelSet(UARTA0_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. // MAP_UARTEnable(UARTA0_BASE); // // This register write will set the UART to operate in loopback mode. Any // data sent on the TX output will be received on the RX input. // HWREG(UARTA0_BASE + UART_O_CTL) |= UART_CTL_LBE; // // Enable the UART peripheral interrupts. uDMA controller will cause an // interrupt on the UART interrupt signal when a uDMA transfer is complete. // MAP_UARTIntEnable(UARTA0_BASE,UART_INT_DMATX); MAP_UARTIntEnable(UARTA0_BASE,UART_INT_DMARX); // // 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. // UDMASetupTransfer(UDMA_CH8_UARTA0_RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, sizeof(g_ucRxBufA),UDMA_SIZE_8, UDMA_ARB_4, (void *)(UARTA0_BASE + UART_O_DR), UDMA_SRC_INC_NONE, g_ucRxBufA, UDMA_DST_INC_8); UDMASetupTransfer(UDMA_CH8_UARTA0_RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, sizeof(g_ucRxBufB),UDMA_SIZE_8, UDMA_ARB_4, (void *)(UARTA0_BASE + UART_O_DR), UDMA_SRC_INC_NONE, g_ucRxBufB, UDMA_DST_INC_8); UDMASetupTransfer(UDMA_CH9_UARTA0_TX| UDMA_PRI_SELECT, UDMA_MODE_BASIC,sizeof(g_ucTxBuf),UDMA_SIZE_8, UDMA_ARB_4, g_ucTxBuf, UDMA_SRC_INC_8,(void *)(UARTA0_BASE + UART_O_DR), UDMA_DST_INC_NONE); MAP_UARTDMAEnable(UARTA0_BASE, UART_DMA_RX | UART_DMA_TX); }
//***************************************************************************** //! //! The interrupt handler for UART0. This interrupt will occur when a DMA //! transfer is complete using the UART0 uDMA channel.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). //! //! \param None //! //! \return None //***************************************************************************** void UART0IntHandler(void) { unsigned long ulStatus; unsigned long ulMode; // // Read the interrupt status of the UART. // ulStatus = MAP_UARTIntStatus(UARTA0_BASE, 1); // // Clear any pending status, even though there should be none since no UART // interrupts were enabled. // MAP_UARTIntClear(UARTA0_BASE, ulStatus); if(uiCount<6) { // // 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 = MAP_uDMAChannelModeGet(UDMA_CH8_UARTA0_RX | 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. // 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. // UDMASetupTransfer(UDMA_CH8_UARTA0_RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, sizeof(g_ucRxBufA),UDMA_SIZE_8, UDMA_ARB_4, (void *)(UARTA0_BASE + UART_O_DR), UDMA_SRC_INC_NONE, g_ucRxBufA, UDMA_DST_INC_8); } // // 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 = MAP_uDMAChannelModeGet(UDMA_CH8_UARTA0_RX | 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. // 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. // UDMASetupTransfer(UDMA_CH8_UARTA0_RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, sizeof(g_ucRxBufB),UDMA_SIZE_8, UDMA_ARB_4,(void *)(UARTA0_BASE + UART_O_DR), UDMA_SRC_INC_NONE, g_ucRxBufB, UDMA_DST_INC_8); } // // If the UART0 DMA TX channel is disabled, that means the TX DMA transfer // is done. // if(!MAP_uDMAChannelIsEnabled(UDMA_CH9_UARTA0_TX)) { g_ulTxCount++; // // Start another DMA transfer to UART0 TX. // UDMASetupTransfer(UDMA_CH9_UARTA0_TX| UDMA_PRI_SELECT, UDMA_MODE_BASIC, sizeof(g_ucTxBuf),UDMA_SIZE_8, UDMA_ARB_4,g_ucTxBuf, UDMA_SRC_INC_8, (void *)(UARTA0_BASE + UART_O_DR), UDMA_DST_INC_NONE); // // The uDMA TX channel must be re-enabled. // MAP_uDMAChannelEnable(UDMA_CH9_UARTA0_TX); } } else { UARTDone=1; MAP_UARTIntUnregister(UARTA0_BASE); } }