Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Revision 0:58bc93cc5d0f, committed 2018-02-28
- Comitter:
- gabinader
- Date:
- Wed Feb 28 05:49:24 2018 +0000
- Commit message:
- final for module 4
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Monitor.cpp Wed Feb 28 05:49:24 2018 +0000
@@ -0,0 +1,570 @@
+/**----------------------------------------------------------------------------
+ \file Monitor.cpp
+-- --
+-- ECEN 5003 Mastering Embedded System Architecture --
+-- Project 1 Module 3 --
+-- Microcontroller Firmware --
+-- Monitor.cpp --
+-- --
+-------------------------------------------------------------------------------
+--
+-- Designed for: University of Colorado at Boulder
+--
+--
+-- Designed by: Tim Scherr
+-- Revised by: Glenn Feinberg and George Abi-Nader
+--
+-- Version: 2.0
+-- Date of current revision: 2016-09-29
+-- Target Microcontroller: Freescale MKL25ZVMT4
+-- Tools used: ARM mbed compiler
+-- ARM mbed SDK
+-- Freescale FRDM-KL25Z Freedom Board
+--
+--
+ Functional Description: See below
+--
+-- Copyright (c) 2015 Tim Scherr All rights reserved.
+--
+*/
+
+#include <stdio.h>
+#include "shared.h"
+
+//Const String Array to Debug Registers
+const char* regNames[] = {"R0: ", "R1: ", "R2: ", "R3: ", "R4: ", "R5: ", "R6: ", "R7: ", "R8: ", "R9: ", "R10: ", "R11: ", "R12: ", "R13: ", "R14: ", "PC: "};
+
+
+/*******************************************************************************
+* Set Display Mode Function
+* Function determines the correct display mode. The 3 display modes operate as
+* follows:
+*
+* NORMAL MODE Outputs only mode and state information changes
+* and calculated outputs
+*
+* QUIET MODE No Outputs
+*
+* DEBUG MODE Outputs mode and state information, error counts,
+* register displays, sensor states, and calculated output
+*
+*
+* There is deliberate delay in switching between modes to allow the RS-232 cable
+* to be plugged into the header without causing problems.
+*******************************************************************************/
+
+void set_display_mode(void)
+{
+ UART_direct_msg_put("\r\nSelect Mode");
+ UART_direct_msg_put("\r\n Hit NOR - Normal");
+ UART_direct_msg_put("\r\n Hit QUI - Quiet");
+ UART_direct_msg_put("\r\n Hit DEB - Debug" );
+ UART_direct_msg_put("\r\n Hit RES - Reset" );
+ UART_direct_msg_put("\r\n Hit V - Version#\r\n");
+ UART_direct_msg_put("\r\nSelect: ");
+}
+
+
+//*****************************************************************************/
+/// \fn void chk_UART_msg(void)
+///
+//*****************************************************************************/
+void chk_UART_msg(void)
+{
+ UCHAR j;
+ while( UART_input() ) // becomes true only when a byte has been received
+ { // skip if no characters pending
+ j = UART_get(); // get next character
+
+ if( j == '\r' ) // on a enter (return) key press
+ { // complete message (all messages end in carriage return)
+ UART_msg_put("->");
+ UART_msg_process();
+ }
+ else
+ {
+ if ((j != 0x02) ) // if not ^B
+ { // if not command, then
+ UART_put(j); // echo the character
+ }
+ else
+ {
+ ;
+ }
+ if( j == '\b' )
+ { // backspace editor
+ if( msg_buf_idx != 0)
+ { // if not 1st character then destructive
+ UART_msg_put(" \b");// backspace
+ msg_buf_idx--;
+ }
+ }
+ else if( msg_buf_idx >= MSG_BUF_SIZE )
+ { // check message length too large
+ UART_msg_put("\r\nToo Long!");
+ msg_buf_idx = 0;
+ }
+ else if ((display_mode == QUIET) && (msg_buf[0] != 0x02) &&
+ (msg_buf[0] != 'D') && (msg_buf[0] != 'N') &&
+ (msg_buf[0] != 'V') && (msg_buf[0] != 'R') &&
+ (msg_buf_idx != 0))
+ { // if first character is bad in Quiet mode
+ msg_buf_idx = 0; // then start over
+ }
+ else { // not complete message, store character
+
+ msg_buf[msg_buf_idx] = j;
+ msg_buf_idx++;
+ if (msg_buf_idx > 2)
+ {
+ UART_msg_process();
+ }
+ }
+ }
+ }
+}
+
+//*****************************************************************************/
+/// \fn void UART_msg_process(void)
+///UART Input Message Processing
+//*****************************************************************************/
+void UART_msg_process(void)
+{
+ UCHAR chr,err=0;
+// unsigned char data;
+
+
+ if( (chr = msg_buf[0]) <= 0x60 )
+ { // Upper Case
+ switch( chr )
+ {
+ case 'D':
+ if((msg_buf[1] == 'E') && (msg_buf[2] == 'B') && (msg_buf_idx == 3))
+ {
+ display_mode = DEBUG;
+ UART_msg_put("\r\nMode=DEBUG\n");
+ display_timer = 0;
+ }
+ else
+ err = 1;
+ break;
+
+ case 'N':
+ if((msg_buf[1] == 'O') && (msg_buf[2] == 'R') && (msg_buf_idx == 3))
+ {
+ display_mode = NORMAL;
+ UART_msg_put("\r\nMode=NORMAL\n");
+ //display_timer = 0;
+ }
+ else
+ err = 1;
+ break;
+
+ case 'Q':
+ if((msg_buf[1] == 'U') && (msg_buf[2] == 'I') && (msg_buf_idx == 3))
+ {
+ display_mode = QUIET;
+ UART_msg_put("\r\nMode=QUIET\n");
+ display_timer = 0;
+ }
+ else
+ err = 1;
+ break;
+
+ case 'R':
+ if((msg_buf[1] == 'E') && (msg_buf[2] == 'S') && (msg_buf_idx == 3))
+ {
+ //RESdisplay_mode = RESET;
+ UART_msg_put("\r\nMode=RESETTING BOARD!\n");
+
+ UART_direct_msg_put("\r\nSystem Reset\r\nCode ver. ");
+ UART_direct_msg_put( CODE_VERSION );
+ UART_direct_msg_put("\r\n");
+ UART_direct_msg_put( COPYRIGHT );
+ UART_direct_msg_put("\r\n");
+
+ //Set All Values back to 0
+ display_timer = 0;
+ serial_flag = 0;
+
+ display_mode = QUIET;
+
+ resetTimers();
+
+ set_display_mode();
+
+ err = 0;
+ }
+ else
+ err = 1;
+ break;
+
+ case 'V':
+ display_mode = VERSION;
+ UART_msg_put("\r\n");
+ UART_msg_put( CODE_VERSION );
+ UART_msg_put("\r\nSelect ");
+ display_timer = 0;
+ break;
+
+ default:
+ err = 1;
+ }
+ }
+
+ else
+ { // Lower Case
+ switch( chr )
+ {
+ default:
+ err = 1;
+ }
+ }
+
+ if( err == 1 )
+ {
+ UART_msg_put("\n\rError!");
+ }
+ else if( err == 2 )
+ {
+ UART_msg_put("\n\rNot in DEBUG Mode!");
+ }
+ else
+ {
+ msg_buf_idx = 0; // put index to start of buffer for next message
+ ;
+ }
+ msg_buf_idx = 0; // put index to start of buffer for next message
+
+
+}
+
+
+//*****************************************************************************
+/// \fn is_hex
+/// Function takes
+/// @param a single ASCII character and returns
+/// @return 1 if hex digit, 0 otherwise.
+///
+//*****************************************************************************
+UCHAR is_hex(UCHAR c)
+{
+ if( (((c |= 0x20) >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f')) )
+ return 1;
+ return 0;
+}
+
+ /**
+ * @brief value of R0
+ *
+ * Gets the value of general purpose register R0
+ *
+ * @param[]
+ * Void, takes no inputs
+ *
+ * @return
+ * The return value is an integer: the content of R0.
+ *
+ */
+__asm int reg0(void)
+ {
+ BX lr ; return control to C
+ }
+
+ /**
+ * @brief value of general purpose register
+ *
+ * returns value of any general purpose register except R0
+ *
+ * @param[x]
+ * integer the number of the register to be inspected.
+ * Value range between 1 and 15
+ *
+ * @return
+ * The return value is an integer: the content of register R[x].
+ * For values outside the range 1-15, x is returned
+ */
+__asm int reg(int x)
+ {
+ CMP r0 , #1 ; is it asking for r1
+ BNE two ; if not try r2
+ MOV r0, r1 ; otherwise return what is in r1
+ BX lr
+two
+ CMP r0 , #2
+ BNE three
+ MOV r0, r2
+ BX lr
+three
+ CMP r0 , #3
+ BNE four
+ MOV r0, r3
+ BX lr
+four
+ CMP r0 , #4
+ BNE five
+ MOV r0, r4
+ BX lr
+five
+ CMP r0 , #5
+ BNE six
+ MOV r0, r5
+ BX lr
+six
+ CMP r0 , #6
+ BNE seven
+ MOV r0, r6
+ BX lr
+seven
+ CMP r0 , #7
+ BNE eight
+ MOV r0, r7
+ BX lr
+eight
+ CMP r0 , #8
+ BNE nine
+ MOV r0, r9
+ BX lr
+nine
+ CMP r0 , #9
+ BNE ten
+ MOV r0, r9
+ BX lr
+ten
+ CMP r0 , #10
+ BNE eleven
+ MOV r0, r10
+ BX lr
+eleven
+ CMP r0 , #11
+ BNE twelve
+ MOV r0, r11
+ BX lr
+twelve
+ CMP r0 , #12
+ BNE thirteen
+ MOV r0, r12
+ BX lr
+thirteen
+ CMP r0 , #13
+ BNE fourteen
+ MOV r0, r13
+ BX lr
+fourteen
+ CMP r0 , #14
+ BNE done
+ MOV r0, r14
+done
+ BX lr
+
+ }
+
+ /**
+ * @brief contents of memory location
+ *
+ * Gets the contents of a memory location
+ *
+ * @param[x]
+ * 32 bit address of memory
+ *
+ * @return
+ * The return value is a 32 bit integer: the content of the memory location.
+ *
+ */
+__asm int content(uint32_t x )
+ {
+ LDR r0,[r0];
+ BX lr ; return control to C
+ }
+
+/*******************************************************************************
+* \fn DEBUG and DIAGNOSTIC Mode UART Operation
+*******************************************************************************/
+void monitor(void)
+{
+ char tmp[20];
+/**********************************/
+/* Spew outputs */
+/**********************************/
+
+ switch(display_mode)
+ {
+ case(QUIET):
+ {
+ UART_msg_put("\r\n ");
+ display_flag = 0;
+ }
+ break;
+ case(RESET):
+ {
+ UART_msg_put("\r\n RESETTING!!!!");
+ display_flag = 0;
+ }
+ break;
+ case(VERSION):
+ {
+ display_flag = 0;
+ }
+ break;
+ case(NORMAL):
+ {
+
+ if (display_flag == 1)
+ {
+ UART_direct_msg_put("\r\n------------+------------+---------+--------+-----------+");
+ UART_direct_msg_put("\r\nNORMAL MODE ");
+ UART_direct_msg_put("\r\n Time: ");
+ itoa(systemTime, tmp);
+ UART_direct_msg_put(tmp);
+ UART_direct_msg_put("\r\n Frequency: ");
+ itoa(F, tmp);
+ UART_direct_msg_put(tmp);
+ UART_direct_msg_put("\r\n Temperature C: ");
+ itoa(Temp, tmp);
+ UART_direct_msg_put(tmp);
+ UART_direct_msg_put("\r\n Flow G/min: ");
+ itoa(flowG, tmp);
+ UART_direct_msg_put(tmp);
+ UART_direct_msg_put("\r\n------------+------------+---------+--------+-----------+");
+ display_flag = 0;
+
+ }
+ }
+ break;
+ case(DEBUG):
+ {
+ if (display_flag == 1)
+ {
+ UART_direct_msg_put("\r\n-----------+------------+---------+--------+-----------+");
+ UART_direct_msg_put("\r\nDEBUG MODE +");
+ UART_direct_msg_put("\r\n------------+------------+---------+--------+-----------+");
+ /*
+ UART_direct_msg_put("\r\n Time: ");
+ itoa(systemTime, tmp);
+ UART_direct_msg_put(tmp);
+ UART_direct_msg_put("\r\n Frequency: ");
+ itoa(F, tmp);
+ UART_direct_msg_put(tmp);
+ UART_direct_msg_put("\r\n Temperature C: ");
+ itoa(Temp, tmp);
+ UART_direct_msg_put(tmp);
+ UART_direct_msg_put("\r\n Flow G/min: ");
+ itoa(flowG, tmp);
+ UART_direct_msg_put(tmp);
+ UART_direct_msg_put("\r\n------------+------------+---------+--------+-----------+");
+
+ */
+ UART_direct_msg_put("\r\n-----------+------------+---------+--------+-----------+");
+
+ //Debug R0-R15
+ UART_direct_msg_put("\r\n R0 to R15: ");
+ UART_direct_msg_put("\r\n");
+
+ volatile uint32_t x;
+ int i = 0;
+ x = reg0();
+
+ UART_direct_msg_put(regNames[i]);
+ UART_direct_hex_put(x >> 24);
+ UART_direct_hex_put(x >> 16);
+ UART_direct_hex_put(x >> 8);
+ UART_direct_hex_put(x);
+
+ for ( i = 1; i < 16; i++)
+ {
+ UART_direct_msg_put("\r\n");
+ UART_direct_msg_put(regNames[i]);
+ x = reg(i);
+ UART_direct_hex_put(x >> 24);
+ UART_direct_hex_put(x >> 16);
+ UART_direct_hex_put(x >> 8);
+ UART_direct_hex_put(x);
+ }
+ UART_direct_msg_put("\r\n");
+ /*
+ // Create a command to read 16 words from the current stack
+ // and display it in reverse chronological order.
+ UART_direct_msg_put("\r\n 16 words of the stack, most recent first: ");
+ UART_direct_msg_put("\r\n");
+ volatile uint32_t SP; // variable to hold the stack pointer
+
+ SP = reg(13); // register 13 is the stack pointer
+ for( i = 0; i < 16; i++)
+ {
+ UART_direct_msg_put("\r\n");
+ x = content(SP+4*i);
+ UART_direct_hex_put(x >> 24);
+ UART_direct_hex_put(x >> 16);
+ UART_direct_hex_put(x >> 8);
+ UART_direct_hex_put(x);
+ }
+ */
+ // clear flag to ISR
+ display_flag = 0;
+ }
+ }
+ break;
+
+ default:
+ {
+ UART_msg_put("Mode Error");
+ }
+ }
+}
+
+/**
+ * @brief Reverse the order of characters
+ *
+ * Reverses the order of characters of a string
+ *
+ * @param[*str, len]
+ *
+ * char *str pointer to the string to be reversed
+ * unint32_t len, legnth of the string to be reversed
+ *
+ * @return
+ *
+ * Void, reversed string replaced the input
+ */
+void reverse(char *str, uint32_t len)
+{
+ uint32_t i=0, j=len-1, temp;
+ while (i<j)
+ {
+ temp = str[i];
+ str[i] = str[j];
+ str[j] = temp;
+ i++; j--;
+ }
+}
+
+/**
+ * @brief Integer to Ascii
+ *
+ * creates ascii equivalent of an integer
+ *
+ * @param[n, char]
+ *
+ * int32_t n, the integer that requires ascii equivalent
+ * char s[], string to receive the ascii characters
+ *
+ * @return
+ *
+ * Void, characters put in the passed string
+ */
+void itoa(int32_t n, char s[])
+{
+ uint32_t i = 0;
+ int32_t sign;
+
+ if ((sign = n) < 0) /* record sign */
+ n = -n; /* make n positive */
+ i = 0;
+ do { /* generate digits in reverse order */
+ s[i++] = n % 10 + '0'; /* get next digit */
+ } while ((n /= 10) > 0); /* delete it */
+ if (sign < 0)
+ s[i++] = '-';
+ s[i] = '\0';
+ reverse(s, i);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/UART_poll.cpp Wed Feb 28 05:49:24 2018 +0000
@@ -0,0 +1,284 @@
+/**-----------------------------------------------------------------------------
+ \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: Glenn Feinberg and George Abi-Nader
+--
+-- 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();
+ }
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Wed Feb 28 05:49:24 2018 +0000
@@ -0,0 +1,291 @@
+/**----------------------------------------------------------------------------
+
+ \file main.cpp
+-- --
+-- ECEN 5803 Mastering Embedded System Architecture --
+-- Project 1 Module 4 --
+-- Microcontroller Firmware --
+-- main.cpp --
+-- --
+-------------------------------------------------------------------------------
+--
+-- Designed for: University of Colorado at Boulder
+--
+--
+-- Designed by: Tim Scherr
+-- Revised by: Glenn Feinberg and George Abi-Nader
+--
+-- Version: 2.1
+-- Date of current revision: 2017-09-25
+-- Target Microcontroller: Freescale MKL25ZVMT4
+-- Tools used: ARM mbed compiler
+-- ARM mbed SDK
+-- Freescale FRDM-KL25Z Freedom Board
+--
+--
+-- Functional Description: Main code file generated by mbed, and then
+-- modified to implement a super loop bare metal OS.
+--
+-- Copyright (c) 2015, 2016 Tim Scherr All rights reserved.
+--
+*/
+
+#define MAIN
+#include "shared.h"
+#undef MAIN
+
+#define ADC_0 (0U)
+#define CHANNEL_0 (0U)
+#define CHANNEL_1 (1U)
+#define CHANNEL_2 (2U)
+#define LED_ON (0U)
+#define LED_OFF (1U)
+#define ADCR_VDD (65535U) /*! Maximum value when use 16b resolution */
+#define V_BG (1000U) /*! BANDGAP voltage in mV (trim to 1.0V) */
+#define V_TEMP25 (716U) /*! Typical VTEMP25 in mV */
+#define M (1620U) /*! Typical slope: (mV x 1000)/oC */
+#define STANDARD_TEMP (25)
+
+
+extern volatile uint16_t SwTimerIsrCounter;
+
+
+Ticker tick; // Creates a timer interrupt using mbed methods
+ /**************** ECEN 5803 add code as indicated ***************/
+
+//Initialize LEDs to OFF (HIGH)
+DigitalOut redLED(LED_RED, 1);
+DigitalOut blueLED(LED_BLUE, 1);
+DigitalOut greenLED(LED_GREEN, 1);
+
+//Add Analog Channels
+AnalogIn VREFL(PTB0); //ADC channel 0 is reference low
+AnalogIn freqIn(PTB1); //ADC channel 1 is vortex frequency in
+AnalogIn ADCR(PTB2); //ADC channel 2 is raw internal temperature
+
+//Setup SPI Pins
+PinName const SCK = PTC5;
+PinName const MOSI = PTC6;
+PinName const MISO = PTC7;
+DigitalOut CS(PTC4);
+
+#define PIN_SCK PTD1
+#define PIN_MISO PTD3
+#define PIN_MOSI PTD2
+#define PIN_CS0 PTD0
+
+//Setup PWM Pins
+PwmOut pwm420(PTE30);
+PwmOut pwmPulse(PTE31);
+
+Serial pc(USBTX, USBRX);
+
+//Initalize SPI
+ SPI device(MOSI, MISO, SCK);
+
+const uint16_t freq[] = {0x7FFF,0x866D,0x8CD8,0x933A,0x998F,0x9FD4,0xA604,0xAC1C,0xB217,0xB7F2,0xBDA9,0xC338,0xC89B,0xCDCF,0xD2D1,0xD79E,0xDC32,0xE08A,0xE4A4,0xE87C,0xEC12,0xEF61,0xF268,0xF525,0xF797,0xF9BB,0xFB90,0xFD16,0xFE4A,0xFF2D,0xFFBE,0xFFFC,0xFFE7,0xFF80,0xFEC6,0xFDBA,0xFC5D,0xFAAF,0xF8B2,0xF667,0xF3D0,0xF0ED,0xEDC2,0xEA50,0xE698,0xE29F,0xDE65,0xD9EF,0xD53F,0xD057,0xCB3B,0xC5EF,0xC075,0xBAD2,0xB509,0xAF1E,0xA914,0xA2EF,0x9CB4,0x9666,0x900A,0x89A3,0x8336,0x7CC8,0x765B,0x6FF4,0x6998,0x634A,0x5D0F,0x56EA,0x50E0,0x4AF5,0x452C,0x3F89,0x3A0F,0x34C3,0x2FA7,0x2ABF,0x260F,0x2199,0x1D5F,0x1966,0x15AE,0x123C,0x0F11,0x0C2E,0x0997,0x074C,0x054F,0x03A1,0x0244,0x0138,0x007E,0x0017,0x0002,0x0040,0x00D1,0x01B4,0x02E8,0x046E,0x0643,0x0867,0x0AD9,0x0D96,0x109D,0x13EC,0x1782,0x1B5A,0x1F74,0x23CC,0x2860,0x2D2D,0x322F,0x3763,0x3CC6,0x4255,0x480C,0x4DE7,0x53E2,0x59FA,0x602A,0x666F,0x6CC4,0x7326,0x7991,0x7FFF,0x866D,0x8CD8,0x933A,0x998F,0x9FD4,0xA604,0xAC1C,0xB217,0xB7F2,0xBDA9,0xC338,0xC89B,0xCDCF,0xD2D1,0xD79E,0xDC32,0xE08A,0xE4A4,0xE87C,0xEC12,0xEF61,0xF268,0xF525,0xF797,0xF9BB,0xFB90,0xFD16,0xFE4A,0xFF2D,0xFFBE,0xFFFC,0xFFE7,0xFF80,0xFEC6,0xFDBA,0xFC5D,0xFAAF,0xF8B2,0xF667,0xF3D0,0xF0ED,0xEDC2,0xEA50,0xE698,0xE29F,0xDE65,0xD9EF,0xD53F,0xD057,0xCB3B,0xC5EF,0xC075,0xBAD2,0xB509,0xAF1E,0xA914,0xA2EF,0x9CB4,0x9666,0x900A,0x89A3,0x8336,0x7CC8,0x765B,0x6FF4,0x6998,0x634A,0x5D0F,0x56EA,0x50E0,0x4AF5,0x452C,0x3F89,0x3A0F,0x34C3,0x2FA7,0x2ABF,0x260F,0x2199,0x1D5F,0x1966,0x15AE,0x123C,0x0F11,0x0C2E,0x0997,0x074C,0x054F,0x03A1,0x0244,0x0138,0x007E,0x0017,0x0002,0x0040,0x00D1,0x01B4,0x02E8,0x046E,0x0643,0x0867,0x0AD9,0x0D96,0x109D,0x13EC,0x1782,0x1B5A,0x1F74,0x23CC,0x2860,0x2D2D,0x322F,0x3763,0x3CC6,0x4255,0x480C,0x4DE7,0x53E2,0x59FA,0x602A,0x666F,0x6CC4,0x7326,0x7991,0x7FFF,0x866D,0x8CD8,0x933A,0x998F,0x9FD4,0xA604,0xAC1C,0xB217,0xB7F2,0xBDA9,0xC338,0xC89B,0xCDCF,0xD2D1,0xD79E,0xDC32,0xE08A,0xE4A4,0xE87C,0xEC12,0xEF61,0xF268,0xF525,0xF797,0xF9BB,0xFB90,0xFD16,0xFE4A,0xFF2D,0xFFBE,0xFFFC,0xFFE7,0xFF80,0xFEC6,0xFDBA,0xFC5D,0xFAAF,0xF8B2,0xF667,0xF3D0,0xF0ED,0xEDC2,0xEA50,0xE698,0xE29F,0xDE65,0xD9EF,0xD53F,0xD057,0xCB3B,0xC5EF,0xC075,0xBAD2,0xB509,0xAF1E,0xA914,0xA2EF,0x9CB4,0x9666,0x900A,0x89A3,0x8336,0x7CC8,0x765B,0x6FF4,0x6998,0x634A,0x5D0F,0x56EA,0x50E0,0x4AF5,0x452C,0x3F89,0x3A0F,0x34C3,0x2FA7,0x2ABF,0x260F,0x2199,0x1D5F,0x1966,0x15AE,0x123C,0x0F11,0x0C2E,0x0997,0x074C,0x054F,0x03A1,0x0244,0x0138,0x007E,0x0017,0x0002,0x0040,0x00D1,0x01B4,0x02E8,0x046E,0x0643,0x0867,0x0AD9,0x0D96,0x109D,0x13EC,0x1782,0x1B5A,0x1F74,0x23CC,0x2860,0x2D2D,0x322F,0x3763,0x3CC6,0x4255,0x480C,0x4DE7,0x53E2,0x59FA,0x602A,0x666F,0x6CC4,0x7326,0x7991,0x7FFF,0x866D,0x8CD8,0x933A,0x998F,0x9FD4,0xA604,0xAC1C,0xB217,0xB7F2,0xBDA9,0xC338,0xC89B,0xCDCF,0xD2D1,0xD79E,0xDC32,0xE08A,0xE4A4,0xE87C,0xEC12,0xEF61,0xF268,0xF525,0xF797,0xF9BB,0xFB90,0xFD16,0xFE4A,0xFF2D,0xFFBE,0xFFFC,0xFFE7,0xFF80,0xFEC6,0xFDBA,0xFC5D,0xFAAF,0xF8B2,0xF667,0xF3D0,0xF0ED,0xEDC2,0xEA50,0xE698,0xE29F,0xDE65,0xD9EF,0xD53F,0xD057,0xCB3B,0xC5EF,0xC075,0xBAD2,0xB509,0xAF1E,0xA914,0xA2EF,0x9CB4,0x9666,0x900A,0x89A3,0x8336,0x7CC8,0x765B,0x6FF4,0x6998,0x634A,0x5D0F,0x56EA,0x50E0,0x4AF5,0x452C,0x3F89,0x3A0F,0x34C3,0x2FA7,0x2ABF,0x260F,0x2199,0x1D5F,0x1966,0x15AE,0x123C,0x0F11,0x0C2E,0x0997,0x074C,0x054F,0x03A1,0x0244,0x0138,0x007E,0x0017,0x0002,0x0040,0x00D1,0x01B4,0x02E8,0x046E,0x0643,0x0867,0x0AD9,0x0D96,0x109D,0x13EC,0x1782,0x1B5A,0x1F74,0x23CC,0x2860,0x2D2D,0x322F,0x3763,0x3CC6,0x4255,0x480C,0x4DE7,0x53E2,0x59FA,0x602A,0x666F,0x6CC4,0x7326,0x7991,0x7FFF,0x866D,0x8CD8,0x933A,0x998F,0x9FD4,0xA604,0xAC1C,0xB217,0xB7F2,0xBDA9,0xC338,0xC89B,0xCDCF,0xD2D1,0xD79E,0xDC32,0xE08A,0xE4A4,0xE87C,0xEC12,0xEF61,0xF268,0xF525,0xF797,0xF9BB,0xFB90,0xFD16,0xFE4A,0xFF2D,0xFFBE,0xFFFC,0xFFE7,0xFF80,0xFEC6,0xFDBA,0xFC5D,0xFAAF,0xF8B2,0xF667,0xF3D0,0xF0ED,0xEDC2,0xEA50,0xE698,0xE29F,0xDE65,0xD9EF,0xD53F,0xD057,0xCB3B,0xC5EF,0xC075,0xBAD2,0xB509,0xAF1E,0xA914,0xA2EF,0x9CB4,0x9666,0x900A,0x89A3,0x8336,0x7CC8,0x765B,0x6FF4,0x6998,0x634A,0x5D0F,0x56EA,0x50E0,0x4AF5,0x452C,0x3F89,0x3A0F,0x34C3,0x2FA7,0x2ABF,0x260F,0x2199,0x1D5F,0x1966,0x15AE,0x123C,0x0F11,0x0C2E,0x0997,0x074C,0x054F,0x03A1,0x0244,0x0138,0x007E,0x0017,0x0002,0x0040,0x00D1,0x01B4,0x02E8,0x046E,0x0643,0x0867,0x0AD9,0x0D96,0x109D,0x13EC,0x1782,0x1B5A,0x1F74,0x23CC,0x2860,0x2D2D,0x322F,0x3763,0x3CC6,0x4255,0x480C,0x4DE7,0x53E2,0x59FA,0x602A,0x666F,0x6CC4,0x7326,0x7991,0x7FFF,0x866D,0x8CD8,0x933A,0x998F,0x9FD4,0xA604,0xAC1C,0xB217,0xB7F2,0xBDA9,0xC338,0xC89B,0xCDCF,0xD2D1,0xD79E,0xDC32,0xE08A,0xE4A4,0xE87C,0xEC12,0xEF61,0xF268,0xF525,0xF797,0xF9BB,0xFB90,0xFD16,0xFE4A,0xFF2D,0xFFBE,0xFFFC,0xFFE7,0xFF80,0xFEC6,0xFDBA,0xFC5D,0xFAAF,0xF8B2,0xF667,0xF3D0,0xF0ED,0xEDC2,0xEA50,0xE698,0xE29F,0xDE65,0xD9EF,0xD53F,0xD057,0xCB3B,0xC5EF,0xC075,0xBAD2,0xB509,0xAF1E,0xA914,0xA2EF,0x9CB4,0x9666,0x900A,0x89A3,0x8336,0x7CC8,0x765B,0x6FF4,0x6998,0x634A,0x5D0F,0x56EA,0x50E0,0x4AF5,0x452C,0x3F89,0x3A0F,0x34C3,0x2FA7,0x2ABF,0x260F,0x2199,0x1D5F,0x1966,0x15AE,0x123C,0x0F11,0x0C2E,0x0997,0x074C,0x054F,0x03A1,0x0244,0x0138,0x007E,0x0017,0x0002,0x0040,0x00D1,0x01B4,0x02E8,0x046E,0x0643,0x0867,0x0AD9,0x0D96,0x109D,0x13EC,0x1782,0x1B5A,0x1F74,0x23CC,0x2860,0x2D2D,0x322F,0x3763,0x3CC6,0x4255,0x480C,0x4DE7,0x53E2,0x59FA,0x602A,0x666F,0x6CC4,0x7326,0x7991,0x7FFF,0x866D,0x8CD8,0x933A,0x998F,0x9FD4,0xA604,0xAC1C,0xB217,0xB7F2,0xBDA9,0xC338,0xC89B,0xCDCF,0xD2D1,0xD79E,0xDC32,0xE08A,0xE4A4,0xE87C,0xEC12,0xEF61,0xF268,0xF525,0xF797,0xF9BB,0xFB90,0xFD16,0xFE4A,0xFF2D,0xFFBE,0xFFFC,0xFFE7,0xFF80,0xFEC6,0xFDBA,0xFC5D,0xFAAF,0xF8B2,0xF667,0xF3D0,0xF0ED,0xEDC2,0xEA50,0xE698,0xE29F,0xDE65,0xD9EF,0xD53F,0xD057,0xCB3B,0xC5EF,0xC075,0xBAD2,0xB509,0xAF1E,0xA914,0xA2EF,0x9CB4,0x9666,0x900A,0x89A3,0x8336,0x7CC8,0x765B,0x6FF4,0x6998,0x634A,0x5D0F,0x56EA,0x50E0,0x4AF5,0x452C,0x3F89,0x3A0F,0x34C3,0x2FA7,0x2ABF,0x260F,0x2199,0x1D5F,0x1966,0x15AE,0x123C,0x0F11,0x0C2E,0x0997,0x074C,0x054F,0x03A1,0x0244,0x0138,0x007E,0x0017,0x0002,0x0040,0x00D1,0x01B4,0x02E8,0x046E,0x0643,0x0867,0x0AD9,0x0D96,0x109D,0x13EC,0x1782,0x1B5A,0x1F74,0x23CC,0x2860,0x2D2D,0x322F,0x3763,0x3CC6,0x4255,0x480C,0x4DE7,0x53E2,0x59FA,0x602A,0x666F,0x6CC4,0x7326,0x7991,0x7FFF,0x866D,0x8CD8,0x933A,0x998F,0x9FD4,0xA604,0xAC1C,0xB217,0xB7F2,0xBDA9,0xC338,0xC89B,0xCDCF,0xD2D1,0xD79E,0xDC32,0xE08A,0xE4A4,0xE87C,0xEC12,0xEF61,0xF268,0xF525,0xF797,0xF9BB,0xFB90,0xFD16,0xFE4A,0xFF2D,0xFFBE,0xFFFC,0xFFE7,0xFF80,0xFEC6,0xFDBA,0xFC5D,0xFAAF,0xF8B2,0xF667,0xF3D0,0xF0ED,0xEDC2,0xEA50,0xE698,0xE29F,0xDE65,0xD9EF,0xD53F,0xD057,0xCB3B,0xC5EF,0xC075,0xBAD2,0xB509,0xAF1E,0xA914,0xA2EF,0x9CB4,0x9666,0x900A,0x89A3,0x8336,0x7CC8,0x765B,0x6FF4,0x6998,0x634A,0x5D0F,0x56EA,0x50E0,0x4AF5,0x452C,0x3F89,0x3A0F,0x34C3,0x2FA7,0x2ABF,0x260F,0x2199,0x1D5F,0x1966,0x15AE,0x123C,0x0F11,0x0C2E,0x0997,0x074C,0x054F,0x03A1,0x0244,0x0138,0x007E,0x0017,0x0002,0x0040,0x00D1,0x01B4,0x02E8,0x046E,0x0643,0x0867,0x0AD9,0x0D96,0x109D,0x13EC,0x1782,0x1B5A,0x1F74,0x23CC,0x2860,0x2D2D,0x322F,0x3763,0x3CC6,0x4255,0x480C,0x4DE7,0x53E2,0x59FA,0x602A,0x666F,0x6CC4,0x7326,0x7991};
+
+uint32_t flowG =0;
+uint32_t F =0;
+uint32_t Temp =0;
+
+void flip()
+{
+ greenLED = !greenLED;
+}
+
+
+
+int main()
+{
+/**************** ECEN 5803 add code as indicated ***************/
+
+
+ //Configure ADC
+
+SIM->SCGC5 |= 0x400;
+ PORTB->PCR[0] = PORT_PCR_MUX(0);
+ PORTB->PCR[1] = PORT_PCR_MUX(0);
+ PORTB->PCR[2] = PORT_PCR_MUX(0);
+ SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK;
+ ADC0->CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_ADLSMP_MASK | ADC_CFG1_MODE(3) | ADC_CFG1_ADICLK(1);
+ ADC0->SC3 |= 0x4;
+ ADC0->SC3 |= ADC_SC3_AVGS(3);
+ ADC0->SC3 |= 0x8;
+ ADC0->SC3 |= 0x80; //Start Calibration
+
+
+ while(ADC0->SC3 & 0x40); /*wait for calibration*/
+
+ //Plus side cal
+ uint16_t cal =0; //clear 16bit RAM variable
+ cal = cal + ADC0->CLP0 + ADC0->CLP1 + ADC0->CLP2 + ADC0->CLP3 + ADC0->CLP4 + ADC0->CLPS;
+ cal = cal/2;
+ cal |= 0xFF00;
+ ADC0->PG = cal;
+ //Minus side cal
+ cal = 0;
+ cal = cal + ADC0->CLM0 + ADC0->CLM1 + ADC0->CLM2 + ADC0->CLM3 + ADC0->CLM4 + ADC0->CLMS;
+ cal = cal/2;
+ cal |= 0xFF00;
+ ADC0->MG = cal;
+
+ //Calibration done start ADC
+ ADC0->SC3 |= 0x0C; //continuous mode
+
+ //Call Timer 0 every 100 uS
+ tick.attach(&timer0, 0.0001);
+
+
+ // pc.printf("Hello World!\n");
+ uint32_t count = 0;
+
+// initialize serial buffer pointers
+ rx_in_ptr = rx_buf; /* pointer to the receive in data */
+ rx_out_ptr = rx_buf; /* pointer to the receive out data*/
+ tx_in_ptr = tx_buf; /* pointer to the transmit in data*/
+ tx_out_ptr = tx_buf; /*pointer to the transmit out */
+
+
+ // Print the initial banner
+ // pc.printf("\r\nHello World!\n\n\r");
+
+ /**************** ECEN 5803 add code as indicated ***************/
+ // uncomment this section after adding monitor code.
+ /* send a message to the terminal */
+
+ UART_direct_msg_put("\r\nSystem Reset\r\nCode ver. ");
+ UART_direct_msg_put( CODE_VERSION );
+ UART_direct_msg_put("\r\n");
+ UART_direct_msg_put( COPYRIGHT );
+ UART_direct_msg_put("\r\n");
+
+ set_display_mode();
+
+
+
+ float tempC = 25;
+ float tempK = 298;
+ float P = 0.0737; //PID in meters
+ float d = 0.0127; //bluff body width in meters
+ float viscosity, rho, velocity;
+
+ float flow = 0;
+ float frequency = 0;
+
+ //estimate Frequency from Data
+ uint32_t prevSample = 0;
+ uint32_t currentSample = 0;
+ uint32_t zeroCrossCount = 0;
+ //float sampleTime = .1;
+
+ uint16_t i = 0; //counter
+ currentSample = freq[i];
+
+
+
+ while(1) // Cyclical Executive Loop
+ {
+
+ count++; // counts the number of times through the loop
+// __enable_interrupts();
+// __clear_watchdog_timer();
+
+ serial(); // Polls the serial port
+ chk_UART_msg(); // checks for a serial port message received
+ monitor(); // Sends serial port output messages depending
+ // on commands received and display mode
+
+ /**************** ECEN 5803 add code as indicated ***************/
+
+// readADC()
+
+ VREFL.read_u16();
+ ADCR.read_u16();
+ freqIn.read_u16();
+
+ tempC = 25 - ( (ADCR / ADCR_VDD *3 -V_TEMP25))/ M ; // assume VDD stable 3V;
+
+ Temp = (uint32_t)(tempC);
+ tempK = 273.15 + tempC;
+
+ viscosity = (2.4*.00001)*pow(10,247.8/(tempK-140));
+ rho = 1000*(1-(tempC+288.9414)/(508929.2*(tempC+68.12963))*pow((tempC-3.9863),2));
+
+ // pc.printf("Viscosity: %.5f\r\n", viscosity);
+ // pc.printf("Rho: %.5f\r\n", rho);
+
+
+ //calculate frequency
+ zeroCrossCount = 0;
+ for(i = 0; i<1000;i++)
+ {
+ currentSample = freq[i] + freqIn.read_u16()/1000; //adding ADC reading to simulate noise
+ if ( ((currentSample >= 32678) && (prevSample < 32678)) || ( (currentSample <= 32678) && (prevSample > 32678) ) )
+ {
+ zeroCrossCount++;
+ }
+ prevSample = currentSample;
+
+ }
+ frequency = 5*(zeroCrossCount); //div (sampleTime *2 );
+ // pc.printf("Frequency: %.1f Hz\r\n", frequency);
+ F = (uint32_t)(frequency);
+// calculating velocity
+
+ velocity = 1/viscosity *(-3.96778 *pow(10,-8.0)* sqrt(viscosity*viscosity*(8817368566642459 -8817368566642457*d*d*frequency*frequency)+35195095456744964*P*P*rho*rho + 35232265234031368*P*rho*viscosity)+7.4437*P*rho+3.72578*viscosity);
+
+ // pc.printf("Velocity: %.5f m/s\r\n", velocity);
+// calculate flow()
+
+ flow = 2.45*P*P*velocity; // in m^3 per sec
+ // pc.printf("Flow: %.5f m^3/s \r\n", flow);
+
+ flow = 15850*flow;
+ flowG = (uint32_t)(flow); // convert to Gallons/min
+
+// 4-20 output () // use TMP0 channel 3 proporional rate to flow
+ pwm420 = 1.0f - (flow/(0.04)); //scaled to max flow at 2000 Hz freq
+
+// Pulse output() // use TMP0 channel 4 propotional rate to frequency
+ pwmPulse = 1.0f - (frequency/2000);
+
+// LCD_Display() // use the SPI port to send flow number
+ updateLCD(flow);
+
+// End ECEN 5803 code addition
+
+
+ if ((SwTimerIsrCounter & 0x1FFF) > 0x0FFF)
+
+ {
+ flip(); // Toggle Green LED
+ }
+ }
+}
+
+ /**
+ * @brief Display value on LCD
+ *
+ * Updates the LCD to display the value of a parameter
+ *
+ * @param[flow]
+ * uint32_t flow, a 32 bit interger to be displayed
+ *
+ * @return
+ *
+ * Void
+ */
+
+void updateLCD(uint32_t flow)
+{
+ CS = 0;
+ device.write(0xFF);
+ device.write((flow >> 24) & 0xFF);
+ device.write((flow >> 16) & 0xFF);
+ device.write((flow >> 8) & 0xFF);
+ device.write(flow & 0xFF);
+ CS = 1;
+}
+
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Feb 28 05:49:24 2018 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/5571c4ff569f \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shared.h Wed Feb 28 05:49:24 2018 +0000
@@ -0,0 +1,181 @@
+/**-----------------------------------------------------------------------------
+ \file shared.h
+-- --
+-- ECEN 5803 Mastering Embedded System Architecture --
+-- Project 1 Module 3 --
+-- Microcontroller Firmware --
+-- shared.h --
+-- --
+-------------------------------------------------------------------------------
+--
+-- Designed for: University of Colorado at Boulder
+--
+--
+-- Designed by: Tim Scherr
+-- Revised by: Glenn Feinberg and George Abi-Nader
+--
+-- Version: 2.0
+-- 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: Header file for all globals
+--
+-- Copyright (c) 2015 Tim Scherr All rights reserved.
+--
+*/
+
+ #include "mbed.h"
+
+ /*****************************************************************************
+* #defines available to all modules included here
+******************************************************************************/
+#define OFF 0 /* used for readability */
+#define ON 1 /* used for readability */
+#define NO 0 /* used for readability */
+#define YES 1 /* used for readability */
+#define TEN 10
+
+#define TIMER0 TMR0
+#define SEC 10000 /* 10000 timer0 interrupts per second (100 usec.) */
+
+#define T100MS 0.1*SEC
+#define T2S 2*SEC
+
+#define LED_FLASH_PERIOD .5 /* in seconds */
+
+#define CLOCK_FREQUENCY_MHZ 8
+#define CODE_VERSION "2.0 2016/09/29" /* YYYY/MM/DD */
+#define COPYRIGHT "Copyright (c) University of Colorado"
+
+#define rho(TEMP) 1000*(1-(TEMP+288.9414)/(508929.2*(TEMP+68.12963))*(TEMP-3.9863)*(TEMP-3.9863))
+
+ enum boolean { FALSE, TRUE }; /// \enum boolean
+ enum dmode {QUIET, NORMAL, DEBUG, VERSION, RESET};
+
+ typedef unsigned char UCHAR;
+ typedef unsigned char bit;
+ typedef unsigned int uint32_t;
+ typedef unsigned short uint16_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/************************************************************************/
+/* Global Variable declarations */
+/************************************************************************/
+
+ extern unsigned char Error_status; // Variable for debugging use
+ extern UCHAR display_timer; // \var 1 second software timer for display
+ extern UCHAR display_flag; // flag between timer interrupt and monitor.c,
+ // like a binary semaphore
+ extern UCHAR adc_flag; // flag which times ADC sampling using the timer
+ // interrupt semaphore to main
+ extern UCHAR heartbeat_timer;
+ extern UCHAR heartbeat_flag;
+ extern UCHAR tx_in_progress;
+ extern UCHAR *rx_in_ptr; /* pointer to the receive in data */
+ extern UCHAR *rx_out_ptr; /* pointer to the receive out data*/
+ extern UCHAR *tx_in_ptr; /* pointer to the transmit in data*/
+ extern UCHAR *tx_out_ptr; /*pointer to the transmit out */
+ extern uint32_t flowG, F, Temp;
+
+#define RX_BUF_SIZE 10 /* size of receive buffer in bytes */
+#define TX_BUF_SIZE 80 /* size of transmit buffer in bytes */
+ extern Timer timer;
+
+/******************************************************************************
+* Some variable definitions are done in the module main.c and are externed in
+* all other modules. The following section is visible to main.c only.
+******************************************************************************/
+#ifdef MAIN
+
+ enum dmode display_mode = QUIET;
+
+ UCHAR serial_flag = 0;
+
+ UCHAR tx_in_progress;
+ UCHAR *rx_in_ptr; /* pointer to the receive in data */
+ UCHAR *rx_out_ptr; /* pointer to the receive out data*/
+ UCHAR *tx_in_ptr; /* pointer to the transmit in data*/
+ UCHAR *tx_out_ptr; /*pointer to the transmit out */
+
+ UCHAR rx_buf[RX_BUF_SIZE]; /* define the storage */
+ UCHAR tx_buf[TX_BUF_SIZE]; /* define the storage */
+
+#define MSG_BUF_SIZE 10
+ UCHAR msg_buf[MSG_BUF_SIZE]; // define the storage for UART received messages
+ UCHAR msg_buf_idx = 0; // index into the received message buffer
+
+/******************************************************************************
+* Some variable definitions are done in the module main.c and are externed in
+* all other modules. The following section is visible to all modules EXCEPT
+* main.c.
+*******************************************************************************/
+#else
+
+/**********************/
+/* Declarations */
+/**********************/
+
+ extern volatile UCHAR swtimer0;
+ extern volatile UCHAR swtimer1;
+ extern volatile UCHAR swtimer2;
+ extern volatile UCHAR swtimer3;
+ extern volatile UCHAR swtimer4;
+ extern volatile UCHAR swtimer5;
+ extern volatile UCHAR swtimer6;
+ extern volatile UCHAR swtimer7;
+
+ extern UCHAR serial_flag;
+
+ extern enum dmode display_mode;
+ extern uint32_t systemTime;
+
+ extern UCHAR rx_buf[]; /* declare the storage */
+ extern UCHAR tx_buf[]; /* declare the storage */
+
+#define MSG_BUF_SIZE 10
+ extern UCHAR msg_buf[MSG_BUF_SIZE]; // declare the storage for UART received messages
+ extern UCHAR msg_buf_idx; // index into the received message buffer
+#endif
+
+/*******************************************************************************
+* All function prototypes are externed in all the modules.
+*******************************************************************************/
+extern void monitor(void); /* located in module monitor.c */
+extern void timer0(void); /* located in module timer0.c */
+extern void serial(void); /* located in module UART_poll.c */
+extern void resetTimers(void); /* located in module timer0.x */
+
+extern void UART_put(UCHAR); /* located in module UART_poll.c */
+extern UCHAR UART_get(void); /* located in module UART_poll.c */
+extern UCHAR UART_input(void); /* located in module UART_poll.c */
+extern void UART_direct_msg_put(const char *);
+ /* located in module UART_poll.c */
+extern void UART_msg_put(const char *);
+ /* located in module UART_poll.c */
+extern void UART_direct_hex_put(UCHAR); /* located in module UART_poll.c */
+extern void UART_direct_put(UCHAR); /* located in module UART_poll.c */
+extern void UART_hex_put(UCHAR); /* located in module UART_poll.c */
+extern void UART_low_nibble_put(UCHAR); /* located in module UART_poll.c */
+extern void UART_high_nibble_put(UCHAR); /* located in module UART_poll.c */
+extern void chk_UART_msg(void); /* located in module monitor.c */
+extern void UART_msg_process(void); /* located in module monitors.c */
+extern void status_report(void); /* located in module monitor.c */
+extern void set_display_mode(void); /* located in module monitor.c */
+extern void reverse(char *str, uint32_t len); /* located in module monitor.c */
+extern void itoa(int32_t n, char s[]); /* located in module monitor.c */
+
+extern void updateLCD(uint32_t);
+extern void calculateFlow(void);
+extern void pulseOutput(void);
+extern void readADC(void);
+//extern void output420(void);
+#ifdef __cplusplus
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/timer0.cpp Wed Feb 28 05:49:24 2018 +0000
@@ -0,0 +1,313 @@
+/**----------------------------------------------------------------------------
+ *
+ * \file timer0.cpp
+-- --
+-- ECEN 5803 Mastering Embedded System Architecture --
+-- Project 1 Module 4 --
+-- Microcontroller Firmware --
+-- Timer0.cpp --
+-- --
+-------------------------------------------------------------------------------
+--
+-- Designed for: University of Colorado at Boulder
+--
+--
+-- Designed by: Tim Scherr
+-- Revised by: Glenn Feinberg and George Abi-Nader
+--
+-- Version: 2.1
+-- Date of current revision: 2017-09-25
+-- Target Microcontroller: Freescale MKL25ZVMT4
+-- Tools used: ARM mbed compiler
+-- ARM mbed SDK
+-- Freescale FRDM-KL25Z Freedom Board
+--
+--
+ Functional Description:
+ This file contains code for the only interrupt routine, based on the System
+ Timer.
+ The System Timer interrupt happens every
+ 100 us as determined by mbed Component Configuration.
+ The System Timer interrupt acts as the real time scheduler for the firmware.
+ Each time the interrupt occurs, different tasks are done based on critical
+ timing requirement for each task.
+ There are 256 timer states (an 8-bit counter that rolls over) so the
+ period of the scheduler is 25.6 ms. However, some tasks are executed every
+ other time (the 200 us group) and some every 4th time (the 400 us group) and
+ so on. Some high priority tasks are executed every time. The code for the
+ tasks is divided up into the groups which define how often the task is
+ executed. The structure of the code is shown below:
+
+ I. Entry and timer state calculation
+ II. 100 us group
+ A. Fast Software timers
+ B. Read Sensors
+ C. Update
+ III. 200 us group
+ A.
+ B.
+ IV. 400 us group
+ A. Medium Software timers
+ B.
+ V. 800 us group
+ A. Set 420 PWM Period
+ VI 1.6 ms group
+ A. Display timer and flag
+ B. Heartbeat/ LED outputs
+ VII 3.2 ms group
+ A. Slow Software Timers
+ VIII 6.4 ms group A
+ A. Very Slow Software Timers
+ IX. Long time group
+ A. Determine Mode
+ B. Heartbeat/ LED outputs
+ X. Exit
+
+--
+-- Copyright (c) 2015 Tim Scherr All rights reserved.
+*/
+
+
+#include "shared.h"
+//#include "mbed.h"
+//#include "MKL25Z4.h"
+#define System Timer_INCREMENT_IN_US 1000
+
+ typedef unsigned char UCHAR;
+ typedef unsigned char bit;
+ typedef unsigned int uint32_t;
+ typedef unsigned short uint16_t;
+
+/*******************/
+/* Configurations */
+/*******************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**********************/
+/* Definitions */
+/**********************/
+
+ volatile UCHAR swtimer0 = 0;
+ volatile UCHAR swtimer1 = 0;
+ volatile UCHAR swtimer2 = 0;
+ volatile UCHAR swtimer3 = 0;
+ volatile UCHAR swtimer4 = 0;
+ volatile UCHAR swtimer5 = 0;
+ volatile UCHAR swtimer6 = 0;
+ volatile UCHAR swtimer7 = 0;
+
+ volatile uint16_t SwTimerIsrCounter = 0U;
+ UCHAR display_timer = 0; // 1 second software timer for display
+ UCHAR display_flag = 0; // flag between timer interrupt and monitor.c, like
+ // a binary semaphore
+
+ static uint32_t System_Timer_count = 0; // 32 bits, counts for
+ // 119 hours at 100 us period
+ static uint16_t timer0_count = 0; // 16 bits, counts for
+ // 6.5 seconds at 100 us period
+ static UCHAR timer_state = 0;
+ static UCHAR long_time_state = 0;
+ uint32_t systemTime = 0;
+ // variable which splits timer_states into groups
+ // tasks are run in their assigned group times
+// DigitalOut BugMe (PTB9); // debugging information out on PTB9
+#ifdef __cplusplus
+}
+#endif
+
+/*********************************/
+/* Start of Code */
+/*********************************/
+// I. Entry and Timer State Calculation
+
+void timer0(void)
+ {
+
+ // BugMe = 1; // debugging signal high during Timer0 interrupt on PTB9
+
+/************************************************/
+// Determine Timer0 state and task groups
+/************************************************/
+ timer_state++; // increment timer_state each time
+ if (timer_state == 0)
+ {
+ long_time_state++; // increment long time state every 25.6 ms
+
+ }
+
+/*******************************************************************/
+/* 100 us Group */
+/*******************************************************************/
+// II. 100 us Group
+
+// A. Update Fast Software timers
+ if (swtimer0 > 0) // if not yet expired,
+ (swtimer0)--; // then decrement fast timer (1 ms to 256 ms)
+ if (swtimer1 > 0) // if not yet expired,
+ (swtimer1)--; // then decrement fast timer (1 ms to 256 ms)
+
+// B. Update Sensors
+
+ /**************** ECEN 5803 add code as indicated ***************/
+ // adc_flag = 1; // time to sample the ADC in main
+
+/*******************************************************************/
+/* 200 us Group */
+/*******************************************************************/
+
+ if ((timer_state & 0x01) != 0) // 2 ms group, odds only
+ {
+ ;
+ } // end 2 ms group
+
+/*******************************************************************/
+/* 400 us Group */
+/*******************************************************************/
+ else if ((timer_state & 0x02) != 0)
+ {
+// IV. 400 us group
+// timer states 2,6,10,14,18,22,...254
+
+// A. Medium Software timers
+ if (swtimer2 > 0) // if not yet expired, every other time
+ (swtimer2)--; // then decrement med timer (4 ms to 1024 ms)
+ if (swtimer3 > 0) // if not yet expired, every other time
+ (swtimer3)--; // then decrement med timer (4 ms to 1024 ms)
+
+// B.
+ } // end 400 us group
+
+/*******************************************************************/
+/* 800 us Group */
+/*******************************************************************/
+ else if ((timer_state & 0x04) != 0)
+ {
+// V. 8 ms group
+// timer states 4, 12, 20, 28 ... 252 every 1/8
+
+// A. Set
+ } // end 800 us group
+
+/*******************************************************************/
+/* 1.6 ms Group */
+/*******************************************************************/
+ else if ((timer_state & 0x08) != 0)
+ {
+// VI 1.6 ms group
+// timer states 8, 24, 40, 56, .... 248 every 1/16
+
+ } // end 1.6 ms group
+
+/*******************************************************************/
+/* 3.2 ms Group */
+/*******************************************************************/
+ else if ((timer_state & 0x10) != 0)
+ {
+// VII 3.2 ms group
+// timer states 16, 48, 80, 112, 144, 176, 208, 240
+
+// A. Slow Software Timers
+ if (swtimer4 > 0) // if not yet expired, every 32nd time
+ (swtimer4)--; // then decrement slow timer (32 ms to 8 s)
+ if (swtimer5 > 0) // if not yet expired, every 32nd time
+ (swtimer5)--; // then decrement slow timer (32 ms to 8 s)
+
+// B. Update
+
+ } // end 3.2 ms group
+
+/*******************************************************************/
+/* 6.4 ms Group A */
+/*******************************************************************/
+ else if ((timer_state & 0x20) != 0)
+ {
+// VIII 6.4 ms group A
+// timer states 32, 96, 160, 224
+
+// A. Very Slow Software Timers
+ if (swtimer6 > 0) // if not yet expired, every 64th
+ // time
+ (swtimer6)--; // then decrement very slow timer (6.4 ms to 1.6s)
+
+ if (swtimer7 > 0) // if not yet expired, every 64th
+ // time
+ (swtimer7)--; // then decrement very slow timer (64 ms to 1.6s)
+
+// B. Update
+
+ } // end 6.4 ms group A
+
+/*******************************************************************/
+/* 6.4 ms Group B */
+/*******************************************************************/
+ else
+ {
+// IX. 6.4 ms group B
+// timer states 0, 64, 128, 192
+
+// A. Update
+
+// A. Display timer and flag
+ display_timer--; // decrement display timer every 6.4 ms. Total time is
+ // 256*6.4ms = 1.6384 seconds.
+ if (display_timer == 1)
+ display_flag = 1; // every 1.6384 seconds, now OK to display
+
+
+// B. Heartbeat/ LED outputs
+// Generate Outputs ************************************
+
+ //ECEN 5803 add code as indicated
+ // Create an 0.5 second RED LED heartbeat here.
+
+
+
+ } // end 6.4 ms group B
+
+/*******************************************************************/
+/* Long Time Group */
+/*******************************************************************/
+ if (((long_time_state & 0x01) != 0) && (timer_state == 0))
+ // every other long time, every 51.2 ms
+ {
+// X. Long time group
+//
+// clear_watchdog_timer();
+ }
+// Re-enable interrupts and return
+ System_Timer_count++;
+ timer0_count++;
+ SwTimerIsrCounter++;
+ systemTime = System_Timer_count;
+// Bugme = 0; // debugging signal high during Timer0 interrupt on PTB9
+ // unmask Timer interrupt (now done by mBed library)
+
+ // enables timer interrupt again (now done by mBed Library
+
+}
+/*!
+ * @brief Reset Timers
+ *
+ * This function resets the timers that are incremented in Timer 0 Module
+ *
+ * @return void
+*/
+void resetTimers()
+{
+ System_Timer_count = 0;
+ systemTime = 0;
+ timer0_count = 0;
+ SwTimerIsrCounter = 0;
+ swtimer0 = 0;
+ swtimer1 = 0;
+ swtimer2 = 0;
+ swtimer3 = 0;
+ swtimer4 = 0;
+ swtimer5 = 0;
+ swtimer6 = 0;
+ swtimer7 = 0;
+ timer_state = 0;
+ long_time_state = 0;
+}
+