revised code

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UART_poll.cpp Source File

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