Libraries and Example of mbed parallel bus using I2C port expanders

Dependencies:   HDSP253X mbed PCF8574_Bus

Revision:
2:1dab1089c332
Child:
3:3fbfdec782f4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Aug 20 12:49:44 2011 +0000
@@ -0,0 +1,588 @@
+/* LF28A Simulator - Main
+ * Copyright (c) 2011 Wim Huiskamp
+ *
+ * Released under the MIT License: http://mbed.org/license/mit
+ *
+ * version 0.2 Initial Release
+*/
+#include "mbed.h"
+#include "BusDefines.h"
+#include "PCF8574_DataBus.h"
+#include "PCF8574_AddressBus.h"
+#include "PCF8574_EnableBus.h"
+#include "MBED_ControlBus.h"
+#include "HDSP253X_Display.h"
+#include "Status_Display.h"
+#include "Keyboard.h"
+#include "STANAG_Codes.h"
+  
+// Debug stuff
+#define __DEBUG  
+#include "Dbg.h"
+
+#define __TESTCODE  
+
+
+// Software version
+#define LF28A_SOFTWARE_DESCRIPTOR    "LF28A Testsoftware"
+#define LF28A_SW_VERSION_MAJOR       0
+#define LF28A_SW_VERSION_MINOR       2
+#define LF28A_COPYRIGHT_DESCRIPTOR   "(C)TNO 2011"
+
+// mbed Interface Hardware definitions
+DigitalOut myled1(LED1);
+DigitalOut myled2(LED2);
+DigitalOut myled3(LED3);
+DigitalOut heartbeatLED(LED4);
+
+Serial pc(USBTX, USBRX);
+
+I2C i2c(D_SDA, D_SCL);
+
+// CDA Interface Hardware definitions
+PCF8574_DataBus    databus = PCF8574_DataBus(i2c, D_I2C_DATA_BUS);  //Copy constructors..
+PCF8574_AddressBus addressbus = PCF8574_AddressBus(i2c, D_I2C_ADDR_BUS);
+PCF8574_EnableBus  enablebus = PCF8574_EnableBus(i2c, D_I2C_ENA_BUS);
+MBED_ControlBus  controlbus = MBED_ControlBus(D_WR, D_RD, D_DTR, D_CDBUF, D_CDINT, D_FIRE);
+
+// CDA Hardware definitions
+HDSP253X_Display LF28A_display = HDSP253X_Display(databus, addressbus, enablebus, controlbus);
+Status_Display LF28A_status = Status_Display(databus, enablebus, controlbus);
+Keyboard LF28A_keyboard = Keyboard(databus, enablebus, controlbus);
+
+
+//Enums for LF28A Statemachines
+enum Mode { IDLE,
+            INIT_ENTRY, INIT, INIT_EXIT,  
+            DESIG_ENTRY, DESIG_DISP, DESIG_LASER, DESIG_EXIT,
+            RANGE_ENTRY, RANGE_DISP, RANGE_FIRE, RANGE_EXIT,
+            CODE_ENTRY, CODE_DISP, CODE_EDIT, CODE_EXIT,
+            ADDR_ENTRY, ADDR, ADDR_EXIT,
+            FREQ_ENTRY, FREQ, FREQ_EXIT,
+            PATH_ENTRY, PATH, PATH_EXIT };                                    
+
+enum RangeSelect { RNG_F, RNG_L };
+
+enum MessageToHost { LFPON, LFRDY, LFSTA };
+enum MessageFromHost { LFRES, LFRNG };
+
+//Typedef for Laser Range finder data
+typedef struct {
+ uint16_t first;
+ uint16_t last;
+ RangeSelect select; 
+} Range_t;
+ 
+// Variables for Statemachine
+Mode mode; 
+Brightness brightness, graticule; 
+Key_Code keycode;
+Range_t range;
+bool hostResetCmd;
+MessageToHost messageToHost;
+STANAG_Codes STANAG_codes;
+
+// Variables for Heartbeat and Status monitoring
+Ticker heartbeat;
+bool heartbeatflag=false;
+
+
+// Local functions
+void clear_screen() {
+//ANSI Terminal Commands
+    pc.printf("\x1B[2J");
+    pc.printf("\x1B[H");
+}
+
+void version_string() {
+    pc.printf("\r\r");            
+    pc.printf("%s\r", LF28A_SOFTWARE_DESCRIPTOR);
+    pc.printf("Version v%1d.%1d\r", LF28A_SW_VERSION_MAJOR, LF28A_SW_VERSION_MINOR);
+    pc.printf("Build on %s at %s\r", __DATE__, __TIME__);    
+    pc.printf("%s\r", LF28A_COPYRIGHT_DESCRIPTOR);
+    pc.printf("\r\n");            
+}
+
+void init_interfaces() {
+// Init Host PC communication, default is 9600
+    pc.baud(D_BAUDRATE);
+      
+// Init LF28A CDA I/F hardware
+    i2c.frequency(100000);  
+//    pc.printf("SCL0 H, L = 0x%x, 0x%x\r", LPC_I2C0->I2SCLH, LPC_I2C0->I2SCLL);
+//    pc.printf("SCL1 H, L = 0x%x, 0x%x\r", LPC_I2C1->I2SCLH, LPC_I2C1->I2SCLL);
+//    pc.printf("SCL2 H, L = 0x%x, 0x%x\r", LPC_I2C2->I2SCLH, LPC_I2C2->I2SCLL);
+
+// Reset LF28A CDA
+// NOTE: On LF28A CDA the Reset* pin is connected to the Display and to the Latches.
+//       That implies they are all reset when the Reset* pin is used !
+    enablebus.reset(LOW);   
+    wait_ms(50);    
+    enablebus.reset(HIGH);             
+  
+    //Done, Tell me about it
+    myled1 = 1;
+    DBG("Init Interfaces Done, Main, Step = %d\r", 10);    
+}
+
+
+void lamp_test() {
+    LF28A_status.set_brightness(BRT_LOW);       
+    LF28A_status.lamptest(LED_ON);  // All LEDs On, including Backlight and NoGo
+
+    LF28A_display.locate(0);
+    LF28A_display.printf("XXXXXXXX");
+
+    wait(2.0);      
+
+    LF28A_status.lamptest(LED_OFF);  // All LEDs Off, including Backlight and NoGo
+    
+    LF28A_display.cls();  
+//    LF28A_status.set_brightness(D_STATUS_LED_BRIGHT_OFF); 
+
+    //Done, Tell me about it          
+    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
+    brightness = BRT_LOW;   // Should be BRT_OFF, but then you dont see anything.. 
+    graticule  = BRT_LOW;   // Should be BRT_OFF, but then you dont see anything.. 
+
+    range.last = 0;
+    range.first = 0;
+    range.select = RNG_F;
+
+// Read Config File if needed..
+// Reload STANAG Codes ?
+    STANAG_codes.setCodeIdx(0);
+    STANAG_codes.setDigitIdx(0);
+                
+    // Init Status LEDs 
+    LF28A_status.lamptest(LED_OFF); // All LEDs off   
+    LF28A_status.backlight(LED_ON);
+    LF28A_status.set_brightness(brightness);          
+   
+    // Init Alphanumeric Display
+    LF28A_display.cls(); 
+    
+    //Done, Tell me about it 
+    DBG("Init Done, Originator = %d\r", hostResetCmd);               
+}
+
+
+void grat_bright_selector() {
+  int result;
+  
+  switch (graticule) {
+    case BRT_OFF : graticule = BRT_LOW;
+                   break;
+    case BRT_LOW : graticule = BRT_MED;
+                   break;
+    case BRT_MED : graticule = BRT_HIGH;
+                   break;
+    case BRT_HIGH : graticule = BRT_OFF;
+                   break;
+    default:       // Oops, we should never end up here....
+                   graticule = BRT_LOW;
+                   result = -1;
+                   break;                   
+  } //end switch              
+     
+  //Done, Tell me about it 
+  DBG("Graticule Brightness Change, current val = %d\r", graticule);
+}
+
+void disp_bright_selector() {
+  int result;
+  
+  switch (brightness) {
+    case BRT_OFF : brightness = BRT_LOW;
+                   LF28A_status.set_brightness(BRT_LOW);    
+                   break;
+    case BRT_LOW : brightness = BRT_MED;
+                   LF28A_status.set_brightness(BRT_MED);        
+                   break;
+    case BRT_MED : brightness = BRT_HIGH;
+                   LF28A_status.set_brightness(BRT_HIGH);    
+                   break;
+    case BRT_HIGH : brightness = BRT_OFF;
+                   LF28A_status.set_brightness(BRT_OFF);        
+                   break;
+    default:       // Oops, we should never end up here....
+                   brightness = BRT_LOW;
+                   LF28A_status.set_brightness(BRT_LOW);                       
+                   result = -1;
+                   break;                   
+  } //end switch              
+        
+  //Done, Tell me about it 
+  DBG("Display Brightness Change, current val = %d\r", brightness);
+}
+
+void range_selector() {
+  int result;
+  
+  switch (range.select) {
+    case RNG_F : range.select = RNG_L;
+                 break;
+    case RNG_L : range.select = RNG_F;
+                 break;
+    default:     // Oops, we should never end up here....
+                 range.select = RNG_F;
+                 result = -1;
+                 break;                 
+  } //end switch              
+     
+  //Done, Tell me about it   
+  DBG("Range Change, current val = %d\r", range.select);
+}
+
+// Heartbeat monitor
+void pulse() {
+  heartbeatLED = !heartbeatLED;
+}
+
+void heartbeat_start() {
+  heartbeat.attach(&pulse, 0.5);
+  heartbeatflag = true;
+}
+
+void heartbeat_stop() {
+  heartbeat.detach();
+  heartbeatflag = false;
+}
+
+//------------------------------------------------------------//
+// Testing Stuff                                              //   
+//------------------------------------------------------------//
+#ifdef __TESTCODE
+#include "Testloop.h"
+#endif
+//------------------------------------------------------------//
+// End Testing Stuff                                          //   
+//------------------------------------------------------------//
+
+
+// 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   : if (!hostResetCmd) {
+                     pc.printf("$LFRDY,0*00\r\n");
+                   }
+                   else {
+                     pc.printf("$LFRDY,1*00\r\n");
+                     hostResetCmd = false;
+                   }       
+                   break;
+
+    case LFSTA   : pc.printf("$LFSTA,D,0,1234,1*00\r\n");
+                   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;
+   
+    init_interfaces();
+    
+    heartbeat_start();
+          
+    clear_screen(); 
+    version_string();
+        
+    lamp_test();
+    
+    BITE();
+
+    DBG("Start Main Loop, Step = %d\r", 50);    
+
+    // Prepare main State Machine 
+    mode = INIT_ENTRY;    // Start with Init
+    hostResetCmd = false; // Start with regular PowerOn reset   
+    
+    
+#ifndef __TESTCODE
+    // Main Controlloop:
+    //   Check keyboard input and respond as required in the current device mode
+    //   Check Host commands and respond as required
+    while(1) {
+        
+        // Handle mode statemachine
+        switch (mode) {
+        
+          // INIT MODEs - Init LF28A after Power On or Host Reset
+          case INIT_ENTRY:  // Transitional state
+                            mode = INIT;
+                            break;
+
+          case INIT:        // Init LF28A after Power On or Host Reset
+                            init_state(); 
+
+                           // Inform Host that Init has completed
+                            SendHostMessage(LFRDY);  
+                            
+                            mode = INIT_EXIT;                            
+                            break;                            
+        
+          case INIT_EXIT:  // Transitional state
+                            mode = DESIG_ENTRY;
+                            break;
+        
+          // DESIG MODEs - Laser Designator
+          case DESIG_ENTRY:  // Transitional state
+
+                            //Display current STANAG Code
+                          
+                            // Inform Host of change
+                            SendHostMessage(LFSTA);  
+                          
+                            mode = DESIG_DISP;
+                            break;
+
+          case DESIG_DISP:
+                            // Check and handle Keyboard
+                            if (LF28A_keyboard.readable()) {
+                              keycode = LF28A_keyboard.getkey();
+
+                              switch (keycode) {
+                                case KEY_GRAT_RT: grat_bright_selector();
+                                                  // Inform Host of change
+                                                  SendHostMessage(LFSTA);  
+                                                  break;
+
+                                case KEY_BRIGHT:  disp_bright_selector();
+                                                  break;                              
+
+                                case KEY_MODE:    mode = DESIG_EXIT;
+                                                  break;                              
+
+                                default:          // Ignore other keys
+                                                  break;                                                            
+                              }; //End Keyswitch            
+                            }; // End Keyread
+                              
+                            // Check and handle Fire key
+
+                            break;                              
+
+          case DESIG_EXIT:  // Transitional state
+          
+                            mode = RANGE_ENTRY;
+                            break;                              
+
+          // RANGE MODEs
+          case RANGE_ENTRY: // Transitional state
+          
+                            //Display current STANAG Code
+                            
+                            // Inform Host of change
+                            SendHostMessage(LFSTA);  
+                           
+                            mode = RANGE_DISP;
+                            break;
+
+          case RANGE_DISP:
+                            // Check and handle Keyboard
+                            if (LF28A_keyboard.readable()) {
+                              keycode = LF28A_keyboard.getkey();
+
+                              switch (keycode) {
+                                case KEY_GRAT_RT: grat_bright_selector();
+
+                                                  // Inform Host of change
+                                                  SendHostMessage(LFSTA);  
+
+                                                  break;
+
+                                case KEY_BRIGHT:  disp_bright_selector();
+                                                  break;                              
+
+                                case KEY_MODE:    mode = RANGE_EXIT;
+                                                  break;                              
+  
+                                default:          // Ignore other keys
+                                                  break;                                                              
+                              }; //End Keyswitch            
+                            }; // End Keyread          
+
+                            // Check and handle Fire key
+                            // Toggle Laser On/Off
+                            // Update and show Range, Toggle First/Last Range
+
+                            break;                              
+
+          case RANGE_EXIT:  // Transitional state
+
+                            mode = CODE_ENTRY;
+                            break;                              
+
+
+          // CODE MODEs
+          case CODE_ENTRY:  // Transitional state
+          
+                            //Display current STANAG Code
+                            
+                            // Inform Host of change
+                            SendHostMessage(LFSTA);  
+                            
+                            mode = CODE_DISP;
+                            break;
+
+          case CODE_DISP:
+                            // Check and handle Keyboard
+                            if (LF28A_keyboard.readable()) {
+                              keycode = LF28A_keyboard.getkey();
+
+                              switch (keycode) {
+                                case KEY_GRAT_RT: grat_bright_selector();
+
+                                                  // Inform Host of change
+                                                  SendHostMessage(LFSTA);  
+                                
+                                                  break;
+
+                                case KEY_BRIGHT:  disp_bright_selector();
+                                                  break;                              
+
+                                case KEY_MODE:    mode = CODE_EXIT;
+                                                  break;                              
+
+                                case KEY_EDIT:    mode = CODE_EDIT;
+                                                  break;                              
+
+                                case KEY_F_L_UP : //Incr STANAG code idx
+                                                  STANAG_code.incIdx();
+                                                  
+                                                  //Display current STANAG Code                                                  
+
+                                                  // Inform Host of change ??
+                                                  //SendHostMessage(LFSTA);  
+                                                  
+                                                  break;
+                                                    
+                                default:          // Ignore other keys
+                                                  break;                                
+                              }; //End Keyswitch            
+                            }; //End Keyread            
+
+                            break;                              
+
+          case CODE_EDIT:
+                            // Check and handle Keyboard
+                            if (LF28A_keyboard.readable()) {
+                              keycode = LF28A_keyboard.getkey();
+
+                              switch (keycode) {
+                                case KEY_GRAT_RT: //Cursor Right;
+                                                  break;
+
+                                case KEY_BRIGHT:  disp_bright_selector();
+                                                  break;                              
+
+                                case KEY_MODE:                                                     
+                                                  // Inform Host of change
+                                                  SendHostMessage(LFSTA);  
+                                                  
+                                                  mode = CODE_EXIT;                                                                                  
+                                                  
+                                                  break;                              
+
+                                case KEY_EDIT:
+                                                  // Inform Host of change
+                                                  SendHostMessage(LFSTA);  
+                                
+                                                  mode = CODE_DISP;
+                                                  
+                                                  break;                              
+
+                                case KEY_F_L_UP : //Incr current digit
+                                                  STANAG_code.incDigitIdx();
+                                
+                                                  // Inform Host of change ro wait untip done editing ??
+                                                  //SendHostMessage(LFSTA);  
+                                                                                  
+                                                  break;                              
+                                                                                                
+                                default:          // Ignore other keys
+                                                  break;                                                              
+                              }; //End Keyswitch            
+                            }; //End Keyread                      
+
+                            break;                              
+
+          case CODE_EXIT:  // Transitional state
+
+                            mode = DESIG_ENTRY;
+                            break;                              
+
+          // ADDR MODEs 
+          case ADDR_ENTRY: // Transitional state                    
+          case ADDR:       // Transitional state                              
+          case ADDR_EXIT:  // Transitional state          
+          // FREQ MODEs 
+          case FREQ_ENTRY: // Transitional state                    
+          case FREQ:       // Transitional state                              
+          case FREQ_EXIT:  // Transitional state          
+          // PATH MODEs
+          case PATH_ENTRY: // Transitional state                    
+          case PATH:       // Transitional state                              
+          case PATH_EXIT:  // Transitional state          
+                        
+          default:          // Oops, we should never end up here....try to recover
+                            mode = INIT_ENTRY;
+                            hostResetCmd = false;
+                            
+                            result = -1;
+                            DBG("Error - Result = %d\r", result);                            
+                            break;                                                          
+        }; //End mode statemachine switch              
+
+
+        // Handle Host commands
+        //  Reset command 
+        //  Range data         
+
+// Just for Info, lets see how fast this cycle is...
+//
+    } // end while(1)
+
+
+#else
+//testing stuff
+    testloop();
+    
+#endif
+
+    DBG("I'll be back...\r\r");
+}