Libraries and Example of mbed parallel bus using I2C port expanders
Dependencies: HDSP253X mbed PCF8574_Bus
Revision 2:1dab1089c332, committed 2011-08-20
- Comitter:
- wim
- Date:
- Sat Aug 20 12:49:44 2011 +0000
- Child:
- 3:3fbfdec782f4
- Commit message:
- First commit, testloop
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BusDefines.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,39 @@ +/* BusDefines - Use the MBED Port pins and PCF8574s for controlling the Bus + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#ifndef _BUS_DEFINES_H +#define _BUS_DEFINES_H + + +//Pin Defines for MBED Control Bus (inputs) +#define D_FIRE p19 +#define D_CDINT p20 +//Pin Defines for MBED Control Bus (outputs) +#define D_DTR p21 +#define D_CDBUF p22 +#define D_RD p23 +#define D_WR p24 + +#define D_CTRL_MSK 0xFF + +//Pin Defines for I2C Bus +//#define D_SDA p9 +//#define D_SCL p10 +#define D_SDA p28 +#define D_SCL p27 + +//I2C Bus Address Defines for PCF8574 slaves +#define D_I2C_DATA_BUS 0x40 +#define D_I2C_ADDR_BUS 0x42 +#define D_I2C_ENA_BUS 0x44 + + +//Host PC Baudrate (Virtual Com Port on USB) +#define D_BAUDRATE 9600 +//#define D_BAUDRATE 57600 + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BusEnums.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,17 @@ +/* BusEnums - Use the MBED Port pins and PCF8574s for controlling the Bus + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#ifndef _BUS_ENUMS_H +#define _BUS_ENUMS_H + +//Enums for Control Bus and Enable Bus +enum Bit_Level { LOW, HIGH }; +enum Bus_Dir { READ, WRITE }; +enum Bus_Ena { ENABLE, DISABLE }; + + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ChangeLog.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,12 @@ +/* LF28A Simulator - ChangeLog + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +/* 0.2 Jun 2011 - Testversion + + 0.1 23 Mar 2011 - Initial release. + +*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Dbg.cpp Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,62 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#define __DEBUG +#include "Dbg.h" +#include "mbed.h" +#include <cstdarg> + +void DebugStream::debug(const char* format, ...) +{ + va_list argp; + + va_start(argp, format); + vprintf(format, argp); + va_end(argp); +} + +void DebugStream::release() +{ + +} + +void DebugStream::breakPoint(const char* file, int line) +{ + printf("\r\nBREAK in %s at line %d\r\n", file, line); + fflush(stdout); + getchar(); + fflush(stdin); +} + +/* +int snprintf(char *str, int size, const char *format, ...) +{ + va_list argp; + + va_start(argp, format); + vsprintf(str, format, argp); + va_end(argp); + + return strlen(str); +} +*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Dbg.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,78 @@ +/** \file +Debugging helpers header file +*/ + +/** + Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef DBG_H +#define DBG_H + +/*! + Define to enable debugging in one file + #define __DEBUG +*/ + +#ifdef __DEBUG + +#ifndef __DEBUGSTREAM +#define __DEBUGSTREAM + +class DebugStream { + public: + static void debug(const char* format, ...); + static void release(); + static void breakPoint(const char* file, int line); + private: + +}; + +#undef DBG +#undef DBGL +#undef DBG_END +#undef BREAK + +//Debug output (if enabled), same syntax as printf, with heading info +//#define DBG(...) do{ DebugStream::debug("[%s:%s@%d] ", __FILE__, __FUNCTION__, __LINE__); DebugStream::debug(__VA_ARGS__); } while(0); +#define DBG(...) do{ DebugStream::debug("[%s @%d] ", __FUNCTION__, __LINE__); DebugStream::debug(__VA_ARGS__); } while(0); + +//Debug output (if enabled), same syntax as printf, no heading info +#define DBGL(...) do{ DebugStream::debug(__VA_ARGS__); } while(0); +#define DBG_END DebugStream::release + +//Breakpoint using serial debug interface (if debug enabled) +#define BREAK() DebugStream::breakPoint(__FILE__, __LINE__) +#endif + +#else +#undef DBG +#undef DBGL +#undef DBG_END +#undef BREAK + +#define DBG(...) +#define DBGL(...) +#define DBG_END() +#define BREAK() +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HDSP253X_Display.cpp Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,747 @@ +/* HDSP253X_Display - Intelligent 8 digit 5x7 LED matrix display + * + * Copyright (c) 2011 Wim Huiskamp + * Modified software based on sourcecode by RAC 06/08/2008 + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#include "mbed.h" +//#include "Utils.h" +#include "PCF8574_DataBus.h" +#include "PCF8574_AddressBus.h" +#include "PCF8574_EnableBus.h" +#include "MBED_ControlBus.h" +#include "HDSP253X_Display.h" + +/** Create an HDSP253X_Display object connected to the proper busses + * + * @param PCF8574_DataBus data databus to connect to + * @param PCF8574_AddressBus address addressbus to connect to + * @param PCF8574_EnableBus enable enablebus to connect to + * @param MBED_ControlBus control controlbus to connect to +*/ +HDSP253X_Display::HDSP253X_Display (PCF8574_DataBus &databus, PCF8574_AddressBus &addressbus, PCF8574_EnableBus &enablebus, MBED_ControlBus &controlbus) : + _databus(databus), _addressbus(addressbus), _enablebus(enablebus), _controlbus(controlbus) { + + _init(); +} + +/** Init HDSP253X_Display + * @param + * @returns + */ +void HDSP253X_Display::_init(void) +{ + // Apply reset + reset(); // Note that this also resets the LED status display. + + // Note: Brightness is 100% after reset + set_brightness(HDSP253X_DEF_DISPLAY_BRIGHT); + + // Reset cursor + locate(0); +} + + +/*****************************************************************************/ +/******************* LOW LEVEL HDSP253X SUPPORT FUNCTIONS ******************/ +/*****************************************************************************/ + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_reset + | + | Description: Reset routine for HDSP253X display, applying reset, + | removing reset, then waiting for preset delay. + | With the internal clock, the delay should be around 1 + | millisecond, but slower clocks will require longer delays. + | After reset the Char RAM and Flash RAM is cleared, the CTRL word is + | cleared (Blink Off, Flash Off, Brightness 100%). UDC RAM and address + | are unaffected. + | + | Parameters: None + | + | Returns: Nothing. + | +\*---------------------------------------------------------------------------*/ +void HDSP253X_Display::reset(void) +{ +//NOTE: On LF28A the Reset* pin is connected to the display and to the latches. +// That implies they are all reset when the Reset* pin is used ! +// +// Alternative for the Display may be SW reset instruction + + // Apply the reset condition and then remove after short delay + _enablebus.chipselect(CS_DISP, HIGH); + wait_ms(HDSP253X_1TCY_WAIT_MS); + + _enablebus.reset(LOW); + wait_ms(HDSP253X_1TCY_WAIT_MS); + wait_ms(HDSP253X_1TCY_WAIT_MS); + _enablebus.reset(HIGH); + + // Wait for the preset delay to allow operation to complete + wait_ms(HDSP253X_RST_CLR_DELAY_MS); + + // Reset cursor + locate(0); +} + + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_write + | + | Description: Low level data write routine for HDSP253X. Takes in data + | and address (including Flash as top bit) and writes + | it to the display. For simplicity, entire address byte + | is written, even though top two bits are unused inputs. + | After performing the operation, address lines are set + | all high, in order to eliminate current drain through + | pullup resistors (0.5mA per pin with 10K pullups) + | + | Parameters: address - full address in bits 0-5 (bit 5 is flash) + | data - data byte to write out + | + | Returns: Nothing. + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::_write(uint8_t address, uint8_t data) +{ +// // Switch databus buffer to outputs +// _controlbus.busdir(WRITE); +// // Switch databus to outputs +// _databus.busdir(WRITE); + + + // Write out the address on to the addressbus and wait + _addressbus.write(address); + wait_ms(HDSP253X_1TCY_WAIT_MS); + + // Set CE low and wait + _enablebus.chipselect(CS_DISP, LOW); + wait_ms(HDSP253X_1TCY_WAIT_MS); + + // Write data to the databus + _databus.write(data); + + // Set WR low, wait, then set high and wait + _controlbus.WR(LOW); + wait_ms(HDSP253X_1TCY_WAIT_MS); + _controlbus.WR(HIGH); + wait_ms(HDSP253X_1TCY_WAIT_MS); + + // Set CE high and wait + _enablebus.chipselect(CS_DISP, HIGH); + wait_ms(HDSP253X_1TCY_WAIT_MS); + +// // Switch databus back to inputs +// _databus.busdir(READ); +// // Switch databus buffer back to inputs +// _controlbus.busdir(READ); + +// // Set address lines all high to minimise power through pullups +// _addressbus.write(HDSP253X_ADDR_LOW_POWER); +} + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_read + | + | Description: Low level data read routine for HDSP253X. Takes in + | address (including Flash as top bit) and reads data + | from the display. For simplicity, entire address byte + | is written, even though top two bits are unused inputs. + | After performing the operation, address lines are set + | all high, in order to eliminate current drain through + | pullup resistors (0.5mA per pin with 10K pullups) + | + | Parameters: address - full address in bits 0-5 (bit 5 is flash) + | + | Returns: data - data byte read in + | +\*---------------------------------------------------------------------------*/ + +uint8_t HDSP253X_Display::_read(uint8_t address) +{ + uint8_t data = 0; + + // Switch databus to inputs + _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); + + // Set CE low and wait + _enablebus.chipselect(CS_DISP, LOW); + wait_ms(HDSP253X_1TCY_WAIT_MS); + + // Set RD low and wait + _controlbus.RD(LOW); + wait_ms(HDSP253X_1TCY_WAIT_MS); + + // Read the data byte from databus + data = _databus.read(); + + // set RD high and wait + _controlbus.RD(HIGH); + wait_ms(HDSP253X_1TCY_WAIT_MS); + + // Set CE high and wait + _enablebus.chipselect(CS_DISP, HIGH); + wait_ms(HDSP253X_1TCY_WAIT_MS); + +// // Set address lines all high to minimise power through pullups +// _addressbus.write(HDSP253X_ADDR_LOW_POWER); + + // Switch databus buffer back to outputs + _controlbus.busdir(WRITE); + // Switch databus to outputs + _databus.busdir(WRITE); + + // Return read data to caller + return data; +} + + +/*****************************************************************************/ +/************** HIGH LEVEL HDSP253X CHARACTER DISPLAY FUNCTIONS ************/ +/*****************************************************************************/ + +#if(0) + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_display_ascii_char + | + | Description: Displays specified character on the display at specified + | position. + | + | Parameters: disp_char - single character display + | char_pos - position on the display (0 to 7, Leftmost = 0) + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::_display_ascii_char(char ascii_char, char char_pos) +{ + // Write selected character to display at wrapped position + char_pos %= HDSP253X_NUM_CHARS; + ascii_char &= HDSP253X_CHAR_MASK; // mask off unused bits + _write(HDSP253X_ADDR_CHAR_BASE + char_pos, ascii_char); +} + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_display_udc_char + | + | Description: Displays specified UDC character on the display at specified + | position. Used defined characters use codes from 128-142. + | Note that the normal write routines can be used + | to set UDCs, using ASCII values 128 to 143 inclusive. + | + | Parameters: udc_char - UDC character, 15 possible UDC values from 128-142 + | char_pos - position on the display (0 to 7, Leftmost = 0) + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::_display_udc_char(char udc_char, char char_pos) +{ + // Write selected UDC character to display at wrapped position + char_pos %= HDSP253X_NUM_CHARS; + udc_char &= HDSP253X_UDC_MASK; // mask off unused bits + udc_char |= HDSP253X_UDC_SEL; // add in top bit to specify UDC + _write(HDSP253X_ADDR_CHAR_BASE + char_pos, udc_char); +} +#endif + + + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_display_part_string + | + | Description: Displays specified string on the display, starting + | from specified position, up to end position or end of + | string, whichever is less. NOTE this function must + | NOT be used with read-only strings in program memory. + | + | Parameters: disp_string - character string to display + | start_pos - starting position on the display (0 to 7) + | end_pos - end position on the display (0 to 7) + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::_display_part_string(const char *disp_string, uint8_t start_pos, uint8_t end_pos) +{ + int i; + int string_len; + + // loop round from start pos, writing characters until end reached + string_len = strlen(disp_string); // obtain length of string + for (i = start_pos; (i < HDSP253X_NUM_CHARS) && ((i - start_pos) < string_len) && (i <= end_pos); i++) + { + // write selected character to display at selected position + _write(HDSP253X_ADDR_CHAR_BASE + i, disp_string[i - start_pos]); + } +} + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_display_fixed_string + | + | Description: Displays specified fixed string on the display, starting + | from first character and filling in with spaces until specified + | starting position. If string is shorter than remaining display, + | extra characters will be filled with spaces. If string is longer, + | remaining characters will not be displayed. NOTE this function + | must NOT be used with read-only strings in program memory. + | + | Parameters: disp_string - fixed character string to display + | start_pos - starting position on the display (0 to 7) + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::_display_fixed_string(const char *disp_string, uint8_t start_pos) +{ + int i; + int string_len; + uint8_t char_value; + + // loop round, writing characters or spaces to whole display from start + string_len = strlen(disp_string); // obtain length of string + for (i = 0; i < HDSP253X_NUM_CHARS; i++) + { + // work out whether to display a character or space + if ((i < start_pos) || ((i - start_pos) >= string_len)) + { + // out of string range, so select space character + char_value = ' '; + } + else + { + // within string, so select string character + char_value = disp_string[i - start_pos]; + } + + // write selected character to display at selected position + _write(HDSP253X_ADDR_CHAR_BASE + i, char_value); + } +} + + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_printf + | + | Description: Displays specified string on the display at current + | cursor position. Increments cursor. + | + | Parameters: format - format string + | args - data + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::printf (char * format, ...) { + char buffer[40]; + va_list args; + va_start (args, format); + int rv=vsprintf (buffer, format, args); +// ::printf("printing:'%s'\n", buffer); +// writeString (buffer); + va_end (args); + +// return rv; +} + + + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_putc + | + | Description: Displays specified character on the display at current + | cursor position. Increments cursor. + | Position on the display (0 to 7, Leftmost = 0) + | + | Parameters: disp_char - single character to display + | - ASCII characters, 128 values between 0-127 + | - UDC character, 15 possible UDC values from 128-142 + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::putc(char disp_char) +{ + // Write selected character to display at current position + + if ((disp_char & HDSP253X_UDC_SEL) == HDSP253X_UDC_SEL) { + // Write UDC character to display, code between 128-142 + disp_char &= HDSP253X_UDC_MASK; // mask off unused bits + disp_char |= HDSP253X_UDC_SEL; // add in top bit to specify UDC + _write(HDSP253X_ADDR_CHAR_BASE + _column, disp_char); + } + else { + // Write ASCII character, code between 0-127 + disp_char &= HDSP253X_CHAR_MASK; // mask off unused bits + _write(HDSP253X_ADDR_CHAR_BASE + _column, disp_char); + } + + // Incr and wrap around cursorposition + _column = (_column++) % HDSP253X_NUM_CHARS; +} + + +#if(0) + if (disp_char == '\n') { + _column = 0; + _row = (_row++) % HDSP253X_NUM_LINES; + } + else { + _putc(_column, _row, disp_char); + _column = (_column++) % HDSP253X_NUM_CHARS; + if (_column == 0) { + _row = (_row++) % HDSP253X_NUM_LINES; + } + + +char HDSP253X_Display::getc() { + return -1; +} + +#endif + + + + + + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_locate + | + | Description: Set the cursor address where the next character will be written. + | + | Parameters: Cursor Column address + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::locate(uint8_t column) +{ +// _row = row % HDSP253X_NUM_ROWS; + _column = column % HDSP253X_NUM_CHARS; +} + + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_cls + | + | Description: Clears the displayed data and flash RAM, but not the user + | defined characters. Waits for the preset delay to ensure the + | display is ready for operation; with an internal clock, + | this delay needs to be around 1 millisecond. + | + | Parameters: None + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::cls(void) +{ + uint8_t disp_data; + + // Read in control word, modify and write back out + disp_data = _read(HDSP253X_ADDR_CTRL_WORD); + disp_data |= HDSP253X_CTRL_CLEAR_MASK; + _write(HDSP253X_ADDR_CTRL_WORD, disp_data); + + // Wait for the preset delay to allow operation to complete + wait_ms(HDSP253X_RST_CLR_DELAY_MS); + + // Reset cursor + locate(0); +} + + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_set_brightness + | + | Description: Sets the brightness of the HDSP253X display, by performing + | a read-modify-write on the control register. + | + | Parameters: brightness - 3 bit brightness value + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::set_brightness(uint8_t brightness) +{ + uint8_t ctrl_data; + + // Read in control word, modify and write back out + ctrl_data = _read(HDSP253X_ADDR_CTRL_WORD); + ctrl_data &= ~HDSP253X_CTRL_BRIGHT_MASK; + ctrl_data |= (brightness & HDSP253X_CTRL_BRIGHT_MASK); + _write(HDSP253X_ADDR_CTRL_WORD, ctrl_data); +} + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_start_self_test + | + | Description: Starts the HDSP253X self test, setting the relevant + | control word bit. The caller should then wait for + | the required number of seconds before checking the result. + | With the internal display clock, the self test takes + | around 5 seconds, so waiting for 6 seconds should + | be OK. Slower clocks will require longer delays. + | + | Note that some displays such as the Siemens HDSP2111 + | appear to take longer than the official 4.5 seconds + | so it is advisable to wait for longer (say 6 seconds) + | before checking the result. Attempting to access the + | display before it is ready may result in the self test + | status failing to clear down. + | + | Also note that some display datasheets suggest that + | the display must be reset BEFORE running the self + | test routine, so this routine does this. + | + | Parameters: None + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::start_self_test(void) +{ + // Reset the display to ensure it is ready for the self test + reset(); + + // Directly write the self test request, as control word is wiped at end + _write(HDSP253X_ADDR_CTRL_WORD, HDSP253X_CTRL_SELFTEST_MASK); +} + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_finish_self_test + | + | Description: Reads the control register to determine the self test + | result. Then issues a display reset to ensure + | that it is ready for operation afterwards. While such + | a reset should not be necessary if an adequate delay + | occurs between starting the self test and checking the + | result, issuing a reset guarantees that the display will + | be ready for operation. This also means that this function + | can be called early to prematurely terminate a self test. + | + | Parameters: None + | + | Returns: True if passed, False if failed + | +\*---------------------------------------------------------------------------*/ + +bool HDSP253X_Display::finish_self_test(void) +{ + uint8_t ctrl_data; + bool result; + + // Read back control word and obtain self test result + ctrl_data = _read(HDSP253X_ADDR_CTRL_WORD); + result = ((ctrl_data & HDSP253X_CTRL_STRESULT_MASK) != 0); + + // Reset the display to ensure it is ready for normal operation + reset(); + + // Indicate the self test result + return result; +} + + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_set_blink_mode + | + | Description: Enables or disables the blinking function on the display. + | When enabled, blinking will flash the whole display + | irrespective of the flash RAM. With the internal clock, + | the blink rate is 2Hz. Note that blink mode overrides + | the normal flashing mode. + | + | Parameters: enable - true to enable, false to disable + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::set_blink_mode(bool enable) +{ + uint8_t ctrl_data; + + // read in control word, modify and write back out + ctrl_data = _read(HDSP253X_ADDR_CTRL_WORD); + if (enable) + { + ctrl_data |= HDSP253X_CTRL_BLINK_MASK; + } + else + { + ctrl_data &= ~HDSP253X_CTRL_BLINK_MASK; + } + _write(HDSP253X_ADDR_CTRL_WORD, ctrl_data); +} + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_set_flash_mode + | + | Description: Enables or disables the flashing function on the display. + | When enabled, characters with the flashing bit set in the + | RAM will flash. With the internal clock, the flash rate is 2Hz. + | + | Parameters: enable - true to enable, false to disable + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::set_flash_mode(bool enable) +{ + uint8_t ctrl_data; + + // read in control word, modify and write back out + ctrl_data = _read(HDSP253X_ADDR_CTRL_WORD); + if (enable) + { + ctrl_data |= HDSP253X_CTRL_FLASH_MASK; + } + else + { + ctrl_data &= ~HDSP253X_CTRL_FLASH_MASK; + } + _write(HDSP253X_ADDR_CTRL_WORD, ctrl_data); +} + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_set_all_flash_states + | + | Description: Sets flashing states of all characters in flash RAM, using + | supplied bit mask. Each bit corresponds to a character + | (bit 7 on left, bit 0 on right), and is set to flash and + | clear for steady operation. NOTE: The overall flashing + | enable/disable state is set by the separate set flash + | mode function. + | + | Parameters: flash_bits - bitmask containing flash states + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::set_all_flash_states(uint8_t flash_bits) +{ + int i; + uint8_t char_pos; + + // loop round all character positions, extracting each bit in turn + for (i = 1; i <= HDSP253X_NUM_CHARS; i++) + { + // Get state of bottom bit from mask and use to adjust flash state + // Note that character address is reversed as we start from right + char_pos = HDSP253X_NUM_CHARS - i; + _write(HDSP253X_ADDR_FLASH_BASE + char_pos, flash_bits & 0x01); + + // Shift the mask to the right, ready for the next go + flash_bits >>= 1; + } +} + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_set_char_flash_state + | + | Description: Sets flashing state of one character in flash RAM, using + | supplied character position and enable state. NOTE: The + | overall flashing enable/disable state is set by the + | separate set flash mode function. + | + | Parameters: flash_state - TRUE to flash, FALSE for steady operation + | char_pos - position on the display (0 to 7) + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::set_char_flash_state(bool flash_state, uint8_t char_pos) +{ + // Write out the new flash state to the flash RAM + _write(HDSP253X_ADDR_FLASH_BASE + char_pos, flash_state); +} + +/*---------------------------------------------------------------------------*\ + | + | Function: HDSP253X_define_user_char + | + | Description: Full definition of UDC, firstly setting the UDC address + | to specified character, and then loading all 7 data rows. + | Note that for each row, only the bottom 5 bits are used. + | + | Parameters: udc_char_num - number of UDC character, from 0 to 15 + | row_data_1 - top row data + | row_data_2 - second row data + | row_data_3 - third row data + | row_data_4 - fourth row data + | row_data_5 - fifth row data + | row_data_6 - sixth row data + | row_data_7 - bottomp row data + | + | Returns: Nothing + | +\*---------------------------------------------------------------------------*/ + +void HDSP253X_Display::define_user_char(uint8_t udc_char_num, uint8_t row_data_1, uint8_t row_data_2, + uint8_t row_data_3, uint8_t row_data_4, uint8_t row_data_5, + uint8_t row_data_6, uint8_t row_data_7) +{ + // firstly set the UDC character address, by writing to the UDC addr reg + _write(HDSP253X_ADDR_UDC_ADDRESS, udc_char_num); + + // now write out the 7 rows to the UDC RAM + _write(HDSP253X_ADDR_UDC_ROW_BASE+0, row_data_1); + _write(HDSP253X_ADDR_UDC_ROW_BASE+1, row_data_2); + _write(HDSP253X_ADDR_UDC_ROW_BASE+2, row_data_3); + _write(HDSP253X_ADDR_UDC_ROW_BASE+3, row_data_4); + _write(HDSP253X_ADDR_UDC_ROW_BASE+4, row_data_5); + _write(HDSP253X_ADDR_UDC_ROW_BASE+5, row_data_6); + _write(HDSP253X_ADDR_UDC_ROW_BASE+6, row_data_7); +} + + +/*****************************************************************************/ +/****************************** END OF FILE ********************************/ +/*****************************************************************************/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HDSP253X_Display.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,243 @@ +/* HDSP253X_Display - Intelligent 8 digit 5x7 LED matrix display + * + * Copyright (c) 2011 Wim Huiskamp + * Modified software based on sourcecode by RAC 06/08/2008 + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#ifndef _HDSP253X_DISPLAY_H +#define _HDSP253X_DISPLAY_H +/*---------------------------------------------------------------------------*\ + | Original text by RAC 06/08/2008 has been modified to fix those parts of + | the description which explain hardware or software that has been removed or + | adapted in the new version. + | + | Description: Display driver and demonstrator for HDSP253X series intelligent + | 8 character LED display modules. Options include adjusting + | brightness and message blinking. + | This software drives a single display module using 8 bit databus, + | 5 bit addressbus and controlsignals. Note that this software + | will drive all display devices in the series, including HDSP2530 Orange, + | HDSP2531 Yellow, HDSP2532 red and HDSP2533 green devices. It will also + | drive the smaller HDSP21XX series. + | + | The peripheral is connected to the following pins: + | HDSP253X + | - Reset (pin 1) to EnableBus.RESET + | - Flash (pin 2) to AddressBus.A5 + | - Addr A0 (pin 3) to AddressBus.A0 + | - Addr A1 (pin 4) to AddressBus.A1 + | - Addr A2 (pin 5) to AddressBus.A2 + | - Addr A3 (pin 6) to AddressBus.A3 + | - Addr A4 (pin 10) to AddressBus.A4 + | - Clock select (pin 11) to VCC (Pull Up) + | - Clock in/out (pin 12) to Not Connected + | - Write (pin 13) to ControlBus.WR + | - CE (Pin 14) to EnableBus.CSDISP + | - VDD 5V (Pin 15) + | - GND (supply) (Pin 16) + | - TST (Pin 16) NC + | - GND (logic) (Pin 18) + | - Read (pin 19) to ControlBus.RD + | - Data D0 (pin 20) to Databus.D0 + | - Data D1 (pin 21) to Databus.D1 + | - Data D2 (pin 25) to Databus.D2 + | - Data D3 (pin 26) to Databus.D3 + | - Data D4 (pin 27) to Databus.D4 + | - Data D5 (pin 28) to Databus.D5 + | - Data D6 (pin 29) to Databus.D6 + | - Data D7 (pin 30) to Databus.D7 + | + | The peripheral is connected to the following pins: + | HDSP211X + | - Reset (pin 1) to EnableBus.RESET + | - Flash (pin 2) to AddressBus.A5 + | - Addr A0 (pin 3) to AddressBus.A0 + | - Addr A1 (pin 4) to AddressBus.A1 + | - Addr A2 (pin 5) to AddressBus.A2 + | - Addr A3 (pin 6) to AddressBus.A3 + | - Addr A4 (pin 10) to AddressBus.A4 + | - Clock select (pin 11) to VCC (Pull Up) + | - Clock in/out (pin 12) to Not Connected + | - Write (pin 13) to ControlBus.WR + | - VDD 5V (Pin 14) + | - GND (supply) (Pin 15) + | - GND (logic) (Pin 16) + | - CE (Pin 17) to EnableBus.CSDISP + | - Read (pin 18) to ControlBus.RD + | - Data D0 (pin 19) to Databus.D0 + | - Data D1 (pin 20) to Databus.D1 + | - Data D2 (pin 23) to Databus.D2 + | - Data D3 (pin 24) to Databus.D3 + | - Data D4 (pin 25) to Databus.D4 + | - Data D5 (pin 26) to Databus.D5 + | - Data D6 (pin 27) to Databus.D6 + | - Data D7 (pin 28) to Databus.D7 + | + | Details: All signals to the HDSP253X are pulled up by 10K resistors. + | The device must be reset by pulsing Reset low with Chip Enable + | set high. Other signals are don't cares during a reset. This + | firmware meets these conditions, as long as the pullups are + | correctly installed. + | + | Connecting the clock select and in/out lines to the CPU is optional, + | and may be used for experimentation. + | If using one display, the clock select should normally be pulled + | up high, which results in the clock signal being an output. + | This driver software does not currently control these signals. + | + | If using more than one display, the driver software will + | require modification and extension. Multiple displays should + | have reset, data, address, flash and read/write lines paralleled. + | Each display requires a unique Chip Enable input, and the + | driver software will need to select which display to access. + | The first display should have clock select high, and its clock + | output connected to the clock inputs on all the other displays; + | these should have clock select low to input the clock signal. + | + | Calls to wait_ms() are used to meet the display timing specs + | may need to be modified at higher CPU speeds. + | + | + | Legalese: This software is FREEWARE, and you can adapt it for any + | purpose whatsoever. I cannot be held responsible for any + | loss, injury, damage or death caused by the use of this + | software. + | +\*---------------------------------------------------------------------------*/ + +//Useful stuff to simplify porting of some third party software + #include <stdarg.h> + //#include "Utils.h" + + +/*****************************************************************************/ +/********************* DEFINITIONS FOR HDSP253X DISPLAY ********************/ +/*****************************************************************************/ + +// Specific delays for display operation, assuming internal clocking +// This may need to be lengthened if a significantly slower external clock is used +#define HDSP253X_1TCY_WAIT_MS 1 +#define HDSP253X_RST_CLR_DELAY_MS 2 // delay AFTER issuing reset or clear +#define HDSP253X_SELFTEST_WAIT_MS 6000 // duration of self test operation + +// address values and masks for HDSP253X display access +#define HDSP253X_ADDR_FLASH_BASE 0x00 +#define HDSP253X_ADDR_UDC_ADDRESS 0x20 +#define HDSP253X_ADDR_UDC_ROW_BASE 0x28 +#define HDSP253X_ADDR_CTRL_WORD 0x30 +#define HDSP253X_ADDR_CHAR_BASE 0x38 +// minimises address line power consumption through pullups +#define HDSP253X_ADDR_LOW_POWER 0x3F + +// control word masks for HDSP253X display +#define HDSP253X_CTRL_BRIGHT_MASK 0x07 +#define HDSP253X_CTRL_FLASH_MASK 0x08 +#define HDSP253X_CTRL_BLINK_MASK 0x10 +#define HDSP253X_CTRL_STRESULT_MASK 0x20 +#define HDSP253X_CTRL_SELFTEST_MASK 0x40 +#define HDSP253X_CTRL_CLEAR_MASK 0x80 + +// display brightness definitions, indicating percentage brightness +#define HDSP253X_BRIGHT_100 0x00 +#define HDSP253X_BRIGHT_80 0x01 +#define HDSP253X_BRIGHT_53 0x02 +#define HDSP253X_BRIGHT_40 0x03 +#define HDSP253X_BRIGHT_27 0x04 +#define HDSP253X_BRIGHT_20 0x05 +#define HDSP253X_BRIGHT_13 0x06 +#define HDSP253X_BRIGHT_0 0x07 + +// miscellaneous definitions for HDSP253X display +#define HDSP253X_NUM_CHARS 8 +#define HDSP253X_CHAR_MASK 0x7F +#define HDSP253X_UDC_SEL 0x80 +#define HDSP253X_UDC_MASK 0x0F +//#define HDSP253X_ASCII_UDC_CHARS 144 +//#define HDSP253X_POUND_CHAR 0x1E + + +// 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 + + +/** Create an HDSP253X_Display object connected to the proper busses + * + * @param PCF8574_DataBus data databus to connect to + * @param PCF8574_AddressBus address addressbus to connect to + * @param PCF8574_EnableBus enable enablebus to connect to + * @param MBED_ControlBus control controlbus to connect to +*/ +class HDSP253X_Display { +public: + HDSP253X_Display(PCF8574_DataBus &databus, PCF8574_AddressBus &addressbus, + PCF8574_EnableBus &enablebus, MBED_ControlBus &controlbus); + void cls(); + void putc(char disp_char); +// char getc(); + + void printf (char * format, ...); + void locate(uint8_t column); + void define_user_char(uint8_t udc_char_num, uint8_t row_data_1, uint8_t row_data_2, + uint8_t row_data_3, uint8_t row_data_4, uint8_t row_data_5, + uint8_t row_data_6, uint8_t row_data_7); + + void set_char_flash_state(bool flash_state, uint8_t char_pos); + void set_all_flash_states(uint8_t flash_bits); + void set_brightness(uint8_t brightness); + void set_blink_mode(bool enable); + void set_flash_mode(bool enable); + void reset(); +// void putudc(char byte); + void start_self_test(); + bool finish_self_test(); + +protected: + PCF8574_DataBus &_databus; + PCF8574_AddressBus &_addressbus; + PCF8574_EnableBus &_enablebus; + MBED_ControlBus &_controlbus; + +// int _row; + int _column; + void _write(uint8_t address, uint8_t data); + uint8_t _read(uint8_t address); + 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); + +}; + + +#endif +/*****************************************************************************/ +/****************************** END OF FILE ********************************/ +/*****************************************************************************/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Keyboard.cpp Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,147 @@ +/* Keyboard - Keyboard and Fire Switch control + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#include "mbed.h" +#include "PCF8574_DataBus.h" +#include "PCF8574_EnableBus.h" +#include "MBED_ControlBus.h" +#include "Keyboard.h" + + +/** Create a Keyboard object connected to the specified buses + * + * @param PCF8574_DataBus databus to connect to + * @param PCF8574_EnableBus enable enablebus to connect to + * @param MBED_ControlBus control controlbus to connect to +*/ +Keyboard::Keyboard (PCF8574_DataBus &databus, PCF8574_EnableBus &enablebus, MBED_ControlBus &controlbus) : + _databus(databus), _enablebus(enablebus), _controlbus(controlbus) { + _init(); +} + +/** Init Keyboard + * @param + * @returns + */ +void Keyboard::_init(void) +{ + _KeyReady = false; + _KeyCode = KEY_NONE; +} + + +/** Check Keypressed or Fire switch pressed + * + * @param none + * @returns bool keypressed +*/ +bool Keyboard::readable () { + uint8_t data = 0; + + // Init to No keypressed + _KeyReady = false; + + if (_controlbus.CDINT() == HIGH) { + // CDA Key pressed + _KeyReady = true; + + data = _read(); // Get the switchvalue and decode it + 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; + } + } + + if (_controlbus.FIRE() == HIGH) { + // Manual Fire Key pressed + _KeyReady = true; + + _KeyCode = KEY_FIRE; + } + + return _KeyReady; +} + + +/** Read keycode + * + * @param none + * @returns keycode +*/ +Key_Code Keyboard::getkey() { + + if (_KeyReady) { + _KeyReady = false; + return _KeyCode; + } + else { + return KEY_NONE; + } +} + + +/** Read switch value + * + * @param none + * @returns switch register value +*/ +uint8_t Keyboard::_read() { + uint8_t data = 0; + + // Switch databus to inputs + _databus.busdir(READ); + // Switch databus buffer to inputs + _controlbus.busdir(READ); + + + // Set CE low and wait + _enablebus.chipselect(CS_SWITCH, LOW); + wait_ms(1.0); + + // Set RD low and wait + _controlbus.RD(LOW); + wait_ms(1.0); + + // Read the data byte from databus + data = _databus.read(); + + // set RD high and wait + _controlbus.RD(HIGH); + wait_ms(1.0); + + // Set CE high and wait + _enablebus.chipselect(CS_SWITCH, HIGH); + wait_ms(1.0); + + // Switch databus buffer back to outputs + _controlbus.busdir(WRITE); + // Switch databus to outputs + _databus.busdir(WRITE); + + // Return read data to caller + return data; +} + + + + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Keyboard.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,63 @@ +/* Keyboard - Keyboard and Fire Switch control + * + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#ifndef _KEYBOARD_H +#define _KEYBOARD_H + +/*****************************************************************************/ +/********************* DEFINITIONS FOR KEYBOARD ***************************/ +/*****************************************************************************/ + +// Definitions for Keyboard Latch +// NOTE: NEED TO CHECK THESE !!!! +#define D_KEYBOARD_NONE 0x00 +#define D_KEYBOARD_MODE 0x01 +#define D_KEYBOARD_EDIT_PATH 0x02 +#define D_KEYBOARD_BRIGHT 0x03 +#define D_KEYBOARD_NOTUSED_4 0x04 +#define D_KEYBOARD_GRAT_RT 0x05 +#define D_KEYBOARD_F_L_UP 0x06 +#define D_KEYBOARD_NOTUSED_7 0x07 + +// Masks for keyboard codes, bit 7 not used +#define D_KEYBOARD_MASK 0x7F + +//Enums for Keyboard codes +enum Key_Code { KEY_NONE, KEY_MODE, KEY_EDIT_PATH, KEY_BRIGHT, KEY_GRAT_RT, KEY_F_L_UP, KEY_FIRE }; + + +/** Create a Keyboard object connected to the proper busses + * + * @param PCF8574_DataBus data databus to connect to + * @param PCF8574_EnableBus enable enablebus to connect to + * @param MBED_ControlBus control controlbus to connect to +*/ +class Keyboard { +public: + Keyboard(PCF8574_DataBus &databus, + PCF8574_EnableBus &enablebus, MBED_ControlBus &controlbus); + bool readable (); + Key_Code getkey(); + +protected: + PCF8574_DataBus &_databus; + PCF8574_EnableBus &_enablebus; + MBED_ControlBus &_controlbus; + bool _KeyReady; + Key_Code _KeyCode; + + uint8_t _read(); + void _init(); +}; + + +#endif +/*****************************************************************************/ +/****************************** END OF FILE ********************************/ +/*****************************************************************************/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MBED_ControlBus.cpp Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,395 @@ +/* MBED_ControlBus - Use MBED Port Pins for controlling the external Bus + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#include "mbed.h" +#include "MBED_ControlBus.h" + +//Debounce and Edge detecting stuff +#include "PinDetect.h" +//#define __DIGITAL_IN +//#define __INTERRUPT_IN +#define __PINDETECT_IN + + + + +/** Create an MBED_ControlBus object connected to the specified Pins + * + * @param PinName WR the Write pin + * @param PinName RD the Read pin + * @param PinName DTR the databuffer Transmit/Receive direction pin + * @param PinName CDBUF the databuffer enable pin + * @param PinName CDINT the Keyboard interrupt pin + * @param PinName FIRE the Manual Fire Unit pin +*/ +MBED_ControlBus::MBED_ControlBus(PinName WR, PinName RD, PinName DTR, PinName CDBUF, PinName CDINT, PinName FIRE) : + _WR(WR), // WR pin + _RD(RD), // RD pin + _DTR(DTR), // DTR pin + _CDBUF(CDBUF), // CDBUF pin + _CDINT(CDINT), // CDINT pin + _FIRE(FIRE) { // FIRE pin + _init(); +} + + +/** Set or Clear the WR pin on Control Bus + * + * @param Bit_Level wr_level +*/ +void MBED_ControlBus::WR (Bit_Level wr_level) { + + if (wr_level == LOW) { + // Make sure that databus buffer is enabled for Write + //busctrl(ENABLE, WRITE); + + _RD = 1; // RD Pin High, make sure there is no collision + _WR = 0; // WR Pin Low + } + else { + _WR = 1; // WR Pin High + } +} + + +/** Set or Clear the RD pin on Control Bus + * + * @param Bit_Level rd_level +*/ +void MBED_ControlBus::RD (Bit_Level rd_level) { + + if (rd_level == LOW) { + // Make sure that databus buffer is enabled for Read + //busctrl(ENABLE, READ); + + _WR = 1; // WR Pin High, make sure there is no collision + _RD = 0; // RD Pin Low + } + else { + _RD = 1; // RD Pin High + } +} + + +/** Enable databus buffer for Write or Read + * + * @param Bus_Dir buf_dir +*/ +void MBED_ControlBus::busdir (Bus_Dir buf_dir) { + + if (buf_dir == READ) { + // Make sure that databus buffer is enabled for READ + _DTR = 0; // DTR Pin Low, Read Direction + _CDBUF = 0; // CDBUF Pin Low, Enable Buffer + } + else { + // Make sure that databus buffer is enabled for Write + _DTR = 1; // DTR Pin High, Write Direction + _CDBUF = 0; // CDBUF Pin Low, Enable Buffer + } +} + + +/** Enable/Disable databus buffer and control Write or Read Direction + * + * @param Bus_Ena buf_ena + * @param Bus_Dir buf_dir +*/ +void MBED_ControlBus::busctrl (Bus_Ena buf_ena, Bus_Dir buf_dir) { + + if (buf_ena == ENABLE) { + _CDBUF = 0; // CDBUF Pin Low, Enable Buffer + } + else { + _CDBUF = 1; // CDBUF Pin High, Disable Buffer + } + + if (buf_dir == READ) { + _DTR = 0; // DTR Pin Low, Read Direction + } + else { + _DTR = 1; // DTR Pin High, Write Direction + } +} + + +#ifdef __DIGITAL_IN +/** Get the CDINT pin value from Control Bus + * + * @returns Bit_Level CDINT_level +*/ +Bit_Level MBED_ControlBus::CDINT () { + + // CDINT Pin value, used as regular Pin rather than as interrupt + if (_CDINT == 0) + return LOW; + else + return HIGH; +} + +/** Get the FIRE pin value from Control Bus + * + * @returns Bit_Level FIRE_level +*/ +Bit_Level MBED_ControlBus::FIRE() { + + // FIRE Pin value, used as regular Pin rather than as interrupt + if (_FIRE == 0) + return LOW; + else + return HIGH; +} + +/** Setup debouncing and edge detection on the CDINT pin + * + * @returns +*/ +void MBED_ControlBus::_CDINT_init() { +} + +/** Setup debouncing and edge detection on the FIRE pin + * + * @returns +*/ +void MBED_ControlBus::_FIRE_init() { +} +#endif //__DIGITAL_IN + + + +#ifdef __INTERRUPT_IN +/** Get the CDINT pin value from Control Bus + * + * @returns Bit_Level CDINT_detected +*/ +Bit_Level MBED_ControlBus::CDINT () { + + // CDINT pin has been Debounced and Edge detected + // Respond only once for every keypress + if (_CDINT_detected) { + _CDINT_detected = false; + return HIGH; + } + else { + return LOW; + } +} + +/** Get the FIRE pin value from Control Bus + * + * @returns Bit_Level FIRE_detected +*/ +Bit_Level MBED_ControlBus::FIRE() { + + // FIRE pin has been Debounced and Edge detected + // Respond only once for every keypress + if (_FIRE_detected) { + _FIRE_detected = false; + return HIGH; + } + else { + return LOW; + } +} + + +/** Called on detection of a rising edge at the CDINT pin + * + * @returns +*/ + void MBED_ControlBus::_CDINT_activated(void) { + _CDINT_detected = true; +} + + +/** Called on detection of a rising edge at the FIRE pin + * + * @returns +*/ + void MBED_ControlBus::_FIRE_activated(void) { + _FIRE_detected = true; +} + + +/** Setup simple edge detection on the CDINT pin + * + * @returns +*/ +void MBED_ControlBus::_CDINT_init() { + // Setup the callback function + _CDINT.mode(PullDown); + _CDINT.rise(this, &MBED_ControlBus::_CDINT_activated); + + // Init the edge detection boolean + _CDINT_detected = false; +} + +/** Setup simple edge detection on the FIRE pin + * + * @returns +*/ +void MBED_ControlBus::_FIRE_init() { + // Setup the callback function + _FIRE.mode(PullDown); + _FIRE.rise(this, &MBED_ControlBus::_FIRE_activated); + + // Init the edge detection boolean + _FIRE_detected = false; +} + +/** Setup debouncing and edge detection on the CDINT pin + * + * @returns +*/ +void MBED_ControlBus::_CDINT_init() { +} + +/** Setup debouncing and edge detection on the FIRE pin + * + * @returns +*/ +void MBED_ControlBus::_FIRE_init() { +} +#endif //__INTERRUPT_IN + + + +#ifdef __PINDETECT_IN +/** Get the CDINT pin value from Control Bus + * + * @returns Bit_Level CDINT_detected +*/ +Bit_Level MBED_ControlBus::CDINT () { + + // CDINT pin has been Debounced and Edge detected + // Respond only once for every keypress + if (_CDINT_detected) { + _CDINT_detected = false; + return HIGH; + } + else { + return LOW; + } +} + + /** Get the FIRE pin value from Control Bus + * + * @returns Bit_Level FIRE_detected +*/ +Bit_Level MBED_ControlBus::FIRE() { + + // FIRE pin has been Debounced and Edge detected + // Respond only once for every keypress + if (_FIRE_detected) { + _FIRE_detected = false; + return HIGH; + } + else { + return LOW; + } +} + +/** Called on detection of a rising edge at the CDINT pin + * + * @returns +*/ + void MBED_ControlBus::_CDINT_activated(void) { + _CDINT_detected = true; +} + +/** Called on detection of a falling edge at the CDINT pin + * + * @returns +*/ +void MBED_ControlBus::_CDINT_deactivated(void) { + _CDINT_detected = false; +} + +/** Called on detection of a rising edge at the FIRE pin + * + * @returns +*/ + void MBED_ControlBus::_FIRE_activated(void) { + _FIRE_detected = true; +} + +/** Called on detection of a falling edge at the FIRE pin + * + * @returns +*/ +void MBED_ControlBus::_FIRE_deactivated(void) { + _FIRE_detected = false; +} + +/** Setup debouncing and edge detection on the CDINT pin + * + * @returns +*/ +void MBED_ControlBus::_CDINT_init() { + + // Setup the callback functions + _CDINT.mode(PullDown); + _CDINT.attach_asserted(this, &MBED_ControlBus::_CDINT_activated); + _CDINT.attach_deasserted(this, &MBED_ControlBus::_CDINT_deactivated); +// _CDINT.attach_asserted_held( &keyPressedHeld ); +// _CDINT.attach_deasserted_held( &keyReleasedHeld ); + + // Init the edge detection boolean + _CDINT_detected = false; + + // Sampling does not begin until you set a frequency. + // The default is 20ms. If you want a different frequency + // then pass the period in microseconds for example, for 10ms :- + // _CDINT.setSampleFrequency(10000); + // + _CDINT.setSampleFrequency(); // Defaults to 20ms. +} + +/** Setup debouncing and edge detection on the FIRE pin + * + * @returns +*/ +void MBED_ControlBus::_FIRE_init() { + + // Setup the callback functions + _FIRE.mode(PullDown); + _FIRE.attach_asserted(this, &MBED_ControlBus::_FIRE_activated); + _FIRE.attach_deasserted(this, &MBED_ControlBus::_FIRE_deactivated); +// _FIRE.attach_asserted_held( &keyPressedHeld ); +// _FIRE.attach_deasserted_held( &keyReleasedHeld ); + + // Init the edge detection boolean + _FIRE_detected = false; + + // Sampling does not begin until you set a frequency. + // The default is 20ms. If you want a different frequency + // then pass the period in microseconds for example, for 10ms :- + // _FIRE.setSampleFrequency(10000); + // + _FIRE.setSampleFrequency(); // Defaults to 20ms. +} +#endif // __PINDETECT_IN + + +/** Init MBED_ControlBus + * @param + * @returns + */ +void MBED_ControlBus::_init() { + // Make sure that all Control pins are disabled + _RD = 1; // RD Pin High + _WR = 1; // WR Pin High + + // Make sure that databus buffer is enabled for Write + busctrl(ENABLE, WRITE); + + // Setup debouncing and edge detection for CDINT + _CDINT_init(); + + // Setup debouncing and edge detection for FIRE + _FIRE_init(); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MBED_ControlBus.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,67 @@ +/* MBED_ControlBus - Use the MBED Port pins for controlling the Bus + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#ifndef _MBED_CONTROLBUS_H +#define _MBED_CONTROLBUS_H + +//Enums for Control Bus +#include "BusEnums.h" + +//Debounce and Edge detecting stuff +#include "PinDetect.h" + +/** Create an MBED_ControlBus object connected to the specified Pins + * + * @param PinName WR the Write pin + * @param PinName RD the Read pin + * @param PinName DTR the databuffer Transmit/Receive direction pin + * @param PinName CDBUF the databuffer enable pin + * @param PinName CDINT the Keyboard interrupt pin + * @param PinName FIRE the Manual Fire Unit pin +*/ +class MBED_ControlBus { +public: + MBED_ControlBus(PinName WR, PinName RD, PinName DTR, PinName CDBUF, PinName CDINT, PinName FIRE); + void WR (Bit_Level wr_level); + void RD (Bit_Level rd_level); + void busdir (Bus_Dir buf_dir); + void busctrl (Bus_Ena buf_ena, Bus_Dir buf_dir); + Bit_Level CDINT (); + Bit_Level FIRE (); +protected: + DigitalOut _WR; // Write pin + DigitalOut _RD; // Read pin + DigitalOut _DTR; // Databuffer Transmit/Receive direction pin + DigitalOut _CDBUF; // Databuffer enable pin + +//Plain digital input pin +// DigitalIn _CDINT; // Keyboard interrupt pin +// DigitalIn _FIRE; // Fire interrupt pin + +//Plain digital interrupt pin +// InterruptIn _CDINT; // Keyboard interrupt pin +// InterruptIn _FIRE; // Fire interrupt pin + +//Debounced and Edge detected input pin (Andy Kirkmans's Lib + PinDetect _CDINT; // Keyboard interrupt pin + PinDetect _FIRE; // Fire interrupt pin + + bool _CDINT_detected; + bool _FIRE_detected; + + void _CDINT_activated(); + void _CDINT_deactivated(); + void _CDINT_init(); + + void _FIRE_activated(); + void _FIRE_deactivated(); + void _FIRE_init(); + + void _init(); +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCF8574_AddressBus.cpp Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,40 @@ +/* PCF8574_AddressBus - Use the PCF8574 I2C Port Extender for controlling the Address Bus + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#include "mbed.h" +#include "PCF8574_AddressBus.h" + +/** Create an PCF8574_AddressBus object connected to the specified I2C object and using the specified deviceAddress + * + * @param I2C &i2c the I2C port to connect to + * @param char deviceAddress the address of the PCF8574 +*/ +PCF8574_AddressBus::PCF8574_AddressBus(I2C &i2c, char deviceAddress) : _i2c(i2c) { + _writeOpcode = deviceAddress & 0xFE; // low order bit = 0 for write + _readOpcode = deviceAddress | 0x01; // low order bit = 1 for read + _init(); +} + +/** Optimised AddressBus write operation. + * @param address the addressvalue to output on the bus +*/ +void PCF8574_AddressBus::write(char address) { + char data[1]; + + data[0] = address; + _i2c.write(_writeOpcode, data, 1); // Write addressvalue to bus +} + + +/** Init PCF8574_AddressBus + * @param + * @returns + */ +void PCF8574_AddressBus::_init() { + + write(0x00); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCF8574_AddressBus.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,41 @@ +/* PCF8574_AddressBus - Use the PCF8574 I2C Port Extender for controlling the Address Bus + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#ifndef _PCF8574_ADDRESSBUS_H +#define _PCF8574_ADDRESSBUS_H + + +//Pin Defines for PCF8574 Address Bus +#define D_A0 0x01 +#define D_A1 0x02 +#define D_A2 0x04 +#define D_A3 0x08 +#define D_A4 0x10 +#define D_A5 0x20 +#define D_A6 0x40 +#define D_A7 0x80 + +#define D_ADDR_MSK 0x3F + + +/** Create an PCF8574_AddressBus object connected to the specified I2C object and using the specified deviceAddress + * + * @param I2C &i2c the I2C port to connect to + * @param char deviceAddress the address of the PCF8574 +*/ +class PCF8574_AddressBus { +public: + PCF8574_AddressBus(I2C &i2c, char deviceAddress); + void write(char address); +protected: + I2C &_i2c; + char _readOpcode; + char _writeOpcode; + void _init(); +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCF8574_DataBus.cpp Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,75 @@ +/* PCF8574_DataBus - Use the PCF8574 I2C Port Extender for controlling the Data Bus + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#include "mbed.h" +#include "PCF8574_DataBus.h" + +/** Create an PCF8574_DataBus object connected to the specified I2C object and using the specified deviceAddress + * + * @param I2C &i2c the I2C port to connect to + * @param char deviceAddress the address of the PCF8574 +*/ +PCF8574_DataBus::PCF8574_DataBus(I2C &i2c, char deviceAddress) : _i2c(i2c) { + _writeOpcode = deviceAddress & 0xFE; // low order bit = 0 for write + _readOpcode = deviceAddress | 0x01; // low order bit = 1 for read + _init(); +} + +/** Optimised DataBus write operation. + * @param byte the datavalue to output on the bus +*/ +void PCF8574_DataBus::write(char byte) { + char data[1]; + + data[0] = byte; + _i2c.write(_writeOpcode, data, 1); // Write datavalue to bus +} + +/** Optimised DataBus read operation. + * + * @returns current data from Databus +*/ +char PCF8574_DataBus::read() { + char data[1]; + +//Make sure that databus is enabled for Read +// data[0] = 0xFF; // Init Port for datainput by Writing 0xFF +// _i2c.write(_writeOpcode, data, 1); // Write to bus + + _i2c.read(_readOpcode, data, 1); // Read data from bus + + return data[0]; +} + + +/** Enable databus for Write or Read + * + * @param Bus_Dir bus_dir +*/ +void PCF8574_DataBus::busdir (Bus_Dir bus_dir) { + + if (bus_dir == READ) { + // Make sure that databus is enabled for READ + write(0xFF); // Init Port as input by Writing 0xFF + + } + else { + // Make sure that databus is enabled for WRITE + write(0xFF); // Not really needed, just Init Port to safe settings + } +} + + + +/** Init PCF8574_DataBus + * @param + * @returns + */ +void PCF8574_DataBus::_init() { + + busdir(WRITE); // Init Port as output +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCF8574_DataBus.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,45 @@ +/* PCF8574_DataBus - Use the PCF8574 I2C Port Extender for controlling the Data Bus + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#ifndef _PCF8574_DATABUS_H +#define _PCF8574_DATABUS_H + +//Pin Defines for PCF8574 Data Bus +#define D_D0 0x01 +#define D_D1 0x02 +#define D_D2 0x04 +#define D_D3 0x08 +#define D_D4 0x10 +#define D_D5 0x20 +#define D_D6 0x40 +#define D_D7 0x80 + +#define D_DATA_MSK 0xFF + +//Enums for Data Bus +#include "BusEnums.h" + + +/** Create an PCF8574_DataBus object connected to the specified I2C object and using the specified deviceAddress + * + * @param I2C &i2c the I2C port to connect to + * @param char deviceAddress the address of the PCF8574 +*/ +class PCF8574_DataBus { +public: + PCF8574_DataBus(I2C &i2c, char deviceAddress); + char read(); + void write(char byte); + void busdir (Bus_Dir bus_dir); +protected: + I2C &_i2c; + char _readOpcode; + char _writeOpcode; + void _init(); +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCF8574_EnableBus.cpp Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,130 @@ +/* PCF8574_EnableBus - Use the PCF8574 I2C Port Extender for controlling the Chip Enable Bus + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#include "mbed.h" +#include "PCF8574_EnableBus.h" + + +/** Create an PCF8574_EnableBus object connected to the specified I2C object and using the specified deviceAddress + * + * @param I2C &i2c the I2C port to connect to + * @param char deviceAddress the address of the PCF8574 +*/ +PCF8574_EnableBus::PCF8574_EnableBus(I2C &i2c, char deviceAddress) : _i2c(i2c) { + _writeOpcode = deviceAddress & 0xFE; // low order bit = 0 for write + _readOpcode = deviceAddress | 0x01; // low order bit = 1 for read + _init(); +} + + +/** Set or Reset Chip Select pins on Enable Bus + * + * @param CS_Pin cs_pin + * @param Bit_Level cs_level +*/ +void PCF8574_EnableBus::chipselect (CS_Pin cs_pin, Bit_Level cs_level) { + int result = 1; + + switch (cs_pin) { + case CS_SWITCH : if (cs_level == LOW) + _enable_bus = ~D_CS_SWITCH; // CS Pin Low, make sure that only one CS is active + else + _enable_bus |= D_CS_SWITCH; // CS Pin High + break; + case LATCHEN_1 : if (cs_level == LOW) + _enable_bus = ~D_LATCHEN_1; // CS Pin Low, make sure that only one CS is active + else + _enable_bus |= D_LATCHEN_1; // CS Pin High + break; + case LATCHEN_2 : if (cs_level == LOW) + _enable_bus = ~D_LATCHEN_2; // CS Pin Low, make sure that only one CS is active + else + _enable_bus |= D_LATCHEN_2; // CS Pin High + break; + case CS_BRIGHT : if (cs_level == LOW) + _enable_bus = ~D_CS_BRIGHT; // CS Pin Low, make sure that only one CS is active + else + _enable_bus |= D_CS_BRIGHT; // CS Pin High + break; + case CS_DISP : if (cs_level == LOW) + _enable_bus = ~D_CS_DISP; // CS Pin Low, make sure that only one CS is active + else + _enable_bus |= D_CS_DISP; // CS Pin High + break; + + default: // Oops, we should never end up here.... + result = -1; + } + + _write(); // Write chip enable bits to bus +} + +/** Set or Clear the Reset pin on Enable Bus + * + * @param Bit_Level rst_level +*/ +void PCF8574_EnableBus::reset (Bit_Level rst_level) { + + if (rst_level == LOW) { + _reset_pin = 0x00; // Reset Pin Low + } + else { + _reset_pin = D_RESET; // Reset Pin High + } + + _write(); // Write RST bit to bus +} + + +/** Set or Clear the NoGo pin on Enable Bus + * + * @param Bit_Level nogo_level +*/ +void PCF8574_EnableBus::nogo (Bit_Level nogo_level) { + + if (nogo_level == LOW) { + _nogo_pin = 0x00; // NOGO Pin Low + } + else { + _nogo_pin = D_NOGO; // NOGO Pin High + } + + _write(); // Write NoGo bit to bus +} + + +/** Optimised EnableBus write operation. + * @param byte the value to output on the bus +*/ +void PCF8574_EnableBus::_write(char byte) { + char data[1]; + + data[0] = byte; + _i2c.write(_writeOpcode, data, 1); // Write value to bus +} + +/** Optimised EnableBus write operation. + * @param +*/ +void PCF8574_EnableBus::_write() { + char data[1]; + + data[0] = (_enable_bus & D_ENABLE_MSK) | _reset_pin | _nogo_pin; // Combine enable bits and control bits + _i2c.write(_writeOpcode, data, 1); // Write value to bus +} + + +/** Init PCF8574_EnableBus + * @param + * @returns + */ +void PCF8574_EnableBus::_init() { + _enable_bus = 0xFF; // Make sure that all CS pins are disabled + _reset_pin = D_RESET; // Make sure that Reset pin is disabled + _nogo_pin = D_NOGO; // Make sure that NoGo pin is disabled + _write(); // Write value to bus +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCF8574_EnableBus.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,53 @@ +/* PCF8574_EnableBus - Use the PCF8574 I2C Port Extender for controlling the Chip Enable Bus + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#ifndef _PCF8574_ENABLEBUS_H +#define _PCF8574_ENABLEBUS_H + +//Pin Defines for PCF8574 Enable Bus +//Note: 'Reset' causes all devices on the 'Control & Display Unit' to be reset! +#define D_CS_SWITCH 0x01 +#define D_LATCHEN_1 0x02 +#define D_LATCHEN_2 0x04 +#define D_CS_BRIGHT 0x08 +#define D_CS_DISP 0x10 +#define D_CS_SPARE 0x20 +#define D_RESET 0x40 +#define D_NOGO 0x80 + +#define D_ENABLE_MSK 0x3F + +//Enums for Enable Bus +#include "BusEnums.h" +enum CS_Pin { CS_SWITCH, LATCHEN_1, LATCHEN_2, CS_BRIGHT, CS_DISP, CS_SPARE }; + + +/** Create an PCF8574_EnableBus object connected to the specified I2C object and using the specified deviceAddress + * + * @param I2C &i2c the I2C port to connect to + * @param char deviceAddress the address of the PCF8574 +*/ +class PCF8574_EnableBus { +public: + PCF8574_EnableBus(I2C &i2c, char deviceAddress); + void chipselect (CS_Pin cs_pin, Bit_Level cs_level); + void reset (Bit_Level rst_level); + void nogo (Bit_Level nogo_level); +protected: + I2C &_i2c; + char _readOpcode; + char _writeOpcode; + char _enable_bus; + char _reset_pin; + char _nogo_pin; +// char _read(); + void _write(); + void _write(char byte); + void _init(); +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PinDetect.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,501 @@ +/* + Copyright (c) 2010 Andy Kirkham + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef AJK_PIN_DETECT_H +#define AJK_PIN_DETECT_H + +#ifndef MBED_H +#include "mbed.h" +#endif + +#ifndef PINDETECT_PIN_ASSTERED +#define PINDETECT_PIN_ASSTERED 1 +#endif + +#ifndef PINDETECT_SAMPLE_PERIOD +#define PINDETECT_SAMPLE_PERIOD 20000 +#endif + +#ifndef PINDETECT_ASSERT_COUNT +#define PINDETECT_ASSERT_COUNT 1 +#endif + +#ifndef PINDETECT_HOLD_COUNT +#define PINDETECT_HOLD_COUNT 50 +#endif + +namespace AjK { + +/** PinDetect adds mechanical switch debouncing to DigitialIn and interrupt callbacks. + * + * This is done by sampling the specified pin at regular intervals and detecting any + * change of state ( 0 -> 1 or 1 -> 0 ). When a state change is detected the attached + * callback handler is called. Additionally, if the pin stays in the same state after + * a state change for a defined period of time, an extra callback is made allowing a + * program to detect when a "key is pressed and held down" rather than a momentary + * key/switch press. + * + * All parameters are customisable which include:- + * <ul> + * <li> The sampling frequency. </li> + * <li> The number of continuous samples until a state change is detected. </li> + * <li> The number of continuous samples until a key is assumed held after a state change. </li> + * <li> The logic level which is assumed to be asserted (0volts or +volts). </li> + * </ul> + * + * Only callbacks that have been attached will be called by the library. + * + * Example: + * @code + * #include "mbed.h" + * #include "PinDetect.h" + * + * PinDetect pin( p30 ); + * DigitialOut led1( LED1 ); + * DigitialOut led2( LED2 ); + * DigitialOut led3( LED3 ); + * DigitialOut led4( LED4 ); + * + * void keyPressed( void ) { + * led2 = 1; + * led3 = 0; + * led4 = 0; + * } + * + * void keyReleased( void ) { + * led2 = 0; + * led3 = 0; + * led4 = 0; + * } + * + * void keyPressedHeld( void ) { + * led3 = 1; + * } + * + * void keyReleasedHeld( void ) { + * led4 = 1; + * } + * + * int main() { + * + * pin.mode( PullDown ); + * pin.attach_asserted( &keyPressed ); + * pin.attach_deasserted( &keyReleased ); + * pin.attach_asserted_held( &keyPressedHeld ); + * pin.attach_deasserted_held( &keyReleasedHeld ); + * + * // Sampling does not begin until you set a frequency. + * // The default is 20ms. If you want a different frequency + * // then pass the period in microseconds for example, for 10ms :- + * // pin.setSampleFrequency( 10000 ); + * // + * pin.setSampleFrequency(); // Defaults to 20ms. + * + * while( 1 ) { + * led1 = !led1; + * wait( 0.2 ); + * } + * } + * @endcode + * + * This example will flash led1 in a similar to a standard starting program. + * + * Applying a "1" (switch on) to pin 30 will switch on led2, removing the "1" to "0" + * (switch off) led2 goes out. Holding the "switch" at one for one second will switch + * on led3. An unasserted P30 (switched off) will, after one second illuminate led4 + * when the deasserted calledback is called. + * + * The above is a very basic introduction. For more details:- + * @see example.h + */ +class PinDetect { + +protected: + DigitalIn *_in; + Ticker *_ticker; + int _prevState; + int _currentStateCounter; + int _sampleTime; + int _assertValue; + int _samplesTillAssertReload; + int _samplesTillAssert; + int _samplesTillHeldReload; + int _samplesTillHeld; + FunctionPointer _callbackAsserted; + FunctionPointer _callbackDeasserted; + FunctionPointer _callbackAssertedHeld; + FunctionPointer _callbackDeassertedHeld; + + /** initialise class + * + * @param PinName p is a valid pin that supports DigitalIn + * @param PinMode m The mode the DigitalIn should use. + */ + void init(PinName p, PinMode m) { + _sampleTime = PINDETECT_SAMPLE_PERIOD; + _samplesTillAssert = PINDETECT_ASSERT_COUNT; + _samplesTillHeld = 0; + _samplesTillAssertReload = PINDETECT_ASSERT_COUNT; + _samplesTillHeldReload = PINDETECT_HOLD_COUNT; + _assertValue = PINDETECT_PIN_ASSTERED; + + _in = new DigitalIn( p ); + _in->mode( m ); + _prevState = _in->read(); + _ticker = new Ticker; + } + +public: + + friend class Ticker; + + PinDetect() { error("You must supply a PinName"); } + + /** PinDetect constructor + * + * By default the PinMode is set to PullDown. + * + * @see http://mbed.org/handbook/DigitalIn + * @param p PinName is a valid pin that supports DigitalIn + */ + PinDetect(PinName p) { + init( p, PullDown ); + } + + /** PinDetect constructor + * + * @see http://mbed.org/handbook/DigitalIn + * @param PinName p is a valid pin that supports DigitalIn + * @param PinMode m The mode the DigitalIn should use. + */ + PinDetect(PinName p, PinMode m) { + init( p, m ); + } + + /** PinDetect destructor + */ + ~PinDetect() { + if ( _ticker ) delete( _ticker ); + if ( _in ) delete( _in ); + } + + /** Set the sampling time in microseconds. + * + * @param int The time between pin samples in microseconds. + */ + void setSampleFrequency(int i = PINDETECT_SAMPLE_PERIOD) { + _sampleTime = i; + _prevState = _in->read(); + _ticker->attach_us( this, &PinDetect::isr, _sampleTime ); + } + + /** Set the value used as assert. + * + * Defaults to 1 (ie if pin == 1 then pin asserted). + * + * @param int New assert value (1 or 0) + */ + void setAssertValue (int i = PINDETECT_PIN_ASSTERED) { _assertValue = i & 1; } + + /** Set the number of continuous samples until assert assumed. + * + * Defaults to 1 (1 * sample frequency). + * + * @param int The number of continuous samples until assert assumed. + */ + void setSamplesTillAssert(int i) { _samplesTillAssertReload = i; } + + /** Set the number of continuous samples until held assumed. + * + * Defaults to 50 * sample frequency. + * + * @param int The number of continuous samples until held assumed. + */ + void setSamplesTillHeld(int i) { _samplesTillHeldReload = i; } + + /** Set the pin mode. + * + * @see http://mbed.org/projects/libraries/api/mbed/trunk/DigitalInOut#DigitalInOut.mode + * @param PinMode m The mode to pass on to the DigitalIn + */ + void mode(PinMode m) { _in->mode( m ); } + + /** Attach a callback function + * + * @code + * + * DigitalOut led1( LED1 ); + * PinDetect pin( p30 ); + * + * void myCallback( void ) { + * led1 = 1; + * }; + * + * main() { + * pin.attach_asserted( &myCallback ); + * } + * + * @endcode + * + * Call this function when a pin is asserted. + * @param function A C function pointer + */ + void attach_asserted(void (*function)(void)) { + _callbackAsserted.attach( function ); + } + + /** Attach a callback object/method + * + * @code + * + * class Bar { + * public: + * void myCallback( void ) { led1 = 1; } + * }; + * + * DigitalOut led1( LED1 ); + * PinDetect pin( p30 ); + * Bar bar; + * + * main() { + * pin.attach_asserted( &bar, &Bar::myCallback ); + * } + * + * @endcode + * + * Call this function when a pin is asserted. + * @param object An object that conatins the callback method. + * @param method The method within the object to call. + */ + template<typename T> + void attach_asserted(T *object, void (T::*member)(void)) { + _callbackAsserted.attach( object, member ); + } + + /** Attach a callback function + * + * @code + * + * DigitalOut led1( LED1 ); + * PinDetect pin( p30 ); + * + * void myCallback( void ) { + * led1 = 0; + * }; + * + * main() { + * pin.attach_deasserted( &myCallback ); + * } + * + * @endcode + * + * Call this function when a pin is deasserted. + * @param function A C function pointer + */ + void attach_deasserted(void (*function)(void)) { + _callbackDeasserted.attach( function ); + } + + /** Attach a callback object/method + * + * @code + * + * class Bar { + * public: + * void myCallback( void ) { led1 = 0; } + * }; + * + * DigitalOut led1( LED1 ); + * PinDetect pin( p30 ); + * Bar bar; + * + * main() { + * pin.attach_deasserted( &bar, &Bar::myCallback ); + * } + * + * @endcode + * + * Call this function when a pin is deasserted. + * @param object An object that conatins the callback method. + * @param method The method within the object to call. + */ + template<typename T> + void attach_deasserted(T *object, void (T::*member)(void)) { + _callbackDeasserted.attach( object, member ); + } + + /** Attach a callback function + * + * @code + * + * DigitalOut led2( LED2 ); + * PinDetect pin( p30 ); + * + * void myCallback( void ) { + * led2 = 1; + * }; + * + * main() { + * pin.attach_asserted_held( &myCallback ); + * } + * + * @endcode + * + * Call this function when a pin is asserted and held. + * @param function A C function pointer + */ + void attach_asserted_held(void (*function)(void)) { + _callbackAssertedHeld.attach( function ); + } + + /** Attach a callback object/method + * + * @code + * + * class Bar { + * public: + * void myCallback( void ) { led2 = 0; } + * }; + * + * DigitalOut led2( LED2 ); + * PinDetect pin( p30 ); + * Bar bar; + * + * main() { + * pin.attach_asserted_held( &bar, &Bar::myCallback ); + * } + * + * @endcode + * + * Call this function when a pin is asserted and held. + * @param object An object that conatins the callback method. + * @param method The method within the object to call. + */ + template<typename T> + void attach_asserted_held(T *object, void (T::*member)(void)) { + _callbackAssertedHeld.attach( object, member ); + } + + /** Attach a callback function + * + * @code + * + * DigitalOut led3( LED3 ); + * PinDetect pin( p30 ); + * + * void myCallback( void ) { + * led3 = 1; + * }; + * + * main() { + * pin.attach_deasserted_held( &myCallback ); + * } + * + * @endcode + * + * Call this function when a pin is deasserted and held. + * @param function A C function pointer + */ + void attach_deasserted_held(void (*function)(void)) { + _callbackDeassertedHeld.attach( function ); + } + + /** Attach a callback object/method + * + * @code + * + * class Bar { + * public: + * void myCallback( void ) { led3 = 0; } + * }; + * + * DigitalOut led3( LED3 ); + * PinDetect pin( p30 ); + * Bar bar; + * + * main() { + * pin.attach_deasserted_held( &bar, &Bar::myCallback ); + * } + * + * @endcode + * + * Call this function when a pin is deasserted and held. + * @param object An object that conatins the callback method. + * @param method The method within the object to call. + */ + template<typename T> + void attach_deasserted_held(T *object, void (T::*member)(void)) { + _callbackDeassertedHeld.attach( object, member ); + } + + /** operator int() + * + * Read the value of the pin being sampled. + */ + operator int() { return _in->read(); } + +protected: + /** The Ticker periodic callback function + */ + void isr(void) { + int currentState = _in->read(); + + if ( currentState != _prevState ) { + if ( _samplesTillAssert == 0 ) { + _prevState = currentState; + _samplesTillHeld = _samplesTillHeldReload; + if ( currentState == _assertValue ) + _callbackAsserted.call(); + else + _callbackDeasserted.call(); + } + else { + _samplesTillAssert--; + } + } + else { + _samplesTillAssert = _samplesTillAssertReload; + } + + if ( _samplesTillHeld ) { + if ( _prevState == currentState ) { + _samplesTillHeld--; + if ( _samplesTillHeld == 0 ) { + if ( currentState == _assertValue ) + _callbackAssertedHeld.call(); + else + _callbackDeassertedHeld.call(); + } + } + else { + _samplesTillHeld = 0; + } + } + } + +}; + +}; // namespace AjK ends. + +using namespace AjK; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/STANAG_Codes.cpp Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,249 @@ +/* STANAG Codes - LTD STANAG Codes + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#include "mbed.h" +#include "STANAG_Codes.h" + + +/** Create a STANAG Codes object + * + * @param none + * @brief +*/ +STANAG_Codes::STANAG_Codes() { + + _init(); +} + +/** Init STANAG_Codes() + * @param + * @returns + */ +void STANAG_Codes::_init(void) { + + for (_codeIdx=0; _codeIdx < D_STANAG_CODES; _codeIdx++) { + + for (_digitIdx=0; _digitIdx < D_STANAG_DIGITS; _digitIdx++) { + _codes[_codeIdx][_digitIdx] = STANAG_DEFAULTS[_codeIdx][_digitIdx]; + } + } + +#if(0) + for (_codeIdx=0; _codeIdx < D_STANAG_CODES; _codeIdx++) { + _codes[_codeIdx] = STANAG_DEFAULTS[_codeIdx]; + } +#endif + + _codeIdx = 0; + _digitIdx = 0; +} + + +/** Set the code Index of the selected STANAG Code + * @param uint8_t codeIdx + * @returns value of STANAG code Index + */ +uint8_t STANAG_Codes::setCodeIdx(uint8_t codeIdx) { + + //Check upper boundary + if (codeIdx > D_STANAG_CODES-1) { + _codeIdx = D_STANAG_CODES-1; + } + else { + _codeIdx = codeIdx; + }; + + return _codeIdx; +} + + +/** Get code Index of the selected STANAG Code + * @param + * @returns value of STANAG code Index + */ +uint8_t STANAG_Codes::getCodeIdx() { + + return _codeIdx; +} + + +/** Increment code Index of the selected STANAG Code + * @param + * @returns value of STANAG code Index + */ +uint8_t STANAG_Codes::incCodeIdx() { + + _codeIdx++; + + //Check upper boundary and wrap around + if (_codeIdx > D_STANAG_CODES-1) { + _codeIdx = 0; + }; + + return _codeIdx; +} + + +/** Set the digit index of the selected STANAG Code + * @param uint8_t digitIdx + * @returns value of the digit index + */ +uint8_t STANAG_Codes::setDigitIdx(uint8_t digitIdx) { + + //Check upper boundary + if (digitIdx > D_STANAG_DIGITS-1) { + _digitIdx = D_STANAG_DIGITS-1; + } + else { + _digitIdx = digitIdx; + }; + + return _digitIdx; +} + + +/** Get digit Index of the selected STANAG Code + * @param + * @returns value of digit Index + */ +uint8_t STANAG_Codes::getDigitIdx() { + + return _digitIdx; +} + + +/** Increment digit Index of the selected STANAG Code + * @param + * @returns value of digit Index + */ +uint8_t STANAG_Codes::incDigitIdx() { + + _digitIdx++; + + //Check upper boundary and wrap around + if (_digitIdx > D_STANAG_DIGITS-1) { + _digitIdx = 0; + }; + + return _digitIdx; +} + + +/** Increment Digit of the selected STANAG Code + * @param + * @returns value of Digit + */ +uint8_t STANAG_Codes::incDigit() { + uint8_t digit; + + //Get digit value and increment + digit = _codes[_codeIdx][_digitIdx]; + digit++; + +//NOTE: maybe additional checks required. Valid codes seem to start with a "1" ??? + + //Check upper boundary and wrap around + if (digit > 9) { + digit=0; + }; + + // Save updated digit + _codes[_codeIdx][_digitIdx]=digit; + + return digit; +} + + + +/** Compute the integer value of the selected STANAG Code + * @param uint8_t codeIdx + * @returns integer value of STANAG code + */ +int STANAG_Codes::getCode(uint8_t codeIdx) { + uint8_t digitIdx; + int code; + + code=0; + for (digitIdx=0; digitIdx < D_STANAG_DIGITS; digitIdx++) { + + // ..., thousands, hundreds, tens, units + code = code + _codes[codeIdx][digitIdx] * DECIMALS[D_STANAG_DIGITS - 1 - digitIdx]; + }; + + return code; +} + + +/** Compute the integer value of the currently selected STANAG Code + * @param + * @returns integer value of STANAG code + */ +int STANAG_Codes::getCode() { + + return getCode(_codeIdx); +} + + +/** Compute and Set the digits of the selected STANAG Code + * @param uint8_t codeIdx + * @param int code + * @returns valid integer value of STANAG code + */ +int STANAG_Codes::setCode(uint8_t codeIdx, int code) { + uint8_t digitIdx; + int temp; + + //Check lower boundary + if (code<0) { + code=0; + } + else { + //Check upper boundary + if (code > DECIMALS[D_STANAG_DIGITS]) { + code = DECIMALS[D_STANAG_DIGITS] - 1; + } + }; + + // Extract decimal digits + temp=code; + for (digitIdx=0; digitIdx < D_STANAG_DIGITS; digitIdx++) { + + // ..., thousands, hundreds, tens, units + _codes[codeIdx][digitIdx] = temp / DECIMALS[D_STANAG_DIGITS - 1 - digitIdx]; // Extract most significant decimal digit + temp = temp % DECIMALS[D_STANAG_DIGITS - 1 - digitIdx]; // Remainder for next digit + }; + + return code; +} + + +/** Compute and Set the digits of the currently selected STANAG Code + * @param int code + * @returns valid integer value of STANAG code + */ +int STANAG_Codes::setCode(int code) { + + return setCode(_codeIdx, code); +} + + + +#if(0) +int STANAG_Codes::setCodeDigits(uint8_t codeIdx, STANAG_Code_t STANAG_code) { +} + +STANAG_Code_t STANAG_Codes::getCodeDigits(uint8_t codeIdx) { +} +#endif + + + +/*****************************************************************************/ +/****************************** END OF FILE ********************************/ +/*****************************************************************************/ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/STANAG_Codes.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,72 @@ +/* STANAG Codes - LTD STANAG Codes + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#ifndef _STANAG_H +#define _STANAG_H + +/*****************************************************************************/ +/********************* DEFINITIONS FOR STANAG *****************************/ +/*****************************************************************************/ + +// Definitions +#define D_STANAG_CODES 20 +#define D_STANAG_DIGITS 4 + +// Typedefs +typedef uint8_t STANAG_Code_t[D_STANAG_DIGITS]; + +const int DECIMALS[D_STANAG_DIGITS+1] = {1, 10, 100, 1000, 10000}; + +const STANAG_Code_t STANAG_DEFAULTS[D_STANAG_CODES] = {{1,0,0,0},{1,0,0,1},{1,0,0,2},{1,0,0,3},{1,0,0,4}, + {1,0,1,0},{1,0,1,1},{1,0,1,2},{1,0,1,3},{1,0,1,4}, + {1,0,2,0},{1,0,2,1},{1,0,2,2},{1,0,2,3},{1,0,2,4}, + {1,0,3,0},{1,0,3,1},{1,0,3,2},{1,0,3,3},{1,0,3,4}}; + +// Masks + +// Enums + +/** Create a STANAG Codes object + * + * @param none + * @brief +*/ +class STANAG_Codes { +public: + STANAG_Codes(); + uint8_t setCodeIdx(uint8_t codeIdx); + uint8_t getCodeIdx(); + uint8_t incCodeIdx(); + + uint8_t setDigitIdx(uint8_t digitIdx); + uint8_t getDigitIdx(); + uint8_t incDigitIdx(); + uint8_t incDigit(); + + int setCode(uint8_t codeIdx, int code); + int getCode(uint8_t codeIdx); + int setCode(int code); + int getCode(); + +// int setCodeDigits(uint8_t codeIdx, STANAG_Code_t STANAG_code); +// STANAG_Code_t getCodeDigits(uint8_t codeIdx); + +protected: + uint8_t _codeIdx; + uint8_t _digitIdx; +// int _codes[D_STANAG_CODES][D_STANAG_DIGITS]; + STANAG_Code_t _codes[D_STANAG_CODES]; + + void _init(); +}; + + +#endif +/*****************************************************************************/ +/****************************** END OF FILE ********************************/ +/*****************************************************************************/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Status_Display.cpp Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,355 @@ +/* Status_Display - LED Status Display control + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#include "mbed.h" +#include "PCF8574_DataBus.h" +#include "PCF8574_EnableBus.h" +#include "MBED_ControlBus.h" +#include "Status_Display.h" + + +/** Create a Status_Display object connected to the specified buses + * + * @param PCF8574_DataBus data databus to connect to + * @param PCF8574_EnableBus enable enablebus to connect to + * @param MBED_ControlBus control controlbus to connect to +*/ +Status_Display::Status_Display (PCF8574_DataBus &databus, PCF8574_EnableBus &enablebus, MBED_ControlBus &controlbus) : + _databus(databus), _enablebus(enablebus), _controlbus(controlbus) { + _init(); +} + +/** Init Status_Display + * @param + * @returns + * + * @brief + */ +void Status_Display::_init(void) +{ + // Apply reset +// reset(); // Note that this would also reset the Alphanumeric display. + + _latch1 = 0x00; // Make sure that all LEDs are disabled + _latch2 = 0x00; // Make sure that all LEDs are disabled + _brightness = D_STATUS_LED_BRIGHT_DEF; // Default Brightness + + _write_latch1(); // Write Status LED + _write_latch2(); // Write Status LED + _write_latchbrightness(); // Write Brightness + + NoGo (LED_OFF); // NoGo Off (separate control) +} + + +/** Set or Reset LED lamptest, note that current LED state is lost + * + * @param LED_State led_state + * + * @brief +*/ +void Status_Display::lamptest (LED_State led_state) { + int result = 1; + + if (led_state == LED_ON) { + // Status LEDs controlled by Latch1 + _latch1 = D_STATUS_LED_MULT | D_STATUS_LED_LASER | D_STATUS_LED_BATT | D_STATUS_LED_TEMP | D_STATUS_LED_ENRGY; + // Backlight On + _latch1 |= D_STATUS_BACKLIGHT; + + // Status LEDs controlled by Latch2 + _latch2 = D_STATUS_LED_CODE | D_STATUS_LED_RANGE | D_STATUS_LED_DESIG | D_STATUS_LED_ADDR | D_STATUS_LED_FREQ | D_STATUS_LED_PATH; + + // NoGo On (separate control) + NoGo (LED_ON); + } + else { + _latch1 = 0x00; // Make sure that all LEDs are disabled + _latch2 = 0x00; // Make sure that all LEDs are disabled + + // NoGo Off (separate control) + NoGo (LED_OFF); + } + + // Write LED status + _write_latch1(); + _write_latch2(); +} + + + +/** Set or Reset Status LEDs + * + * @param LED_Pin led_pin + * @param LED_State led_state + * + * @brief +*/ +void Status_Display::LED (LED_Pin led_pin, LED_State led_state) { + int result = 1; + + switch (led_pin) { +// Status LEDs controlled by Latch1 + case LED_MULT : if (led_state == LED_ON) + _latch1 |= D_STATUS_LED_MULT; // LED Pin High + else + _latch1 &= ~D_STATUS_LED_MULT; // LED Pin Low + break; + case LED_LASER : if (led_state == LED_ON) + _latch1 |= D_STATUS_LED_LASER; // LED Pin High + else + _latch1 &= ~D_STATUS_LED_LASER; // LED Pin Low + break; + case LED_BATT : if (led_state == LED_ON) + _latch1 |= D_STATUS_LED_BATT; // LED Pin High + else + _latch1 &= ~D_STATUS_LED_BATT; // LED Pin Low + break; + case LED_TEMP : if (led_state == LED_ON) + _latch1 |= D_STATUS_LED_TEMP; // LED Pin High + else + _latch1 &= ~D_STATUS_LED_TEMP; // LED Pin Low + break; + case LED_ENRGY : if (led_state == LED_ON) + _latch1 |= D_STATUS_LED_ENRGY; // LED Pin High + else + _latch1 &= ~D_STATUS_LED_ENRGY; // LED Pin Low + break; + +// Status LEDs controlled by Latch2 + case LED_CODE : if (led_state == LED_ON) + _latch2 |= D_STATUS_LED_CODE; // LED Pin High + else + _latch2 &= ~D_STATUS_LED_CODE; // LED Pin Low + break; + case LED_RANGE : if (led_state == LED_ON) + _latch2 |= D_STATUS_LED_RANGE; // LED Pin High + else + _latch2 &= ~D_STATUS_LED_RANGE; // LED Pin Low + break; + case LED_DESIG : if (led_state == LED_ON) + _latch2 |= D_STATUS_LED_DESIG; // LED Pin High + else + _latch2 &= ~D_STATUS_LED_DESIG; // LED Pin Low + break; + case LED_ADDR : if (led_state == LED_ON) + _latch2 |= D_STATUS_LED_ADDR; // LED Pin High + else + _latch2 &= ~D_STATUS_LED_ADDR; // LED Pin Low + break; + case LED_FREQ : if (led_state == LED_ON) + _latch2 |= D_STATUS_LED_FREQ; // LED Pin High + else + _latch2 &= ~D_STATUS_LED_FREQ; // LED Pin Low + break; + case LED_PATH : if (led_state == LED_ON) + _latch2 |= D_STATUS_LED_PATH; // LED Pin High + else + _latch2 &= ~D_STATUS_LED_PATH; // LED Pin Low + break; + + default: // Oops, we should never end up here.... + result = -1; + } + + _write_latch1(); // Write LED status + _write_latch2(); +} + + +/** Set or Clear the NoGo LED + * + * @param LED_State nogo_state + * + * @brief +*/ +void Status_Display::NoGo(LED_State NoGo_state) { + // Note that the NoGo LED has a separate pin and is directly connected to the Enable bus + // 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 + } + else { + _enablebus.nogo(LOW); // NoGo LED Off + } + +} + +/** Set or Clear the Backlight + * + * @param LED_State led_state + * + * @brief +*/ +void Status_Display::backlight (LED_State backlight_state) { + + if (backlight_state == LED_ON) { + _latch1 |= D_STATUS_BACKLIGHT; // Backlight On + } + else { + _latch1 &= ~D_STATUS_BACKLIGHT; // Backlight Off + } + + _write_latch1(); // Write Backlight state +} + + +/** Set Backlight and Status LEDs Brightness + * + * @param uint8_t brightness + * + * @brief +*/ +void Status_Display::set_brightness (uint8_t brightness) { + + _brightness = brightness & STATUS_LED_BRIGHT_MASK; + + _write_latchbrightness(); // Write Brightness value +} + + +/** Set Backlight and Status LEDs Brightness + * + * @param Brightness brightness + * + * @brief +*/ +void Status_Display::set_brightness (Brightness brightness) { + + switch (brightness) { + case BRT_OFF : set_brightness(D_STATUS_LED_BRIGHT_OFF); + break; + case BRT_LOW : set_brightness(D_STATUS_LED_BRIGHT_LOW); + break; + case BRT_MED : set_brightness(D_STATUS_LED_BRIGHT_MED); + break; + case BRT_HIGH : set_brightness(D_STATUS_LED_BRIGHT_HGH); + break; + default: // Oops, we should never end up here.... + set_brightness(D_STATUS_LED_BRIGHT_DEF); + } + +} + + +/** Write Latch1 value + * + * @param none + * + * @brief +*/ +void Status_Display::_write_latch1() +{ +// // Switch databus buffer to outputs +// _controlbus.busdir(WRITE); +// // Switch databus to outputs +// _databus.busdir(WRITE); + + // Set CE low and wait + _enablebus.chipselect(LATCHEN_1, LOW); + wait_ms(STATUS_1TCY_WAIT_MS); + + // Write data to the databus + _databus.write(_latch1); + + // Set WR low, wait, then set high and wait + _controlbus.WR(LOW); + wait_ms(STATUS_1TCY_WAIT_MS); + _controlbus.WR(HIGH); + wait_ms(STATUS_1TCY_WAIT_MS); + + + // Set CE high and wait + _enablebus.chipselect(LATCHEN_1, HIGH); + wait_ms(STATUS_1TCY_WAIT_MS); + + +// // Switch databus back to inputs +// _databus.busdir(READ); +// // Switch databus buffer back to inputs +// _controlbus.busdir(READ); + +} + + +/** Write Latch2 value + * + * @param none + * + * @brief +*/ +void Status_Display::_write_latch2() +{ +// // Switch databus buffer to outputs +// _controlbus.busdir(WRITE); +// // Switch databus to outputs +// _databus.busdir(WRITE); + + // Set CE low and wait + _enablebus.chipselect(LATCHEN_2, LOW); + wait_ms(STATUS_1TCY_WAIT_MS); + + // Write data to the databus + _databus.write(_latch2); + + // Set WR low, wait, then set high and wait + _controlbus.WR(LOW); + wait_ms(STATUS_1TCY_WAIT_MS); + _controlbus.WR(HIGH); + wait_ms(STATUS_1TCY_WAIT_MS); + + // Set CE high and wait + _enablebus.chipselect(LATCHEN_2, HIGH); + wait_ms(STATUS_1TCY_WAIT_MS); + + +// // Switch databus back to inputs +// _databus.busdir(READ); +// // Switch databus buffer back to inputs +// _controlbus.busdir(READ); + +} + +/** Write Brightness value + * + * @param none + * + * @brief +*/ +void Status_Display::_write_latchbrightness() +{ +// // Switch databus buffer to outputs +// _controlbus.busdir(WRITE); +// // Switch databus to outputs +// _databus.busdir(WRITE); + + // Set CE low and wait + _enablebus.chipselect(CS_BRIGHT, LOW); + wait_ms(STATUS_1TCY_WAIT_MS); + + // Write data to the databus + _databus.write(_brightness); + + // Set WR low, wait, then set high and wait + _controlbus.WR(LOW); + wait_ms(STATUS_1TCY_WAIT_MS); + _controlbus.WR(HIGH); + wait_ms(STATUS_1TCY_WAIT_MS); + + // Set CE high and wait + _enablebus.chipselect(CS_BRIGHT, HIGH); + wait_ms(STATUS_1TCY_WAIT_MS); + + +// // Switch databus back to inputs +// _databus.busdir(READ); +// // Switch databus buffer back to inputs +// _controlbus.busdir(READ); + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Status_Display.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,111 @@ +/* Status_Display - LED status indicators + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#ifndef _STATUS_DISPLAY_H +#define _STATUS_DISPLAY_H + +//Useful stuff to simplify porting of some third party software +#include "Utils.h" + +/*****************************************************************************/ +/********************* DEFINITIONS FOR STATUS DISPLAY ** ********************/ +/*****************************************************************************/ + +// Specific delays for display operation +#define STATUS_1TCY_WAIT_MS 1 + +// Definitions for Latch1 of Status LEDs +#define D_STATUS_LED_MULT 0x01 +#define D_STATUS_LED_LASER 0x02 +#define D_STATUS_LED_BATT 0x04 +#define D_STATUS_LED_TEMP 0x08 +#define D_STATUS_LED_ENRGY 0x10 +#define D_STATUS_LED_NOTUSED_15 0x20 +#define D_STATUS_LED_NOTUSED_16 0x40 +#define D_STATUS_BACKLIGHT 0x80 + +// Definitions for Latch2 of Status LEDs +#define D_STATUS_LED_NOTUSED_20 0x01 +#define D_STATUS_LED_CODE 0x02 +#define D_STATUS_LED_RANGE 0x04 +#define D_STATUS_LED_DESIG 0x08 +#define D_STATUS_LED_ADDR 0x10 +#define D_STATUS_LED_FREQ 0x20 +#define D_STATUS_LED_PATH 0x40 +#define D_STATUS_LED_NOTUSED_27 0x80 + + +// Definitions for LatchBrightness of Status LEDs +// Value indicates cd/m2 +#define D_STATUS_LED_BRIGHT_000 0x00 +#define D_STATUS_LED_BRIGHT_022 0x01 +#define D_STATUS_LED_BRIGHT_053 0x02 +#define D_STATUS_LED_BRIGHT_112 0x03 +#define D_STATUS_LED_BRIGHT_253 0x04 +#define D_STATUS_LED_BRIGHT_570 0x05 +#define D_STATUS_LED_BRIGHT_129 0x06 +#define D_STATUS_LED_BRIGHT_360 0x07 + +// control word masks for Status LEDs +#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_MED D_STATUS_LED_BRIGHT_570 +#define D_STATUS_LED_BRIGHT_HGH D_STATUS_LED_BRIGHT_360 + +// default display brightness +#define D_STATUS_LED_BRIGHT_DEF D_STATUS_LED_BRIGHT_LOW + +//Enums for Status LEDs +enum LED_Pin { LED_MULT, LED_LASER, LED_BATT, LED_TEMP, LED_ENRGY, LED_CODE, LED_RANGE, LED_DESIG, LED_ADDR, LED_FREQ, LED_PATH }; +enum LED_State { LED_ON, LED_OFF}; + +//Enums for Brightness +enum Brightness { BRT_OFF, BRT_LOW, BRT_MED, BRT_HIGH }; + +/** Create a Status_Display object connected to the proper busses + * + * @param PCF8574_DataBus data databus to connect to + * @param PCF8574_EnableBus enable enablebus to connect to + * @param MBED_ControlBus control controlbus to connect to +*/ +class Status_Display { +public: + Status_Display(PCF8574_DataBus &databus, + PCF8574_EnableBus &enablebus, MBED_ControlBus &controlbus); + void lamptest (LED_State led_state); + void LED (LED_Pin led_pin, LED_State led_state); + void NoGo(LED_State NoGo_state); + void backlight (LED_State backlight_state); + void set_brightness(uint8_t brightness); + void set_brightness(Brightness brightness); + +protected: + PCF8574_DataBus &_databus; + PCF8574_EnableBus &_enablebus; + MBED_ControlBus &_controlbus; + + uint8_t _latch1; + uint8_t _latch2; + uint8_t _brightness; +// void _write_latch1(char data); +// void _write_latch2(char data); + void _write_latch1(); + void _write_latch2(); + void _write_latchbrightness(); + void _init(); + +}; + + +#endif +/*****************************************************************************/ +/****************************** END OF FILE ********************************/ +/*****************************************************************************/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Testloop.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,342 @@ +//------------------------------------------------------------// +// Testing Stuff // +//------------------------------------------------------------// +void show_LEDS () { + static int state = 0; + + switch (state) { + case 0: + myled1 = 1; + myled2 = 0; + myled3 = 0; + state = 1; + break; + case 1: + myled1 = 0; + myled2 = 1; + myled3 = 0; + state = 2; + break; + case 2: + myled1 = 0; + myled2 = 0; + myled3 = 1; + state = 0; + break; + } +} + + +void show_menu() { + pc.printf("0: Exit\r"); + pc.printf("1: Show Menu\r"); + pc.printf("2: Send Message\r"); + pc.printf("3: Toggle Heartbeat\r"); + pc.printf("4: Show STANAGs\r"); + pc.printf("5: Set all STANAGs\r"); + pc.printf("6: Inc STANAG Code Idx\r"); + pc.printf("7: Inc STANAG Digit Idx\r"); + pc.printf("8: Inc STANAG Digit\r"); + pc.printf("9: Test I2C Databus\r"); + pc.printf("A: Test I2C Addressbus\r"); + pc.printf("B: Test I2C Enablebus\r"); + pc.printf("C: Test Status LEDs\r"); + pc.printf("D: Test Brightness LEDs\r"); + pc.printf("\r"); +} + + +void testloop() { + bool running=true; + char command; + int count; + + pc.printf("Start Test!\r"); + show_LEDS(); + show_menu(); + myled4=1; + while(running) { + + if(pc.readable()) { + command = pc.getc(); + pc.printf("\r"); + show_LEDS(); + + switch (command) { + case '0' : + pc.printf("Done\r"); + running = false; + break; + + case '1' : + show_menu(); + break; + + case '2' : + pc.printf("Hello World!\r"); + break; + + case '3' : + if (heartbeatflag){ + heartbeat_stop(); + } + else { + heartbeat.start(); + }; + break; + + case '4' : + pc.printf("Show STANAGs\r"); + for (int codeIdx=0; codeIdx < D_STANAG_CODES; codeIdx++) { + pc.printf("Code[%d] = %d\r", codeIdx, STANAG_codes.getCode(codeIdx) ); + } + break; + + case '5' : + pc.printf("Set STANAGs\r"); + for (int codeIdx=0; codeIdx < D_STANAG_CODES; codeIdx++) { + STANAG_codes.setCode(codeIdx, 2000 + codeIdx ); + } + + break; + + case '6' : + pc.printf("Inc STANAG Code Idx\r"); + pc.printf("New Idx = %d\r", STANAG_codes.incCodeIdx() ); + + break; + case '7' : + pc.printf("Inc STANAG Digit Idx\r"); + pc.printf("New Idx = %d\r", STANAG_codes.incDigitIdx() ); + + break; + + case '8' : + pc.printf("Inc STANAG Digit\r"); + pc.printf("New Digit = %d\r", STANAG_codes.incDigit() ); + + pc.printf("New Code = %4d\r", STANAG_codes.getCode() ); + break; + case '9' : + pc.printf("Test I2C Databus\r"); + pc.printf("Press any key to quit..."); + count=0; + while(! pc.readable()) { + myled2 = 1; + wait(0.1); + myled2 = 0; + wait(0.1); + + databus.write(count); + //addressbus.write(count); + //enablebus.chipselect(CS_DISP, HIGH); + count = (count + 1) & 0xFF; + } + + command = pc.getc(); + pc.printf("..Done\r"); + + break; + case 'A' : + pc.printf("Test I2C Addressbus\r"); + pc.printf("Press any key to quit..."); + count=0; + while(! pc.readable()) { + myled2 = 1; + wait(0.1); + myled2 = 0; + wait(0.1); + + //databus.write(count); + addressbus.write(count); + //enablebus.chipselect(CS_DISP, HIGH); + count = (count + 1) & 0xFF; + } + + command = pc.getc(); + pc.printf("..Done\r"); + + break; + + case 'B' : + pc.printf("Test I2C Enablebus\r"); + pc.printf("Press any key to quit..."); + count=0; + while(! pc.readable()) { + + myled2 = 1; + enablebus.chipselect(CS_SWITCH, LOW); + wait(0.1); + myled2 = 0; +// enablebus.chipselect(CS_SWITCH, HIGH); + wait(0.1); + + myled2 = 1; + enablebus.chipselect(LATCHEN_1, LOW); + wait(0.1); + myled2 = 0; +// enablebus.chipselect(LATCHEN_1, HIGH); + wait(0.1); + + myled2 = 1; + enablebus.chipselect(LATCHEN_2, LOW); + wait(0.1); + myled2 = 0; +// enablebus.chipselect(LATCHEN_2, HIGH); + wait(0.1); + + myled2 = 1; + enablebus.chipselect(CS_BRIGHT, LOW); + wait(0.1); + myled2 = 0; +// enablebus.chipselect(CS_BRIGHT, HIGH); + wait(0.1); + + myled2 = 1; + enablebus.chipselect(CS_DISP, LOW); + wait(0.1); + myled2 = 0; + enablebus.chipselect(CS_DISP, HIGH); + wait(0.1); + + myled2 = 1; + enablebus.reset(LOW); + wait(0.1); + myled2 = 0; + enablebus.reset(HIGH); + wait(0.1); + + myled2 = 1; + enablebus.nogo(LOW); + wait(0.1); + myled2 = 0; + enablebus.nogo(HIGH); + wait(0.1); + + //databus.write(count); + //addressbus.write(count); + //count = (count + 1) & 0xFF; + } + + command = pc.getc(); + pc.printf("..Done\r"); + + break; + + case 'C' : + pc.printf("Test Status LEDs\r"); + pc.printf("Press any key to quit..."); + count=0; + while(! pc.readable()) { + // LEDs On + LF28A_status.NoGo(LED_ON); + wait(0.1); + LF28A_status.LED(LED_LASER, LED_ON); + wait(0.1); + LF28A_status.LED(LED_TEMP, LED_ON); + wait(0.1); + + LF28A_status.LED(LED_MULT, LED_ON); + wait(0.1); + LF28A_status.LED(LED_ENRGY, LED_ON); + wait(0.1); + LF28A_status.LED(LED_BATT, LED_ON); + wait(0.1); + + LF28A_status.LED(LED_DESIG, LED_ON); + wait(0.1); + LF28A_status.LED(LED_RANGE, LED_ON); + wait(0.1); + LF28A_status.LED(LED_CODE, LED_ON); + wait(0.1); + + LF28A_status.LED(LED_ADDR, LED_ON); + wait(0.1); + LF28A_status.LED(LED_FREQ, LED_ON); + wait(0.1); + LF28A_status.LED(LED_PATH, LED_ON); + wait(0.1); + + LF28A_status.backlight(LED_ON); + wait(0.1); + + // LEDs Off + LF28A_status.NoGo(LED_OFF); + wait(0.1); + LF28A_status.LED(LED_LASER, LED_OFF); + wait(0.1); + LF28A_status.LED(LED_TEMP, LED_OFF); + wait(0.1); + + LF28A_status.LED(LED_MULT, LED_OFF); + wait(0.1); + LF28A_status.LED(LED_ENRGY, LED_OFF); + wait(0.1); + LF28A_status.LED(LED_BATT, LED_OFF); + wait(0.1); + + LF28A_status.LED(LED_DESIG, LED_OFF); + wait(0.1); + LF28A_status.LED(LED_RANGE, LED_OFF); + wait(0.1); + LF28A_status.LED(LED_CODE, LED_OFF); + wait(0.1); + + LF28A_status.LED(LED_ADDR, LED_OFF); + wait(0.1); + LF28A_status.LED(LED_FREQ, LED_OFF); + wait(0.1); + LF28A_status.LED(LED_PATH, LED_OFF); + wait(0.1); + + LF28A_status.backlight(LED_OFF); + wait(0.1); + } + + command = pc.getc(); + pc.printf("..Done\r"); + + break; + + case 'D' : + pc.printf("Test Brightness LEDs\r"); + pc.printf("Press any key to quit..."); + + // LEDs On + LF28A_status.NoGo(LED_ON); + LF28A_status.LED(LED_LASER, LED_ON); + LF28A_status.LED(LED_TEMP, LED_ON); + + while(! pc.readable()) { + LF28A_status.set_brightness(BRT_LOW); + 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_OFF); + wait(0.5); + } + // LEDs Off + LF28A_status.NoGo(LED_OFF); + LF28A_status.LED(LED_LASER, LED_OFF); + LF28A_status.LED(LED_TEMP, LED_OFF); + + LF28A_status.set_brightness(BRT_LOW); + + command = pc.getc(); + pc.printf("..Done\r"); + + break; + + } //switch + }//if + }//while + + pc.printf("End Test!\r\r"); +} + +//------------------------------------------------------------// +// End Testing Stuff // +//------------------------------------------------------------// +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utils.h Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,18 @@ +/* Utils - Useful stuff to simplify porting of some third party software + * Copyright (c) 2011 Wim Huiskamp + * + * Released under the MIT License: http://mbed.org/license/mit + * + * version 0.2 Initial Release +*/ +#ifndef _UTILS_H +#define _UTILS_H + +//Typedefs + +#ifndef min +#define min(_a,_b) ((_a) < (_b) ? (_a) : (_b)) +#endif + + +#endif \ No newline at end of file
--- /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"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.lib Sat Aug 20 12:49:44 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/projects/libraries/svn/mbed/trunk@28 \ No newline at end of file