revised code
Embed:
(wiki syntax)
Show/hide line numbers
UART_poll.cpp
Go to the documentation of this file.
00001 /**----------------------------------------------------------------------------- 00002 \file UART_poll.cpp 00003 00004 -- -- 00005 -- ECEN 5803 Mastering Embedded System Architecture -- 00006 -- Project 1 Module 3 -- 00007 -- Microcontroller Firmware -- 00008 -- UART_poll.c -- 00009 -- -- 00010 ------------------------------------------------------------------------------- 00011 -- 00012 -- Designed for: University of Colorado at Boulder 00013 -- 00014 -- 00015 -- Designed by: Tim Scherr 00016 -- Revised by: Student's name 00017 -- 00018 -- Version: 2.1 00019 -- Date of current revision: 2017-09-20 00020 -- Target Microcontroller: Freescale MKL25ZVMT4 00021 -- Tools used: ARM mbed compiler 00022 -- ARM mbed SDK 00023 -- Freescale FRDM-KL25Z Freedom Board 00024 -- 00025 -- 00026 -- Functional Description: This file contains routines that support messages 00027 -- to and from the UART port. Included are: 00028 -- Serial() - a routine to send/receive bytes on the UART port to 00029 -- the transmit/receive buffers 00030 -- UART_put() - a routine that puts a character in the transmit buffer 00031 -- UART_get() - a routine that gets the next character from the receive 00032 -- buffer 00033 -- UART_msg_put() - a routine that puts a string in the transmit buffer 00034 -- UART_direct_msg_put() - routine that sends a string out the UART port 00035 -- UART_input() - determines if a character has been received 00036 -- UART_hex_put() - a routine that puts a hex byte in the transmit buffer 00037 -- 00038 -- Copyright (c) 2015 Tim Scherr All rights reserved. 00039 -- 00040 */ 00041 00042 00043 00044 /*******************/ 00045 /* Configurations */ 00046 /*******************/ 00047 /* 00048 00049 */ 00050 00051 #include <stdio.h> 00052 #include "shared.h" 00053 #include "MKL25Z4.h" 00054 00055 // NOTE: UART0 is also called UARTLP in mbed 00056 #define OERR (UART0->S1 & UARTLP_S1_OR_MASK) // Overrun Error bit 00057 #define CREN (UART0->C2 & UARTLP_C2_RE_MASK) // continuous receive enable bit 00058 #define RCREG UART0->D // Receive Data Register 00059 #define FERR (UART0->S1 & UARTLP_S1_FE_MASK) // Framing Error bit 00060 #define RCIF (UART0->S1 & UARTLP_S1_RDRF_MASK) // Receive Interrupt Flag (full) 00061 #define TXIF (UART0->S1 & UARTLP_S1_TDRE_MASK) // Transmit Interrupt Flag (empty) 00062 #define TXREG UART0->D // Transmit Data Register 00063 #define TRMT (UART0->S1 & UARTLP_S1_TC_MASK) // Transmit Shift Register Empty 00064 00065 /*********************************** 00066 * Start of code * 00067 ***********************************/ 00068 00069 UCHAR error_count = 0; 00070 00071 /// \fn void serial(void) 00072 /// function polls the serial port for Rx or Tx data 00073 void serial(void) // The serial function polls the serial port for 00074 // received data or data to transmit 00075 { 00076 // deals with error handling first 00077 if ( OERR ) // if an overrun error, clear it and continue. 00078 { 00079 error_count++; 00080 // resets and sets continous receive enable bit 00081 UART0->C2 = UART0->C2 & (!UARTLP_C2_RE_MASK); 00082 UART0->C2 = UART0->C2 | UARTLP_C2_RE_MASK; 00083 } 00084 00085 if ( FERR){ // if a framing error, read bad byte, clear it and continue. 00086 error_count++; 00087 RCREG; // This will also clear RCIF if only one byte has been 00088 // received since the last int, which is our assumption. 00089 00090 // resets and sets continous receive enable bit 00091 UART0->C2 = UART0->C2 & (!UARTLP_C2_RE_MASK); 00092 UART0->C2 = UART0->C2 | UARTLP_C2_RE_MASK; 00093 } 00094 else // else if no frame error, 00095 { 00096 if ( RCIF ) // Check if we have received a byte 00097 { // Read byte to enable reception of more bytes 00098 // For PIC, RCIF automatically cleared when RCREG is read 00099 // Also true of Freescale KL25Z 00100 *rx_in_ptr++ = RCREG; /* get received character */ 00101 if( rx_in_ptr >= RX_BUF_SIZE + rx_buf ) 00102 { 00103 rx_in_ptr = rx_buf; /* if at end of buffer, circles rx_in_ptr 00104 to top of buffer */ 00105 } 00106 00107 } 00108 } 00109 00110 if (TXIF) // Check if transmit buffer empty 00111 { 00112 if ((tx_in_ptr != tx_out_ptr) && (display_mode != QUIET)) 00113 { 00114 TXREG = *tx_out_ptr++; /* send next char */ 00115 if( tx_out_ptr >= TX_BUF_SIZE + tx_buf ) 00116 tx_out_ptr = tx_buf; /* 0 <= tx_out_idx < TX_BUF_SIZE */ 00117 tx_in_progress = YES; /* flag needed to start up after idle */ 00118 } 00119 else 00120 { 00121 tx_in_progress = NO; /* no more to send */ 00122 } 00123 } 00124 // serial_count++; // increment serial counter, for debugging only 00125 serial_flag = 1; // and set flag 00126 } 00127 00128 /******************************************************************************* 00129 * The function UART_direct_msg_put puts a null terminated string directly 00130 * (no ram buffer) to the UART in ASCII format. 00131 *******************************************************************************/ 00132 void UART_direct_msg_put(const char *str) 00133 { 00134 while( *str != '\0' ) 00135 { 00136 TXREG = *str++; 00137 while( TXIF == 0 || TRMT == 0 ) // waits here for UART transmit buffer 00138 // to be empty 00139 { 00140 // __clear_watchdog_timer(); 00141 } 00142 } 00143 } 00144 00145 /******************************************************************************* 00146 * The function UART_put puts a byte, to the transmit buffer at the location 00147 * pointed to by tx_in_idx. The pointer is incremented circularly as described 00148 * previously. If the transmit buffer should wrap around (should be designed 00149 * not to happen), data will be lost. The serial interrupt must be temporarily 00150 * disabled since it reads tx_in_idx and this routine updates tx_in_idx which is 00151 * a 16 bit value. 00152 *******************************************************************************/ 00153 void UART_put(UCHAR c) 00154 { 00155 *tx_in_ptr++ = c; /* save character to transmit buffer */ 00156 if( tx_in_ptr >= TX_BUF_SIZE + tx_buf) 00157 tx_in_ptr = tx_buf; /* 0 <= tx_in_idx < TX_BUF_SIZE */ 00158 } 00159 00160 /******************************************************************************* 00161 * The function UART_get gets the next byte if one is available from the receive 00162 * buffer at the location pointed to by rx_out_idx. The pointer is circularly 00163 * incremented and the byte is returned in R7. Should no byte be available the 00164 * function will wait until one is available. There is no need to disable the 00165 * serial interrupt which modifies rx_in_idx since the function is looking for a 00166 * compare only between rx_in_idx & rx_out_idx. 00167 *******************************************************************************/ 00168 UCHAR UART_get(void) 00169 { 00170 UCHAR c; 00171 while( rx_in_ptr == rx_out_ptr ); /* wait for a received character, 00172 indicated */ 00173 // when pointers are different 00174 // this could be an infinite loop, but 00175 // is not because of UART_input check 00176 c = *rx_out_ptr++; 00177 if( rx_out_ptr >= RX_BUF_SIZE + rx_buf ) // if at end of buffer 00178 { 00179 rx_out_ptr = rx_buf; /* 0 <= rx_out_idx < RX_BUF_SIZE */ 00180 // return byte from beginning of buffer 00181 } // next time. 00182 return(c); 00183 } 00184 00185 /******************************************************************************* 00186 * The function UART_input returns a 1 if 1 or more receive byte(s) is(are) 00187 * available and a 0 if the receive buffer rx_buf is empty. There is no need to 00188 * disable the serial interrupt which modifies rx_in_idx since function is 00189 * looking for a compare only between rx_in_idx & rx_out_idx. 00190 *******************************************************************************/ 00191 UCHAR UART_input(void) 00192 { 00193 if( rx_in_ptr == rx_out_ptr ) 00194 return(0); /* no characters in receive buffer */ 00195 else 00196 return(1); /* 1 or more receive characters ready */ 00197 } 00198 00199 /******************************************************************************* 00200 * The function UART_msg_put puts a null terminated string through the transmit 00201 * buffer to the UART port in ASCII format. 00202 *******************************************************************************/ 00203 void UART_msg_put(const char *str) 00204 { 00205 while( *str != '\0' ) 00206 { 00207 *tx_in_ptr++ = *str++; /* save character to transmit buffer */ 00208 if( tx_in_ptr >= TX_BUF_SIZE + tx_buf) 00209 tx_in_ptr = tx_buf; /* 0 <= tx_in_idx < TX_BUF_SIZE */ 00210 } 00211 } 00212 00213 00214 /******************************************************************************* 00215 * The function UART_low_nibble_put puts the low nibble of a byte in hex through 00216 * the transmit buffer to the UART port. 00217 *******************************************************************************/ 00218 //void UART_low_nibble_put(UCHAR c) 00219 //{ 00220 // UART_put( hex_to_asc( c & 0x0f )); 00221 //} 00222 00223 /******************************************************************************* 00224 * The function UART_high_nibble_put puts the high nibble of a byte in h 00225 * UART port. 00226 *******************************************************************************/ 00227 //void UART_high_nibble_put(unsigned char c) 00228 //{ 00229 // UART_put( hex_to_asc( (c>>4) & 0x0f )); 00230 //} 00231 00232 /******************************************************************************* 00233 * HEX_TO_ASC Function 00234 * Function takes a single hex character (0 thru Fh) and converts to ASCII. 00235 ******************************************************************************/ 00236 UCHAR hex_to_asc(UCHAR c) 00237 { 00238 if( c <= 9 ) 00239 return( c + 0x30 ); 00240 return( ((c & 0x0f) + 0x37 )); /* add 37h */ 00241 } 00242 00243 /******************************************************************************* 00244 * ASC_TO_HEX Function 00245 * Function takes a single ASCII character and converts to hex. 00246 *******************************************************************************/ 00247 UCHAR asc_to_hex(UCHAR c) 00248 { 00249 if( c <= '9' ) 00250 return( c - 0x30 ); 00251 return( (c & 0xdf) - 0x37 ); /* clear bit 5 (lower case) & subtract 37h */ 00252 } 00253 00254 00255 /******************************************************************************* 00256 * The function UART_hex_put puts 1 byte in hex through the transmit buffer to 00257 * the UART port. 00258 *******************************************************************************/ 00259 void UART_hex_put(unsigned char c) 00260 { 00261 UART_put( hex_to_asc( (c>>4) & 0x0f )); // could eliminate & as >> of UCHAR 00262 // by definition clears upper bits. 00263 UART_put( hex_to_asc( c & 0x0f )); 00264 } 00265 00266 /******************************************************************************* 00267 * The function UART_direct_hex_put puts 1 byte in hex directly (no ram buffer) 00268 * to the UART. 00269 *******************************************************************************/ 00270 void UART_direct_hex_put(unsigned char c) 00271 { 00272 TXREG = hex_to_asc( (c>>4) & 0x0f ); 00273 while( TXIF == 0 ) 00274 { 00275 // __clear_watchdog_timer(); 00276 } 00277 TXREG = hex_to_asc( c & 0x0f ); 00278 while( TXIF == 0 ) 00279 { 00280 // __clear_watchdog_timer(); 00281 } 00282 } 00283 00284 /******************************************************************************* 00285 * The function UART_direct_hex_put_word puts 1 word in hex directly (no ram buffer) 00286 * to the UART. Used to display full words within registers and memory locations 00287 *******************************************************************************/ 00288 void UART_direct_hex_put_word(uint32_t c) 00289 { 00290 UART_direct_hex_put((c>>24)); 00291 UART_direct_hex_put((c>>16)); 00292 UART_direct_hex_put((c>>8)); 00293 UART_direct_hex_put((c)); 00294 } 00295 00296 00297
Generated on Tue Jul 12 2022 20:46:01 by
1.7.2