Wim Huiskamp / TM1637

Dependents:   mbed_TM1637 TM1637_test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TM1637.cpp Source File

TM1637.cpp

00001 /* mbed TM1637 Library, for TM1637 LED controller
00002  * Copyright (c) 2016, v01: WH, Initial version
00003  *               2017, v02: WH, Added RobotDyn 6 Digit module,
00004  *                          Added Eyewink 6 Digit + 6 Keys module,   
00005  *                          Constructor adapted to 2 pins: dio, clk  
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a copy
00008  * of this software and associated documentation files (the "Software"), to deal
00009  * in the Software without restriction, inclumosig without limitation the rights
00010  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00011  * copies of the Software, and to permit persons to whom the Software is
00012  * furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included in
00015  * all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018  * IMPLIED, INCLUmosiG BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00020  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00022  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00023  * THE SOFTWARE.
00024  */
00025 #include "mbed.h" 
00026 #include "TM1637.h"
00027 
00028 #if(SPI==1)
00029 /** Constructor for class for driving TM1637 LED controller with Serial bus interface device. 
00030   *
00031   * @brief Supports 6 Grids @ 8 segments. Also supports upto 16 Keys. 
00032   *        Serial bus interface device.
00033   *        DEPRECATED version 
00034   *
00035   *  @param  PinName mosi_nc  Serial bus NC pin
00036   *  @param  PinName miso_dio Serial bus DIO pin  
00037   *  @param  PinName sclk_clk Serial bus CLK pin 
00038   */
00039 TM1637::TM1637(PinName mosi_nc, PinName miso_dio, PinName sclk_clk) : _mosi_nc(mosi_nc), _dio(miso_dio), _clk(sclk_clk) {
00040 
00041   _init();
00042 }
00043 
00044 /** Constructor for class for driving TM1637 LED controller with Serial bus interface device. 
00045  *  @brief Supports 6 digits @ 8 segments. Also supports upto 16 Keys.
00046  *   
00047  *  @param  PinName dio Serial bus DIO pin 
00048  *  @param  PinName clk Serial bus CLK pin
00049 */
00050 TM1637::TM1637(PinName dio, PinName clk) : _mosi_nc(NC), _dio(dio), _clk(clk) {
00051 
00052   _init();
00053 }
00054 #else
00055 
00056 /** Constructor for class for driving TM1637 LED controller with Serial bus interface device. 
00057  *  @brief Supports 6 digits @ 8 segments. Also supports upto 16 Keys.
00058  *   
00059  *  @param  PinName dio Serial bus DIO pin 
00060  *  @param  PinName clk Serial bus CLK pin
00061 */
00062 TM1637::TM1637(PinName dio, PinName clk) : _dio(dio), _clk(clk) {
00063 
00064   _init();
00065 }
00066 
00067 #endif
00068 /** Init the Serial interface and the controller
00069   * @param  none
00070   * @return none
00071   */ 
00072 void TM1637::_init(){
00073   
00074 //TM1637 uses a Serial bus that looks like I2C, but really is not.
00075 //It has Start and Stop conditions like I2C and an Ack pulse, but instead of slaveaddresses and a RW bit it just transmits commands and data.
00076 
00077 //init Serial bus
00078   _dio.output();
00079 //  _dio.mode(PullUp);
00080   wait_us(1);
00081 
00082   _dio=1;  
00083   _clk=1;  
00084 
00085 //init controller  
00086   _display = TM1637_DSP_ON;
00087   _bright  = TM1637_BRT_DEF; 
00088   _writeCmd(TM1637_DSP_CTRL_CMD, _display | _bright );                                 // Display control cmd, display on/off, brightness   
00089   
00090   _writeCmd(TM1637_DATA_SET_CMD, TM1637_DATA_WR | TM1637_ADDR_INC | TM1637_MODE_NORM); // Data set cmd, normal mode, auto incr, write data  
00091 }   
00092 
00093 
00094 /** Clear the screen and locate to 0
00095  */  
00096 void TM1637::cls() {
00097 
00098   _start();  
00099 
00100   _write(TM1637_ADDR_SET_CMD | 0x00); // Address set cmd, 0      
00101   for (int cnt=0; cnt<TM1637_DISPLAY_MEM; cnt++) {
00102     _write(0x00); // data 
00103   }
00104 
00105   _stop();  
00106 }  
00107 
00108 /** Set Brightness
00109   *
00110   * @param  char brightness (3 significant bits, valid range 0..7 (1/16 .. 14/14 dutycycle)  
00111   * @return none
00112   */
00113 void TM1637::setBrightness(char brightness){
00114 
00115   _bright = brightness & TM1637_BRT_MSK; // mask invalid bits
00116   
00117   _writeCmd(TM1637_DSP_CTRL_CMD, _display | _bright );  // Display control cmd, display on/off, brightness  
00118 }
00119 
00120 /** Set the Display mode On/off
00121   *
00122   * @param bool display mode
00123   */
00124 void TM1637::setDisplay(bool on) {
00125   
00126   if (on) {
00127     _display = TM1637_DSP_ON;
00128   }
00129   else {
00130     _display = TM1637_DSP_OFF;
00131   }
00132   
00133   _writeCmd(TM1637_DSP_CTRL_CMD, _display | _bright );  // Display control cmd, display on/off, brightness   
00134 }
00135 
00136 /** Write databyte to TM1637
00137   *  @param  int address display memory location to write byte
00138   *  @param  char data byte written at given address
00139   *  @return none
00140   */ 
00141 void TM1637::writeData(char data, int address) {
00142   
00143   _start();
00144 
00145   _write(TM1637_ADDR_SET_CMD | (address & TM1637_ADDR_MSK)); // Set Address cmd     
00146   _write(data); // data 
00147 
00148   _stop();  
00149 }
00150 
00151 /** Write Display datablock to TM1637
00152   *  @param  DisplayData_t data Array of TM1637_DISPLAY_MEM (=16) bytes for displaydata
00153   *  @param  length number bytes to write (valid range 0..(TM1637_MAX_NR_GRIDS * TM1637_BYTES_PER_GRID) (=16), when starting at address 0)  
00154   *  @param  int address display memory location to write bytes (default = 0) 
00155   *  @return none
00156   */  
00157 void TM1637::writeData(DisplayData_t data, int length, int address) {
00158 
00159   _start();
00160 
00161 // sanity check
00162   address &= TM1637_ADDR_MSK;
00163   if (length < 0) {length = 0;}
00164   if ((length + address) > TM1637_DISPLAY_MEM) {length = (TM1637_DISPLAY_MEM - address);}
00165     
00166 //  _write(TM1637_ADDR_SET_CMD | 0x00); // Set Address at 0
00167   _write(TM1637_ADDR_SET_CMD | address); // Set Address
00168   
00169   for (int idx=0; idx<length; idx++) {    
00170 //    _write(data[idx]); // data 
00171     _write(data[address + idx]); // data 
00172   }
00173   
00174   _stop();  
00175 }
00176 
00177 /** Read keydata block from TM1637
00178   *  @param  *keydata Ptr to bytes for keydata
00179   *  @return bool keypress True when at least one key was pressed
00180   */   
00181 bool TM1637::getKeys(KeyData_t *keydata) {
00182 
00183   _start();
00184 
00185   // Enable Key Read mode
00186   _write(TM1637_DATA_SET_CMD | TM1637_KEY_RD | TM1637_ADDR_INC | TM1637_MODE_NORM); // Data set cmd, normal mode, auto incr, read data
00187 
00188   // Read keys
00189   // Bitpattern S0 S1 S2 K1 K2 1 1 1  
00190   *keydata = _read();
00191 //  printf("Key = 0x%02x\r\n", *keydata);
00192 
00193   _stop();  
00194   
00195   // Restore Data Write mode
00196   _writeCmd(TM1637_DATA_SET_CMD, TM1637_DATA_WR | TM1637_ADDR_INC | TM1637_MODE_NORM); // Data set cmd, normal mode, auto incr, write data  
00197       
00198   return (*keydata != TM1637_SW_NONE);    
00199 }
00200   
00201 
00202 /** Generate Start condition for TM1637
00203   *  @param  none
00204   *  @return none
00205   */ 
00206 void TM1637::_start() {
00207 
00208   _dio=0;
00209   wait_us(1);
00210   _clk=0;
00211   wait_us(1);
00212 }
00213   
00214 /** Generate Stop condition for TM1637
00215   *  @param  none
00216   *  @return none
00217   */ 
00218 void TM1637::_stop() {
00219 
00220   _dio=0;
00221   wait_us(1);  
00222   _clk=1;
00223   wait_us(1);
00224   _dio=1;
00225   wait_us(1);
00226 }
00227 
00228 /** Send byte to TM1637
00229   *  @param  int data
00230   *  @return none
00231   */ 
00232 void TM1637::_write(int data) {
00233  
00234   for (int bit=0; bit<8; bit++) {    
00235     //The TM1637 expects LSB first
00236     if (((data >> bit) & 0x01) == 0x01) {
00237       _dio=1;      
00238     }
00239     else {    
00240       _dio=0;      
00241     }  
00242     wait_us(1);
00243     _clk=1;
00244     wait_us(1);
00245     _clk=0;  
00246     wait_us(1);
00247   }  
00248 
00249   _dio=1;
00250   
00251   // Prepare DIO to read data
00252   _dio.input();
00253   wait_us(3);
00254       
00255   // dummy Ack
00256   _clk=1;
00257   wait_us(1);
00258 //  _ack = _dio;  
00259   _clk=0;  
00260   wait_us(1); 
00261   
00262   // Return DIO to output mode
00263   _dio.output();  
00264   wait_us(3);  
00265 
00266   _dio=1; //idle  
00267 }
00268 
00269 /** Read byte from TM1637
00270   *  @return read byte 
00271   */ 
00272 char TM1637::_read() {
00273   char keycode = 0;
00274 
00275   // Prepare DIO to read data
00276   _dio.input();
00277   wait_us(3);
00278     
00279   for (int bit=0; bit<8; bit++) {    
00280    
00281     //The TM1637 sends bitpattern: S0 S1 S2 K1 K2 1 1 1
00282     //Data is shifted out by the TM1637 on the falling edge of CLK
00283     //Observe sufficient delay to allow the Open Drain DIO to rise to H levels
00284     // Prepare to read next bit, LSB (ie S0) first. 
00285     // The code below flips bits for easier matching with datasheet
00286     keycode = keycode << 1;  
00287 
00288     _clk=1;
00289     wait_us(1);
00290     
00291     // Read next bit
00292     if (_dio) { keycode |= 0x01; }        
00293 
00294     _clk=0;        
00295     wait_us(5); // Delay to allow for slow risetime
00296   }  
00297   
00298   // Return DIO to output mode
00299   _dio.output();
00300   wait_us(3);  
00301 
00302   // dummy Ack
00303   _dio=0; //Ack   
00304   wait_us(1);
00305   
00306   _clk=1;
00307   wait_us(1);
00308   _clk=0;  
00309   wait_us(1); 
00310 
00311   _dio=1; //idle
00312 
00313   return keycode;
00314 }
00315 
00316 /** Write command and parameter to TM1637
00317   *  @param  int cmd Command byte
00318   *  &Param  int data Parameters for command
00319   *  @return none
00320   */  
00321 void TM1637::_writeCmd(int cmd, int data){
00322     
00323   _start();
00324 
00325   _write((cmd & TM1637_CMD_MSK) | (data & ~TM1637_CMD_MSK));   
00326  
00327   _stop();          
00328 }  
00329 
00330 
00331 #if (CATALEX_TEST == 1) 
00332 // Derived class for TM1637 used in LED&KEY display unit
00333 //
00334 
00335 #if(SPI==1)
00336 /** Constructor for class for driving TM1637 LED controller as used in CATALEX
00337   *
00338   *  @brief Supports 4 Digits of 7 Segments + DP (or Colon for Digit2 on some models).
00339   *         DEPRECATED version 
00340   *   
00341   *  @param  PinName mosi_nc  Serial bus NC pin
00342   *  @param  PinName miso_dio Serial bus DIO pin  
00343   *  @param  PinName sclk_clk Serial bus CLK pin
00344   */
00345 TM1637_CATALEX::TM1637_CATALEX(PinName mosi_nc, PinName miso_dio, PinName sclk_clk) : TM1637(mosi_nc, miso_dio, sclk_clk) {
00346   _column  = 0;
00347   _columns = CATALEX_NR_DIGITS;    
00348 }  
00349 #endif
00350 
00351 /** Constructor for class for driving TM1637 LED controller
00352  *
00353  * @brief Supports 4 Digits of 7 Segments + DP (or Colon for Digit2 on some models).
00354  *        Serial bus interface device. 
00355  *
00356  *  @param  PinName dio Serial bus DIO pin
00357  *  @param  PinName sck Serial bus CLK pin 
00358  */
00359 TM1637_CATALEX::TM1637_CATALEX(PinName dio, PinName clk) : TM1637(dio, clk) {
00360   _column  = 0;
00361   _columns = CATALEX_NR_DIGITS;    
00362 }  
00363 
00364 #if(0)
00365 #if DOXYGEN_ONLY
00366     /** Write a character to the Display
00367      *
00368      * @param c The character to write to the display
00369      */
00370     int putc(int c);
00371 
00372     /** Write a formatted string to the Display
00373      *
00374      * @param format A printf-style format string, followed by the
00375      *               variables to use in formatting the string.
00376      */
00377     int printf(const char* format, ...);   
00378 #endif
00379 #endif
00380 
00381 /** Locate cursor to a screen column
00382   *
00383   * @param column  The horizontal position from the left, indexed from 0
00384   */
00385 void TM1637_CATALEX::locate(int column) {
00386   //sanity check
00387   if (column < 0) {column = 0;}
00388   if (column > (_columns - 1)) {column = _columns - 1;}  
00389   
00390   _column = column;       
00391 }
00392 
00393 
00394 /** Number of screen columns
00395   *
00396   * @param none
00397   * @return columns
00398   */
00399 int TM1637_CATALEX::columns() {
00400     return _columns;
00401 }
00402 
00403     
00404 /** Clear the screen and locate to 0
00405   * @param bool clrAll Clear Icons also (default = false)
00406   */ 
00407 void TM1637_CATALEX::cls(bool clrAll) {  
00408 
00409   if (clrAll) {
00410     //clear local buffer (inclumosig Icons)
00411     for (int idx=0; idx < CATALEX_NR_GRIDS; idx++) {
00412       _displaybuffer[idx] = 0x00;  
00413     }
00414   }  
00415   else {
00416     //clear local buffer (preserving Icons)
00417     for (int idx=0; idx < CATALEX_NR_GRIDS; idx++) {
00418       _displaybuffer[idx] = _displaybuffer[idx] & MASK_ICON_GRID[idx];  
00419     }  
00420   }
00421 
00422   writeData(_displaybuffer, (CATALEX_NR_GRIDS * TM1637_BYTES_PER_GRID), 0);
00423 
00424   _column = 0;   
00425 }     
00426 
00427 /** Set Icon
00428   *
00429   * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
00430   * @return none
00431   */
00432 void TM1637_CATALEX::setIcon(Icon icon) {
00433   int addr, icn;
00434 
00435    icn =        icon  & 0xFFFF;
00436   addr = (icon >> 24) & 0xFF; 
00437   addr = (addr - 1);
00438     
00439   //Save char...and set bits for icon to write
00440   _displaybuffer[addr] = _displaybuffer[addr] | LO(icn);      
00441 //  writeData(_displaybuffer, (CATALEX_NR_GRIDS * TM1637_BYTES_PER_GRID), 0);
00442   writeData(_displaybuffer, TM1637_BYTES_PER_GRID, addr);  
00443 }
00444 
00445 /** Clr Icon
00446   *
00447   * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
00448   * @return none
00449   */
00450 void TM1637_CATALEX::clrIcon(Icon icon) {
00451   int addr, icn;
00452 
00453    icn =        icon  & 0xFFFF;
00454   addr = (icon >> 24) & 0xFF; 
00455   addr = (addr - 1);
00456     
00457   //Save char...and clr bits for icon to write
00458   _displaybuffer[addr] = _displaybuffer[addr] & ~LO(icn);      
00459 //  writeData(_displaybuffer, (CATALEX_NR_GRIDS * TM1637_BYTES_PER_GRID), 0);
00460   writeData(_displaybuffer, TM1637_BYTES_PER_GRID, addr);    
00461 }
00462 
00463 
00464 /** Set User Defined Characters (UDC)
00465   *
00466   * @param unsigned char udc_idx  The Index of the UDC (0..7)
00467   * @param int udc_data           The bitpattern for the UDC (8 bits)       
00468   */
00469 void TM1637_CATALEX::setUDC(unsigned char udc_idx, int udc_data) {
00470 
00471   //Sanity check
00472   if (udc_idx > (CATALEX_NR_UDC-1)) {
00473     return;
00474   }
00475   // Mask out Icon bits?
00476 
00477   _UDC_7S[udc_idx] = LO(udc_data);
00478 }
00479 
00480 
00481 /** Write a single character (Stream implementation)
00482   */
00483 int TM1637_CATALEX::_putc(int value) {
00484 //The CATALAX mapping between Digit positions (Left to Right) and Grids is:
00485 //  GR1 GR2 GR3 GR4
00486 //The memory addresses or column numbers are:
00487 //   0   1   2   3
00488     
00489     int addr;
00490     bool validChar = false;
00491     char pattern   = 0x00;
00492     
00493     if ((value == '\n') || (value == '\r')) {
00494       //No character to write
00495       validChar = false;
00496       
00497       //Update Cursor      
00498       _column = 0;
00499     }
00500     else if ((value == '.') || (value == ',')) {
00501       //No character to write
00502       validChar = false;
00503       pattern = S7_DP; // placeholder for all DPs
00504       
00505       // Check to see that DP can be shown for current column
00506       if (_column > 0) {
00507         //Translate between _column and displaybuffer entries
00508         //Add DP to bitpattern of digit left of current column.
00509         addr = (_column - 1);
00510       
00511         //Save icons...and set bits for decimal point to write
00512         _displaybuffer[addr] = _displaybuffer[addr] | pattern;
00513 //        writeData(_displaybuffer, (CATALEX_NR_GRIDS * TM1637_BYTES_PER_GRID));
00514         writeData(_displaybuffer, TM1637_BYTES_PER_GRID, addr); 
00515         
00516         //No Cursor Update
00517       }
00518     }
00519     else if ((value >= 0) && (value < CATALEX_NR_UDC)) {
00520       //Character to write
00521       validChar = true;
00522       pattern = _UDC_7S[value];
00523     }  
00524     
00525 #if (SHOW_ASCII == 1)
00526     //display all ASCII characters
00527     else if ((value >= FONT_7S_START) && (value <= FONT_7S_END)) {   
00528       //Character to write
00529       validChar = true;
00530       pattern = FONT_7S[value - FONT_7S_START];
00531     } // else
00532 #else    
00533     //display only digits and hex characters      
00534     else if (value == '-') {
00535       //Character to write
00536       validChar = true;
00537       pattern = C7_MIN;         
00538     }
00539     else if ((value >= (int)'0') && (value <= (int) '9')) {   
00540       //Character to write
00541       validChar = true;
00542       pattern = FONT_7S[value - (int) '0'];
00543     }
00544     else if ((value >= (int) 'A') && (value <= (int) 'F')) {   
00545       //Character to write
00546       validChar = true;
00547       pattern = FONT_7S[10 + value - (int) 'A'];
00548     }
00549     else if ((value >= (int) 'a') && (value <= (int) 'f')) {   
00550       //Character to write
00551       validChar = true;
00552       pattern = FONT_7S[10 + value - (int) 'a'];
00553     } //else
00554 #endif
00555 
00556     if (validChar) {
00557       //Character to write
00558  
00559       //Translate between _column and displaybuffer entries
00560       addr = _column;
00561 
00562       //Save icons...and set bits for character to write
00563       _displaybuffer[addr] = (_displaybuffer[addr] & MASK_ICON_GRID[_column]) | pattern;
00564 
00565 //      writeData(_displaybuffer, (CATALEX_NR_GRIDS * TM1637_BYTES_PER_GRID));
00566       writeData(_displaybuffer, TM1637_BYTES_PER_GRID, addr);        
00567                                 
00568       //Update Cursor
00569       _column++;
00570       if (_column > (CATALEX_NR_DIGITS - 1)) {
00571         _column = 0;
00572       }
00573 
00574     } // if validChar           
00575 
00576     return value;
00577 }
00578 
00579 
00580 // get a single character (Stream implementation)
00581 int TM1637_CATALEX::_getc() {
00582     return -1;
00583 }
00584 
00585 #endif
00586 
00587 #if (ROBOTDYN_TEST == 1) 
00588 // Derived class for TM1637 used in ROBOTDYN display unit
00589 //
00590 
00591 /** Constructor for class for driving TM1637 LED controller as used in ROBOTDYN
00592   *
00593   *  @brief Supports 6 Digits of 7 Segments + DP.
00594   *   
00595   *  @param  PinName dio Serial bus DIO pin
00596   *  @param  PinName clk Serial bus CLK pin
00597   */
00598 TM1637_ROBOTDYN::TM1637_ROBOTDYN(PinName dio, PinName clk) : TM1637(dio, clk) {
00599   _column  = 0;
00600   _columns = ROBOTDYN_NR_DIGITS;    
00601 }  
00602 
00603 
00604 #if(0)
00605 #if DOXYGEN_ONLY
00606     /** Write a character to the Display
00607      *
00608      * @param c The character to write to the display
00609      */
00610     int putc(int c);
00611 
00612     /** Write a formatted string to the Display
00613      *
00614      * @param format A printf-style format string, followed by the
00615      *               variables to use in formatting the string.
00616      */
00617     int printf(const char* format, ...);   
00618 #endif
00619 #endif
00620 
00621 /** Locate cursor to a screen column
00622   *
00623   * @param column  The horizontal position from the left, indexed from 0
00624   */
00625 void TM1637_ROBOTDYN::locate(int column) {
00626   //sanity check
00627   if (column < 0) {column = 0;}
00628   if (column > (_columns - 1)) {column = _columns - 1;}  
00629   
00630   _column = column;       
00631 }
00632 
00633 
00634 /** Number of screen columns
00635   *
00636   * @param none
00637   * @return columns
00638   */
00639 int TM1637_ROBOTDYN::columns() {
00640     return _columns;
00641 }
00642 
00643     
00644 /** Clear the screen and locate to 0
00645   * @param bool clrAll Clear Icons also (default = false)
00646   */ 
00647 void TM1637_ROBOTDYN::cls(bool clrAll) {  
00648 
00649   if (clrAll) {
00650     //clear local buffer (including Icons)
00651     for (int idx=0; idx < ROBOTDYN_NR_GRIDS; idx++) {
00652       _displaybuffer[idx] = 0x00;  
00653     }
00654   }  
00655   else {
00656     //clear local buffer (preserving Icons)
00657     for (int idx=0; idx < ROBOTDYN_NR_GRIDS; idx++) {
00658       _displaybuffer[idx] = _displaybuffer[idx] & MASK_ICON_GRID[idx];  
00659     }  
00660   }
00661 
00662   writeData(_displaybuffer, (ROBOTDYN_NR_GRIDS * TM1637_BYTES_PER_GRID), 0);
00663 
00664   _column = 0;   
00665 }     
00666 
00667 /** Set Icon
00668   *
00669   * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
00670   * @return none
00671   */
00672 void TM1637_ROBOTDYN::setIcon(Icon icon) {
00673   int addr, icn;
00674 
00675    icn =        icon  & 0xFFFF;
00676   addr = (icon >> 24) & 0xFF; 
00677   addr = (addr - 1);
00678     
00679   //Save char...and set bits for icon to write
00680   _displaybuffer[addr] = _displaybuffer[addr] | LO(icn);      
00681 //  writeData(_displaybuffer, (ROBOTDYN_NR_GRIDS * TM1637_BYTES_PER_GRID), 0);
00682   writeData(_displaybuffer, TM1637_BYTES_PER_GRID, addr);  
00683 }
00684 
00685 /** Clr Icon
00686   *
00687   * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
00688   * @return none
00689   */
00690 void TM1637_ROBOTDYN::clrIcon(Icon icon) {
00691   int addr, icn;
00692 
00693    icn =        icon  & 0xFFFF;
00694   addr = (icon >> 24) & 0xFF; 
00695   addr = (addr - 1);
00696     
00697   //Save char...and clr bits for icon to write
00698   _displaybuffer[addr] = _displaybuffer[addr] & ~LO(icn);      
00699 //  writeData(_displaybuffer, (ROBOTDYN_NR_GRIDS * TM1637_BYTES_PER_GRID), 0);
00700   writeData(_displaybuffer, TM1637_BYTES_PER_GRID, addr);    
00701 }
00702 
00703 
00704 /** Set User Defined Characters (UDC)
00705   *
00706   * @param unsigned char udc_idx  The Index of the UDC (0..7)
00707   * @param int udc_data           The bitpattern for the UDC (8 bits)       
00708   */
00709 void TM1637_ROBOTDYN::setUDC(unsigned char udc_idx, int udc_data) {
00710 
00711   //Sanity check
00712   if (udc_idx > (ROBOTDYN_NR_UDC-1)) {
00713     return;
00714   }
00715   // Mask out Icon bits?
00716 
00717   _UDC_7S[udc_idx] = LO(udc_data);
00718 }
00719 
00720 /** Write a single character (Stream implementation)
00721   *
00722   */
00723 int TM1637_ROBOTDYN::_putc(int value) {
00724 //The ROBOTDYN mapping between Digit positions (Left to Right) and Grids is:
00725 //  GR3 GR2 GR1 GR6 GR5 GR4
00726 //The memory addresses or column numbers are:
00727 //   2   1   0   5   4   3
00728 //The Grids are reversed for 2 sets of 3 digits: 
00729     const int col2addr[] = {2, 1, 0, 5, 4, 3};
00730 
00731     int addr;
00732     bool validChar = false;
00733     char pattern   = 0x00;
00734     
00735     if ((value == '\n') || (value == '\r')) {
00736       //No character to write
00737       validChar = false;
00738       
00739       //Update Cursor      
00740       _column = 0;
00741     }
00742     else if ((value == '.') || (value == ',')) {
00743       //No character to write
00744       validChar = false;
00745       pattern = S7_DP; // placeholder for all DPs
00746       
00747       // Check to see that DP can be shown for current column
00748       if (_column > 0) {
00749         //Translate between _column and displaybuffer entries
00750         //Add DP to bitpattern of digit left of current column.
00751         addr = col2addr [_column - 1];
00752       
00753         //Save icons...and set bits for decimal point to write
00754         _displaybuffer[addr] = _displaybuffer[addr] | pattern;
00755 //        writeData(_displaybuffer, (ROBOTDYN_NR_GRIDS * TM1637_BYTES_PER_GRID));
00756         writeData(_displaybuffer, TM1637_BYTES_PER_GRID, addr); 
00757         
00758         //No Cursor Update
00759       }
00760     }
00761     else if ((value >= 0) && (value < ROBOTDYN_NR_UDC)) {
00762       //Character to write
00763       validChar = true;
00764       pattern = _UDC_7S[value];
00765     }  
00766     
00767 #if (SHOW_ASCII == 1)
00768     //display all ASCII characters
00769     else if ((value >= FONT_7S_START) && (value <= FONT_7S_END)) {   
00770       //Character to write
00771       validChar = true;
00772       pattern = FONT_7S[value - FONT_7S_START];
00773     } // else
00774 #else    
00775     //display only digits and hex characters      
00776     else if (value == '-') {
00777       //Character to write
00778       validChar = true;
00779       pattern = C7_MIN;         
00780     }
00781     else if ((value >= (int)'0') && (value <= (int) '9')) {   
00782       //Character to write
00783       validChar = true;
00784       pattern = FONT_7S[value - (int) '0'];
00785     }
00786     else if ((value >= (int) 'A') && (value <= (int) 'F')) {   
00787       //Character to write
00788       validChar = true;
00789       pattern = FONT_7S[10 + value - (int) 'A'];
00790     }
00791     else if ((value >= (int) 'a') && (value <= (int) 'f')) {   
00792       //Character to write
00793       validChar = true;
00794       pattern = FONT_7S[10 + value - (int) 'a'];
00795     } //else
00796 #endif
00797 
00798     if (validChar) {
00799       //Character to write
00800  
00801       //Translate between _column and displaybuffer entries
00802       addr = col2addr[_column];
00803 
00804       //Save icons...and set bits for character to write
00805       _displaybuffer[addr] = (_displaybuffer[addr] & MASK_ICON_GRID[_column]) | pattern;
00806 
00807 //      writeData(_displaybuffer, (ROBOTDYN_NR_GRIDS * TM1637_BYTES_PER_GRID));
00808       writeData(_displaybuffer, TM1637_BYTES_PER_GRID, addr);        
00809                                 
00810       //Update Cursor
00811       _column++;
00812       if (_column > (ROBOTDYN_NR_DIGITS - 1)) {
00813         _column = 0;
00814       }
00815 
00816     } // if validChar           
00817 
00818     return value;
00819 }
00820 
00821 
00822 // get a single character (Stream implementation)
00823 int TM1637_ROBOTDYN::_getc() {
00824     return -1;
00825 }
00826 
00827 #endif
00828 
00829 
00830 #if (EYEWINK_TEST == 1) 
00831 // Derived class for TM1637 used in EYEWINK display unit
00832 //
00833 
00834 /** Constructor for class for driving TM1637 LED controller as used in EYEWINK
00835   *
00836   *  @brief Supports 6 Digits of 7 Segments + DP and 6 Keys.
00837   *   
00838   *  @param  PinName dio Serial bus DIO pin
00839   *  @param  PinName clk Serial bus CLK pin
00840   */
00841 TM1637_EYEWINK::TM1637_EYEWINK(PinName dio, PinName clk) : TM1637(dio, clk) {
00842   _column  = 0;
00843   _columns = EYEWINK_NR_DIGITS;    
00844 }  
00845 
00846 
00847 #if(0)
00848 #if DOXYGEN_ONLY
00849     /** Write a character to the Display
00850      *
00851      * @param c The character to write to the display
00852      */
00853     int putc(int c);
00854 
00855     /** Write a formatted string to the Display
00856      *
00857      * @param format A printf-style format string, followed by the
00858      *               variables to use in formatting the string.
00859      */
00860     int printf(const char* format, ...);   
00861 #endif
00862 #endif
00863 
00864 /** Locate cursor to a screen column
00865   *
00866   * @param column  The horizontal position from the left, indexed from 0
00867   */
00868 void TM1637_EYEWINK::locate(int column) {
00869   //sanity check
00870   if (column < 0) {column = 0;}
00871   if (column > (_columns - 1)) {column = _columns - 1;}  
00872   
00873   _column = column;       
00874 }
00875 
00876 
00877 /** Number of screen columns
00878   *
00879   * @param none
00880   * @return columns
00881   */
00882 int TM1637_EYEWINK::columns() {
00883     return _columns;
00884 }
00885 
00886     
00887 /** Clear the screen and locate to 0
00888   * @param bool clrAll Clear Icons also (default = false)
00889   */ 
00890 void TM1637_EYEWINK::cls(bool clrAll) {  
00891 
00892   if (clrAll) {
00893     //clear local buffer (including Icons)
00894     for (int idx=0; idx < EYEWINK_NR_GRIDS; idx++) {
00895       _displaybuffer[idx] = 0x00;  
00896     }
00897   }  
00898   else {
00899     //clear local buffer (preserving Icons)
00900     for (int idx=0; idx < EYEWINK_NR_GRIDS; idx++) {
00901       _displaybuffer[idx] = _displaybuffer[idx] & MASK_ICON_GRID[idx];  
00902     }  
00903   }
00904 
00905   writeData(_displaybuffer, (EYEWINK_NR_GRIDS * TM1637_BYTES_PER_GRID), 0);
00906 
00907   _column = 0;   
00908 }     
00909 
00910 /** Set Icon
00911   *
00912   * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
00913   * @return none
00914   */
00915 void TM1637_EYEWINK::setIcon(Icon icon) {
00916   int addr, icn;
00917 
00918    icn =        icon  & 0xFFFF;
00919   addr = (icon >> 24) & 0xFF; 
00920   addr = (addr - 1);
00921     
00922   //Save char...and set bits for icon to write
00923   _displaybuffer[addr] = _displaybuffer[addr] | LO(icn);      
00924 //  writeData(_displaybuffer, (EYEWINK_NR_GRIDS * TM1637_BYTES_PER_GRID), 0);
00925   writeData(_displaybuffer, TM1637_BYTES_PER_GRID, addr);  
00926 }
00927 
00928 /** Clr Icon
00929   *
00930   * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
00931   * @return none
00932   */
00933 void TM1637_EYEWINK::clrIcon(Icon icon) {
00934   int addr, icn;
00935 
00936    icn =        icon  & 0xFFFF;
00937   addr = (icon >> 24) & 0xFF; 
00938   addr = (addr - 1);
00939     
00940   //Save char...and clr bits for icon to write
00941   _displaybuffer[addr] = _displaybuffer[addr] & ~LO(icn);      
00942 //  writeData(_displaybuffer, (EYEWINK_NR_GRIDS * TM1637_BYTES_PER_GRID), 0);
00943   writeData(_displaybuffer, TM1637_BYTES_PER_GRID, addr);    
00944 }
00945 
00946 
00947 /** Set User Defined Characters (UDC)
00948   *
00949   * @param unsigned char udc_idx  The Index of the UDC (0..7)
00950   * @param int udc_data           The bitpattern for the UDC (8 bits)       
00951   */
00952 void TM1637_EYEWINK::setUDC(unsigned char udc_idx, int udc_data) {
00953 
00954   //Sanity check
00955   if (udc_idx > (EYEWINK_NR_UDC-1)) {
00956     return;
00957   }
00958   // Mask out Icon bits?
00959 
00960   _UDC_7S[udc_idx] = LO(udc_data);
00961 }
00962 
00963 /** Write a single character (Stream implementation)
00964   *
00965   */
00966 int TM1637_EYEWINK::_putc(int value) {
00967 //The EYEWINK mapping between Digit positions (Left to Right) and Grids is:
00968 //  GR1 GR2 GR3 GR4 GR5 GR6
00969 //The memory addresses or column numbers are:
00970 //   0   1   2   3   4   5
00971 //The Grids for all digits: 
00972 //    const int col2addr[] = {0, 1, 2, 3, 4, 5};
00973 
00974     int addr;
00975     bool validChar = false;
00976     char pattern   = 0x00;
00977     
00978     if ((value == '\n') || (value == '\r')) {
00979       //No character to write
00980       validChar = false;
00981       
00982       //Update Cursor      
00983       _column = 0;
00984     }
00985     else if ((value == '.') || (value == ',')) {
00986       //No character to write
00987       validChar = false;
00988       pattern = S7_DP; // placeholder for all DPs
00989       
00990       // Check to see that DP can be shown for current column
00991       if (_column > 0) {
00992         //Translate between _column and displaybuffer entries
00993         //Add DP to bitpattern of digit left of current column.
00994 //        addr = col2addr [_column - 1];
00995         addr = _column - 1;
00996       
00997         //Save icons...and set bits for decimal point to write
00998         _displaybuffer[addr] = _displaybuffer[addr] | pattern;
00999 //        writeData(_displaybuffer, (EYEWINK_NR_GRIDS * TM1637_BYTES_PER_GRID));
01000         writeData(_displaybuffer, TM1637_BYTES_PER_GRID, addr); 
01001         
01002         //No Cursor Update
01003       }
01004     }
01005     else if ((value >= 0) && (value < EYEWINK_NR_UDC)) {
01006       //Character to write
01007       validChar = true;
01008       pattern = _UDC_7S[value];
01009     }  
01010     
01011 #if (SHOW_ASCII == 1)
01012     //display all ASCII characters
01013     else if ((value >= FONT_7S_START) && (value <= FONT_7S_END)) {   
01014       //Character to write
01015       validChar = true;
01016       pattern = FONT_7S[value - FONT_7S_START];
01017     } // else
01018 #else    
01019     //display only digits and hex characters      
01020     else if (value == '-') {
01021       //Character to write
01022       validChar = true;
01023       pattern = C7_MIN;         
01024     }
01025     else if ((value >= (int)'0') && (value <= (int) '9')) {   
01026       //Character to write
01027       validChar = true;
01028       pattern = FONT_7S[value - (int) '0'];
01029     }
01030     else if ((value >= (int) 'A') && (value <= (int) 'F')) {   
01031       //Character to write
01032       validChar = true;
01033       pattern = FONT_7S[10 + value - (int) 'A'];
01034     }
01035     else if ((value >= (int) 'a') && (value <= (int) 'f')) {   
01036       //Character to write
01037       validChar = true;
01038       pattern = FONT_7S[10 + value - (int) 'a'];
01039     } //else
01040 #endif
01041 
01042     if (validChar) {
01043       //Character to write
01044  
01045       //Translate between _column and displaybuffer entries
01046 //      addr = col2addr[_column];
01047       addr = _column;      
01048 
01049       //Save icons...and set bits for character to write
01050       _displaybuffer[addr] = (_displaybuffer[addr] & MASK_ICON_GRID[_column]) | pattern;
01051 
01052 //      writeData(_displaybuffer, (EYEWINK_NR_GRIDS * TM1637_BYTES_PER_GRID));
01053       writeData(_displaybuffer, TM1637_BYTES_PER_GRID, addr);        
01054                                 
01055       //Update Cursor
01056       _column++;
01057       if (_column > (EYEWINK_NR_DIGITS - 1)) {
01058         _column = 0;
01059       }
01060 
01061     } // if validChar           
01062 
01063     return value;
01064 }
01065 
01066 
01067 // get a single character (Stream implementation)
01068 int TM1637_EYEWINK::_getc() {
01069     return -1;
01070 }
01071 
01072 #endif