Libraries and Example of mbed parallel bus using I2C port expanders
Dependencies: HDSP253X mbed PCF8574_Bus
main.cpp
- Committer:
- wim
- Date:
- 2011-08-20
- Revision:
- 2:1dab1089c332
- Child:
- 3:3fbfdec782f4
File content as of revision 2:1dab1089c332:
/* 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"); }