Alphanumeric LED display, 8 digits, 5x7 pattern. Supports 8x1, 8x2, 16x1 and 16x2 display configuration.

Dependents:   mbed_HCMS2975

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HCMS2975.cpp Source File

HCMS2975.cpp

Go to the documentation of this file.
00001 /** 
00002  * @file HCMS2975.cpp 
00003  * @brief  mbed Avago/HP HCMS2975 LED matrix display Library. 
00004  * @author WH
00005  * @date   Copyright (c) 2014
00006  *         v01: WH, Initial release
00007  *              Info available at http://playground.arduino.cc/Main/LedDisplay and http://www.pjrc.com/teensy/td_libs_LedDisplay.html 
00008  *         v02: WH, added getVersion()  
00009  *         v03: WH, fixed setBrightness at init() when there is no HW reset.   
00010  *
00011  * Permission is hereby granted, free of charge, to any person obtaining a copy
00012  * of this software and associated documentation files (the "Software"), to deal
00013  * in the Software without restriction, including without limitation the rights
00014  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00015  * copies of the Software, and to permit persons to whom the Software is
00016  * furnished to do so, subject to the following conditions:
00017  *
00018  * The above copyright notice and this permission notice shall be included in
00019  * all copies or substantial portions of the Software.
00020  *
00021  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00022  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00023  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00024  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00025  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00026  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00027  * THE SOFTWARE.
00028  */
00029 #include "mbed.h"
00030 #include "HCMS2975.h"
00031 #include "font_5x7.h" // Pascal Stang's 5x7 font library
00032 
00033 // User Defined Characters (UDCs) are defined by a 5 byte bitpattern. The P0..P6 form the character pattern, P7 is ignored.
00034 //     Byte0 Byte1 Byte2 Byte3 Byte4 
00035 // b0  P0    P0    P0    P0    P0
00036 // b1  P1    P1    P1    P1    P1
00037 // .         .............
00038 // b6  P6    P6    P6    P6    P6
00039 // b7  x     x     x     x     x 
00040 
00041 /** Some sample User Defined Chars 5x7 dots */
00042 const char udc_0[]      = {0x7F, 0x41, 0x22, 0x14, 0x08};  /* |> */
00043 const char udc_1[]      = {0x08, 0x14, 0x22, 0x41, 0x7F};  /* <| */
00044 const char udc_2[]      = {0x7F, 0x00, 0x00, 0x00, 0x00};  /* |  */
00045 const char udc_3[]      = {0x7F, 0x00, 0x7F, 0x00, 0x00};  /* || */
00046 const char udc_4[]      = {0x7F, 0x00, 0x7F, 0x00, 0x7F};  /* ||| */
00047 const char udc_5[]      = {0x2A, 0x2A, 0x2A, 0x2A, 0x2A};  /* = */
00048 const char udc_6[]      = {0x55, 0x2A, 0x55, 0x2A, 0x55};  /* checkerboard */
00049 const char udc_7[]      = {0x01, 0x02, 0x04, 0x08, 0x10};  /* \ */
00050 
00051 const char udc_Bat_Hi[] = {0x7E, 0x7F, 0x7F, 0x7F, 0x7E};  /* Battery Full */
00052 const char udc_Bat_Ha[] = {0x7E, 0x7D, 0x7D, 0x7D, 0x7E};  /* Battery Half */
00053 const char udc_Bat_Lo[] = {0x7E, 0x61, 0x61, 0x61, 0x7E};  /* Battery Low */
00054 const char udc_AC[]     = {0x0C, 0x17, 0x74, 0x17, 0x0C};  /* AC Power */
00055 const char udc_smiley[] = {0x10, 0x22, 0x28, 0x22, 0x10};  /* Smiley */
00056 
00057 /** Create an HCMS2975 Display object connected to the proper pins
00058   *
00059   * @param  *spi SPI port
00060   * @param  cs   PinName for Chip Select (active low)
00061   * @param  rs   PinName for RS ()
00062   * @param  rst  PinName for Rst (active low, optional, default=NC) 
00063   * @param type  Sets the panel size (default = LED8x1)     
00064   */
00065 HCMS2975::HCMS2975(SPI *spi, PinName cs, PinName rs, PinName rst, LEDType type) : _spi(spi), _cs(cs), _rs(rs), _type(type) {
00066   
00067   // Extract LCDType data  
00068 
00069   // Columns encoded in b7..b0
00070   _nr_cols = (_type & 0xFF);          
00071 
00072   // Rows encoded in b15..b8  
00073   _nr_rows = ((_type >> 8) & 0xFF);  
00074   
00075   _displaySize = _nr_cols * _nr_rows;
00076 
00077   // Number of devices encoded in b23..b16  
00078   _deviceCount = ((_type >> 16) & 0xFF);  
00079 
00080 
00081   // The hardware Reset pin is optional. Test and make sure whether it exists or not to prevent illegal access.
00082   if (rst != NC) {
00083     _rst = new DigitalOut(rst);   //Construct new pin 
00084     _rst->write(1);               //Deactivate    
00085   }
00086   else {
00087     // No Hardware Backlight pin       
00088     _rst = NULL;                 //Construct dummy pin     
00089   }  
00090 
00091   _init();    
00092 }
00093 
00094 /** Destructor for HCMS2975 Display object
00095   *
00096   */ 
00097 HCMS2975::~HCMS2975() {
00098    if (_rst != NULL) {delete _rst;}  // RST pin
00099 }
00100 
00101 #if(HCMS2975_PRINTF != 1)
00102 /** Write a character to the Display
00103   *
00104   * @param c The character to write to the display
00105   */
00106 int HCMS2975::putc(int c){
00107   return _putc(c);  
00108 }
00109 
00110 /** Write a raw string to the Display
00111   *
00112   * @param string text, may be followed by variables to emulate formatting the string.
00113   *                     However, printf formatting is NOT supported and variables will be ignored! 
00114   */
00115 int HCMS2975::printf(const char* text, ...) {
00116   
00117   while (*text !=0) {
00118     _putc(*text);
00119     text++;
00120   }
00121   return 0;
00122 }
00123 #else    
00124 #if DOXYGEN_ONLY
00125 /** Write a character to the Display
00126   *
00127   * @param c The character to write to the display
00128   */
00129 int HCMS2975::putc(int c){
00130     return _putc(c);
00131 }
00132 
00133 /** Write a formatted string to the Display
00134   *
00135   * @param format A printf-style format string, followed by the
00136   *               variables to use in formatting the string.
00137   */
00138 int HCMS2975::printf(const char* format, ...){
00139 }   
00140 #endif
00141     
00142 #endif    
00143 
00144 /** Clear the screen and locate to 0,0
00145   */
00146 void HCMS2975::cls(){
00147 
00148   // fill _displayBuffer with spaces
00149   for (int i=0; i < HCMS2975_BUFFER_SIZE; i++) {
00150     _displayBuffer[i] = ' ';
00151   }
00152     
00153   // display buffer  
00154   _pushBuffer();
00155   
00156   //cursor
00157   _row = 0;
00158   _column = 0;     
00159 }                              
00160 
00161 /** Locate cursor to a screen column and row
00162   *
00163   * @param column  The horizontal position from the left, indexed from 0
00164   * @param row     The vertical position from the top, indexed from 0
00165   */
00166 void HCMS2975::locate(int column, int row){
00167 
00168 // Sanity Check column
00169     if (column < 0) {
00170       _column = 0;
00171     }
00172     else {
00173       if (column >= _nr_cols) {
00174         _column = _nr_cols - 1;
00175       }
00176       else {
00177         _column = column;
00178       }
00179     }
00180     
00181 // Sanity Check row
00182     if (row < 0) {
00183       _row = 0;
00184     }
00185     else {
00186       if (row >= _nr_rows) {
00187         _row = _nr_rows - 1;
00188       }
00189       else { 
00190         _row = row;
00191       }  
00192     }  
00193 }
00194 
00195 /** Return the number of columns
00196   *
00197   * @return int The number of columns
00198   */   
00199 int HCMS2975::columns() {
00200     
00201   // Columns encoded in b7..b0
00202   //return (_type & 0xFF);          
00203   return _nr_cols;           
00204 }
00205 
00206 /** Return the number of rows
00207   *
00208   * @return int The number of rows
00209   */
00210 int HCMS2975::rows() {
00211 
00212   // Rows encoded in b15..b8  
00213   //return ((_type >> 8) & 0xFF); 
00214   return _nr_rows;          
00215 }
00216 
00217 
00218 /** Set Brightness
00219   *
00220   * @param brightness The brightness level (valid range 0..15)
00221   */
00222 void HCMS2975::setBrightness(uint8_t brightness){
00223 
00224   _brightness = brightness & 0x0F;    
00225 
00226   //Set brightness
00227   //Set display to normal
00228   _writeCommand(HCMS2975_CONTROL0 | HCMS2975_NORMAL | _peak | _brightness);
00229 }  
00230 
00231 /** Set the Displaymode
00232   *
00233   * @param displayMode The Display mode (DispOff, DispOn)
00234   */
00235 void HCMS2975::setMode(DisplayMode displayMode){
00236     
00237   if (displayMode == DispOff) {
00238     //Set brightness to Zero
00239     _writeCommand(HCMS2975_CONTROL0 | HCMS2975_NORMAL | _peak | HCMS2975_BRIGHT_0);   
00240 //    //Set Sleep mode    
00241 //    _writeCommand(HCMS2975_CONTROL0 | HCMS2975_SLP | _peak | _brightness);       
00242   }  
00243   else {
00244     //Restore brightness
00245     //Set display to normal
00246     _writeCommand(HCMS2975_CONTROL0 | HCMS2975_NORMAL | _peak | _brightness);   
00247   }
00248 }     
00249 
00250 /** Set User Defined Characters (UDC)
00251   *
00252   * @param unsigned char c   The Index of the UDC (0..7)
00253   * @param char *udc_data    The bitpatterns for the UDC (5 bytes of 7 significant bits for bitpattern)       
00254   */
00255 void HCMS2975::setUDC(unsigned char c, char *udc_data){
00256   char *udc;
00257   int idx;
00258   
00259   c = c & 0x07; // mask to valid range
00260   
00261   udc = (char *) _udc[c];
00262 
00263   // Copy UDC data to local UDC memory
00264   for (idx=0; idx < 5; idx++) {
00265     *udc++ = *udc_data++; 
00266   }
00267 }   
00268   
00269 
00270 /** Low level Reset method for controller
00271   */  
00272 void HCMS2975::_reset(){
00273 
00274   // Reset when pin defined
00275   if (_rst) {
00276     _rst->write(0);   
00277     wait_us(500);    
00278     _rst->write(1);       
00279   }      
00280 }
00281     
00282 /** Low level Init method for controller
00283   */  
00284 void HCMS2975::_init(){ 
00285 
00286   // Hard Reset
00287   _reset();
00288       
00289   // Init CS en RS
00290   _cs = 1;
00291   _rs = 0;
00292 
00293   // Setup the spi for 8 bit data, low steady state clock,
00294   // rising edge capture, with a 500KHz or 1MHz clock rate  
00295   _spi->format(8,0);
00296   _spi->frequency(1000000);    // Max SCL is 5 MHz for HCMS2975
00297 //  _spi->frequency(50000);    // Max SCL is 5 MHz for HCMS2975
00298 
00299   //Set display to serial mode
00300   _writeCommand(HCMS2975_CONTROL1 | HCMS2975_PRE_1 | HCMS2975_SERIAL);
00301 
00302   // default display brightness and peak
00303   _brightness = HCMS2975_DEF_BRIGHT;
00304   _peak       = HCMS2975_DEF_PEAK;
00305    
00306   //Set display to normal
00307   _writeCommand(HCMS2975_CONTROL0 | HCMS2975_NORMAL | _peak | _brightness);
00308 
00309   //Clear display
00310   cls();
00311 } 
00312  
00313  
00314 /** Low level command byte write operation.
00315   * @param command commandbyte to write
00316   */
00317 void HCMS2975::_writeCommand(uint8_t command){
00318   int cnt;
00319   
00320   // Set RS 
00321   _rs = 1;
00322   wait_us(1);
00323     
00324   // Enable CS
00325   _cs = 0;
00326   wait_us(1);
00327   
00328   // Must write the command to all devices...!
00329   // Note that internally the 8 digit display consist of 2 display devices with 4 digits each!
00330   for (cnt=0; cnt < (_deviceCount << 1); cnt++) {
00331     _spi->write(command);         
00332     // wait_us(1);  // Min setup time is x ns for HCMS2975    
00333   }  
00334    
00335   // Disable CS
00336   _cs = 1;
00337 
00338   // Reset RS 
00339   _rs = 0; 
00340   
00341 }
00342 
00343 /** Low level _dataBuffer write operation.
00344   */
00345 void HCMS2975::_pushBuffer(){
00346   char charcode;
00347   char *fnt_ptr;
00348   int idx, pidx;
00349    
00350   // Reset RS 
00351   _rs = 0; 
00352   wait_us(1);  
00353   
00354   // Enable CS
00355   _cs = 0;
00356   wait_us(1);
00357 
00358   // Encode and push the character data to the display
00359   for (idx=0; idx < _displaySize; idx++) {
00360     charcode = _displayBuffer[idx];
00361     
00362     //Sanity check and font pointer
00363     if (charcode < 0x08) {
00364       //UDC  
00365       fnt_ptr = (char *) _udc[charcode];           
00366     }
00367     else {
00368       if ((charcode < 0x20) || (charcode > 0x7F)) {
00369         // non-printable, show 'space'
00370         fnt_ptr = (char *) font_5x7[0];                      
00371       }
00372       else {
00373         //Pointer to char pattern 
00374         fnt_ptr = (char *) font_5x7[charcode - 0x20];       
00375       }
00376     } // end sanity check 
00377         
00378     //Write char pattern of 5 bytes
00379     for (pidx=0; pidx < 5; pidx++) {
00380       _spi->write(*fnt_ptr);
00381       fnt_ptr++;
00382       //wait_us(1);  // Min setup time is x ns for HCMS2975      
00383     } //for pidx
00384  
00385   } //for idx
00386  
00387   // Disable CS
00388   _cs = 1;
00389     
00390 }
00391 
00392 
00393 // Stream implementation functions
00394 int HCMS2975::_putc(int value){
00395  
00396   if ((value == '\n') || (value == '\r')) {
00397     //No character to write
00398        
00399     //Update Cursor      
00400     _column = 0;
00401     _row++;
00402     if (_row >= _nr_rows) {
00403       _row = 0;
00404     }
00405     
00406     return 0;
00407   }          
00408   else {
00409     //Character to write      
00410     _displayBuffer[(_row * _nr_cols) + _column] = value; 
00411               
00412     //Update Cursor
00413     _column++;
00414     if (_column >= _nr_cols) {
00415       _column = 0;
00416       _row++;
00417       if (_row >= _nr_rows) {
00418         _row = 0;
00419       }
00420     }
00421     
00422     // push new data to display
00423     _pushBuffer();
00424     
00425     return 0;              
00426   } //else
00427  
00428 }
00429 
00430 
00431 // Stream implementation functions
00432 int HCMS2975::_getc(){
00433   return -1;    
00434 }
00435 
00436 
00437 /** Returns the version number of the library
00438   * @return int version number
00439   */
00440 int HCMS2975::getVersion() {
00441   return HCMS2975_VERSION;
00442 }