Libraries and Example of mbed parallel bus using I2C port expanders

Dependencies:   HDSP253X mbed PCF8574_Bus

Files at this revision

API Documentation at this revision

Comitter:
wim
Date:
Fri Aug 26 20:35:11 2011 +0000
Parent:
4:745fbbd5e4e5
Child:
6:aaefa04f06be
Commit message:
Included Messages to Host

Changed in this revision

HDSP253X_Display.cpp Show annotated file Show diff for this revision Revisions of this file
HDSP253X_Display.h Show annotated file Show diff for this revision Revisions of this file
Host_Coms.cpp Show annotated file Show diff for this revision Revisions of this file
Host_Coms.h Show annotated file Show diff for this revision Revisions of this file
Keyboard.cpp Show annotated file Show diff for this revision Revisions of this file
Keyboard.h Show annotated file Show diff for this revision Revisions of this file
Status_Display.cpp Show annotated file Show diff for this revision Revisions of this file
Status_Display.h Show annotated file Show diff for this revision Revisions of this file
Testloop.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/HDSP253X_Display.cpp	Tue Aug 23 20:26:05 2011 +0000
+++ b/HDSP253X_Display.cpp	Fri Aug 26 20:35:11 2011 +0000
@@ -162,7 +162,7 @@
  |
  |  Parameters:     address - full address in bits 0-5 (bit 5 is flash)
  |
- |  Returns:        data - data byte read in
+ |  Returns:        data - data byte read in (Note that D7 is masked out)
  |
 \*---------------------------------------------------------------------------*/
 
@@ -174,8 +174,7 @@
     _databus.busdir(READ);        
     // Switch databus buffer to inputs
     _controlbus.busdir(READ);      
-    
-    
+       
     // Write out the address on to the addressbus and wait
     _addressbus.write(address);
     wait_ms(HDSP253X_1TCY_WAIT_MS);
@@ -189,7 +188,10 @@
     wait_ms(HDSP253X_1TCY_WAIT_MS);
     
     // Read the data byte from databus
-    data = _databus.read();
+    // Mask out the not-readable D7 bit, this mask is needed for my specific targetboard !
+    // Reading the unconnected D7 bit results in 'H' level. A RMW cycle on the Ctrl register
+    // would then always result in a Clearscreen !
+    data = _databus.read() & HDSP253X_CTRL_MASK;
 
     // set RD high and wait
     _controlbus.RD(HIGH);
@@ -263,8 +265,6 @@
     udc_char |= HDSP253X_UDC_SEL;         // add in top bit to specify UDC
     _write(HDSP253X_ADDR_CHAR_BASE + char_pos, udc_char);
 }
-#endif
-
 
 
 /*---------------------------------------------------------------------------*\
@@ -339,7 +339,7 @@
       _write(HDSP253X_ADDR_CHAR_BASE + i, char_value);
     }
 }
-
+#endif
 
 /*---------------------------------------------------------------------------*\
  |
--- a/HDSP253X_Display.h	Tue Aug 23 20:26:05 2011 +0000
+++ b/HDSP253X_Display.h	Fri Aug 26 20:35:11 2011 +0000
@@ -141,6 +141,10 @@
 #define HDSP253X_CTRL_SELFTEST_MASK 0x40 
 #define HDSP253X_CTRL_CLEAR_MASK    0x80 
 
+// Masks for register read, Bit 7 not readable in the target hardware 
+#define HDSP253X_CTRL_MASK          0x7F 
+
+
 // display brightness definitions, indicating percentage brightness
 #define HDSP253X_BRIGHT_100         0x00
 #define HDSP253X_BRIGHT_80          0x01
@@ -161,30 +165,7 @@
 
 
 // default display brightness
-#define HDSP253X_DEF_DISPLAY_BRIGHT HDSP253X_BRIGHT_53
-
-#if(0)
-// static array of display brightness to index number setting
-static byte disp_bright_lookup[] =
-{
-    HDSP253X_BRIGHT_100,    // 0
-    HDSP253X_BRIGHT_13,        // 1
-    HDSP253X_BRIGHT_20,        // 2
-    HDSP253X_BRIGHT_27,        // 3
-    HDSP253X_BRIGHT_40,        // 4
-    HDSP253X_BRIGHT_53,        // 5
-    HDSP253X_BRIGHT_53,        // 6
-    HDSP253X_BRIGHT_80,        // 7
-    HDSP253X_BRIGHT_80,        // 8
-    HDSP253X_BRIGHT_100        // 9
-};
-#endif
-
-#if (0)
-//Enums for HDSP253X Display
-enum HDSP253X_Brightness { HDSP253X_Bright_0, HDSP253X_Bright_13, HDSP253X_Bright_20, HDSP253X_Bright_27,
-                             HDSP253X_Bright_40, HDSP253X_Bright_53, HDSP253X_Bright_80, HDSP253X_Bright_100 };
-#endif
+#define HDSP253X_DEF_DISPLAY_BRIGHT HDSP253X_BRIGHT_100
 
 
 /** Create an HDSP253X_Display object connected to the proper busses
@@ -231,8 +212,8 @@
     void _init(); 
 //    void _display_ascii_char(char ascii_char, uint8_t char_pos);  
 //    void _display_udc_char(char udc_char, uint8_t char_pos);  
-    void _display_part_string(const char *disp_string, uint8_t start_pos, uint8_t end_pos);  
-    void _display_fixed_string(const char *disp_string, uint8_t start_pos);
+//    void _display_part_string(const char *disp_string, uint8_t start_pos, uint8_t end_pos);  
+//    void _display_fixed_string(const char *disp_string, uint8_t start_pos);
           
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Host_Coms.cpp	Fri Aug 26 20:35:11 2011 +0000
@@ -0,0 +1,526 @@
+/* Host_Coms - Communications with Host PC
+ *
+ * Copyright (c) 2011 Wim Huiskamp
+ *
+ * Released under the MIT License: http://mbed.org/license/mit
+ *
+ * version 0.2 Initial Release
+*/
+#include "mbed.h"
+#include "Host_Coms.h"
+
+
+/** Create a Host Coms object connected to the proper channel
+ *
+ * @param  Serial serial channel to connect to 
+ * @brief 
+*/
+Host_Coms::Host_Coms(Serial &hostChannel) : _hostChannel(hostChannel) {
+  
+  _init();  
+}   
+
+
+/** Send a formatted string to the Host PC
+ * @param
+ * @returns int message length
+ */
+int Host_Coms::sendString(char * format, ...) {
+   va_list args;
+   va_start (args, format);
+   int rv;
+
+   rv = _hostChannel.printf(format, args);
+
+   va_end (args);
+
+   return rv;
+}
+
+
+
+/** Send a formatted message to the Host PC
+ * @param
+ * @returns int message length
+ */
+int Host_Coms::sendMessage(char * format, ...) {
+   va_list args;
+   va_start (args, format);
+   int rv=vsprintf (_sendBuffer, format, args);
+
+//   _hostChannel.printf("%s:len=%d\r\n", _sendBuffer, strlen(_sendBuffer));
+   
+   _hostChannel.printf("%s*%02X\r\n", _sendBuffer, _calcChecksum());
+
+   va_end (args);
+
+   return (rv + 5);  // length + * + checksum + <CR> + <NL>
+}
+
+/** Compute the XOR checksum on the message
+ * @param
+ * @returns int checksum
+ */
+int Host_Coms::_calcChecksum() {
+  int checksum = 0;
+  int i, last;
+
+  //_sendBuffer[0] should be '$' and is ignored in checksum  
+  last = strlen(_sendBuffer);
+  for (i=1; i<last; i++) {
+    checksum ^= (int) _sendBuffer[i];
+  }  
+  
+  return checksum;
+}
+
+
+/** Parse the LFRNG message and decode the fields
+ * @param
+ * @returns bool valid message 
+ * @brief
+ */
+bool Host_Coms::_parseLFRNG(char *data) {
+   char *token;
+   int tokenfield;
+   bool result=true;
+   
+//   char hostmessage[] = "1234,5678,0";
+//   strcpy(hostmessage, "1234,5678,0");
+      
+   token = strtok(data, ","); // get first token, separator is ','
+   tokenfield = 1;   
+
+   while ((token != NULL) && (tokenfield <= 3)) {     
+     switch (tokenfield) {
+        case 1:
+                // Range First
+                _hostChannel.printf("#%d: %s\r\n", tokenfield, token);
+                
+                // Convert and perform sanity check
+                rangeFirst = atoi(token);
+                if ((rangeFirst < 0) || (rangeFirst > 9999)) {
+                  rangeFirst = 0;
+                  result=false;
+                }
+                _hostChannel.printf("#%d: int=%04d\r\n", tokenfield, rangeFirst);                
+                break;
+
+        case 2:
+                // Range Last
+                _hostChannel.printf("#%d: %s\r\n", tokenfield, token);
+
+                // Convert and perform sanity check
+                rangeLast = atoi(token);
+                if ((rangeLast < 0) || (rangeLast > 9999)) {
+                  rangeLast = 0;
+                  result=false;
+                }
+
+                _hostChannel.printf("#%d: int=%04d\r\n", tokenfield, rangeLast);                                
+                break;
+
+        case 3:
+                // Multiple Returns
+                _hostChannel.printf("#%d: %s\r\n", tokenfield, token);
+
+                // Convert and perform sanity check
+                mult = atoi(token);
+                if ((mult < 0) || (mult > 1)) {
+                  mult = 0;
+                  result=false;
+                }
+
+                _hostChannel.printf("#%d: int=%1d\r\n", tokenfield, mult);                
+                break;
+
+        default:
+                break;
+     } // switch
+     
+     token = strtok(NULL, ","); // Get next token
+     tokenfield++;     
+   } // while
+
+   // Could do additional sanity check on correct number of fields
+      
+   return result;
+}
+
+/** Parse the LFRES message and decode the fields
+ * @param
+ * @returns bool valid message
+ * @brief
+ */
+bool Host_Coms::_parseLFRES(char *data) {
+   char *token;
+   int tokenfield;
+   int STANAG_Code;
+   bool result=true;
+      
+   token = strtok(data, ","); // get first token, separator is ','
+   tokenfield = 1;   
+   
+   while ((token != NULL) && (tokenfield <= D_HOST_STANAG_CODES)) {   
+     switch (tokenfield) {
+        case 1:
+        case 2:        
+        case 3:        
+        case 4:
+        case 5:                        
+        case 6:
+        case 7:        
+        case 8:        
+        case 9:
+        case 10:                        
+        case 11:
+        case 12:        
+        case 13:        
+        case 14:
+        case 15:                        
+        case 16:
+        case 17:        
+        case 18:        
+        case 19:
+        case 20:                        
+                _hostChannel.printf("#%d: %s\r\n", tokenfield, token);
+                
+                // STANAG_Code[i] and sanity check
+                STANAG_Code = atoi(token);
+                if ((STANAG_Code < 0) || (STANAG_Code > 9999)) {
+//                if (STANAG_Code < 0) || (STANAG_Code > 1999) {    // Check on limited code value            
+                  STANAG_Code = 0;
+                  result = false;
+                }
+                 
+                STANAG_Codes[tokenfield - 1] = STANAG_Code;                 
+
+                _hostChannel.printf("#%d: %s\r\n", tokenfield, STANAG_Codes[tokenfield - 1]);
+
+                break;
+
+        default:
+                break;
+     } // switch
+     
+     token = strtok(NULL, ","); // Get next token
+     tokenfield++;     
+   } // while
+   
+   // Could do additonal sanity check on correct number of fields
+   
+   return result;
+}
+
+
+/** Receive and Parse the Host message
+ * @param
+ * @returns Host_Mess message type that was received
+ * @brief 
+ *              Check LF28A Host channel and Parse received data for valid messages.
+ *              Since the parser is a state machine, partial data may
+ *              be supplied where the next time this method is called, the
+ *              rest of the partial data will complete the message and 
+ *              parsing will begin. A typical message is constructed as:
+ *
+ *                  $LFCMD,DDDD,DDDD,....DD*CS<CR><LF>
+ *
+ *              Where:
+ *                        '$'            Hex 24 (Start of Message)
+ *                        'LFCMD'        LF28A command or data
+ *                        ',DDDD'        Zero or more data fields
+ *                        '*CS'          Checksum field (optional)
+ *                        <CR><LF>       Hex 0D 0A (End of Message)
+ *
+ *              When a complete message is received, this function sends the
+ *              LF28A command and data to the parseCommand methods for
+ *              individual field parsing. The received data will be stored
+ *              in a datastructure. The return value informs the caller which
+ *              command has been received to decide on proper action. 
+ */
+Host_Mess Host_Coms::parseMessage() {
+  char data;
+  static int cmdIdx = 0;                    // index for received command
+  static int datIdx = 0;                    // index for received data
+  static int computedChecksum = 0;          // computed from the received data   
+  static int receivedChecksum = 0;          // checksum that was part of the received data
+  static bool checksumReceived = false;     // received data included the optional checksum
+  static bool messageComplete = false;      // message has been received that is ready for decoding
+  Host_Mess   messageType;                  // valid decoded message type   
+  static LFP_State parseState = LFP_STATE_SOM;
+     
+  // init while loop, no valid decoded message is available initially
+  messageType = HOST_CMD_NONE;
+  
+  // Continue reading from host as long as data is available or until a
+  // valid message has been received that needs to be processed first.
+  while ((_hostChannel.readable()) && (messageType == HOST_CMD_NONE)) {
+    data = _hostChannel.getc();
+
+    // The main state machine which processes individual characters
+    // until a complete message has been received that is ready for decoding.
+    switch(parseState) {
+      // Search for start of message '$'
+      case LFP_STATE_SOM :
+                            if(data == '$') {
+                              cmdIdx = 0;                   // reset index
+                              computedChecksum = 0;        // reset checksum
+                              receivedChecksum = 0; 
+                              messageComplete = false;     // restart                               
+                              checksumReceived = false;    // restart                                                             
+                              parseState = LFP_STATE_CMD;  // next state
+                              
+_hostChannel.printf("#start cmd\r\n");                              
+                            }
+  
+  
+                            break;
+
+      // Retrieve command field
+      case LFP_STATE_CMD :
+                            switch (data) {
+                              case ',':  
+                                        // terminate command
+                                        _command[cmdIdx] = '\0';
+
+                                        // update checksum
+                                        computedChecksum ^= (int) data;
+
+                                        // goto get data state
+                                        datIdx = 0;          // reset index                                                                                
+                                        parseState = LFP_STATE_DATA;
+_hostChannel.printf("#, end cmd\r\n");                                        
+                                        break;
+                              case '*':  
+                                        // terminate command
+                                        _command[cmdIdx] = '\0';
+
+                                        // goto get checksum state 
+                                        checksumReceived = true;                                                                               
+                                        parseState = LFP_STATE_CS1;   
+_hostChannel.printf("#* end cmd\r\n");
+                                        break;                                        
+
+                              case '\r':  
+                              case '\n':                                
+                                        // terminate command
+                                        _command[cmdIdx] = '\0';
+                                        
+                                        // done, decode data and restart
+                                        messageComplete = true;
+                                        parseState = LFP_STATE_SOM;
+_hostChannel.printf("#cr nl end cmd\r\n");
+                                        break;
+                                        
+                              case '$' : 
+                                        // unexpected restart 
+                                        cmdIdx = 0;                     // reset index
+                                        computedChecksum = 0;        // reset checksum 
+_hostChannel.printf("#$ restart cmd\r\n");                                        
+                                        break;
+
+                              default :  
+                                        // store command
+                                        _command[cmdIdx++] = data;                                        
+                                        
+                                        // update checksum
+                                        computedChecksum ^= (int) data;
+
+                                        // Check for command overflow
+                                        if (cmdIdx > D_HOST_MAX_CMD_LEN) {
+                                          parseState = LFP_STATE_SOM;  // something went wrong, restart
+                                        }
+                                        
+_hostChannel.printf("#in cmd\r\n");                                        
+                                        break;                                                                               
+                                        
+                           } // switch (data)
+                           break;
+
+        // Store data and check for end of sentence or checksum flag
+        case LFP_STATE_DATA :
+                           switch (data) {
+                              case '*':  
+                                        // terminate data
+                                        _data[datIdx] = '\0';
+
+                                        // goto get checksum state
+                                        checksumReceived = true;
+                                        parseState = LFP_STATE_CS1;
+_hostChannel.printf("#* end data\r\n");                                                                                                                                                                   
+                                        break;                                        
+
+                              case '\r':  
+                              case '\n':                                
+                                        // terminate data
+                                        _data[datIdx] = '\0';
+                                        
+                                        // done, decode data and restart
+                                        messageComplete = true;
+                                        parseState = LFP_STATE_SOM;
+_hostChannel.printf("#cr nl end data\r\n");                                                                                    
+                                        break;
+
+                              case '$' : 
+                                        // unexpected restart 
+                                        cmdIdx = 0;                     // reset index
+                                        computedChecksum = 0;        // reset checksum 
+
+                                        parseState = LFP_STATE_CMD;  // restart                                      
+_hostChannel.printf("#$ in data, restart cmd\r\n");                                        
+                                        break;
+                                        
+                              default :  
+                                        // store data
+                                        _data[datIdx++] = data;                                        
+
+                                        // update checksum
+                                        computedChecksum ^= (int) data;
+                                        
+                                        // Check for data overflow
+                                        if (datIdx > D_HOST_MAX_DATA_LEN) {
+                                          parseState = LFP_STATE_SOM;  // something went wrong, restart
+                                        }
+                                        
+_hostChannel.printf("#in data\r\n");                                                                                
+                                        break;                                                                               
+                                        
+                           } // switch (data)
+                           break;
+        
+        // Handle checksum (part1) from sentence
+        case LFP_STATE_CS1 :
+        
+                           if ((data >= '0') && (data <= '9')) {
+                             receivedChecksum = (data - '0') << 4;
+                             parseState = LFP_STATE_CS2;
+                           }
+                           else if ((data >= 'a') && (data <= 'f')) {
+                             receivedChecksum = ((data - 'a') + 10) << 4;
+                             parseState = LFP_STATE_CS2;                             
+                           }
+                           else if ((data >= 'A') && (data <= 'F')) {
+                             receivedChecksum = ((data - 'A') + 10) << 4;
+                             parseState = LFP_STATE_CS2;                             
+                           }
+                           else {
+                             // not a valid checksum
+                             parseState = LFP_STATE_SOM;  // something went wrong, restart
+                           }
+                      
+                           break;
+
+        // Handle checksum (part2) from sentence
+        case LFP_STATE_CS2 :
+        
+                           if ((data >= '0') && (data <= '9')) {
+                             receivedChecksum |= (data - '0');
+                             
+                             // done, decode data and restart
+                             messageComplete = true;
+                             parseState = LFP_STATE_SOM;                            
+                           }
+                           else if ((data >= 'a') && (data <= 'f')) {
+                             receivedChecksum |= (data - 'a') + 10;
+
+                             // done, decode data and restart
+                             messageComplete = true;
+                             parseState = LFP_STATE_SOM;                            
+                           }
+                           else if ((data >= 'A') && (data <= 'F')) {
+                             receivedChecksum |= (data - 'A') + 10;
+                             parseState = LFP_STATE_SOM;                             
+
+                             // done, decode data and restart
+                             messageComplete = true;
+                             parseState = LFP_STATE_SOM;                                                        
+                           }
+                           else {
+                             // not a valid checksum
+                             parseState = LFP_STATE_SOM;  // something went wrong, restart
+                           }
+                      
+                           break;
+        
+
+        // Something went wrong, restart
+        default :
+                           parseState = LFP_STATE_SOM;    
+    } // switch (_parseState)
+    
+    
+    // Check if done with this message
+    if (messageComplete) {
+_hostChannel.printf("#complete\r\n");                                                                                    
+      if (!checksumReceived) {      
+        // No checksum received, process message
+        messageType = _parseCommand(_command, _data);     
+      }
+      else if (computedChecksum == receivedChecksum) {        
+        // Correct checksum, process message              
+        messageType = _parseCommand(_command, _data);
+      }
+      else {
+       // Ignore messages with an invalid checksum
+        messageType = HOST_CMD_NONE;               
+      }
+      
+      // done processing this received message
+      messageComplete = false;
+    }
+
+                                
+  } // while readable and no valid message available
+
+  
+  // inform the caller when a valid message is available
+  return messageType;
+} // _parseMessage
+
+
+/** Receive and Parse the Host command from the message
+ * @param
+ * @returns Host_Mess valid command type
+ * @brief 
+ *          Process LFCMD message - Use the _command and _data strings to call the
+ *          appropriate command sentence data processor.
+ *          Return which command has been received to let caller decide on proper action !!
+*/
+Host_Mess Host_Coms::_parseCommand(char *command, char *data) {
+  Host_Mess result = HOST_CMD_NONE; 
+
+  //
+  // LFRES
+  //
+  if (strcmp(command, "LFRES") == NULL) {
+    if (_parseLFRES(data))
+      result = HOST_CMD_RES;
+  }
+  //
+  // LFRNG
+  //
+  else if (strcmp(command, "LFRNG") == NULL) {
+    if (_parseLFRNG(data))
+      result = HOST_CMD_RNG;
+  } 
+
+  return result;
+}
+
+
+
+/** Init Host_Coms
+ * @param
+ * @returns 
+ */
+void Host_Coms::_init(void) {
+  int i;
+  
+  rangeFirst=0;
+  rangeLast=0;
+  mult=0;
+  
+  for (i=0; i<D_HOST_STANAG_CODES; i++) {
+    STANAG_Codes[i]=0;
+  }  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Host_Coms.h	Fri Aug 26 20:35:11 2011 +0000
@@ -0,0 +1,70 @@
+/* Host_Coms - Communications with Host PC
+ *
+ * Copyright (c) 2011 Wim Huiskamp
+ *
+ * Released under the MIT License: http://mbed.org/license/mit
+ *
+ * version 0.2 Initial Release
+*/
+#ifndef _HOST_COMS_H
+#define _HOST_COMS_H
+
+#include <stdarg.h>
+#include <string.h>
+
+/*****************************************************************************/
+/*********************  DEFINITIONS FOR HOST_COMS  ***************************/
+/*****************************************************************************/
+
+// Definitions for Host Comms
+#define D_HOST_MAX_MESS_LEN             255
+#define D_HOST_MAX_DATA_LEN             255
+#define D_HOST_MAX_TOKEN_LEN              4
+#define D_HOST_MAX_CMD_LEN                5
+#define D_HOST_STANAG_CODES              20
+
+// Masks
+
+// Enums
+enum LFP_State {LFP_STATE_SOM, LFP_STATE_CMD, LFP_STATE_DATA, LFP_STATE_CS1, LFP_STATE_CS2};   // Message Parser States
+enum Host_Mess {HOST_CMD_NONE, HOST_CMD_RES, HOST_CMD_RNG,                                     // Message Types Host to LF28A Mockup  
+                HOST_MESS_NONE, HOST_MESS_RDY1, HOST_MESS_RDY2, HOST_MESS_STATE};              // Message Types LF28A to Host
+
+
+/** Create a Host Coms object connected to the proper channel
+ *
+ * @param  Serial serial channel to connect to 
+ * @brief 
+*/
+class Host_Coms {
+
+public:
+  Host_Coms(Serial &hostChannel);         
+  int sendString(char * format, ...);  
+  int sendMessage(char * format, ...);
+  Host_Mess parseMessage();
+    
+  int rangeFirst, rangeLast, mult;
+  int STANAG_Codes[D_HOST_STANAG_CODES];
+
+  char _data[D_HOST_MAX_DATA_LEN + 1];           // leave room for '\0'
+
+  bool _parseLFRNG(char *data);
+  bool _parseLFRES(char *data);
+  Host_Mess _parseCommand(char *command, char *data);  
+        
+protected:
+  Serial &_hostChannel;
+  char _sendBuffer[D_HOST_MAX_MESS_LEN + 1];     // leave room for '\0'
+//  char _receiveBuffer[D_HOST_MAX_MESS_LEN + 1];  // leave room for '\0'
+  char _command[D_HOST_MAX_CMD_LEN + 1];         // leave room for '\0'  
+  
+  void _init();          
+  int _calcChecksum();
+};
+
+
+#endif
+/*****************************************************************************/
+/******************************  END OF FILE  ********************************/
+/*****************************************************************************/
--- a/Keyboard.cpp	Tue Aug 23 20:26:05 2011 +0000
+++ b/Keyboard.cpp	Fri Aug 26 20:35:11 2011 +0000
@@ -50,21 +50,7 @@
     _KeyReady = true;
         
     // Get the switchvalue and decode it
-    data = _read() & D_KEYBOARD_MASK;       
-    switch (data) {
-      case D_KEYBOARD_MODE:      _KeyCode = KEY_MODE;
-                                 break;
-      case D_KEYBOARD_EDIT_PATH: _KeyCode = KEY_EDIT_PATH;
-                                 break;
-      case D_KEYBOARD_BRIGHT:    _KeyCode = KEY_BRIGHT;
-                                 break;                               
-      case D_KEYBOARD_GRAT_RT:   _KeyCode = KEY_GRAT_RT;
-                                 break;
-      case D_KEYBOARD_F_L_UP:    _KeyCode = KEY_F_L_UP;
-                                 break;
-      default:                   _KeyCode = KEY_NONE;
-                                 break;                               
-    }
+    _KeyCode = getswitch();
   }
 
   if (_controlbus.FIRE() == HIGH) {
@@ -95,6 +81,36 @@
 }
 
 
+/** Get keycode for pressed switch
+ *
+ * @param none
+ * @returns keycode 
+*/
+Key_Code Keyboard::getswitch() {
+  uint8_t data = 0;
+  Key_Code code;
+
+  // Get the switchvalue and decode it
+  data = _read() & D_KEYBOARD_MASK;       
+  switch (data) {
+    case D_KEYBOARD_MODE:      code = KEY_MODE;
+                               break;
+    case D_KEYBOARD_EDIT_PATH: code = KEY_EDIT_PATH;
+                               break;
+    case D_KEYBOARD_BRIGHT:    code = KEY_BRIGHT;
+                               break;                               
+    case D_KEYBOARD_GRAT_RT:   code = KEY_GRAT_RT;
+                               break;
+    case D_KEYBOARD_F_L_UP:    code = KEY_F_L_UP;
+                               break;
+    default:                   code = KEY_NONE;
+                               break;                               
+  }
+   
+  return code;
+}
+
+
 /** Read switch value
  *
  * @param none
--- a/Keyboard.h	Tue Aug 23 20:26:05 2011 +0000
+++ b/Keyboard.h	Fri Aug 26 20:35:11 2011 +0000
@@ -43,6 +43,7 @@
                PCF8574_EnableBus &enablebus, MBED_ControlBus &controlbus);
     bool readable ();
     Key_Code getkey();
+    Key_Code getswitch();    
             
 protected:
     PCF8574_DataBus &_databus;
--- a/Status_Display.cpp	Tue Aug 23 20:26:05 2011 +0000
+++ b/Status_Display.cpp	Fri Aug 26 20:35:11 2011 +0000
@@ -172,10 +172,10 @@
   // The LED is controlled from this class because it is more convenient and logical
   
   if (NoGo_state == LED_ON) {
-    _enablebus.nogo(HIGH);     // NoGo LED On
+    _enablebus.nogo(LOW);     // NoGo LED On
   }              
   else {
-    _enablebus.nogo(LOW);      // NoGo LED Off
+    _enablebus.nogo(HIGH);    // NoGo LED Off
   }     
   
 }
--- a/Status_Display.h	Tue Aug 23 20:26:05 2011 +0000
+++ b/Status_Display.h	Fri Aug 26 20:35:11 2011 +0000
@@ -54,10 +54,15 @@
 #define STATUS_LED_BRIGHT_MASK      0x07 
 
 // Display brightness modes
-#define D_STATUS_LED_BRIGHT_OFF     D_STATUS_LED_BRIGHT_000
-#define D_STATUS_LED_BRIGHT_LOW     D_STATUS_LED_BRIGHT_053
+//#define D_STATUS_LED_BRIGHT_OFF     D_STATUS_LED_BRIGHT_000
+//#define D_STATUS_LED_BRIGHT_LOW     D_STATUS_LED_BRIGHT_053
+//#define D_STATUS_LED_BRIGHT_MED     D_STATUS_LED_BRIGHT_570
+//#define D_STATUS_LED_BRIGHT_HGH     D_STATUS_LED_BRIGHT_360
+//Test values
+#define D_STATUS_LED_BRIGHT_OFF     D_STATUS_LED_BRIGHT_053
+#define D_STATUS_LED_BRIGHT_LOW     D_STATUS_LED_BRIGHT_112
 #define D_STATUS_LED_BRIGHT_MED     D_STATUS_LED_BRIGHT_570
-#define D_STATUS_LED_BRIGHT_HGH     D_STATUS_LED_BRIGHT_360
+#define D_STATUS_LED_BRIGHT_HGH     D_STATUS_LED_BRIGHT_129
 
 // default display brightness
 #define D_STATUS_LED_BRIGHT_DEF     D_STATUS_LED_BRIGHT_LOW
--- a/Testloop.h	Tue Aug 23 20:26:05 2011 +0000
+++ b/Testloop.h	Fri Aug 26 20:35:11 2011 +0000
@@ -59,6 +59,9 @@
     show_LEDS();
     show_menu();
 
+//make sure we see something    
+    LF28A_status.set_brightness(BRT_MED);           
+
     while(running) {
     
        if(pc.readable()) {
@@ -316,8 +319,8 @@
                         wait(0.5);
                         LF28A_status.set_brightness(BRT_MED);
                         wait(0.5);                                                 
-                        LF28A_status.set_brightness(BRT_HIGH);                         
-                        wait(0.5);                        
+//                        LF28A_status.set_brightness(BRT_HIGH);                         
+//                        wait(0.5);                        
                         LF28A_status.set_brightness(BRT_OFF);                                                 
                         wait(0.5);                        
                       }                      
@@ -441,7 +444,8 @@
 
           case 'N' :
                       pc.printf("Test STANAG\r");
-                                                
+                                               
+                      STANAG_codes.setDigitIdx(0);
                       pc.printf("Code = %04d; CodeIdx=%d; DigitIdx=%d;\r", STANAG_codes.getCode(), STANAG_codes.getCodeIdx(), STANAG_codes.getDigitIdx() );                      
 
                       LF28A_display.locate (0);                      
--- a/main.cpp	Tue Aug 23 20:26:05 2011 +0000
+++ b/main.cpp	Fri Aug 26 20:35:11 2011 +0000
@@ -15,12 +15,13 @@
 #include "Status_Display.h"
 #include "Keyboard.h"
 #include "STANAG_Codes.h"
+#include "Host_Coms.h"
   
 // Debug stuff
 #define __DEBUG  
 #include "Dbg.h"
 
-#define __TESTCODE  
+//#define __TESTCODE  
 
 
 // Software version
@@ -29,14 +30,24 @@
 #define LF28A_SW_VERSION_MINOR       2
 #define LF28A_COPYRIGHT_DESCRIPTOR   "(C)TNO 2011"
 
+// Laser Time-out in Seconds
+//#define LF28A_RANGE_TIME_OUT_S           1      
+//#define LF28A_DESIG_TIME_OUT_S  (3*60 + 20)      
+//Test only:
+#define LF28A_RANGE_TIME_OUT_S           5      
+#define LF28A_DESIG_TIME_OUT_S          10      
+ 
 // mbed Interface Hardware definitions
 DigitalOut myled1(LED1);
 DigitalOut myled2(LED2);
 DigitalOut myled3(LED3);
 DigitalOut heartbeatLED(LED4);
 
+// Host PC Communication channels
 Serial pc(USBTX, USBRX);
+Host_Coms host_coms(pc);
 
+//I2C Bus
 I2C i2c(D_SDA, D_SCL);
 
 // CDA Interface Hardware definitions
@@ -63,7 +74,8 @@
 
 enum RangeSelect { RNG_F, RNG_L };
 
-enum MessageToHost { LFPON, LFRDY_0, LFRDY_1, LFSTA, LFIDL };
+enum MessageToHost { LFPON, LFRDY_0, LFRDY_1, LFSTA_D, LFSTA_R, LFSTA_C, LFSTA_A, LFSTA_F, LFSTA_P, LFIDL };
+//enum MessageToHost { LFPON, LFRDY_0, LFRDY_1, LFSTA, LFIDL };
 enum MessageFromHost { LFRES, LFRNG };
 
 //Typedef for Laser Range finder data
@@ -78,7 +90,7 @@
 Brightness brightness, graticule; 
 Key_Code keycode;
 Range_t range;
-bool laser;
+bool laser;                           // Laser On/Off
 bool hostResetCmd;
 MessageToHost messageToHost;
 STANAG_Codes STANAG_codes;
@@ -87,6 +99,13 @@
 Ticker heartbeat;
 bool heartbeatflag=false;
 
+// Laser Time-out
+Timer timer;
+
+// Cycle Timer
+Timer cycletimer;
+int cyclecount = 0;
+const int maxcount = 1000000;
 
 // Local functions
 void clear_screen() {
@@ -125,7 +144,38 @@
     myled1 = 1;
     DBG("Init Interfaces Done, Main, Step = %d\r", 10);    
 }
+      
+void BITE() {
+  int count;
+  
+    LF28A_status.set_brightness(BRT_MED);           
+    LF28A_status.NoGo(LED_ON);
+    
+    for (count=0; count<5; count++) {
+      LF28A_display.locate(0);
+      LF28A_display.printf("BITE  - ");    
+      LF28A_display.locate(0);    
+      LF28A_display.printf("BITE  \ ");    
+      LF28A_display.locate(0);        
+      LF28A_display.printf("BITE  | ");        
+      LF28A_display.locate(0);    
+      LF28A_display.printf("BITE  / ");    
+      LF28A_display.locate(0);    
+      LF28A_display.printf("BITE  - ");                
+    };
 
+    LF28A_display.locate(0);    
+    LF28A_display.printf("BITE  OK");    
+    LF28A_status.NoGo(LED_OFF);  
+    
+    wait(2.0);          
+    
+    LF28A_display.cls();  
+//    LF28A_status.set_brightness(D_STATUS_LED_BRIGHT_OFF); 
+
+    //Done, Tell me about it                        
+    DBG("BITE Done, Main, Step = %d\r", 30);    
+}
 
 void lamp_test() {
     LF28A_status.set_brightness(BRT_LOW);       
@@ -142,24 +192,9 @@
 //    LF28A_status.set_brightness(D_STATUS_LED_BRIGHT_OFF); 
 
     //Done, Tell me about it          
-    DBG("Lamp Test Done, Main, Step = %d\r", 20);    
+    //DBG("Lamp Test Done, Main, Step = %d\r", 20);    
 }
-      
-void BITE() {
-    LF28A_status.set_brightness(BRT_LOW);           
-    LF28A_status.NoGo(LED_OFF);
-    
-    LF28A_display.locate(0);
-    LF28A_display.printf("--------");
-    
-    wait(0.5);  
-    
-    LF28A_display.cls();  
-//    LF28A_status.set_brightness(D_STATUS_LED_BRIGHT_OFF); 
 
-    //Done, Tell me about it                        
-    DBG("BITE Done, Main, Step = %d\r", 30);    
-}
 
 void init_state() {
     // Default modes and settings after Power On or Host Reset
@@ -171,6 +206,8 @@
     range.select = RNG_F;
 
     laser = false;
+    timer.stop();
+    timer.reset();
 
 // Read Config File if needed..
 // Reload STANAG Codes ?
@@ -184,10 +221,10 @@
    
     // Init Alphanumeric Display
     LF28A_display.cls();                    // Clear display and Cursor home
-    LF28A_display.set_flash_mode(true);     // Enable flashing digits                                     
+    LF28A_display.set_flash_mode(false);    // Disable flashing digits                                     
     
     //Done, Tell me about it 
-    DBG("Init Done, Originator = %d\r", hostResetCmd);               
+    //DBG("Init Done, Originator = %d\r", hostResetCmd);               
 }
 
 
@@ -210,7 +247,7 @@
   } //end switch              
      
   //Done, Tell me about it 
-  DBG("Graticule Brightness Change, current val = %d\r", graticule);
+  //DBG("Grat Bright Chnge, val = %d\r", graticule);
 }
 
 void disp_bright_selector() {
@@ -237,7 +274,7 @@
   } //end switch              
         
   //Done, Tell me about it 
-  DBG("Display Brightness Change, current val = %d\r", brightness);
+  //DBG("Disp Bright Chng, val = %d\r", brightness);
 }
 
 void range_selector() {
@@ -255,7 +292,7 @@
   } //end switch              
      
   //Done, Tell me about it   
-  DBG("Range Change, current val = %d\r", range.select);
+  //DBG("Rng Chng, val = %d\r", range.select);
 }
 
 // Heartbeat monitor
@@ -273,6 +310,56 @@
   heartbeatflag = false;
 }
 
+// Construct and Send messages to Host PC. Need to complete this !!
+void SendHostMessage(MessageToHost messageToHost) {
+  int result;
+
+  switch (messageToHost) {
+    case LFPON:    host_coms.sendMessage("$LFPON");
+                   break;
+                   
+    case LFRDY_0:  // No hostResetCmd
+                   host_coms.sendMessage("$LFRDY,0");
+                   //pc.printf("$LFRDY,0*00\r\n");
+                   break;
+                   
+    case LFRDY_1:  // hostResetCmd
+                   host_coms.sendMessage("$LFRDY,1");
+//                   pc.printf("$LFRDY,1*00\r\n");
+                   break;
+
+    case LFSTA_D:  // Designate
+                   host_coms.sendMessage("$LFSTA,D,%1d,%04d,%1d", laser, STANAG_codes.getCode(), graticule);    
+//                   pc.printf("$LFSTA,D,0,1234,1*00\r\n");
+                   break;
+
+    case LFSTA_R:  // Range
+                   host_coms.sendMessage("$LFSTA,R,%1d,%04d,%1d", laser, STANAG_codes.getCode(), graticule);        
+//                   pc.printf("$LFSTA,D,0,1234,1*00\r\n");
+                   break;
+
+    case LFSTA_C:  // Code
+                   host_coms.sendMessage("$LFSTA,C,%1d,%04d,%1d", laser, STANAG_codes.getCode(), graticule);    
+//                   pc.printf("$LFSTA,D,0,1234,1*00\r\n");
+                   break;
+
+    case LFSTA_A:
+    case LFSTA_F:
+    case LFSTA_P:        
+    case LFIDL:    // No Message
+                   break;
+
+    default:     // Oops, we should never end up here....
+
+                   result = -1;
+                   break;                 
+  } //end switch              
+     
+  //Done, Tell me about it  
+  //DBG("To Host Msg, type = %d\r", messageToHost);
+}
+
+
 //------------------------------------------------------------//
 // Testing Stuff                                              //   
 //------------------------------------------------------------//
@@ -284,39 +371,6 @@
 //------------------------------------------------------------//
 
 
-// Construct and Send messages to Host PC. Need to complete this !!
-void SendHostMessage(MessageToHost messageToHost) {
-  int result;
-
-  switch (messageToHost) {
-    case LFPON   : pc.printf("$LFPON*00\r\n");
-                   break;
-                   
-    case LFRDY_0 : // No hostResetCmd
-                   pc.printf("$LFRDY,0*00\r\n");
-                   break;
-                   
-    case LFRDY_1 : // hostResetCmd
-                   pc.printf("$LFRDY,1*00\r\n");
-                   break;
-
-    case LFSTA   : pc.printf("$LFSTA,D,0,1234,1*00\r\n");
-                   break;
-
-    case LFIDL   : // No Message
-                   break;
-
-    default:     // Oops, we should never end up here....
-
-                   result = -1;
-                   break;                 
-  } //end switch              
-     
-  //Done, Tell me about it  
-  DBG("Message, current val = %d\r", messageToHost);
-}
-
-
 int main() {
     int address, result;
    
@@ -325,7 +379,7 @@
     heartbeat_start();
           
     clear_screen(); 
-    version_string();
+    version_string();    
         
 #ifndef __TESTCODE
     lamp_test();
@@ -338,6 +392,10 @@
     mode = INIT_ENTRY;    // Start with Init
     hostResetCmd = false; // Start with regular PowerOn reset   
 
+//Test cycletime
+    cycletimer.start();      
+    cycletimer.reset();
+          
     // Main Controlloop:
     //   Check keyboard input and respond as required in the current device mode
     //   Check Host commands and respond as required
@@ -355,14 +413,14 @@
                             init_state(); 
 
                            // Inform Host that Init has completed
-                            if (!hostResetCmd) {
-                              // Regular PowerOn Reset                                                        
-                              SendHostMessage(LFRDY_0);
+                            if (hostResetCmd) {
+                              // Host initiated a Reset
+                              SendHostMessage(LFRDY_1);
+                              hostResetCmd = false;                            
                             }
                             else {
-                              // Host initiated a Reset
-                              SendHostMessage(LFRDY_1);
-                              hostResetCmd = false;
+                              // Regular PowerOn Reset                                                        
+                              SendHostMessage(LFRDY_0);                            
                             }
                                                           
                             mode = INIT_EXIT;                            
@@ -383,7 +441,7 @@
                             LF28A_display.printf ("    %04d",STANAG_codes.getCode() );                      
                           
                             // Inform Host of change
-                            SendHostMessage(LFSTA);  
+                            SendHostMessage(LFSTA_D);  
                           
                             mode = DESIG_DISP;
                             break;
@@ -396,25 +454,77 @@
                               switch (keycode) {
                                 case KEY_GRAT_RT: grat_bright_selector();
                                                   // Inform Host of change
-                                                  SendHostMessage(LFSTA);  
+                                                  SendHostMessage(LFSTA_D);  
                                                   break;
 
                                 case KEY_BRIGHT:  disp_bright_selector();
                                                   break;                              
 
                                 case KEY_MODE:    mode = DESIG_EXIT;
+                                                  break;
+                                                  
+                                case KEY_FIRE:    // Check and handle Fire key
+                                                  
+                                                  // Toggle Laser On/Off
+                                                  if (laser) {
+                                                    // Laser is On, Switch Off
+                                                    laser=false;
+                                                    timer.stop();  // Stop time-out timer
+                                                    timer.reset();
+                                
+                                                    // Status LEDs
+                                                    LF28A_status.LED(LED_LASER, LED_OFF);                                                    
+                                                  }
+                                                  else {
+                                                    // Laser is Off, Switch On
+                                                    laser=true;
+                                                    timer.start(); // Start time-out timer
+
+                                                    // Status LEDs
+                                                    LF28A_status.LED(LED_LASER, LED_ON);                                                                                                         
+                                                  };
+                                                  
+                                                  // Inform Host of change (laser on/off)
+                                                  SendHostMessage(LFSTA_D);  
+                                
                                                   break;                              
+                                                                                
 
                                 default:          // Ignore other keys
                                                   break;                                                            
                               }; //End Keyswitch            
                             }; // End Keyread
                               
-                            // Check and handle Fire key
+                            // Check Automatic Time-out for Laser
+                            if (laser) {
+                              // Laser is On, Test Time-out to Switch Off
+                              if (timer.read() > LF28A_DESIG_TIME_OUT_S) {
+                                laser=false;   // Laser Off
+                                timer.stop();  // Stop time-out timer
+                                timer.reset();
 
+                                // Status LEDs
+                                LF28A_status.LED(LED_LASER, LED_OFF); 
+
+                                // Inform Host of change (laser off)
+                                SendHostMessage(LFSTA_D);
+                              }                                                                                     
+                            };
+                                                       
                             break;                              
 
           case DESIG_EXIT:  // Transitional state
+
+                            // Check Laser
+                            if (laser) {
+                              // Laser is On, Switch Off
+                              laser=false;   // Laser Off
+                              timer.stop();  // Stop time-out timer
+                              timer.reset();
+                                
+                              // Status LEDs
+                              LF28A_status.LED(LED_LASER, LED_OFF); 
+                            };
           
                             // Status LEDs
                             LF28A_status.LED(LED_DESIG, LED_OFF);        
@@ -433,7 +543,7 @@
                             LF28A_display.printf ("    %04d",STANAG_codes.getCode() );                      
                             
                             // Inform Host of change
-                            SendHostMessage(LFSTA);  
+                            SendHostMessage(LFSTA_R);  
                            
                             mode = RANGE_DISP;
                             break;
@@ -447,7 +557,7 @@
                                 case KEY_GRAT_RT: grat_bright_selector();
 
                                                   // Inform Host of change
-                                                  SendHostMessage(LFSTA);  
+                                                  SendHostMessage(LFSTA_R);  
 
                                                   break;
 
@@ -467,7 +577,7 @@
                                                   }
                                                   else {
                                                     LF28A_display.locate (0);                      
-                                                    LF28A_display.printf ("F   %04d", range.last);                                                     
+                                                    LF28A_display.printf ("L   %04d", range.last);                                                     
                                                   };
                                                                                                  
                                                   // Inform Host of change ??
@@ -475,29 +585,29 @@
                                                   
                                                   break;
 
-
                                 case KEY_FIRE:    // Check and handle Fire key
                                                   
                                                   // Toggle Laser On/Off
                                                   if (laser) {
                                                     // Laser is On, Switch Off
+                                                    laser=false;
+                                                    timer.stop();  // Stop time-out timer
+                                                    timer.reset();                                                    
 
                                                     // Status LEDs
-                                                    LF28A_status.LED(LED_LASER, LED_ON);
-                                                    
+                                                    LF28A_status.LED(LED_LASER, LED_OFF);                                                    
                                                   }
                                                   else {
-                                                    // Laser is Off, Switch On                                                  
+                                                    // Laser is Off, Switch On
+                                                    laser=true;
+                                                    timer.start(); // Start time-out timer
 
                                                     // Status LEDs
-                                                    LF28A_status.LED(LED_LASER, LED_ON);
-                                                     
-                                                    // Automatic Time-out needed
-                                                     
+                                                    LF28A_status.LED(LED_LASER, LED_ON);                                                                                                         
                                                   };
                                                   
                                                   // Inform Host of change (laser on/off)
-                                                  SendHostMessage(LFSTA);  
+                                                  SendHostMessage(LFSTA_R);  
                                 
                                                   break;                              
   
@@ -506,26 +616,37 @@
                               }; //End Keyswitch            
                             }; // End Keyread          
 
-#if (0)
-                            // tbd Check Automatic Time-out for Laser
-                            Timer.stop()
-                            laser = false;
-                            // Status LEDs
-                            LF28A_status.LED(LED_LASER, LED_ON);
-#endif
+                            // Check Automatic Time-out for Laser
+                            if (laser) {
+                              // Laser is On, Test Time-out to Switch Off
+                              if (timer.read() > LF28A_RANGE_TIME_OUT_S) {
+                                laser=false;   // Laser Off
+                                timer.stop();  // Stop time-out timer
+                                timer.reset();                                
+
+                                // Status LEDs
+                                LF28A_status.LED(LED_LASER, LED_OFF); 
+
+                                // Inform Host of change (laser off)
+                                SendHostMessage(LFSTA_R);
+                              }                                                                                     
+                            };
 
                             break;                              
 
           case RANGE_EXIT:  // Transitional state
 
-#if (0)
-                            // tbd Check Automatic Time-out for Laser
-                            Timer.stop()
-                            laser = false;
-                            // Status LEDs
-                            LF28A_status.LED(LED_LASER, LED_ON);
-#endif
-          
+                            // Check Laser
+                            if (laser) {
+                              // Laser is On, Switch Off
+                              laser=false;   // Laser Off
+                              timer.stop();  // Stop time-out timer
+                              timer.reset();                              
+
+                              // Status LEDs
+                              LF28A_status.LED(LED_LASER, LED_OFF); 
+                            };
+        
                             // Status LEDs
                             LF28A_status.LED(LED_RANGE, LED_OFF);
 
@@ -547,7 +668,7 @@
                             LF28A_display.printf ("    %04d",STANAG_codes.getCode() );                      
  
                             // Inform Host of change
-                            SendHostMessage(LFSTA);  
+                            SendHostMessage(LFSTA_C);  
                             
                             mode = CODE_DISP;
                             break;
@@ -561,7 +682,7 @@
                                 case KEY_GRAT_RT: grat_bright_selector();
 
                                                   // Inform Host of change
-                                                  SendHostMessage(LFSTA);  
+                                                  SendHostMessage(LFSTA_C);  
                                 
                                                   break;
 
@@ -626,7 +747,7 @@
                                                   LF28A_display.set_char_flash_state(false, 4 + STANAG_codes.getDigitIdx());                          
                                 
                                                   // Inform Host of change
-                                                  SendHostMessage(LFSTA);  
+                                                  SendHostMessage(LFSTA_C);  
                                                   
                                                   mode = CODE_EXIT;                                                                                  
                                                   
@@ -638,14 +759,14 @@
                                                   LF28A_display.set_char_flash_state(false, 4 + STANAG_codes.getDigitIdx());                          
                                  
                                                   // Inform Host of change
-                                                  SendHostMessage(LFSTA);  
+                                                  SendHostMessage(LFSTA_C);  
                                 
                                                   mode = CODE_DISP;
                                                   
                                                   break;                              
 
                                 case KEY_F_L_UP : //Incr current digit
-                                                  STANAG_codes.incDigitIdx();
+                                                  STANAG_codes.incDigit();
 
                                                   // Display Current STANAG Code
                                                   LF28A_display.locate (0);                      
@@ -701,8 +822,16 @@
         //  Reset command 
         //  Range data         
 
-// Just for Info, lets see how fast this cycle is...
-//
+#if(0)
+        // Just for Info, lets see how fast this cycle is...
+        cyclecount++;
+        if (cyclecount == maxcount) {
+          pc.printf("Freq = %d Hz\r", (cyclecount * 1000) / cycletimer.read_ms());
+          cyclecount = 0;          
+          cycletimer.reset();      
+        }
+#endif
+      
     } // end while(1)