Naved Maududi
/
DebugMonitor_revised
Diff: UART_poll.cpp
- Revision:
- 0:4fb921928934
- Child:
- 1:9fa7cc80f1a7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/UART_poll.cpp Fri Oct 04 21:09:15 2019 +0000 @@ -0,0 +1,285 @@ +/**----------------------------------------------------------------------------- + \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(); + } +} + + +