HDSP253X Smart Alphanumeric LED matrix display
HDSP253X.cpp
- Committer:
- wim
- Date:
- 2015-01-25
- Revision:
- 0:b3430a613781
File content as of revision 0:b3430a613781:
/* 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.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; int string_len, i; va_list args; va_start (args, format); // rv=vsprintf (display_string, format, args); 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 ********************************/ /*****************************************************************************/