Port of Keils USBCDC example, compiles ok. Gets stuck at init
Embed:
(wiki syntax)
Show/hide line numbers
serial.c
00001 /*---------------------------------------------------------------------------- 00002 * Name: serial.c 00003 * Purpose: serial port handling for LPC17xx 00004 * Version: V1.20 00005 *---------------------------------------------------------------------------- 00006 * This software is supplied "AS IS" without any warranties, express, 00007 * implied or statutory, including but not limited to the implied 00008 * warranties of fitness for purpose, satisfactory quality and 00009 * noninfringement. Keil extends you a royalty-free right to reproduce 00010 * and distribute executable files created using this software for use 00011 * on NXP Semiconductors LPC microcontroller devices only. Nothing else 00012 * gives you the right to use this software. 00013 * 00014 * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. 00015 *---------------------------------------------------------------------------*/ 00016 #include "LPC17xx.h" // LPC17xx definitions 00017 //#include "LPC23xx.h" 00018 #include "type.h" 00019 #include "serial.h" 00020 00021 #include "compatible.h" 00022 00023 /*---------------------------------------------------------------------------- 00024 Defines for ring buffers 00025 *---------------------------------------------------------------------------*/ 00026 #define SER_BUF_SIZE (128) // serial buffer in bytes (power 2) 00027 #define SER_BUF_MASK (SER_BUF_SIZE-1ul) // buffer size mask 00028 00029 /* Buffer read / write macros */ 00030 #define SER_BUF_RESET(serBuf) (serBuf.rdIdx = serBuf.wrIdx = 0) 00031 #define SER_BUF_WR(serBuf, dataIn) (serBuf.data[SER_BUF_MASK & serBuf.wrIdx++] = (dataIn)) 00032 #define SER_BUF_RD(serBuf) (serBuf.data[SER_BUF_MASK & serBuf.rdIdx++]) 00033 #define SER_BUF_EMPTY(serBuf) (serBuf.rdIdx == serBuf.wrIdx) 00034 #define SER_BUF_FULL(serBuf) (serBuf.rdIdx == serBuf.wrIdx+1) 00035 #define SER_BUF_COUNT(serBuf) (SER_BUF_MASK & (serBuf.wrIdx - serBuf.rdIdx)) 00036 00037 // buffer type 00038 typedef struct __SER_BUF_T { 00039 unsigned char data[SER_BUF_SIZE]; 00040 unsigned int wrIdx; 00041 unsigned int rdIdx; 00042 } SER_BUF_T; 00043 00044 unsigned long ser_txRestart; // NZ if TX restart is required 00045 unsigned short ser_lineState; // ((msr << 8) | (lsr)) 00046 SER_BUF_T ser_out; // Serial data buffers 00047 SER_BUF_T ser_in; 00048 00049 /*---------------------------------------------------------------------------- 00050 open the serial port 00051 *---------------------------------------------------------------------------*/ 00052 void ser_OpenPort (char portNum) { 00053 00054 if ( portNum == 0 ) 00055 { 00056 /* Port 0 */ 00057 NVIC_DisableIRQ(UART0_IRQn); 00058 LPC_PINCON->PINSEL0 &= ~0x000000F0; 00059 LPC_PINCON->PINSEL0 |= 0x00000050; /* RxD0 is P0.3 and TxD0 is P0.2 */ 00060 } 00061 else 00062 { 00063 /* Port 1 */ 00064 NVIC_DisableIRQ(UART1_IRQn); 00065 LPC_PINCON->PINSEL4 &= ~0x0000000F; 00066 LPC_PINCON->PINSEL4 |= 0x0000000A; /* Enable RxD1 P2.1, TxD1 P2.0 */ 00067 } 00068 return; 00069 } 00070 00071 /*---------------------------------------------------------------------------- 00072 close the serial port 00073 *---------------------------------------------------------------------------*/ 00074 void ser_ClosePort (char portNum ) { 00075 if ( portNum == 0 ) 00076 { 00077 /* POrt 0 */ 00078 LPC_PINCON->PINSEL0 &= ~0x000000F0; 00079 /* Disable the interrupt in the VIC and UART controllers */ 00080 LPC_UART0->IER = 0; 00081 NVIC_DisableIRQ(UART0_IRQn); 00082 } 00083 else 00084 { 00085 /* Port 1 */ 00086 LPC_PINCON->PINSEL4 &= ~0x0000000F; 00087 /* Disable the interrupt in the VIC and UART controllers */ 00088 LPC_UART1->IER = 0; 00089 NVIC_DisableIRQ(UART1_IRQn); 00090 } 00091 return; 00092 } 00093 00094 /*---------------------------------------------------------------------------- 00095 initialize the serial port 00096 *---------------------------------------------------------------------------*/ 00097 void ser_InitPort0 (unsigned long baudrate, unsigned int databits, 00098 unsigned int parity, unsigned int stopbits) { 00099 00100 unsigned char lcr_p, lcr_s, lcr_d; 00101 unsigned int dll; 00102 unsigned int pclkdiv, pclk; 00103 00104 switch (databits) { 00105 case 5: // 5 Data bits 00106 lcr_d = 0x00; 00107 break; 00108 case 6: // 6 Data bits 00109 lcr_d = 0x01; 00110 break; 00111 case 7: // 7 Data bits 00112 lcr_d = 0x02; 00113 break; 00114 case 8: // 8 Data bits 00115 default: 00116 lcr_d = 0x03; 00117 break; 00118 } 00119 00120 switch (stopbits) { 00121 case 1: // 1,5 Stop bits 00122 case 2: // 2 Stop bits 00123 lcr_s = 0x04; 00124 break; 00125 case 0: // 1 Stop bit 00126 default: 00127 lcr_s = 0x00; 00128 break; 00129 } 00130 00131 switch (parity) { 00132 case 1: // Parity Odd 00133 lcr_p = 0x08; 00134 break; 00135 case 2: // Parity Even 00136 lcr_p = 0x18; 00137 break; 00138 case 3: // Parity Mark 00139 lcr_p = 0x28; 00140 break; 00141 case 4: // Parity Space 00142 lcr_p = 0x38; 00143 break; 00144 case 0: // Parity None 00145 default: 00146 lcr_p = 0x00; 00147 break; 00148 } 00149 00150 SER_BUF_RESET(ser_out); // reset out buffer 00151 SER_BUF_RESET(ser_in); // reset in buffer 00152 00153 /* Bit 6~7 is for UART0 */ 00154 pclkdiv = (LPC_SC->PCLKSEL0 >> 6) & 0x03; 00155 00156 switch ( pclkdiv ) 00157 { 00158 case 0x00: 00159 default: 00160 pclk = SystemFrequency/4; 00161 break; 00162 case 0x01: 00163 pclk = SystemFrequency; 00164 break; 00165 case 0x02: 00166 pclk = SystemFrequency/2; 00167 break; 00168 case 0x03: 00169 pclk = SystemFrequency/8; 00170 break; 00171 } 00172 00173 dll = (pclk/16)/baudrate ; /*baud rate */ 00174 LPC_UART0->FDR = 0; // Fractional divider not used 00175 LPC_UART0->LCR = 0x80 | lcr_d | lcr_p | lcr_s; // Data bits, Parity, Stop bit 00176 LPC_UART0->DLL = dll; // Baud Rate depending on PCLK 00177 LPC_UART0->DLM = (dll >> 8); // High divisor latch 00178 LPC_UART0->LCR = 0x00 | lcr_d | lcr_p | lcr_s; // DLAB = 0 00179 LPC_UART0->IER = 0x03; // Enable TX/RX interrupts 00180 00181 LPC_UART0->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ 00182 ser_txRestart = 1; // TX fifo is empty 00183 00184 /* Enable the UART Interrupt */ 00185 NVIC_EnableIRQ(UART0_IRQn); 00186 return; 00187 } 00188 00189 /*---------------------------------------------------------------------------- 00190 initialize the serial port 00191 *---------------------------------------------------------------------------*/ 00192 void ser_InitPort1 (unsigned long baudrate, unsigned int databits, 00193 unsigned int parity, unsigned int stopbits) { 00194 00195 unsigned char lcr_p, lcr_s, lcr_d; 00196 unsigned int dll; 00197 unsigned int pclkdiv, pclk; 00198 00199 switch (databits) { 00200 case 5: // 5 Data bits 00201 lcr_d = 0x00; 00202 break; 00203 case 6: // 6 Data bits 00204 lcr_d = 0x01; 00205 break; 00206 case 7: // 7 Data bits 00207 lcr_d = 0x02; 00208 break; 00209 case 8: // 8 Data bits 00210 default: 00211 lcr_d = 0x03; 00212 break; 00213 } 00214 00215 switch (stopbits) { 00216 case 1: // 1,5 Stop bits 00217 case 2: // 2 Stop bits 00218 lcr_s = 0x04; 00219 break; 00220 case 0: // 1 Stop bit 00221 default: 00222 lcr_s = 0x00; 00223 break; 00224 } 00225 00226 switch (parity) { 00227 case 1: // Parity Odd 00228 lcr_p = 0x08; 00229 break; 00230 case 2: // Parity Even 00231 lcr_p = 0x18; 00232 break; 00233 case 3: // Parity Mark 00234 lcr_p = 0x28; 00235 break; 00236 case 4: // Parity Space 00237 lcr_p = 0x38; 00238 break; 00239 case 0: // Parity None 00240 default: 00241 lcr_p = 0x00; 00242 break; 00243 } 00244 00245 SER_BUF_RESET(ser_out); // reset out buffer 00246 SER_BUF_RESET(ser_in); // reset in buffer 00247 00248 /* Bit 8,9 are for UART1 */ 00249 pclkdiv = (LPC_SC->PCLKSEL0 >> 8) & 0x03; 00250 00251 switch ( pclkdiv ) 00252 { 00253 case 0x00: 00254 default: 00255 pclk = SystemFrequency/4; 00256 break; 00257 case 0x01: 00258 pclk = SystemFrequency; 00259 break; 00260 case 0x02: 00261 pclk = SystemFrequency/2; 00262 break; 00263 case 0x03: 00264 pclk = SystemFrequency/8; 00265 break; 00266 } 00267 00268 dll = (pclk/16)/baudrate ; /*baud rate */ 00269 LPC_UART1->FDR = 0; // Fractional divider not used 00270 LPC_UART1->LCR = 0x80 | lcr_d | lcr_p | lcr_s; // Data bits, Parity, Stop bit 00271 LPC_UART1->DLL = dll; // Baud Rate depending on PCLK 00272 LPC_UART1->DLM = (dll >> 8); // High divisor latch 00273 LPC_UART1->LCR = 0x00 | lcr_d | lcr_p | lcr_s; // DLAB = 0 00274 LPC_UART1->IER = 0x03; // Enable TX/RX interrupts 00275 00276 LPC_UART1->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ 00277 ser_txRestart = 1; // TX fifo is empty 00278 00279 /* Enable the UART Interrupt */ 00280 NVIC_EnableIRQ(UART1_IRQn); 00281 return; 00282 } 00283 00284 /*---------------------------------------------------------------------------- 00285 read data from serial port 00286 *---------------------------------------------------------------------------*/ 00287 int ser_Read (char *buffer, const int *length) { 00288 int bytesToRead, bytesRead; 00289 00290 /* Read *length bytes, block if *bytes are not avaialable */ 00291 bytesToRead = *length; 00292 bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length); 00293 bytesRead = bytesToRead; 00294 00295 while (bytesToRead--) { 00296 while (SER_BUF_EMPTY(ser_in)); // Block until data is available if none 00297 *buffer++ = SER_BUF_RD(ser_in); 00298 } 00299 return (bytesRead); 00300 } 00301 00302 /*---------------------------------------------------------------------------- 00303 write data to the serial port 00304 *---------------------------------------------------------------------------*/ 00305 int ser_Write (char portNum, const char *buffer, int *length) { 00306 int bytesToWrite, bytesWritten; 00307 00308 // Write *length bytes 00309 bytesToWrite = *length; 00310 bytesWritten = bytesToWrite; 00311 00312 while (!SER_BUF_EMPTY(ser_out)); // Block until space is available if none 00313 while (bytesToWrite) { 00314 SER_BUF_WR(ser_out, *buffer++); // Read Rx FIFO to buffer 00315 bytesToWrite--; 00316 } 00317 00318 if (ser_txRestart) { 00319 ser_txRestart = 0; 00320 if ( portNum == 0 ) 00321 { 00322 LPC_UART0->THR = SER_BUF_RD(ser_out); // Write to the Tx Register 00323 } 00324 else 00325 { 00326 LPC_UART1->THR = SER_BUF_RD(ser_out); // Write to the Tx Register 00327 } 00328 } 00329 00330 return (bytesWritten); 00331 } 00332 00333 /*---------------------------------------------------------------------------- 00334 check if character(s) are available at the serial interface 00335 *---------------------------------------------------------------------------*/ 00336 void ser_AvailChar (int *availChar) { 00337 00338 *availChar = SER_BUF_COUNT(ser_in); 00339 00340 } 00341 00342 /*---------------------------------------------------------------------------- 00343 read the line state of the serial port 00344 *---------------------------------------------------------------------------*/ 00345 void ser_LineState (unsigned short *lineState) { 00346 00347 *lineState = ser_lineState; 00348 ser_lineState = 0; 00349 00350 } 00351 00352 /*---------------------------------------------------------------------------- 00353 serial port 0 interrupt 00354 *---------------------------------------------------------------------------*/ 00355 void UART0_IRQHandler(void) 00356 { 00357 volatile unsigned long iir; 00358 00359 iir = LPC_UART0->IIR; 00360 00361 if ((iir & 0x4) || (iir & 0xC)) { // RDA or CTI pending 00362 while (LPC_UART0->LSR & 0x01) { // Rx FIFO is not empty 00363 SER_BUF_WR(ser_in, LPC_UART0->RBR); // Read Rx FIFO to buffer 00364 } 00365 } 00366 if ((iir & 0x2)) { // TXMIS pending 00367 if (SER_BUF_COUNT(ser_out) != 0) { 00368 LPC_UART0->THR = SER_BUF_RD(ser_out); // Write to the Tx FIFO 00369 ser_txRestart = 0; 00370 } 00371 else { 00372 ser_txRestart = 1; 00373 } 00374 } 00375 ser_lineState = LPC_UART0->LSR & 0x1E; // update linestate 00376 return; 00377 } 00378 00379 /*---------------------------------------------------------------------------- 00380 serial port 1 interrupt 00381 *---------------------------------------------------------------------------*/ 00382 void UART1_IRQHandler(void) 00383 { 00384 volatile unsigned long iir; 00385 00386 iir = LPC_UART1->IIR; 00387 00388 if ((iir & 0x4) || (iir & 0xC)) { // RDA or CTI pending 00389 while (LPC_UART1->LSR & 0x01) { // Rx FIFO is not empty 00390 SER_BUF_WR(ser_in, LPC_UART1->RBR); // Read Rx FIFO to buffer 00391 } 00392 } 00393 if ((iir & 0x2)) { // TXMIS pending 00394 if (SER_BUF_COUNT(ser_out) != 0) { 00395 LPC_UART1->THR = SER_BUF_RD(ser_out); // Write to the Tx FIFO 00396 ser_txRestart = 0; 00397 } 00398 else { 00399 ser_txRestart = 1; 00400 } 00401 } 00402 ser_lineState = ((LPC_UART1->MSR<<8)|LPC_UART1->LSR) & 0xE01E; // update linestate 00403 return; 00404 } 00405 00406
Generated on Thu Jul 14 2022 04:45:41 by
1.7.2