Library for TM1640 LED controller Initial version

Dependents:   mbed_TM1640

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TM1640.cpp Source File

TM1640.cpp

00001 /* mbed TM1640 Library, for TM1640 LED controller
00002  * Copyright (c) 2016, v01: WH, Initial version
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to deal
00006  * in the Software without restriction, inclumosig without limitation the rights
00007  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008  * copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUmosiG BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020  * THE SOFTWARE.
00021  */
00022 #include "mbed.h" 
00023 #include "TM1640.h"
00024 
00025 /** Constructor for class for driving TM1640 LED controller with Serial bus interface device. 
00026  *  @brief Supports 16 digits @ 8 segments. 
00027  *   
00028  *  @param  PinName mosi Serial bus MOSI pin
00029  *  @param  PinName sclk Serial bus SCLK pin
00030 */
00031 TM1640::TM1640(PinName mosi, PinName sclk) : _mosi(mosi), _sclk(sclk) {
00032 
00033   _init();
00034 }
00035 
00036 /** Init the SPI interface and the controller
00037   * @param  none
00038   * @return none
00039   */ 
00040 void TM1640::_init(){
00041   
00042 //TM1640 uses Serial bus that looks like SPI, but uses Start and Stop conditions like I2C instead of CS
00043 //init Serial bus
00044   _mosi=1;
00045   _sclk=1;  
00046 
00047 //init controller  
00048   _display = TM1640_DSP_ON;
00049   _bright  = TM1640_BRT_DEF; 
00050   _writeCmd(TM1640_DSP_CTRL_CMD, _display | _bright );                                 // Display control cmd, display on/off, brightness   
00051   
00052   _writeCmd(TM1640_DATA_SET_CMD, TM1640_DATA_WR | TM1640_ADDR_INC | TM1640_MODE_NORM); // Data set cmd, normal mode, auto incr, write data  
00053 }   
00054 
00055 
00056 /** Clear the screen and locate to 0
00057  */  
00058 void TM1640::cls() {
00059 
00060   _start();  
00061 
00062   _write(TM1640_ADDR_SET_CMD | 0x00); // Address set cmd, 0      
00063   for (int cnt=0; cnt<TM1640_DISPLAY_MEM; cnt++) {
00064     _write(0x00); // data 
00065   }
00066 
00067   _stop();  
00068 }  
00069 
00070 /** Set Brightness
00071   *
00072   * @param  char brightness (3 significant bits, valid range 0..7 (1/16 .. 14/14 dutycycle)  
00073   * @return none
00074   */
00075 void TM1640::setBrightness(char brightness){
00076 
00077   _bright = brightness & TM1640_BRT_MSK; // mask invalid bits
00078   
00079   _writeCmd(TM1640_DSP_CTRL_CMD, _display | _bright );  // Display control cmd, display on/off, brightness  
00080 }
00081 
00082 /** Set the Display mode On/off
00083   *
00084   * @param bool display mode
00085   */
00086 void TM1640::setDisplay(bool on) {
00087   
00088   if (on) {
00089     _display = TM1640_DSP_ON;
00090   }
00091   else {
00092     _display = TM1640_DSP_OFF;
00093   }
00094   
00095   _writeCmd(TM1640_DSP_CTRL_CMD, _display | _bright );  // Display control cmd, display on/off, brightness   
00096 }
00097 
00098 /** Write databyte to TM1640
00099   *  @param  int address display memory location to write byte
00100   *  @param  char data byte written at given address
00101   *  @return none
00102   */ 
00103 void TM1640::writeData(char data, int address) {
00104   
00105   _start();
00106 
00107   _write(TM1640_ADDR_SET_CMD | (address & TM1640_ADDR_MSK)); // Set Address cmd     
00108   _write(data); // data 
00109 
00110   _stop();  
00111 }
00112 
00113 /** Write Display datablock to TM1640
00114   *  @param  DisplayData_t data Array of TM1640_DISPLAY_MEM (=16) bytes for displaydata
00115   *  @param  length number bytes to write (valid range 0..(TM1640_MAX_NR_GRIDS * TM1640_BYTES_PER_GRID) (=16), when starting at address 0)  
00116   *  @param  int address display memory location to write bytes (default = 0) 
00117   *  @return none
00118   */  
00119 void TM1640::writeData(DisplayData_t data, int length, int address) {
00120 
00121   _start();
00122 
00123 // sanity check
00124   address &= TM1640_ADDR_MSK;
00125   if (length < 0) {length = 0;}
00126   if ((length + address) > TM1640_DISPLAY_MEM) {length = (TM1640_DISPLAY_MEM - address);}
00127     
00128 //  _write(TM1640_ADDR_SET_CMD | 0x00); // Set Address at 0
00129   _write(TM1640_ADDR_SET_CMD | address); // Set Address
00130   
00131   for (int idx=0; idx<length; idx++) {    
00132 //    _write(data[idx]); // data 
00133     _write(data[address + idx]); // data 
00134   }
00135   
00136   _stop();  
00137 }
00138 
00139 
00140 /** Generate Start condition for TM1640
00141   *  @param  none
00142   *  @return none
00143   */ 
00144 void TM1640::_start() {
00145 
00146   _mosi=0;
00147   wait_us(1);
00148   _sclk=0;
00149   wait_us(1);
00150 }
00151   
00152 /** Generate Stop condition for TM1640
00153   *  @param  none
00154   *  @return none
00155   */ 
00156 void TM1640::_stop() {
00157 
00158   _mosi=0;
00159   wait_us(1);  
00160   _sclk=1;
00161   wait_us(1);
00162   _mosi=1;
00163   wait_us(1);
00164 }
00165 
00166 /** Send byte to TM1640
00167   *  @param  int data
00168   *  @return none
00169   */ 
00170 void TM1640::_write(int data) {
00171  
00172   for (int bit=0; bit<8; bit++) {    
00173     //The TM1640 expects LSB first, whereas SPI is MSB first      
00174     if (((data >> bit) & 0x01) == 0x01) {
00175       _mosi=1;      
00176     }
00177     else {    
00178       _mosi=0;      
00179     }  
00180     wait_us(1);
00181     _sclk=1;
00182     wait_us(1);
00183     _sclk=0;  
00184     wait_us(1);
00185   }  
00186 }
00187 
00188 
00189 /** Write command and parameter to TM1640
00190   *  @param  int cmd Command byte
00191   *  &Param  int data Parameters for command
00192   *  @return none
00193   */  
00194 void TM1640::_writeCmd(int cmd, int data){
00195     
00196   _start();
00197 
00198   _write((cmd & TM1640_CMD_MSK) | (data & ~TM1640_CMD_MSK));   
00199  
00200   _stop();          
00201 }  
00202 
00203 
00204 #if (LM1640_TEST == 1) 
00205 // Derived class for TM1640 used in LED&KEY display unit
00206 //
00207 
00208 /** Constructor for class for driving TM1640 LED controller as used in LM1640
00209   *
00210   *  @brief Supports 8 Digits of 7 Segments + DP.
00211   *   
00212   *  @param  PinName mosi Serial bus MOSI pin
00213   *  @param  PinName sclk Serial bus SCLK pin
00214   */
00215 TM1640_LM1640::TM1640_LM1640(PinName mosi, PinName sclk) : TM1640(mosi, sclk) {
00216   _column  = 0;
00217   _columns = LM1640_NR_DIGITS;    
00218 }  
00219 
00220 #if(0)
00221 #if DOXYGEN_ONLY
00222     /** Write a character to the Display
00223      *
00224      * @param c The character to write to the display
00225      */
00226     int putc(int c);
00227 
00228     /** Write a formatted string to the Display
00229      *
00230      * @param format A printf-style format string, followed by the
00231      *               variables to use in formatting the string.
00232      */
00233     int printf(const char* format, ...);   
00234 #endif
00235 #endif
00236 
00237 /** Locate cursor to a screen column
00238   *
00239   * @param column  The horizontal position from the left, indexed from 0
00240   */
00241 void TM1640_LM1640::locate(int column) {
00242   //sanity check
00243   if (column < 0) {column = 0;}
00244   if (column > (_columns - 1)) {column = _columns - 1;}  
00245   
00246   _column = column;       
00247 }
00248 
00249 
00250 /** Number of screen columns
00251   *
00252   * @param none
00253   * @return columns
00254   */
00255 int TM1640_LM1640::columns() {
00256     return _columns;
00257 }
00258 
00259     
00260 /** Clear the screen and locate to 0
00261   * @param bool clrAll Clear Icons also (default = false)
00262   */ 
00263 void TM1640_LM1640::cls(bool clrAll) {  
00264 
00265   if (clrAll) {
00266     //clear local buffer (inclumosig Icons)
00267     for (int idx=0; idx < LM1640_NR_GRIDS; idx++) {
00268       _displaybuffer[idx] = 0x00;  
00269     }
00270   }  
00271   else {
00272     //clear local buffer (preserving Icons)
00273     for (int idx=0; idx < LM1640_NR_GRIDS; idx++) {
00274       _displaybuffer[idx] = _displaybuffer[idx] & MASK_ICON_GRID[idx];  
00275     }  
00276   }
00277 
00278   writeData(_displaybuffer, (LM1640_NR_GRIDS * TM1640_BYTES_PER_GRID));
00279 
00280   _column = 0;   
00281 }     
00282 
00283 /** Set Icon
00284   *
00285   * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
00286   * @return none
00287   */
00288 void TM1640_LM1640::setIcon(Icon icon) {
00289   int addr, icn;
00290 
00291    icn =        icon  & 0xFFFF;
00292   addr = (icon >> 24) & 0xFF; 
00293   addr = (addr - 1);
00294     
00295   //Save char...and set bits for icon to write
00296   _displaybuffer[addr] = _displaybuffer[addr] | LO(icn);      
00297 //  writeData(_displaybuffer, (LM1640_NR_GRIDS * TM1640_BYTES_PER_GRID));
00298   writeData(_displaybuffer, TM1640_BYTES_PER_GRID, addr);  
00299 }
00300 
00301 /** Clr Icon
00302   *
00303   * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
00304   * @return none
00305   */
00306 void TM1640_LM1640::clrIcon(Icon icon) {
00307   int addr, icn;
00308 
00309    icn =        icon  & 0xFFFF;
00310   addr = (icon >> 24) & 0xFF; 
00311   addr = (addr - 1);
00312     
00313   //Save char...and clr bits for icon to write
00314   _displaybuffer[addr] = _displaybuffer[addr] & ~LO(icn);      
00315 //  writeData(_displaybuffer, (LM1640_NR_GRIDS * TM1640_BYTES_PER_GRID));
00316   writeData(_displaybuffer, TM1640_BYTES_PER_GRID, addr);    
00317 }
00318 
00319 
00320 /** Set User Defined Characters (UDC)
00321   *
00322   * @param unsigned char udc_idx  The Index of the UDC (0..7)
00323   * @param int udc_data           The bitpattern for the UDC (8 bits)       
00324   */
00325 void TM1640_LM1640::setUDC(unsigned char udc_idx, int udc_data) {
00326 
00327   //Sanity check
00328   if (udc_idx > (LM1640_NR_UDC-1)) {
00329     return;
00330   }
00331   // Mask out Icon bits?
00332 
00333   _UDC_7S[udc_idx] = LO(udc_data);
00334 }
00335 
00336 
00337 /** Write a single character (Stream implementation)
00338   */
00339 int TM1640_LM1640::_putc(int value) {
00340     int addr;
00341     bool validChar = false;
00342     char pattern   = 0x00;
00343     
00344     if ((value == '\n') || (value == '\r')) {
00345       //No character to write
00346       validChar = false;
00347       
00348       //Update Cursor      
00349       _column = 0;
00350     }
00351     else if ((value == '.') || (value == ',')) {
00352       //No character to write
00353       validChar = false;
00354       pattern = S7_DP; // placeholder for all DPs
00355       
00356       // Check to see that DP can be shown for current column
00357       if (_column > 0) {
00358         //Translate between _column and displaybuffer entries
00359         //Add DP to bitpattern of digit left of current column.
00360         addr = (_column - 1);
00361       
00362         //Save icons...and set bits for decimal point to write
00363         _displaybuffer[addr] = _displaybuffer[addr] | pattern;
00364 //        writeData(_displaybuffer, (LM1640_NR_GRIDS * TM1640_BYTES_PER_GRID));
00365         writeData(_displaybuffer, TM1640_BYTES_PER_GRID, addr); 
00366         
00367         //No Cursor Update
00368       }
00369     }
00370     else if ((value >= 0) && (value < LM1640_NR_UDC)) {
00371       //Character to write
00372       validChar = true;
00373       pattern = _UDC_7S[value];
00374     }  
00375     
00376 #if (SHOW_ASCII == 1)
00377     //display all ASCII characters
00378     else if ((value >= FONT_7S_START) && (value <= FONT_7S_END)) {   
00379       //Character to write
00380       validChar = true;
00381       pattern = FONT_7S[value - FONT_7S_START];
00382     } // else
00383 #else    
00384     //display only digits and hex characters      
00385     else if (value == '-') {
00386       //Character to write
00387       validChar = true;
00388       pattern = C7_MIN;         
00389     }
00390     else if ((value >= (int)'0') && (value <= (int) '9')) {   
00391       //Character to write
00392       validChar = true;
00393       pattern = FONT_7S[value - (int) '0'];
00394     }
00395     else if ((value >= (int) 'A') && (value <= (int) 'F')) {   
00396       //Character to write
00397       validChar = true;
00398       pattern = FONT_7S[10 + value - (int) 'A'];
00399     }
00400     else if ((value >= (int) 'a') && (value <= (int) 'f')) {   
00401       //Character to write
00402       validChar = true;
00403       pattern = FONT_7S[10 + value - (int) 'a'];
00404     } //else
00405 #endif
00406 
00407     if (validChar) {
00408       //Character to write
00409  
00410       //Translate between _column and displaybuffer entries
00411       addr = _column;
00412 
00413       //Save icons...and set bits for character to write
00414       _displaybuffer[addr] = (_displaybuffer[addr] & MASK_ICON_GRID[_column]) | pattern;
00415 
00416 //      writeData(_displaybuffer, (LM1640_NR_GRIDS * TM1640_BYTES_PER_GRID));
00417       writeData(_displaybuffer, TM1640_BYTES_PER_GRID, addr);        
00418                                 
00419       //Update Cursor
00420       _column++;
00421       if (_column > (LM1640_NR_DIGITS - 1)) {
00422         _column = 0;
00423       }
00424 
00425     } // if validChar           
00426 
00427     return value;
00428 }
00429 
00430 
00431 // get a single character (Stream implementation)
00432 int TM1640_LM1640::_getc() {
00433     return -1;
00434 }
00435 
00436 #endif