Libraries and Example of mbed parallel bus using I2C port expanders

Dependencies:   HDSP253X mbed PCF8574_Bus

Files at this revision

API Documentation at this revision

Comitter:
wim
Date:
Sat Sep 17 15:35:39 2011 +0000
Parent:
0:2467aed99127
Commit message:
Example of using the parallel bus to control a smart alphanumeric display

Changed in this revision

HDSP253X_Display.cpp Show annotated file Show diff for this revision Revisions of this file
HDSP253X_Display.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HDSP253X_Display.cpp	Sat Sep 17 15:35:39 2011 +0000
@@ -0,0 +1,625 @@
+/* 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);        
+//    wait_ms(HDSP253X_1TCY_WAIT_MS);
+     
+    // 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 (Note that D7 is masked out)
+ |
+\*---------------------------------------------------------------------------*/
+
+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
+    // Mask out the not-readable D7 bit, this mask is needed for my specific targetboard !
+    // Reading the unconnected D7 bit results in 'H' level. A RMW cycle on the Ctrl register
+    // would then always result in a Clearscreen !
+    data = _databus.read() & HDSP253X_CTRL_MASK;
+
+    // set RD high and wait
+    _controlbus.RD(HIGH);
+//    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  ************/
+/*****************************************************************************/
+
+
+/*---------------------------------------------------------------------------*\
+ |
+ |  Function:       HDSP253X_putudc
+ |
+ |  Description:    Displays specified UDC character on the display at current
+ |                  position. Used defined characters use codes from 128-142.
+ |                  Note that the normal putc write routines can also be used
+ |                  to show UDCs, using ASCII values 128 to 143 inclusive.
+ |
+ |  Parameters:     udc_char_num - UDC character, 16 possible UDC values from 0-15
+ |
+ |  Returns:        Nothing
+ |
+\*---------------------------------------------------------------------------*/
+
+void HDSP253X_Display::putudc (char udc_char_num)
+{
+  putc(HDSP253X_ASCII_UDC_CHARS + udc_char_num);
+}
+
+/*---------------------------------------------------------------------------*\
+ |
+ |  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 display_string[64];
+   int rv, string_len, i;   
+   va_list args;
+   va_start (args, format);
+
+   rv=vsprintf (display_string, format, args);
+   va_end (args);   
+// printf("printing:'%s'\n", display_string);
+//   writeString (buffer);
+
+   // loop round, writing characters
+   string_len = strlen(display_string);   // obtain length of string
+   for (i = 0; i < string_len; i++) {
+     putc(display_string[i]);
+   };
+
+   // 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-143
+        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 = _column % HDSP253X_NUM_CHARS;    
+}
+
+
+
+#if(0)
+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 Sep 17 15:35:39 2011 +0000
@@ -0,0 +1,223 @@
+/* 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_1TCY_WAIT_MS       10
+#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 
+
+// Masks for register read, Bit 7 not readable in the target hardware 
+#define HDSP253X_CTRL_MASK          0x7F 
+
+
+// display brightness definitions, indicating percentage brightness
+#define HDSP253X_BRIGHT_100         0x00
+#define HDSP253X_BRIGHT_80          0x01
+#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    0x80
+
+// default display brightness
+#define HDSP253X_DEF_DISPLAY_BRIGHT HDSP253X_BRIGHT_100
+
+
+/** 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 putudc(char udc_char_num);
+                          
+    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 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  ********************************/
+/*****************************************************************************/
+
--- a/main.cpp	Wed Aug 31 19:45:31 2011 +0000
+++ b/main.cpp	Sat Sep 17 15:35:39 2011 +0000
@@ -11,6 +11,7 @@
 #include "PCF8574_AddressBus.h"
 #include "PCF8574_EnableBus.h"
 #include "MBED_ControlBus.h"
+#include "HDSP253X_Display.h"
   
 // Debug stuff
 #define __DEBUG  
@@ -34,6 +35,9 @@
 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);
 
+// Display Hardware definitions
+HDSP253X_Display LED_display = HDSP253X_Display(databus, addressbus, enablebus, controlbus);
+
 // Dummy delay
 #define DEVICE_WAIT_MS   0
 
@@ -64,7 +68,7 @@
   
     //Done, Tell me about it
     myled1 = 1;
-    DBG("Init Interfaces Done\r");    
+//    DBG("Init Interfaces Done\r");    
 }
       
 
@@ -235,6 +239,62 @@
     return data;
 }
 
+
+void HDSP_BITE() {
+  int count;
+    
+    for (count=0; count<5; count++) {
+      LED_display.locate(0);
+      LED_display.printf("BITE  - ");
+      wait(0.05);                    
+      LED_display.locate(0);         
+      LED_display.printf("BITE  \\ ");
+      wait(0.05);                              
+      LED_display.locate(0);        
+      LED_display.printf("BITE  | ");
+      wait(0.05);              
+      LED_display.locate(0);    
+      LED_display.printf("BITE  / ");    
+      wait(0.05);      
+      LED_display.locate(0);    
+      LED_display.printf("BITE  - ");                
+      wait(0.05);      
+    };
+
+    LED_display.locate(0);    
+    LED_display.printf("BITE  OK"); 
+
+    LED_display.set_blink_mode(true);            
+    wait(2.0);          
+    LED_display.set_blink_mode(false);
+                    
+    LED_display.cls();  
+
+    //Done, Tell me about it                        
+//    DBG("BITE Done, Main, Step = %d\r", 30);    
+}
+
+void HDSP_Init_UDC() {
+
+// batt empty
+  LED_display.define_user_char(0, 0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1F);
+// batt full  
+  LED_display.define_user_char(1, 0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F);  
+}  
+  
+
+void HDSP_Show_UDC() {
+ 
+  LED_display.locate(0);    
+  LED_display.printf("Batt "); 
+//  LED_display.putc(HDSP253X_ASCII_UDC_CHARS + 0); 
+//  LED_display.putc(HDSP253X_ASCII_UDC_CHARS + 1); 
+  LED_display.putudc(0); 
+  LED_display.putudc(1); 
+    
+  wait(2.0);          
+}
+
 int main() {
     int address, result;
     uint8_t data, dummy;
@@ -244,15 +304,20 @@
     heartbeat_start();
           
     clear_screen(); 
-        
-    DBG("Start Main Loop\r");    
+    
+    HDSP_Init_UDC();
+            
+//    DBG("Start Main Loop\r");    
 
 //Testing stuff
         
     //Test cycletime
     cycletimer.start();      
     cycletimer.reset();
-    
+
+
+#if (0)
+// Bus test
     while (1) {
       for (address=0; address<256; address++) {
         //data = read(address, CS_SWITCH);
@@ -272,7 +337,27 @@
       
       show_LEDS ();      
     }
+#else
+// LED Display test
+    while (1) {
+      HDSP_BITE();   
 
+      cyclecount++;
+      if (cyclecount == 10) {
+        cyclecount = 0;
+//        LED_display.printf ("Restart ");
+        HDSP_Show_UDC();         
+      }       
+      else {
+        LED_display.printf ("Cnt=  %2d", cyclecount);      
+      }
+      wait(2.0);
+      pc.printf ("."); 
+                     
+      show_LEDS ();      
+    }
+
+#endif
       
     DBG("I'll be back...\r\r");
 }