Example of UART-DMA transfers taken form the npx cmsis driver libary

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers uart_dma_test.c Source File

uart_dma_test.c

Go to the documentation of this file.
00001 /***********************************************************************//**
00002  * tweaked by dps.lwk to work with mbed's online complier
00003  * 30/09/2010
00004  **********************************************************************/ 
00005 
00006 /***********************************************************************//**
00007  * @file        uart_dma_test.c
00008  * @purpose        This example describes how to using UART in DMA mode
00009  * @version        2.0
00010  * @date        21. May. 2010
00011  * @author        NXP MCU SW Application Team
00012  *---------------------------------------------------------------------
00013  * Software that is described herein is for illustrative purposes only
00014  * which provides customers with programming information regarding the
00015  * products. This software is supplied "AS IS" without any warranties.
00016  * NXP Semiconductors assumes no responsibility or liability for the
00017  * use of the software, conveys no license or title under any patent,
00018  * copyright, or mask work right to the product. NXP Semiconductors
00019  * reserves the right to make changes in the software without
00020  * notification. NXP Semiconductors also make no representation or
00021  * warranty that such application will be suitable for the specified
00022  * use without further testing or modification.
00023  **********************************************************************/
00024 #include "lpc17xx_uart.h"
00025 #include "lpc17xx_libcfg.h"
00026 #include "lpc17xx_gpdma.h"
00027 #include "lpc17xx_pinsel.h"
00028 
00029 /* Example group ----------------------------------------------------------- */
00030 /** @defgroup UART_DMA    DMA
00031  * @ingroup UART_Examples
00032  * @{
00033  */
00034 
00035 /************************** PRIVATE DEFINITIONS *************************/
00036 /* Receive buffer size */
00037 #define RX_BUF_SIZE    0x80     // ***LWK*** uped buffer to 128bytes
00038 
00039 /************************** PRIVATE VARIABLES *************************/
00040 uint8_t menu1[] =
00041 "Hello NXP Semiconductors \n\r"
00042 "UART interrupt mode demo using ring buffer \n\r\t "
00043 "MCU LPC17xx - ARM Cortex-M3 \n\r\t "
00044 "UART0 - 9600bps \n\r"
00045 " This is a long string. It transferred in to DMA memory and transmit through Tx line \n\r"
00046 " on UART0 peripheral. To use UART with DMA mode, FIFO function must be enabled \n\r";
00047 
00048 uint8_t menu3[] = "UART demo terminated!\n";
00049 
00050 // Receive buffer
00051 __IO uint8_t rx_buf[RX_BUF_SIZE];
00052 
00053 // Terminal Counter flag for Channel 0
00054 __IO uint32_t Channel0_TC;
00055 
00056 // Error Counter flag for Channel 0
00057 __IO uint32_t Channel0_Err;
00058 
00059 // Terminal Counter flag for Channel 1
00060 __IO uint32_t Channel1_TC;
00061 
00062 // Error Counter flag for Channel 1
00063 __IO uint32_t Channel1_Err;
00064 
00065 
00066 /************************** PRIVATE FUNCTIONS *************************/
00067 extern "C" void DMA_IRQHandler (void);          // ***LWK*** mbed requires IRQHandeler to be extern "C"
00068 
00069 void print_menu(void);
00070 
00071 /*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/
00072 /*********************************************************************//**
00073  * @brief        GPDMA interrupt handler sub-routine
00074  * @param[in]    None
00075  * @return         None
00076  **********************************************************************/
00077 void DMA_IRQHandler (void)
00078 {
00079     
00080   
00081     uint32_t tmp;
00082         // Scan interrupt pending
00083     for (tmp = 0; tmp <= 7; tmp++) {
00084         if (GPDMA_IntGetStatus(GPDMA_STAT_INT, tmp)){
00085             // Check counter terminal status
00086             if(GPDMA_IntGetStatus(GPDMA_STAT_INTTC, tmp)){
00087                 // Clear terminate counter Interrupt pending
00088                 GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, tmp);
00089 
00090                 switch (tmp){
00091                     case 0:
00092                         Channel0_TC++;
00093                         GPDMA_ChannelCmd(0, DISABLE);
00094                         break;
00095                     case 1:
00096                         Channel1_TC++;
00097                         GPDMA_ChannelCmd(1, DISABLE);
00098                         break;
00099                     default:
00100                         break;
00101                 }
00102 
00103             }
00104                 // Check error terminal status
00105             if (GPDMA_IntGetStatus(GPDMA_STAT_INTERR, tmp)){
00106                 // Clear error counter Interrupt pending
00107                 GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, tmp);
00108                 switch (tmp){
00109                     case 0:
00110                         Channel0_Err++;
00111                         GPDMA_ChannelCmd(0, DISABLE);
00112                         break;
00113                     case 1:
00114                         Channel1_Err++;
00115                         GPDMA_ChannelCmd(1, DISABLE);
00116                         break;
00117                     default:
00118                         break;
00119                 }
00120             }
00121         }
00122     }
00123 }
00124 
00125 /*-------------------------MAIN FUNCTION------------------------------*/
00126 /*********************************************************************//**
00127  * @brief        c_entry: Main UART program body
00128  * @param[in]    None
00129  * @return         int
00130  **********************************************************************/
00131 int c_entry(void)
00132 {
00133     uint8_t *rx_char;
00134     uint32_t idx;
00135     // UART Configuration structure variable
00136     UART_CFG_Type UARTConfigStruct;
00137     // UART FIFO configuration Struct variable
00138     UART_FIFO_CFG_Type UARTFIFOConfigStruct;
00139     GPDMA_Channel_CFG_Type GPDMACfg;
00140     // Pin configuration for UART0
00141     PINSEL_CFG_Type PinCfg;
00142 
00143     // ***LWK*** setup pins for debug leds
00144     LPC_GPIO1->FIODIR |= 0xb40000;
00145     LPC_GPIO1->FIOMASK = 0xff4bffff;
00146 
00147     /*
00148      * Initialize UART0 pin connect
00149      */
00150     PinCfg.Funcnum = 1;
00151     PinCfg.OpenDrain = 0;
00152     PinCfg.Pinmode = 0;
00153     PinCfg.Pinnum = 2;
00154     PinCfg.Portnum = 0;
00155     PINSEL_ConfigPin(&PinCfg);
00156     PinCfg.Pinnum = 3;
00157     PINSEL_ConfigPin(&PinCfg);
00158 
00159     /* Initialize UART Configuration parameter structure to default state:
00160      * Baudrate = 9600bps
00161      * 8 data bit
00162      * 1 Stop bit
00163      * None parity
00164      */
00165     UART_ConfigStructInit(&UARTConfigStruct);
00166 
00167     // Initialize UART0 peripheral with given to corresponding parameter
00168     UART_Init((LPC_UART_TypeDef *)LPC_UART0, &UARTConfigStruct);
00169 
00170 
00171     /* Initialize FIFOConfigStruct to default state:
00172      *                 - FIFO_DMAMode = DISABLE
00173      *                 - FIFO_Level = UART_FIFO_TRGLEV0
00174      *                 - FIFO_ResetRxBuf = ENABLE
00175      *                 - FIFO_ResetTxBuf = ENABLE
00176      *                 - FIFO_State = ENABLE
00177      */
00178     UART_FIFOConfigStructInit(&UARTFIFOConfigStruct);
00179 
00180     // Enable DMA mode in UART
00181     UARTFIFOConfigStruct.FIFO_DMAMode = ENABLE;
00182 
00183     // Initialize FIFO for UART0 peripheral
00184     UART_FIFOConfig((LPC_UART_TypeDef *)LPC_UART0, &UARTFIFOConfigStruct);
00185 
00186     // Enable UART Transmit
00187     UART_TxCmd((LPC_UART_TypeDef *)LPC_UART0, ENABLE);
00188 
00189 
00190     /* GPDMA Interrupt configuration section ------------------------------------------------- */
00191 
00192     /* Initialize GPDMA controller */
00193     GPDMA_Init();
00194 
00195 
00196     /* Setting GPDMA interrupt */
00197     // Disable interrupt for DMA
00198     NVIC_DisableIRQ (DMA_IRQn);
00199     /* preemption = 1, sub-priority = 1 */
00200     NVIC_SetPriority(DMA_IRQn, ((0x01<<3)|0x01));
00201 
00202 
00203     // Setup GPDMA channel --------------------------------
00204     // channel 0
00205     GPDMACfg.ChannelNum = 0;
00206     // Source memory
00207     GPDMACfg.SrcMemAddr = (uint32_t) &menu1;
00208     // Destination memory - don't care
00209     GPDMACfg.DstMemAddr = 0;
00210     // Transfer size
00211     GPDMACfg.TransferSize = sizeof(menu1);
00212     // Transfer width - don't care
00213     GPDMACfg.TransferWidth = 0;
00214     // Transfer type
00215     GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_M2P;
00216     // Source connection - don't care
00217     GPDMACfg.SrcConn = 0;
00218     // Destination connection
00219     GPDMACfg.DstConn = GPDMA_CONN_UART0_Tx;
00220     // Linker List Item - unused
00221     GPDMACfg.DMALLI = 0;
00222     // Setup channel with given parameter
00223     GPDMA_Setup(&GPDMACfg);
00224 
00225     // Setup GPDMA channel --------------------------------
00226     // channel 1
00227     GPDMACfg.ChannelNum = 1;
00228     // Source memory - don't care
00229     GPDMACfg.SrcMemAddr = 0;
00230     // Destination memory
00231     GPDMACfg.DstMemAddr = (uint32_t) &rx_buf;
00232     // Transfer size
00233     GPDMACfg.TransferSize = sizeof(rx_buf);
00234     // Transfer width - don't care
00235     GPDMACfg.TransferWidth = 0;
00236     // Transfer type
00237     GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_P2M;
00238     // Source connection
00239     GPDMACfg.SrcConn = GPDMA_CONN_UART0_Rx;
00240     // Destination connection - don't care
00241     GPDMACfg.DstConn = 0;
00242     // Linker List Item - unused
00243     GPDMACfg.DMALLI = 0;
00244     GPDMA_Setup(&GPDMACfg);
00245 
00246     /* Reset terminal counter */
00247     Channel0_TC = 0;
00248     /* Reset Error counter */
00249     Channel0_Err = 0;
00250 
00251     // Enable interrupt for DMA
00252     NVIC_EnableIRQ (DMA_IRQn);
00253 
00254     // ***LWK*** First debug LED1 on
00255     LPC_GPIO1->FIOSET = (1<<18);
00256     
00257     // Enable GPDMA channel 0
00258     GPDMA_ChannelCmd(0, ENABLE);
00259     // Make sure GPDMA channel 1 is disabled
00260     GPDMA_ChannelCmd(1, DISABLE);
00261     
00262     // ***LWK*** DEBUG LED 2 on
00263     LPC_GPIO1->FIOSET = (1<<20);
00264     
00265     
00266     /* Wait for GPDMA on UART0 Tx processing complete */
00267     while ((Channel0_TC == 0) && (Channel0_Err == 0));          // ***LWK*** got stuck here!!! untill i found out the IRQHandeler needed extern "C"
00268     
00269     // ***LWK** LED 1 off
00270     LPC_GPIO1->FIOCLR = (1<<18);
00271     
00272     LPC_GPIO1->FIOCLR = (11<<20);    
00273     // Main loop - echos back to the terminal
00274     while (1)
00275     {
00276         //***LWK*** debug LED
00277 
00278         LPC_GPIO1->FIOSET = (1<<21);  //***LWK*** led 3 in while
00279     
00280         /* Reset terminal counter */
00281         Channel1_TC = 0;
00282         /* Reset Error counter */
00283         Channel1_Err = 0;
00284 
00285         // Setup channel with given parameter
00286         GPDMA_Setup(&GPDMACfg);
00287 
00288         // Enable GPDMA channel 1
00289         GPDMA_ChannelCmd(1, ENABLE);
00290 
00291         // Clear Rx buffer using DMA
00292         for (idx = 0; idx < RX_BUF_SIZE; idx++){
00293             rx_buf[idx] = 0;
00294         }
00295         
00296 
00297         
00298         // now, start receive character using GPDMA
00299         rx_char = (uint8_t *) &rx_buf;
00300         while ((Channel1_TC == 0) && (Channel1_Err == 0)){
00301             // Check whether if there's any character received, then print it back
00302             if (*rx_char != 0)
00303             {
00304                 UART_Send((LPC_UART_TypeDef *)LPC_UART0, rx_char, 1, BLOCKING);
00305         
00306                 //***LWK*** debug LED
00307     //            LPC_GPIO1->FIOSET = (1<<21);    
00308                 rx_char++;
00309             }
00310         }
00311         
00312         //***LWK*** debug LED out of while eithe tc or err
00313         LPC_GPIO1->FIOSET = (1<<23);
00314         
00315     }
00316 
00317     //***LWK*** debug LED
00318  //   LPC_GPIO1->FIOSET = (1<<23);
00319 
00320     // DeInitialize UART0 peripheral
00321     UART_DeInit((LPC_UART_TypeDef *)LPC_UART0);
00322 
00323     /* Loop forever */
00324     while(1);
00325     return 1;
00326 }
00327 
00328 /* With ARM and GHS toolsets, the entry point is main() - this will
00329    allow the linker to generate wrapper code to setup stacks, allocate
00330    heap area, and initialize and copy code and data segments. For GNU
00331    toolsets, the entry point is through __start() in the crt0_gnu.asm
00332    file, and that startup code will setup stacks and data */
00333 int main(void)
00334 {
00335     return c_entry();
00336 }
00337 
00338 
00339 #ifdef  DEBUG
00340 /*******************************************************************************
00341 * @brief        Reports the name of the source file and the source line number
00342 *                 where the CHECK_PARAM error has occurred.
00343 * @param[in]    file Pointer to the source file name
00344 * @param[in]    line assert_param error line source number
00345 * @return        None
00346 *******************************************************************************/
00347 void check_failed(uint8_t *file, uint32_t line)
00348 {
00349     /* User can add his own implementation to report the file name and line number,
00350      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
00351 
00352     /* Infinite loop */
00353     while(1);
00354 }
00355 #endif
00356 
00357 /*
00358  * @}
00359  */