revised code

Dependencies:   mbed

UART_poll.cpp

Committer:
nmaududi
Date:
2019-10-05
Revision:
2:64a34ae90bb1
Parent:
1:9fa7cc80f1a7

File content as of revision 2:64a34ae90bb1:

/**-----------------------------------------------------------------------------
       \file UART_poll.cpp
       
--                                                                           --
--              ECEN 5803 Mastering Embedded System Architecture             --
--                  Project 1 Module 3                                       --
--                Microcontroller Firmware                                   --
--                      UART_poll.c                                          --
--                                                                           --
-------------------------------------------------------------------------------
--
--  Designed for:  University of Colorado at Boulder
--               
--                
--  Designed by:  Tim Scherr
--  Revised by:  Student's name 
-- 
-- Version: 2.1
-- Date of current revision:  2017-09-20   
-- Target Microcontroller: Freescale MKL25ZVMT4 
-- Tools used:  ARM mbed compiler
--              ARM mbed SDK
--              Freescale FRDM-KL25Z Freedom Board
--               
-- 
--  Functional Description:  This file contains routines that support messages
--    to and from the UART port.  Included are:
--       Serial() - a routine to send/receive bytes on the UART port to
--                      the transmit/receive buffers
--       UART_put()  - a routine that puts a character in the transmit buffer
--       UART_get()  - a routine that gets the next character from the receive
--                      buffer
--       UART_msg_put() - a routine that puts a string in the transmit buffer
--       UART_direct_msg_put() - routine that sends a string out the UART port
--       UART_input() - determines if a character has been received 
--       UART_hex_put() - a routine that puts a hex byte in the transmit buffer        
--
--      Copyright (c) 2015 Tim Scherr  All rights reserved.
--
*/              



/*******************/
/*  Configurations */
/*******************/
/*

*/

#include <stdio.h>
#include "shared.h"
#include "MKL25Z4.h"

// NOTE:  UART0 is also called UARTLP in mbed
#define OERR (UART0->S1 & UARTLP_S1_OR_MASK)   // Overrun Error bit
#define CREN (UART0->C2 & UARTLP_C2_RE_MASK)   // continuous receive enable bit
#define RCREG UART0->D                        // Receive Data Register
#define FERR (UART0->S1 & UARTLP_S1_FE_MASK)   // Framing Error bit
#define RCIF (UART0->S1 & UARTLP_S1_RDRF_MASK) // Receive Interrupt Flag (full)
#define TXIF (UART0->S1 & UARTLP_S1_TDRE_MASK) // Transmit Interrupt Flag (empty)
#define TXREG UART0->D                        // Transmit Data Register
#define TRMT (UART0->S1 & UARTLP_S1_TC_MASK)   // Transmit Shift Register Empty

/*********************************** 
 *        Start of code            * 
 ***********************************/
 
 UCHAR error_count = 0;
 
///  \fn void serial(void) 
/// function polls the serial port for Rx or Tx data
void serial(void)       // The serial function polls the serial port for 
                        // received data or data to transmit
{
                         // deals with error handling first
   if ( OERR )           // if an overrun error, clear it and continue.
   {
      error_count++;         
                            // resets and sets continous receive enable bit
      UART0->C2 = UART0->C2 & (!UARTLP_C2_RE_MASK);
      UART0->C2 = UART0->C2 | UARTLP_C2_RE_MASK;
   }
   
   if ( FERR){       // if a framing error, read bad byte, clear it and continue.
      error_count++;
      RCREG;         // This will also clear RCIF if only one byte has been 
                     // received since the last int, which is our assumption.
                     
                     // resets and sets continous receive enable bit
      UART0->C2 = UART0->C2 & (!UARTLP_C2_RE_MASK);
      UART0->C2 = UART0->C2 | UARTLP_C2_RE_MASK;
   }
   else              // else if no frame error,
   {
      if ( RCIF )   // Check if we have received a byte
      {             // Read byte to enable reception of more bytes
                    // For PIC, RCIF automatically cleared when RCREG is read
                    // Also true of Freescale KL25Z
         *rx_in_ptr++ = RCREG;         /* get received character */    
         if( rx_in_ptr >= RX_BUF_SIZE + rx_buf )
         {
            rx_in_ptr = rx_buf;    /* if at end of buffer, circles rx_in_ptr 
                                      to top of buffer */ 
         } 

      }     
   }
   
   if (TXIF)          //  Check if transmit buffer empty  
   {
      if ((tx_in_ptr != tx_out_ptr) && (display_mode != QUIET))
      {
         TXREG = *tx_out_ptr++;     /* send next char */
         if( tx_out_ptr >= TX_BUF_SIZE + tx_buf )
            tx_out_ptr = tx_buf;           /* 0 <= tx_out_idx < TX_BUF_SIZE */        
         tx_in_progress = YES;          /* flag needed to start up after idle */
      }
      else
      {
         tx_in_progress = NO;             /* no more to send */
      }
  }                   
//  serial_count++;         // increment serial counter, for debugging only
  serial_flag = 1;        // and set flag
}

/*******************************************************************************
* The function UART_direct_msg_put puts a null terminated string directly
* (no ram buffer) to the UART in ASCII format.
*******************************************************************************/
void UART_direct_msg_put(const char *str)
{
   while( *str != '\0' )
   {
      TXREG = *str++;
      while( TXIF == 0 || TRMT == 0 )  // waits here for UART transmit buffer
                                      // to be empty
      {
    //  __clear_watchdog_timer();
      }
   }
}

/*******************************************************************************
* The function UART_put puts a byte, to the transmit buffer at the location 
* pointed to by tx_in_idx.  The pointer is incremented circularly as described
* previously.  If the transmit buffer should wrap around (should be designed 
* not to happen), data will be lost.  The serial interrupt must be temporarily
* disabled since it reads tx_in_idx and this routine updates tx_in_idx which is 
* a 16 bit value.           
*******************************************************************************/
void UART_put(UCHAR c)
{
   *tx_in_ptr++ = c;                    /* save character to transmit buffer */
   if( tx_in_ptr >= TX_BUF_SIZE + tx_buf)
      tx_in_ptr = tx_buf;                     /* 0 <= tx_in_idx < TX_BUF_SIZE */          
}

/*******************************************************************************
* The function UART_get gets the next byte if one is available from the receive
* buffer at the location pointed to by rx_out_idx.  The pointer is circularly 
* incremented and the byte is returned in R7. Should no byte be available the 
* function will wait until one is available. There is no need to disable the 
* serial interrupt which modifies rx_in_idx since the function is looking for a 
* compare only between rx_in_idx & rx_out_idx.
*******************************************************************************/
UCHAR UART_get(void)
{
   UCHAR c;
   while( rx_in_ptr == rx_out_ptr );      /* wait for a received character, 
                                                                indicated */
                                          // when pointers are different
                                          // this could be an infinite loop, but 
                                          // is not because of UART_input check   
   c = *rx_out_ptr++;
   if( rx_out_ptr >= RX_BUF_SIZE + rx_buf )  // if at end of buffer
   {
      rx_out_ptr = rx_buf;                /* 0 <= rx_out_idx < RX_BUF_SIZE */        
                                        // return byte from beginning of buffer
   }                                    // next time.  
   return(c);
}

/*******************************************************************************
* The function UART_input returns a 1 if 1 or more receive byte(s) is(are) 
* available and a 0 if the receive buffer rx_buf is empty.  There is no need to 
* disable the serial interrupt which modifies rx_in_idx since function is 
* looking for a compare only between rx_in_idx & rx_out_idx.
*******************************************************************************/
UCHAR UART_input(void)
{
   if( rx_in_ptr == rx_out_ptr )
      return(0);                          /* no characters in receive buffer */
   else
      return(1);                        /* 1 or more receive characters ready */
}

/*******************************************************************************
* The function UART_msg_put puts a null terminated string through the transmit
* buffer to the UART port in ASCII format.
*******************************************************************************/
void UART_msg_put(const char *str)
{
   while( *str != '\0' )
   {
      *tx_in_ptr++ = *str++;        /* save character to transmit buffer */
      if( tx_in_ptr >= TX_BUF_SIZE + tx_buf)
         tx_in_ptr = tx_buf;                  /* 0 <= tx_in_idx < TX_BUF_SIZE */        
   }   
}


/*******************************************************************************
* The function UART_low_nibble_put puts the low nibble of a byte in hex through
* the transmit buffer to the UART port.             
*******************************************************************************/
//void UART_low_nibble_put(UCHAR c)
//{
//   UART_put( hex_to_asc( c & 0x0f ));
//}

/*******************************************************************************
* The function UART_high_nibble_put puts the high nibble of a byte in h
* UART port.
*******************************************************************************/
//void UART_high_nibble_put(unsigned char c)
//{
//   UART_put( hex_to_asc( (c>>4) & 0x0f ));
//}

/*******************************************************************************
* HEX_TO_ASC Function
* Function takes a single hex character (0 thru Fh) and converts to ASCII.
******************************************************************************/
UCHAR hex_to_asc(UCHAR c)
{
   if( c <= 9 )
      return( c + 0x30 );
   return( ((c & 0x0f) + 0x37 ));        /* add 37h */
}

/*******************************************************************************
* ASC_TO_HEX Function
* Function takes a single ASCII character and converts to hex.
*******************************************************************************/
UCHAR asc_to_hex(UCHAR c)
{
   if( c <= '9' )
      return( c - 0x30 );
   return( (c & 0xdf) - 0x37 );    /* clear bit 5 (lower case) & subtract 37h */
}


/*******************************************************************************
* The function UART_hex_put puts 1 byte in hex through the transmit buffer to 
* the UART port.
*******************************************************************************/
void UART_hex_put(unsigned char c)
{
   UART_put( hex_to_asc( (c>>4) & 0x0f ));  // could eliminate & as >> of UCHAR
                                             // by definition clears upper bits.
   UART_put( hex_to_asc( c & 0x0f ));
}

/*******************************************************************************
* The function UART_direct_hex_put puts 1 byte in hex directly (no ram buffer) 
* to the UART.
*******************************************************************************/
void UART_direct_hex_put(unsigned char c)
{
   TXREG = hex_to_asc( (c>>4) & 0x0f );
   while( TXIF == 0 )
   {
    //  __clear_watchdog_timer();
   }
   TXREG = hex_to_asc( c & 0x0f );
   while( TXIF == 0 )
   {
    //  __clear_watchdog_timer();
   }
}

/*******************************************************************************
* The function UART_direct_hex_put_word puts 1 word in hex directly (no ram buffer) 
* to the UART. Used to display full words within registers and memory locations
*******************************************************************************/
void UART_direct_hex_put_word(uint32_t c)
{
   UART_direct_hex_put((c>>24));
     UART_direct_hex_put((c>>16));
     UART_direct_hex_put((c>>8));
     UART_direct_hex_put((c));
}