HDSP253X Smart Alphanumeric LED matrix display
Embed:
(wiki syntax)
Show/hide line numbers
HDSP253X.cpp
00001 /* HDSP253X_Display - Intelligent 8 digit 5x7 LED matrix display 00002 * 00003 * Copyright (c) 2011 Wim Huiskamp 00004 * Modified software based on sourcecode by RAC 06/08/2008 00005 * 00006 * Released under the MIT License: http://mbed.org/license/mit 00007 * 00008 * version 0.2 Initial Release 00009 */ 00010 #include "mbed.h" 00011 //#include "Utils.h" 00012 #include "PCF8574_DataBus.h" 00013 #include "PCF8574_AddressBus.h" 00014 #include "PCF8574_EnableBus.h" 00015 #include "MBED_ControlBus.h" 00016 #include "HDSP253X.h" 00017 00018 /** Create an HDSP253X_Display object connected to the proper busses 00019 * 00020 * @param PCF8574_DataBus data databus to connect to 00021 * @param PCF8574_AddressBus address addressbus to connect to 00022 * @param PCF8574_EnableBus enable enablebus to connect to 00023 * @param MBED_ControlBus control controlbus to connect to 00024 */ 00025 HDSP253X_Display::HDSP253X_Display (PCF8574_DataBus &databus, PCF8574_AddressBus &addressbus, PCF8574_EnableBus &enablebus, MBED_ControlBus &controlbus) : 00026 _databus(databus), _addressbus(addressbus), _enablebus(enablebus), _controlbus(controlbus) { 00027 00028 _init(); 00029 } 00030 00031 /** Init HDSP253X_Display 00032 * @param 00033 * @returns 00034 */ 00035 void HDSP253X_Display::_init(void) 00036 { 00037 // Apply reset 00038 reset(); // Note that this also resets the LED status display. 00039 00040 // Note: Brightness is 100% after reset 00041 set_brightness(HDSP253X_DEF_DISPLAY_BRIGHT); 00042 00043 // Reset cursor 00044 locate(0); 00045 } 00046 00047 00048 /*****************************************************************************/ 00049 /******************* LOW LEVEL HDSP253X SUPPORT FUNCTIONS ******************/ 00050 /*****************************************************************************/ 00051 00052 /*---------------------------------------------------------------------------*\ 00053 | 00054 | Function: HDSP253X_reset 00055 | 00056 | Description: Reset routine for HDSP253X display, applying reset, 00057 | removing reset, then waiting for preset delay. 00058 | With the internal clock, the delay should be around 1 00059 | millisecond, but slower clocks will require longer delays. 00060 | After reset the Char RAM and Flash RAM is cleared, the CTRL word is 00061 | cleared (Blink Off, Flash Off, Brightness 100%). UDC RAM and address 00062 | are unaffected. 00063 | 00064 | Parameters: None 00065 | 00066 | Returns: Nothing. 00067 | 00068 \*---------------------------------------------------------------------------*/ 00069 void HDSP253X_Display::reset(void) 00070 { 00071 //NOTE: On LF28A the Reset* pin is connected to the display and to the latches. 00072 // That implies they are all reset when the Reset* pin is used ! 00073 // 00074 // Alternative for the Display may be SW reset instruction 00075 00076 // Apply the reset condition and then remove after short delay 00077 _enablebus.chipselect(CS_DISP, HIGH); 00078 wait_ms(HDSP253X_1TCY_WAIT_MS); 00079 00080 _enablebus.reset(LOW); 00081 wait_ms(HDSP253X_1TCY_WAIT_MS); 00082 wait_ms(HDSP253X_1TCY_WAIT_MS); 00083 _enablebus.reset(HIGH); 00084 00085 // Wait for the preset delay to allow operation to complete 00086 wait_ms(HDSP253X_RST_CLR_DELAY_MS); 00087 00088 // Reset cursor 00089 locate(0); 00090 } 00091 00092 00093 /*---------------------------------------------------------------------------*\ 00094 | 00095 | Function: HDSP253X_write 00096 | 00097 | Description: Low level data write routine for HDSP253X. Takes in data 00098 | and address (including Flash as top bit) and writes 00099 | it to the display. For simplicity, entire address byte 00100 | is written, even though top two bits are unused inputs. 00101 | After performing the operation, address lines are set 00102 | all high, in order to eliminate current drain through 00103 | pullup resistors (0.5mA per pin with 10K pullups) 00104 | 00105 | Parameters: address - full address in bits 0-5 (bit 5 is flash) 00106 | data - data byte to write out 00107 | 00108 | Returns: Nothing. 00109 | 00110 \*---------------------------------------------------------------------------*/ 00111 00112 void HDSP253X_Display::_write(uint8_t address, uint8_t data) 00113 { 00114 // // Switch databus buffer to outputs 00115 // _controlbus.busdir(WRITE); 00116 // // Switch databus to outputs 00117 // _databus.busdir(WRITE); 00118 00119 00120 // Write out the address on to the addressbus and wait 00121 _addressbus.write(address); 00122 // wait_ms(HDSP253X_1TCY_WAIT_MS); 00123 00124 // Set CE low and wait 00125 _enablebus.chipselect(CS_DISP, LOW); 00126 // wait_ms(HDSP253X_1TCY_WAIT_MS); 00127 00128 // Write data to the databus 00129 _databus.write(data); 00130 // wait_ms(HDSP253X_1TCY_WAIT_MS); 00131 00132 // Set WR low, wait, then set high and wait 00133 _controlbus.WR(LOW); 00134 // wait_ms(HDSP253X_1TCY_WAIT_MS); 00135 _controlbus.WR(HIGH); 00136 // wait_ms(HDSP253X_1TCY_WAIT_MS); 00137 00138 // Set CE high and wait 00139 _enablebus.chipselect(CS_DISP, HIGH); 00140 // wait_ms(HDSP253X_1TCY_WAIT_MS); 00141 00142 // // Switch databus back to inputs 00143 // _databus.busdir(READ); 00144 // // Switch databus buffer back to inputs 00145 // _controlbus.busdir(READ); 00146 00147 // // Set address lines all high to minimise power through pullups 00148 // _addressbus.write(HDSP253X_ADDR_LOW_POWER); 00149 } 00150 00151 /*---------------------------------------------------------------------------*\ 00152 | 00153 | Function: HDSP253X_read 00154 | 00155 | Description: Low level data read routine for HDSP253X. Takes in 00156 | address (including Flash as top bit) and reads data 00157 | from the display. For simplicity, entire address byte 00158 | is written, even though top two bits are unused inputs. 00159 | After performing the operation, address lines are set 00160 | all high, in order to eliminate current drain through 00161 | pullup resistors (0.5mA per pin with 10K pullups) 00162 | 00163 | Parameters: address - full address in bits 0-5 (bit 5 is flash) 00164 | 00165 | Returns: data - data byte read in (Note that D7 is masked out) 00166 | 00167 \*---------------------------------------------------------------------------*/ 00168 00169 uint8_t HDSP253X_Display::_read(uint8_t address) 00170 { 00171 uint8_t data = 0; 00172 00173 // Switch databus to inputs 00174 _databus.busdir(READ); 00175 // Switch databus buffer to inputs 00176 _controlbus.busdir(READ); 00177 00178 // Write out the address on to the addressbus and wait 00179 _addressbus.write(address); 00180 // wait_ms(HDSP253X_1TCY_WAIT_MS); 00181 00182 // Set CE low and wait 00183 _enablebus.chipselect(CS_DISP, LOW); 00184 // wait_ms(HDSP253X_1TCY_WAIT_MS); 00185 00186 // Set RD low and wait 00187 _controlbus.RD(LOW); 00188 // wait_ms(HDSP253X_1TCY_WAIT_MS); 00189 00190 // Read the data byte from databus 00191 // Mask out the not-readable D7 bit, this mask is needed for my specific targetboard ! 00192 // Reading the unconnected D7 bit results in 'H' level. A RMW cycle on the Ctrl register 00193 // would then always result in a Clearscreen ! 00194 data = _databus.read() & HDSP253X_CTRL_MASK; 00195 00196 // set RD high and wait 00197 _controlbus.RD(HIGH); 00198 // wait_ms(HDSP253X_1TCY_WAIT_MS); 00199 00200 // Set CE high and wait 00201 _enablebus.chipselect(CS_DISP, HIGH); 00202 // wait_ms(HDSP253X_1TCY_WAIT_MS); 00203 00204 // // Set address lines all high to minimise power through pullups 00205 // _addressbus.write(HDSP253X_ADDR_LOW_POWER); 00206 00207 // Switch databus buffer back to outputs 00208 _controlbus.busdir(WRITE); 00209 // Switch databus to outputs 00210 _databus.busdir(WRITE); 00211 00212 // Return read data to caller 00213 return data; 00214 } 00215 00216 00217 /*****************************************************************************/ 00218 /************** HIGH LEVEL HDSP253X CHARACTER DISPLAY FUNCTIONS ************/ 00219 /*****************************************************************************/ 00220 00221 00222 /*---------------------------------------------------------------------------*\ 00223 | 00224 | Function: HDSP253X_putudc 00225 | 00226 | Description: Displays specified UDC character on the display at current 00227 | position. Used defined characters use codes from 128-142. 00228 | Note that the normal putc write routines can also be used 00229 | to show UDCs, using ASCII values 128 to 143 inclusive. 00230 | 00231 | Parameters: udc_char_num - UDC character, 16 possible UDC values from 0-15 00232 | 00233 | Returns: Nothing 00234 | 00235 \*---------------------------------------------------------------------------*/ 00236 00237 void HDSP253X_Display::putudc (char udc_char_num) 00238 { 00239 putc(HDSP253X_ASCII_UDC_CHARS + udc_char_num); 00240 } 00241 00242 /*---------------------------------------------------------------------------*\ 00243 | 00244 | Function: HDSP253X_printf 00245 | 00246 | Description: Displays specified string on the display at current 00247 | cursor position. Increments cursor. 00248 | 00249 | Parameters: format - format string 00250 | args - data 00251 | 00252 | Returns: Nothing 00253 | 00254 \*---------------------------------------------------------------------------*/ 00255 00256 void HDSP253X_Display::printf (char * format, ...) { 00257 char display_string[64]; 00258 // int rv; 00259 int string_len, i; 00260 va_list args; 00261 va_start (args, format); 00262 00263 // rv=vsprintf (display_string, format, args); 00264 vsprintf (display_string, format, args); 00265 va_end (args); 00266 // printf("printing:'%s'\n", display_string); 00267 // writeString (buffer); 00268 00269 // loop round, writing characters 00270 string_len = strlen(display_string); // obtain length of string 00271 for (i = 0; i < string_len; i++) { 00272 putc(display_string[i]); 00273 }; 00274 00275 // return rv; 00276 } 00277 00278 00279 00280 /*---------------------------------------------------------------------------*\ 00281 | 00282 | Function: HDSP253X_putc 00283 | 00284 | Description: Displays specified character on the display at current 00285 | cursor position. Increments cursor. 00286 | Position on the display (0 to 7, Leftmost = 0) 00287 | 00288 | Parameters: disp_char - single character to display 00289 | - ASCII characters, 128 values between 0-127 00290 | - UDC character, 15 possible UDC values from 128-142 00291 | 00292 | Returns: Nothing 00293 | 00294 \*---------------------------------------------------------------------------*/ 00295 void HDSP253X_Display::putc(char disp_char) { 00296 00297 // Write selected character to display at current position 00298 00299 if ((disp_char & HDSP253X_UDC_SEL) == HDSP253X_UDC_SEL) { 00300 // Write UDC character to display, code between 128-143 00301 disp_char &= HDSP253X_UDC_MASK; // mask off unused bits 00302 disp_char |= HDSP253X_UDC_SEL; // add in top bit to specify UDC 00303 _write(HDSP253X_ADDR_CHAR_BASE + _column, disp_char); 00304 } 00305 else { 00306 // Write ASCII character, code between 0-127 00307 disp_char &= HDSP253X_CHAR_MASK; // mask off unused bits 00308 _write(HDSP253X_ADDR_CHAR_BASE + _column, disp_char); 00309 } 00310 00311 // Incr and wrap around cursorposition 00312 _column++; 00313 _column = _column % HDSP253X_NUM_CHARS; 00314 } 00315 00316 00317 00318 #if(0) 00319 char HDSP253X_Display::getc() { 00320 return -1; 00321 } 00322 #endif 00323 00324 /*---------------------------------------------------------------------------*\ 00325 | 00326 | Function: HDSP253X_locate 00327 | 00328 | Description: Set the cursor address where the next character will be written. 00329 | 00330 | Parameters: Cursor Column address 00331 | 00332 | Returns: Nothing 00333 | 00334 \*---------------------------------------------------------------------------*/ 00335 00336 void HDSP253X_Display::locate(uint8_t column) { 00337 00338 // _row = row % HDSP253X_NUM_ROWS; 00339 _column = column % HDSP253X_NUM_CHARS; 00340 } 00341 00342 00343 /*---------------------------------------------------------------------------*\ 00344 | 00345 | Function: HDSP253X_cls 00346 | 00347 | Description: Clears the displayed data and flash RAM, but not the user 00348 | defined characters. Waits for the preset delay to ensure the 00349 | display is ready for operation; with an internal clock, 00350 | this delay needs to be around 1 millisecond. 00351 | 00352 | Parameters: None 00353 | 00354 | Returns: Nothing 00355 | 00356 \*---------------------------------------------------------------------------*/ 00357 00358 void HDSP253X_Display::cls(void) { 00359 00360 uint8_t disp_data; 00361 00362 // Read in control word, modify and write back out 00363 disp_data = _read(HDSP253X_ADDR_CTRL_WORD); 00364 disp_data |= HDSP253X_CTRL_CLEAR_MASK; 00365 _write(HDSP253X_ADDR_CTRL_WORD, disp_data); 00366 00367 // Wait for the preset delay to allow operation to complete 00368 wait_ms(HDSP253X_RST_CLR_DELAY_MS); 00369 00370 // Reset cursor 00371 locate(0); 00372 } 00373 00374 00375 /*---------------------------------------------------------------------------*\ 00376 | 00377 | Function: HDSP253X_set_brightness 00378 | 00379 | Description: Sets the brightness of the HDSP253X display, by performing 00380 | a read-modify-write on the control register. 00381 | 00382 | Parameters: brightness - 3 bit brightness value 00383 | 00384 | Returns: Nothing 00385 | 00386 \*---------------------------------------------------------------------------*/ 00387 00388 void HDSP253X_Display::set_brightness(uint8_t brightness) { 00389 00390 uint8_t ctrl_data; 00391 00392 // Read in control word, modify and write back out 00393 ctrl_data = _read(HDSP253X_ADDR_CTRL_WORD); 00394 ctrl_data &= ~HDSP253X_CTRL_BRIGHT_MASK; 00395 ctrl_data |= (brightness & HDSP253X_CTRL_BRIGHT_MASK); 00396 _write(HDSP253X_ADDR_CTRL_WORD, ctrl_data); 00397 } 00398 00399 /*---------------------------------------------------------------------------*\ 00400 | 00401 | Function: HDSP253X_start_self_test 00402 | 00403 | Description: Starts the HDSP253X self test, setting the relevant 00404 | control word bit. The caller should then wait for 00405 | the required number of seconds before checking the result. 00406 | With the internal display clock, the self test takes 00407 | around 5 seconds, so waiting for 6 seconds should 00408 | be OK. Slower clocks will require longer delays. 00409 | 00410 | Note that some displays such as the Siemens HDSP2111 00411 | appear to take longer than the official 4.5 seconds 00412 | so it is advisable to wait for longer (say 6 seconds) 00413 | before checking the result. Attempting to access the 00414 | display before it is ready may result in the self test 00415 | status failing to clear down. 00416 | 00417 | Also note that some display datasheets suggest that 00418 | the display must be reset BEFORE running the self 00419 | test routine, so this routine does this. 00420 | 00421 | Parameters: None 00422 | 00423 | Returns: Nothing 00424 | 00425 \*---------------------------------------------------------------------------*/ 00426 00427 void HDSP253X_Display::start_self_test(void) { 00428 00429 // Reset the display to ensure it is ready for the self test 00430 reset(); 00431 00432 // Directly write the self test request, as control word is wiped at end 00433 _write(HDSP253X_ADDR_CTRL_WORD, HDSP253X_CTRL_SELFTEST_MASK); 00434 } 00435 00436 /*---------------------------------------------------------------------------*\ 00437 | 00438 | Function: HDSP253X_finish_self_test 00439 | 00440 | Description: Reads the control register to determine the self test 00441 | result. Then issues a display reset to ensure 00442 | that it is ready for operation afterwards. While such 00443 | a reset should not be necessary if an adequate delay 00444 | occurs between starting the self test and checking the 00445 | result, issuing a reset guarantees that the display will 00446 | be ready for operation. This also means that this function 00447 | can be called early to prematurely terminate a self test. 00448 | 00449 | Parameters: None 00450 | 00451 | Returns: True if passed, False if failed 00452 | 00453 \*---------------------------------------------------------------------------*/ 00454 00455 bool HDSP253X_Display::finish_self_test(void) { 00456 uint8_t ctrl_data; 00457 bool result; 00458 00459 // Read back control word and obtain self test result 00460 ctrl_data = _read(HDSP253X_ADDR_CTRL_WORD); 00461 result = ((ctrl_data & HDSP253X_CTRL_STRESULT_MASK) != 0); 00462 00463 // Reset the display to ensure it is ready for normal operation 00464 reset(); 00465 00466 // Indicate the self test result 00467 return result; 00468 } 00469 00470 00471 /*---------------------------------------------------------------------------*\ 00472 | 00473 | Function: HDSP253X_set_blink_mode 00474 | 00475 | Description: Enables or disables the blinking function on the display. 00476 | When enabled, blinking will flash the whole display 00477 | irrespective of the flash RAM. With the internal clock, 00478 | the blink rate is 2Hz. Note that blink mode overrides 00479 | the normal flashing mode. 00480 | 00481 | Parameters: enable - true to enable, false to disable 00482 | 00483 | Returns: Nothing 00484 | 00485 \*---------------------------------------------------------------------------*/ 00486 00487 void HDSP253X_Display::set_blink_mode(bool enable) { 00488 uint8_t ctrl_data; 00489 00490 // read in control word, modify and write back out 00491 ctrl_data = _read(HDSP253X_ADDR_CTRL_WORD); 00492 if (enable) { 00493 ctrl_data |= HDSP253X_CTRL_BLINK_MASK; 00494 } 00495 else { 00496 ctrl_data &= ~HDSP253X_CTRL_BLINK_MASK; 00497 } 00498 _write(HDSP253X_ADDR_CTRL_WORD, ctrl_data); 00499 } 00500 00501 /*---------------------------------------------------------------------------*\ 00502 | 00503 | Function: HDSP253X_set_flash_mode 00504 | 00505 | Description: Enables or disables the flashing function on the display. 00506 | When enabled, characters with the flashing bit set in the 00507 | RAM will flash. With the internal clock, the flash rate is 2Hz. 00508 | 00509 | Parameters: enable - true to enable, false to disable 00510 | 00511 | Returns: Nothing 00512 | 00513 \*---------------------------------------------------------------------------*/ 00514 00515 void HDSP253X_Display::set_flash_mode(bool enable) { 00516 uint8_t ctrl_data; 00517 00518 // read in control word, modify and write back out 00519 ctrl_data = _read(HDSP253X_ADDR_CTRL_WORD); 00520 if (enable) { 00521 ctrl_data |= HDSP253X_CTRL_FLASH_MASK; 00522 } 00523 else { 00524 ctrl_data &= ~HDSP253X_CTRL_FLASH_MASK; 00525 } 00526 _write(HDSP253X_ADDR_CTRL_WORD, ctrl_data); 00527 } 00528 00529 /*---------------------------------------------------------------------------*\ 00530 | 00531 | Function: HDSP253X_set_all_flash_states 00532 | 00533 | Description: Sets flashing states of all characters in flash RAM, using 00534 | supplied bit mask. Each bit corresponds to a character 00535 | (bit 7 on left, bit 0 on right), and is set to flash and 00536 | clear for steady operation. NOTE: The overall flashing 00537 | enable/disable state is set by the separate set flash 00538 | mode function. 00539 | 00540 | Parameters: flash_bits - bitmask containing flash states 00541 | 00542 | Returns: Nothing 00543 | 00544 \*---------------------------------------------------------------------------*/ 00545 00546 void HDSP253X_Display::set_all_flash_states(uint8_t flash_bits) 00547 { 00548 int i; 00549 uint8_t char_pos; 00550 00551 // loop round all character positions, extracting each bit in turn 00552 for (i = 1; i <= HDSP253X_NUM_CHARS; i++) 00553 { 00554 // Get state of bottom bit from mask and use to adjust flash state 00555 // Note that character address is reversed as we start from right 00556 char_pos = HDSP253X_NUM_CHARS - i; 00557 _write(HDSP253X_ADDR_FLASH_BASE + char_pos, flash_bits & 0x01); 00558 00559 // Shift the mask to the right, ready for the next go 00560 flash_bits >>= 1; 00561 } 00562 } 00563 00564 /*---------------------------------------------------------------------------*\ 00565 | 00566 | Function: HDSP253X_set_char_flash_state 00567 | 00568 | Description: Sets flashing state of one character in flash RAM, using 00569 | supplied character position and enable state. NOTE: The 00570 | overall flashing enable/disable state is set by the 00571 | separate set flash mode function. 00572 | 00573 | Parameters: flash_state - TRUE to flash, FALSE for steady operation 00574 | char_pos - position on the display (0 to 7) 00575 | 00576 | Returns: Nothing 00577 | 00578 \*---------------------------------------------------------------------------*/ 00579 00580 void HDSP253X_Display::set_char_flash_state(bool flash_state, uint8_t char_pos) { 00581 // Write out the new flash state to the flash RAM 00582 _write(HDSP253X_ADDR_FLASH_BASE + char_pos, flash_state); 00583 } 00584 00585 /*---------------------------------------------------------------------------*\ 00586 | 00587 | Function: HDSP253X_define_user_char 00588 | 00589 | Description: Full definition of UDC, firstly setting the UDC address 00590 | to specified character, and then loading all 7 data rows. 00591 | Note that for each row, only the bottom 5 bits are used. 00592 | 00593 | Parameters: udc_char_num - number of UDC character, from 0 to 15 00594 | row_data_1 - top row data 00595 | row_data_2 - second row data 00596 | row_data_3 - third row data 00597 | row_data_4 - fourth row data 00598 | row_data_5 - fifth row data 00599 | row_data_6 - sixth row data 00600 | row_data_7 - bottomp row data 00601 | 00602 | Returns: Nothing 00603 | 00604 \*---------------------------------------------------------------------------*/ 00605 00606 void HDSP253X_Display::define_user_char(uint8_t udc_char_num, uint8_t row_data_1, uint8_t row_data_2, 00607 uint8_t row_data_3, uint8_t row_data_4, uint8_t row_data_5, 00608 uint8_t row_data_6, uint8_t row_data_7) 00609 { 00610 // firstly set the UDC character address, by writing to the UDC addr reg 00611 _write(HDSP253X_ADDR_UDC_ADDRESS, udc_char_num); 00612 00613 // now write out the 7 rows to the UDC RAM 00614 _write(HDSP253X_ADDR_UDC_ROW_BASE+0, row_data_1); 00615 _write(HDSP253X_ADDR_UDC_ROW_BASE+1, row_data_2); 00616 _write(HDSP253X_ADDR_UDC_ROW_BASE+2, row_data_3); 00617 _write(HDSP253X_ADDR_UDC_ROW_BASE+3, row_data_4); 00618 _write(HDSP253X_ADDR_UDC_ROW_BASE+4, row_data_5); 00619 _write(HDSP253X_ADDR_UDC_ROW_BASE+5, row_data_6); 00620 _write(HDSP253X_ADDR_UDC_ROW_BASE+6, row_data_7); 00621 } 00622 00623 00624 /*****************************************************************************/ 00625 /****************************** END OF FILE ********************************/ 00626 /*****************************************************************************/ 00627
Generated on Wed Jul 13 2022 06:43:48 by 1.7.2