Matt Lloyd
/
DMA_UART_example
Example of UART-DMA transfers taken form the npx cmsis driver libary
Embed:
(wiki syntax)
Show/hide line numbers
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 */
Generated on Tue Jul 12 2022 10:57:55 by 1.7.2