Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
TM1651.cpp
00001 /* mbed TM1651 Library, for TM1651 LED controller 00002 * Copyright (c) 2017, v01: WH, Initial version, Battery monitor 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 "TM1651.h" 00024 00025 00026 /** Constructor for class for driving TM1651 LED controller with Serial bus interface device. 00027 * @brief Supports 4 digits @ 7 segments and 7 Keys. 00028 * 00029 * @param PinName dio Serial bus DIO pin 00030 * @param PinName clk Serial bus CLK pin 00031 */ 00032 TM1651::TM1651(PinName dio, PinName clk) : _dio(dio), _clk(clk) { 00033 00034 _init(); 00035 } 00036 00037 00038 /** Init the Serial interface and the controller 00039 * @param none 00040 * @return none 00041 */ 00042 void TM1651::_init(){ 00043 00044 //TM1651 uses a Serial bus that looks like I2C, but really is not. 00045 //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. 00046 00047 //init Serial bus 00048 _dio.output(); 00049 // _dio.mode(PullUp); 00050 wait_us(1); 00051 00052 _dio=1; 00053 _clk=1; 00054 00055 //init controller 00056 _display = TM1651_DSP_ON; 00057 _bright = TM1651_BRT_DEF; 00058 _writeCmd(TM1651_DSP_CTRL_CMD, _display | _bright ); // Display control cmd, display on/off, brightness 00059 00060 _writeCmd(TM1651_DATA_SET_CMD, TM1651_DATA_WR | TM1651_ADDR_INC | TM1651_MODE_NORM); // Data set cmd, normal mode, auto incr, write data 00061 } 00062 00063 00064 /** Clear the screen and locate to 0 00065 */ 00066 void TM1651::cls() { 00067 00068 _start(); 00069 00070 _write(TM1651_ADDR_SET_CMD | 0x00); // Address set cmd, 0 00071 for (int cnt=0; cnt<TM1651_DISPLAY_MEM; cnt++) { 00072 _write(0x00); // data 00073 } 00074 00075 _stop(); 00076 } 00077 00078 /** Set Brightness 00079 * 00080 * @param char brightness (3 significant bits, valid range 0..7 (1/16 .. 14/14 dutycycle) 00081 * @return none 00082 */ 00083 void TM1651::setBrightness(char brightness){ 00084 00085 _bright = brightness & TM1651_BRT_MSK; // mask invalid bits 00086 00087 _writeCmd(TM1651_DSP_CTRL_CMD, _display | _bright ); // Display control cmd, display on/off, brightness 00088 } 00089 00090 /** Set the Display mode On/off 00091 * 00092 * @param bool display mode 00093 */ 00094 void TM1651::setDisplay(bool on) { 00095 00096 if (on) { 00097 _display = TM1651_DSP_ON; 00098 } 00099 else { 00100 _display = TM1651_DSP_OFF; 00101 } 00102 00103 _writeCmd(TM1651_DSP_CTRL_CMD, _display | _bright ); // Display control cmd, display on/off, brightness 00104 } 00105 00106 /** Write databyte to TM1651 00107 * @param int address display memory location to write byte 00108 * @param char data byte written at given address 00109 * @return none 00110 */ 00111 void TM1651::writeData(char data, int address) { 00112 00113 _start(); 00114 00115 _write(TM1651_ADDR_SET_CMD | (address & TM1651_ADDR_MSK)); // Set Address cmd 00116 _write(data); // data 00117 00118 _stop(); 00119 } 00120 00121 /** Write Display datablock to TM1651 00122 * @param DisplayData_t data Array of TM1651_DISPLAY_MEM (=4) bytes for displaydata 00123 * @param length number bytes to write (valid range 0..(TM1651_MAX_NR_GRIDS * TM1651_BYTES_PER_GRID) (=4), when starting at address 0) 00124 * @param int address display memory location to write bytes (default = 0) 00125 * @return none 00126 */ 00127 void TM1651::writeData(DisplayData_t data, int length, int address) { 00128 00129 _start(); 00130 00131 // sanity check 00132 address &= TM1651_ADDR_MSK; 00133 if (length < 0) {length = 0;} 00134 if ((length + address) > TM1651_DISPLAY_MEM) {length = (TM1651_DISPLAY_MEM - address);} 00135 00136 // _write(TM1651_ADDR_SET_CMD | 0x00); // Set Address at 0 00137 _write(TM1651_ADDR_SET_CMD | address); // Set Address 00138 00139 for (int idx=0; idx<length; idx++) { 00140 // _write(data[idx]); // data 00141 _write(data[address + idx]); // data 00142 } 00143 00144 _stop(); 00145 } 00146 00147 /** Read keydata block from TM1651 00148 * @param *keydata Ptr to bytes for keydata 00149 * @return bool keypress True when at least one key was pressed 00150 */ 00151 bool TM1651::getKeys(KeyData_t *keydata) { 00152 00153 _start(); 00154 00155 // Enable Key Read mode 00156 _write(TM1651_DATA_SET_CMD | TM1651_KEY_RD | TM1651_ADDR_INC | TM1651_MODE_NORM); // Data set cmd, normal mode, auto incr, read data 00157 00158 // Read keys 00159 // Bitpattern S0 S1 S2 K1 K2 1 1 1 00160 *keydata = _read(); 00161 // printf("Key = 0x%02x\r\n", *keydata); 00162 00163 _stop(); 00164 00165 // Restore Data Write mode 00166 _writeCmd(TM1651_DATA_SET_CMD, TM1651_DATA_WR | TM1651_ADDR_INC | TM1651_MODE_NORM); // Data set cmd, normal mode, auto incr, write data 00167 00168 return (*keydata != TM1651_SW_NONE); 00169 } 00170 00171 00172 /** Generate Start condition for TM1651 00173 * @param none 00174 * @return none 00175 */ 00176 void TM1651::_start() { 00177 00178 _dio=0; 00179 wait_us(1); 00180 _clk=0; 00181 wait_us(1); 00182 } 00183 00184 /** Generate Stop condition for TM1651 00185 * @param none 00186 * @return none 00187 */ 00188 void TM1651::_stop() { 00189 00190 _dio=0; 00191 wait_us(1); 00192 _clk=1; 00193 wait_us(1); 00194 _dio=1; 00195 wait_us(1); 00196 } 00197 00198 /** Send byte to TM1651 00199 * @param int data 00200 * @return none 00201 */ 00202 void TM1651::_write(int data) { 00203 00204 for (int bit=0; bit<8; bit++) { 00205 //The TM1651 expects LSB first 00206 if (((data >> bit) & 0x01) == 0x01) { 00207 _dio=1; 00208 } 00209 else { 00210 _dio=0; 00211 } 00212 wait_us(1); 00213 _clk=1; 00214 wait_us(1); 00215 _clk=0; 00216 wait_us(1); 00217 } 00218 00219 _dio=1; 00220 00221 // Prepare DIO to read data 00222 _dio.input(); 00223 wait_us(3); 00224 00225 // dummy Ack 00226 _clk=1; 00227 wait_us(1); 00228 // _ack = _dio; 00229 _clk=0; 00230 wait_us(1); 00231 00232 // Return DIO to output mode 00233 _dio.output(); 00234 wait_us(3); 00235 00236 _dio=1; //idle 00237 } 00238 00239 /** Read byte from TM1651 00240 * @return read byte 00241 */ 00242 char TM1651::_read() { 00243 char keycode = 0; 00244 00245 // Prepare DIO to read data 00246 _dio.input(); 00247 wait_us(3); 00248 00249 for (int bit=0; bit<8; bit++) { 00250 00251 //The TM1651 sends bitpattern: S0 S1 S2 K1 K2 1 1 1 00252 //Data is shifted out by the TM1651 on the falling edge of CLK 00253 //Observe sufficient delay to allow the Open Drain DIO to rise to H levels 00254 // Prepare to read next bit, LSB (ie S0) first. 00255 // The code below flips bits for easier matching with datasheet 00256 keycode = keycode << 1; 00257 00258 _clk=1; 00259 wait_us(1); 00260 00261 // Read next bit 00262 if (_dio) { keycode |= 0x01; } 00263 00264 _clk=0; 00265 wait_us(5); // Delay to allow for slow risetime 00266 } 00267 00268 // Return DIO to output mode 00269 _dio.output(); 00270 wait_us(3); 00271 00272 // dummy Ack 00273 _dio=0; //Ack 00274 wait_us(1); 00275 00276 _clk=1; 00277 wait_us(1); 00278 _clk=0; 00279 wait_us(1); 00280 00281 _dio=1; //idle 00282 00283 return keycode; 00284 } 00285 00286 /** Write command and parameter to TM1651 00287 * @param int cmd Command byte 00288 * &Param int data Parameters for command 00289 * @return none 00290 */ 00291 void TM1651::_writeCmd(int cmd, int data){ 00292 00293 _start(); 00294 00295 _write((cmd & TM1651_CMD_MSK) | (data & ~TM1651_CMD_MSK)); 00296 00297 _stop(); 00298 } 00299 00300 00301 #if (OPENSMART_TEST == 1) 00302 // Derived class for TM1651 used in OPEN_SMART battery display unit 00303 // 00304 00305 /** Constructor for class for driving TM1651 LED controller 00306 * 00307 * @brief Supports battery display unit with 10 segments. 00308 * Serial bus interface device. 00309 * 00310 * @param PinName dio Serial bus DIO pin 00311 * @param PinName sck Serial bus CLK pin 00312 */ 00313 TM1651_OPENSMART::TM1651_OPENSMART(PinName dio, PinName clk) : TM1651(dio, clk) { 00314 00315 } 00316 00317 /** Clear the screen and locate to 0 00318 * @param none 00319 * @return none 00320 */ 00321 void TM1651_OPENSMART::cls() { 00322 00323 //clear local buffer 00324 for (int idx=0; idx < OPENSMART_NR_GRIDS; idx++) { 00325 _displaybuffer[idx] = 0x00; 00326 } 00327 00328 writeData(_displaybuffer, (OPENSMART_NR_GRIDS * TM1651_BYTES_PER_GRID), 0); 00329 } 00330 00331 /** Set Icon 00332 * 00333 * @param Icon Icon Enums Icon has Grid position encoded in 8 MSBs, Pattern encoded in 16 LSBs 00334 * @return none 00335 */ 00336 void TM1651_OPENSMART::setIcon(Icon icon) { 00337 int addr, ld; 00338 00339 ld = icon & 0x7F; 00340 addr = (icon >> 24) & 0xFF; 00341 addr = (addr - 1); 00342 00343 //Set bits for Icon to write 00344 _displaybuffer[addr] |= ld; 00345 writeData(_displaybuffer, TM1651_BYTES_PER_GRID, addr); 00346 } 00347 00348 /** Clr Icon 00349 * 00350 * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Pattern encoded in 16 LSBs 00351 * @return none 00352 */ 00353 void TM1651_OPENSMART::clrIcon(Icon icon) { 00354 int addr, ld; 00355 00356 ld = icon & 0x7F; 00357 addr = (icon >> 24) & 0xFF; 00358 addr = (addr - 1); 00359 00360 //Set bits for Icon to clear 00361 _displaybuffer[addr] &= ~ld; 00362 writeData(_displaybuffer, TM1651_BYTES_PER_GRID, addr); 00363 } 00364 00365 00366 /** Set Level 00367 * 00368 * @param Level level Enums Level indicates the Battery level to be displayed 00369 * @return none 00370 */ 00371 void TM1651_OPENSMART::setLevel(Level level) { 00372 00373 //clear local buffer 00374 _displaybuffer[0] = 0x00; 00375 00376 //Set bits for level to write 00377 switch (level) { 00378 case LVL_0 : 00379 _displaybuffer[0] = R12; 00380 break; 00381 00382 case LVL_1 : 00383 _displaybuffer[0] = R12 | Y3; 00384 break; 00385 00386 case LVL_2 : 00387 _displaybuffer[0] = R12 | Y3 | Y4; 00388 break; 00389 00390 case LVL_3 : 00391 _displaybuffer[0] = R12 | Y3 | Y4 | Y5; 00392 break; 00393 00394 case LVL_4 : 00395 _displaybuffer[0] = R12 | Y3 | Y4 | Y5 | G67; 00396 break; 00397 00398 case LVL_5 : 00399 _displaybuffer[0] = R12 | Y3 | Y4 | Y5 | G67 | G89; 00400 break; 00401 00402 case LVL_6 : 00403 _displaybuffer[0] = R12 | Y3 | Y4 | Y5 | G67 | G89 | B10; 00404 break; 00405 00406 default: 00407 _displaybuffer[0] = 0; 00408 break; 00409 } 00410 00411 writeData(_displaybuffer, TM1651_BYTES_PER_GRID, 0); 00412 } 00413 00414 #endif
Generated on Mon Jul 25 2022 00:01:41 by
1.7.2
TM1651 LED controller (28 LEDs max), Keyboard scan (7 keys max)