TM1638 LED controller. Max 80 LEDs, Max 24 Key scan. Supports LED&KEY, QYF-TM1638 and JY-LKM1638 module.
Dependents: mbed_TM1638 Otjimaniya RL0201-V1
TM1638.cpp
00001 /* mbed TM1638 Library, for TM1638 LED controller 00002 * Copyright (c) 2015, v01: WH, Initial version 00003 * 2016, v02: WH, Added ASCII alphabet display selector, refactored display and keyboard defines 00004 * 2016, v03: WH, Added QYF-TM1638 and LKM1638, refactoring of writeData() 00005 * 00006 * Permission is hereby granted, free of charge, to any person obtaining a copy 00007 * of this software and associated documentation files (the "Software"), to deal 00008 * in the Software without restriction, including without limitation the rights 00009 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00010 * copies of the Software, and to permit persons to whom the Software is 00011 * furnished to do so, subject to the following conditions: 00012 * 00013 * The above copyright notice and this permission notice shall be included in 00014 * all copies or substantial portions of the Software. 00015 * 00016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00019 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00020 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00022 * THE SOFTWARE. 00023 */ 00024 #include "mbed.h" 00025 #include "TM1638.h" 00026 00027 /** Constructor for class for driving TM1638 LED controller with SPI bus interface device. 00028 * @brief Supports 8 digits @ 10 segments. 00029 * Also supports a scanned keyboard of upto 24 keys. 00030 * 00031 * @param PinName mosi, miso, sclk, cs SPI bus pins 00032 */ 00033 TM1638::TM1638(PinName mosi, PinName miso, PinName sclk, PinName cs) : _spi(mosi,miso,sclk), _cs(cs) { 00034 00035 _init(); 00036 } 00037 00038 /** Init the SPI interface and the controller 00039 * @param none 00040 * @return none 00041 */ 00042 void TM1638::_init(){ 00043 00044 //init SPI 00045 _cs=1; 00046 _spi.format(8,3); //TM1638 uses mode 3 (Clock High on Idle, Data latched on second (=rising) edge) 00047 _spi.frequency(500000); 00048 00049 //init controller 00050 _display = TM1638_DSP_ON; 00051 _bright = TM1638_BRT_DEF; 00052 _writeCmd(TM1638_DSP_CTRL_CMD, _display | _bright ); // Display control cmd, display on/off, brightness 00053 00054 _writeCmd(TM1638_DATA_SET_CMD, TM1638_DATA_WR | TM1638_ADDR_INC | TM1638_MODE_NORM); // Data set cmd, normal mode, auto incr, write data 00055 } 00056 00057 00058 /** Clear the screen and locate to 0 00059 */ 00060 void TM1638::cls() { 00061 00062 _cs=0; 00063 wait_us(1); 00064 _spi.write(_flip(TM1638_ADDR_SET_CMD | 0x00)); // Address set cmd, 0 00065 00066 for (int cnt=0; cnt<TM1638_DISPLAY_MEM; cnt++) { 00067 _spi.write(0x00); // data 00068 } 00069 00070 wait_us(1); 00071 _cs=1; 00072 } 00073 00074 /** Set Brightness 00075 * 00076 * @param char brightness (3 significant bits, valid range 0..7 (1/16 .. 14/14 dutycycle) 00077 * @return none 00078 */ 00079 void TM1638::setBrightness(char brightness){ 00080 00081 _bright = brightness & TM1638_BRT_MSK; // mask invalid bits 00082 00083 _writeCmd(TM1638_DSP_CTRL_CMD, _display | _bright ); // Display control cmd, display on/off, brightness 00084 } 00085 00086 /** Set the Display mode On/off 00087 * 00088 * @param bool display mode 00089 */ 00090 void TM1638::setDisplay(bool on) { 00091 00092 if (on) { 00093 _display = TM1638_DSP_ON; 00094 } 00095 else { 00096 _display = TM1638_DSP_OFF; 00097 } 00098 00099 _writeCmd(TM1638_DSP_CTRL_CMD, _display | _bright ); // Display control cmd, display on/off, brightness 00100 } 00101 00102 00103 /** Write databyte to TM1638 00104 * @param char data byte written at given address 00105 * @param int address display memory location to write byte 00106 * @return none 00107 */ 00108 void TM1638::writeData(char data, int address) { 00109 _cs=0; 00110 wait_us(1); 00111 _spi.write(_flip(TM1638_ADDR_SET_CMD | (address & TM1638_ADDR_MSK))); // Set Address cmd 00112 00113 _spi.write(_flip(data)); // data 00114 00115 wait_us(1); 00116 _cs=1; 00117 } 00118 00119 00120 /** Write Display datablock to TM1638 00121 * @param DisplayData_t data Array of TM1638_DISPLAY_MEM (=16) bytes for displaydata 00122 * @param length number bytes to write (valid range 0..TM1638_DISPLAY_MEM (=16), when starting at address 0) 00123 * @param int address display memory location to write bytes (default = 0) 00124 * @return none 00125 */ 00126 void TM1638::writeData(DisplayData_t data, int length, int address) { 00127 _cs=0; 00128 wait_us(1); 00129 00130 // sanity check 00131 address &= TM1638_ADDR_MSK; 00132 if (length < 0) {length = 0;} 00133 if ((length + address) > TM1638_DISPLAY_MEM) {length = (TM1638_DISPLAY_MEM - address);} 00134 00135 // _spi.write(_flip(TM1638_ADDR_SET_CMD | 0x00)); // Set Address at 0 00136 _spi.write(_flip(TM1638_ADDR_SET_CMD | address)); // Set Address 00137 00138 for (int idx=0; idx<length; idx++) { 00139 //_spi.write(_flip(data[idx])); // data 00140 _spi.write(_flip(data[address + idx])); // data 00141 } 00142 00143 wait_us(1); 00144 _cs=1; 00145 } 00146 00147 00148 /** Read keydata block from TM1638 00149 * @param *keydata Ptr to Array of TM1638_KEY_MEM (=4) bytes for keydata 00150 * @return bool keypress True when at least one key was pressed 00151 * 00152 * Note: Due to the hardware configuration the TM1638 key matrix scanner will detect multiple keys pressed at same time, 00153 * but this may also result in some spurious keys being set in keypress data array. 00154 * It may be best to ignore all keys in those situations. That option is implemented in this method depending on #define setting. 00155 */ 00156 bool TM1638::getKeys(KeyData_t *keydata) { 00157 int keypress = 0; 00158 char data; 00159 00160 // Read keys 00161 _cs=0; 00162 wait_us(1); 00163 00164 // Enable Key Read mode 00165 _spi.write(_flip(TM1638_DATA_SET_CMD | TM1638_KEY_RD | TM1638_ADDR_INC | TM1638_MODE_NORM)); // Data set cmd, normal mode, auto incr, read data 00166 00167 for (int idx=0; idx < TM1638_KEY_MEM; idx++) { 00168 data = _flip(_spi.write(0xFF)); // read keys and correct bitorder 00169 00170 data = data & TM1638_KEY_MSK; // Mask valid bits 00171 if (data != 0) { // Check for any pressed key 00172 for (int bit=0; bit < 8; bit++) { 00173 if (data & (1 << bit)) {keypress++;} // Test all significant bits 00174 } 00175 } 00176 00177 (*keydata)[idx] = data; // Store keydata after correcting bitorder 00178 } 00179 00180 wait_us(1); 00181 _cs=1; 00182 00183 // Restore Data Write mode 00184 _writeCmd(TM1638_DATA_SET_CMD, TM1638_DATA_WR | TM1638_ADDR_INC | TM1638_MODE_NORM); // Data set cmd, normal mode, auto incr, write data 00185 00186 #if(1) 00187 // Dismiss multiple keypresses at same time 00188 return (keypress == 1); 00189 #else 00190 // Allow multiple keypress and accept possible spurious keys 00191 return (keypress > 0); 00192 #endif 00193 } 00194 00195 00196 /** Helper to reverse all command or databits. The TM1638 expects LSB first, whereas SPI is MSB first 00197 * @param char data 00198 * @return bitreversed data 00199 */ 00200 #if(1) 00201 char TM1638::_flip(char data) { 00202 char value=0; 00203 00204 if (data & 0x01) {value |= 0x80;} ; 00205 if (data & 0x02) {value |= 0x40;} ; 00206 if (data & 0x04) {value |= 0x20;} ; 00207 if (data & 0x08) {value |= 0x10;} ; 00208 if (data & 0x10) {value |= 0x08;} ; 00209 if (data & 0x20) {value |= 0x04;} ; 00210 if (data & 0x40) {value |= 0x02;} ; 00211 if (data & 0x80) {value |= 0x01;} ; 00212 return value; 00213 } 00214 #else 00215 char TM1638::_flip(char data) { 00216 00217 data = (((data & 0xAA) >> 1) | ((data & 0x55) << 1)); 00218 data = (((data & 0xCC) >> 2) | ((data & 0x33) << 2)); 00219 return (((data & 0xF0) >> 4) | ((data & 0x0F) << 4)); 00220 } 00221 #endif 00222 00223 /** Write command and parameter to TM1638 00224 * @param int cmd Command byte 00225 * &Param int data Parameters for command 00226 * @return none 00227 */ 00228 void TM1638::_writeCmd(int cmd, int data){ 00229 00230 _cs=0; 00231 wait_us(1); 00232 // _spi.write(_flip( (cmd & 0xF0) | (data & 0x0F))); 00233 _spi.write(_flip( (cmd & TM1638_CMD_MSK) | (data & ~TM1638_CMD_MSK))); 00234 00235 wait_us(1); 00236 _cs=1; 00237 } 00238 00239 00240 #if (LEDKEY8_TEST == 1) 00241 // Derived class for TM1638 used in LED&KEY display unit 00242 // 00243 00244 /** Constructor for class for driving TM1638 LED controller as used in LEDKEY8 00245 * 00246 * @brief Supports 8 Digits of 7 Segments + DP + LED Icons. Also supports a scanned keyboard of 8. 00247 * 00248 * @param PinName mosi, miso, sclk, cs SPI bus pins 00249 */ 00250 TM1638_LEDKEY8::TM1638_LEDKEY8(PinName mosi, PinName miso, PinName sclk, PinName cs) : TM1638(mosi, miso, sclk, cs) { 00251 _column = 0; 00252 _columns = LEDKEY8_NR_DIGITS; 00253 } 00254 00255 #if(0) 00256 #if DOXYGEN_ONLY 00257 /** Write a character to the Display 00258 * 00259 * @param c The character to write to the display 00260 */ 00261 int putc(int c); 00262 00263 /** Write a formatted string to the Display 00264 * 00265 * @param format A printf-style format string, followed by the 00266 * variables to use in formatting the string. 00267 */ 00268 int printf(const char* format, ...); 00269 #endif 00270 #endif 00271 00272 /** Locate cursor to a screen column 00273 * 00274 * @param column The horizontal position from the left, indexed from 0 00275 */ 00276 void TM1638_LEDKEY8::locate(int column) { 00277 //sanity check 00278 if (column < 0) {column = 0;} 00279 if (column > (_columns - 1)) {column = _columns - 1;} 00280 00281 _column = column; 00282 } 00283 00284 00285 /** Number of screen columns 00286 * 00287 * @param none 00288 * @return columns 00289 */ 00290 int TM1638_LEDKEY8::columns() { 00291 return _columns; 00292 } 00293 00294 00295 /** Clear the screen and locate to 0 00296 * @param bool clrAll Clear Icons also (default = false) 00297 */ 00298 void TM1638_LEDKEY8::cls(bool clrAll) { 00299 00300 if (clrAll) { 00301 //clear local buffer (including Icons) 00302 for (int idx=0; idx < (LEDKEY8_NR_GRIDS << 1); idx++) { 00303 _displaybuffer[idx] = 0x00; 00304 } 00305 } 00306 else { 00307 //clear local buffer (preserving Icons) 00308 for (int idx=0; idx < LEDKEY8_NR_GRIDS; idx++) { 00309 _displaybuffer[(idx<<1)] = _displaybuffer[(idx<<1)] & MASK_ICON_GRID[idx][0]; 00310 _displaybuffer[(idx<<1) + 1] = _displaybuffer[(idx<<1) + 1] & MASK_ICON_GRID[idx][1]; 00311 } 00312 } 00313 00314 writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00315 00316 _column = 0; 00317 } 00318 00319 /** Set Icon 00320 * 00321 * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs 00322 * @return none 00323 */ 00324 void TM1638_LEDKEY8::setIcon(Icon icon) { 00325 int addr, icn; 00326 00327 icn = icon & 0xFFFF; 00328 addr = (icon >> 24) & 0xFF; 00329 addr = (addr - 1) << 1; // * TM1638_BYTES_PER_GRID 00330 00331 //Save char...and set bits for icon to write 00332 _displaybuffer[addr] = _displaybuffer[addr] | LO(icn); 00333 _displaybuffer[addr+1] = _displaybuffer[addr+1] | HI(icn); 00334 // writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00335 writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr); 00336 } 00337 00338 /** Clr Icon 00339 * 00340 * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs 00341 * @return none 00342 */ 00343 void TM1638_LEDKEY8::clrIcon(Icon icon) { 00344 int addr, icn; 00345 00346 icn = icon & 0xFFFF; 00347 addr = (icon >> 24) & 0xFF; 00348 addr = (addr - 1) << 1; // * TM1638_BYTES_PER_GRID 00349 00350 //Save char...and clr bits for icon to write 00351 _displaybuffer[addr] = _displaybuffer[addr] & ~LO(icn); 00352 _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~HI(icn); 00353 // writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00354 writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr); 00355 } 00356 00357 00358 /** Set User Defined Characters (UDC) 00359 * 00360 * @param unsigned char udc_idx The Index of the UDC (0..7) 00361 * @param int udc_data The bitpattern for the UDC (8 bits) 00362 */ 00363 void TM1638_LEDKEY8::setUDC(unsigned char udc_idx, int udc_data) { 00364 00365 //Sanity check 00366 if (udc_idx > (LEDKEY8_NR_UDC-1)) { 00367 return; 00368 } 00369 // Mask out Icon bits? 00370 00371 _UDC_7S[udc_idx] = LO(udc_data); 00372 } 00373 00374 00375 /** Write a single character (Stream implementation) 00376 */ 00377 int TM1638_LEDKEY8::_putc(int value) { 00378 int addr; 00379 bool validChar = false; 00380 char pattern = 0x00; 00381 00382 if ((value == '\n') || (value == '\r')) { 00383 //No character to write 00384 validChar = false; 00385 00386 //Update Cursor 00387 _column = 0; 00388 } 00389 else if ((value == '.') || (value == ',')) { 00390 //No character to write 00391 validChar = false; 00392 pattern = S7_DP; // placeholder for all DPs 00393 00394 // Check to see that DP can be shown for current column 00395 if (_column > 0) { 00396 //Translate between _column and displaybuffer entries 00397 //Add DP to bitpattern of digit left of current column. 00398 addr = (_column - 1) << 1; // * TM1638_BYTES_PER_GRID 00399 00400 //Save icons...and set bits for decimal point to write 00401 _displaybuffer[addr] = _displaybuffer[addr] | pattern; 00402 // _displaybuffer[addr+1] = _displaybuffer[addr+1] | pattern; 00403 00404 // writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00405 writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr); 00406 00407 //No Cursor Update 00408 } 00409 } 00410 else if ((value >= 0) && (value < LEDKEY8_NR_UDC)) { 00411 //Character to write 00412 validChar = true; 00413 pattern = _UDC_7S[value]; 00414 } 00415 00416 #if (SHOW_ASCII == 1) 00417 //display all ASCII characters 00418 else if ((value >= FONT_7S_START) && (value <= FONT_7S_END)) { 00419 //Character to write 00420 validChar = true; 00421 pattern = FONT_7S[value - FONT_7S_START]; 00422 } // else 00423 #else 00424 //display only digits and hex characters 00425 else if (value == '-') { 00426 //Character to write 00427 validChar = true; 00428 pattern = C7_MIN; 00429 } 00430 else if ((value >= (int)'0') && (value <= (int) '9')) { 00431 //Character to write 00432 validChar = true; 00433 pattern = FONT_7S[value - (int) '0']; 00434 } 00435 else if ((value >= (int) 'A') && (value <= (int) 'F')) { 00436 //Character to write 00437 validChar = true; 00438 pattern = FONT_7S[10 + value - (int) 'A']; 00439 } 00440 else if ((value >= (int) 'a') && (value <= (int) 'f')) { 00441 //Character to write 00442 validChar = true; 00443 pattern = FONT_7S[10 + value - (int) 'a']; 00444 } //else 00445 #endif 00446 00447 if (validChar) { 00448 //Character to write 00449 00450 //Translate between _column and displaybuffer entries 00451 addr = _column << 1; // * TM1638_BYTES_PER_GRID 00452 00453 //Save icons...and set bits for character to write 00454 _displaybuffer[addr] = (_displaybuffer[addr] & MASK_ICON_GRID[_column][0]) | pattern; 00455 // _displaybuffer[addr+1] = (_displaybuffer[addr+1] & MASK_ICON_GRID[_column][0]) | pattern; 00456 00457 // writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00458 writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr); 00459 00460 //Update Cursor 00461 _column++; 00462 if (_column > (LEDKEY8_NR_DIGITS - 1)) { 00463 _column = 0; 00464 } 00465 00466 } // if validChar 00467 00468 return value; 00469 } 00470 00471 00472 // get a single character (Stream implementation) 00473 int TM1638_LEDKEY8::_getc() { 00474 return -1; 00475 } 00476 00477 #endif 00478 00479 00480 #if (QYF_TEST == 1) 00481 // Derived class for TM1638 used in QYF-TM1638 display unit 00482 // 00483 00484 /** Constructor for class for driving TM1638 LED controller as used in QYF 00485 * 00486 * @brief Supports 8 Digits of 7 Segments + DP. Also supports a scanned keyboard of 16 keys. 00487 * 00488 * @param PinName mosi, miso, sclk, cs SPI bus pins 00489 */ 00490 TM1638_QYF::TM1638_QYF(PinName mosi, PinName miso, PinName sclk, PinName cs) : TM1638(mosi, miso, sclk, cs) { 00491 _column = 0; 00492 _columns = QYF_NR_DIGITS; 00493 } 00494 00495 #if(0) 00496 #if DOXYGEN_ONLY 00497 /** Write a character to the Display 00498 * 00499 * @param c The character to write to the display 00500 */ 00501 int putc(int c); 00502 00503 /** Write a formatted string to the Display 00504 * 00505 * @param format A printf-style format string, followed by the 00506 * variables to use in formatting the string. 00507 */ 00508 int printf(const char* format, ...); 00509 #endif 00510 #endif 00511 00512 /** Locate cursor to a screen column 00513 * 00514 * @param column The horizontal position from the left, indexed from 0 00515 */ 00516 void TM1638_QYF::locate(int column) { 00517 //sanity check 00518 if (column < 0) {column = 0;} 00519 if (column > (_columns - 1)) {column = _columns - 1;} 00520 00521 _column = column; 00522 } 00523 00524 00525 /** Number of screen columns 00526 * 00527 * @param none 00528 * @return columns 00529 */ 00530 int TM1638_QYF::columns() { 00531 return _columns; 00532 } 00533 00534 00535 /** Clear the screen and locate to 0 00536 * @param bool clrAll Clear Icons also (default = false) 00537 */ 00538 void TM1638_QYF::cls(bool clrAll) { 00539 00540 if (clrAll) { 00541 //clear local buffer (including Icons) 00542 for (int idx=0; idx < (QYF_NR_GRIDS << 1); idx++) { 00543 _displaybuffer[idx] = 0x00; 00544 } 00545 } 00546 else { 00547 //clear local buffer (preserving Icons) 00548 for (int idx=0; idx < QYF_NR_GRIDS; idx++) { 00549 _displaybuffer[(idx<<1)] = _displaybuffer[(idx<<1)] & MASK_ICON_GRID[idx][0]; 00550 _displaybuffer[(idx<<1) + 1] = _displaybuffer[(idx<<1) + 1] & MASK_ICON_GRID[idx][1]; 00551 } 00552 } 00553 00554 writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00555 00556 _column = 0; 00557 } 00558 00559 /** Set Icon 00560 * 00561 * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs 00562 * @return none 00563 */ 00564 void TM1638_QYF::setIcon(Icon icon) { 00565 int addr, icn; 00566 00567 icn = icon & 0xFFFF; 00568 addr = (icon >> 24) & 0xFF; 00569 addr = (addr - 1) << 1; // * TM1638_BYTES_PER_GRID 00570 00571 //Save char...and set bits for icon to write 00572 _displaybuffer[addr] = _displaybuffer[addr] | LO(icn); 00573 _displaybuffer[addr+1] = _displaybuffer[addr+1] | HI(icn); 00574 // writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00575 writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr); 00576 } 00577 00578 /** Clr Icon 00579 * 00580 * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs 00581 * @return none 00582 */ 00583 void TM1638_QYF::clrIcon(Icon icon) { 00584 int addr, icn; 00585 00586 icn = icon & 0xFFFF; 00587 addr = (icon >> 24) & 0xFF; 00588 addr = (addr - 1) << 1; // * TM1638_BYTES_PER_GRID 00589 00590 //Save char...and clr bits for icon to write 00591 _displaybuffer[addr] = _displaybuffer[addr] & ~LO(icn); 00592 _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~HI(icn); 00593 // writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00594 writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr); 00595 } 00596 00597 00598 /** Set User Defined Characters (UDC) 00599 * 00600 * @param unsigned char udc_idx The Index of the UDC (0..7) 00601 * @param int udc_data The bitpattern for the UDC (8 bits) 00602 */ 00603 void TM1638_QYF::setUDC(unsigned char udc_idx, int udc_data) { 00604 00605 //Sanity check 00606 if (udc_idx > (QYF_NR_UDC-1)) { 00607 return; 00608 } 00609 // Mask out Icon bits? 00610 00611 _UDC_7S[udc_idx] = LO(udc_data); 00612 } 00613 00614 00615 /** Write a single character (Stream implementation) 00616 */ 00617 int TM1638_QYF::_putc(int value) { 00618 bool validChar = false; 00619 char pattern = 0x00; 00620 char bit = 0x00; 00621 00622 if ((value == '\n') || (value == '\r')) { 00623 //No character to write 00624 validChar = false; 00625 00626 //Update Cursor 00627 _column = 0; 00628 } 00629 else if ((value == '.') || (value == ',')) { 00630 //No character to write 00631 validChar = false; 00632 pattern = S7_DP; // placeholder for all DPs 00633 00634 // Check to see that DP can be shown for current column 00635 if (_column > 0) { 00636 //Add DP to bitpattern of digit left of current column. 00637 bit = 1 << (8 - _column); // bitposition for the previous _column 00638 00639 _displaybuffer[14] = (_displaybuffer[14] | bit); // set bit 00640 00641 writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00642 00643 //No Cursor Update 00644 } 00645 } 00646 else if ((value >= 0) && (value < QYF_NR_UDC)) { 00647 //Character to write 00648 validChar = true; 00649 pattern = _UDC_7S[value]; 00650 } 00651 00652 #if (SHOW_ASCII == 1) 00653 //display all ASCII characters 00654 else if ((value >= FONT_7S_START) && (value <= FONT_7S_END)) { 00655 //Character to write 00656 validChar = true; 00657 pattern = FONT_7S[value - FONT_7S_START]; 00658 } // else 00659 #else 00660 //display only digits and hex characters 00661 else if (value == '-') { 00662 //Character to write 00663 validChar = true; 00664 pattern = C7_MIN; 00665 } 00666 else if ((value >= (int)'0') && (value <= (int) '9')) { 00667 //Character to write 00668 validChar = true; 00669 pattern = FONT_7S[value - (int) '0']; 00670 } 00671 else if ((value >= (int) 'A') && (value <= (int) 'F')) { 00672 //Character to write 00673 validChar = true; 00674 pattern = FONT_7S[10 + value - (int) 'A']; 00675 } 00676 else if ((value >= (int) 'a') && (value <= (int) 'f')) { 00677 //Character to write 00678 validChar = true; 00679 pattern = FONT_7S[10 + value - (int) 'a']; 00680 } //else 00681 #endif 00682 00683 if (validChar) { 00684 //Character to write 00685 00686 // Very annoying bitmapping :( 00687 // This display module uses a single byte of each grid to drive a specific segment of all digits. 00688 // So the bits in byte 0 (Grid 1) drive all A-segments, the bits in byte 2 (Grid 2) drive all B-segments etc. 00689 // Bit0 is for the segment in Digit 8, Bit1 is for the segment in Digit 7 etc.. This bit manipulation is handled in _putc(). 00690 00691 bit = 1 << (7 - _column); // bitposition for the current _column 00692 00693 if (pattern & S7_A) {_displaybuffer[0] = (_displaybuffer[0] | bit); } // set bit 00694 else {_displaybuffer[0] = (_displaybuffer[0] & ~bit);} // clr bit 00695 00696 if (pattern & S7_B) {_displaybuffer[2] = (_displaybuffer[2] | bit); } // set bit 00697 else {_displaybuffer[2] = (_displaybuffer[2] & ~bit);} // clr bit 00698 00699 if (pattern & S7_C) {_displaybuffer[4] = (_displaybuffer[4] | bit); } // set bit 00700 else {_displaybuffer[4] = (_displaybuffer[4] & ~bit);} // clr bit 00701 00702 if (pattern & S7_D) {_displaybuffer[6] = (_displaybuffer[6] | bit); } // set bit 00703 else {_displaybuffer[6] = (_displaybuffer[6] & ~bit);} // clr bit 00704 00705 if (pattern & S7_E) {_displaybuffer[8] = (_displaybuffer[8] | bit); } // set bit 00706 else {_displaybuffer[8] = (_displaybuffer[8] & ~bit);} // clr bit 00707 00708 if (pattern & S7_F) {_displaybuffer[10] = (_displaybuffer[10] | bit); } // set bit 00709 else {_displaybuffer[10] = (_displaybuffer[10] & ~bit);} // clr bit 00710 00711 if (pattern & S7_G) {_displaybuffer[12] = (_displaybuffer[12] | bit); } // set bit 00712 else {_displaybuffer[12] = (_displaybuffer[12] & ~bit);} // clr bit 00713 00714 if (pattern & S7_DP) {_displaybuffer[14] = (_displaybuffer[14] | bit); } // set bit 00715 else {_displaybuffer[14] = (_displaybuffer[14] & ~bit);} // clr bit 00716 00717 //Save icons...and set bits for character to write 00718 // _displaybuffer[addr] = (_displaybuffer[addr] & MASK_ICON_GRID[_column][0]) | pattern; 00719 // _displaybuffer[addr+1] = (_displaybuffer[addr+1] & MASK_ICON_GRID[_column][0]) | pattern; 00720 00721 writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00722 00723 //Update Cursor 00724 _column++; 00725 if (_column > (QYF_NR_DIGITS - 1)) { 00726 _column = 0; 00727 } 00728 00729 } // if validChar 00730 00731 return value; 00732 } 00733 00734 00735 // get a single character (Stream implementation) 00736 int TM1638_QYF::_getc() { 00737 return -1; 00738 } 00739 00740 #endif 00741 00742 00743 00744 #if (LKM1638_TEST == 1) 00745 // Derived class for TM1638 used in LMK1638 display unit 00746 // 00747 00748 /** Constructor for class for driving TM1638 LED controller as used in LKM1638 00749 * 00750 * @brief Supports 8 Digits of 7 Segments + DP + Bi-Color LED Icons. Also supports a scanned keyboard of 8. 00751 * 00752 * @param PinName mosi, miso, sclk, cs SPI bus pins 00753 */ 00754 TM1638_LKM1638::TM1638_LKM1638(PinName mosi, PinName miso, PinName sclk, PinName cs) : TM1638(mosi, miso, sclk, cs) { 00755 _column = 0; 00756 _columns = LKM1638_NR_DIGITS; 00757 } 00758 00759 #if(0) 00760 #if DOXYGEN_ONLY 00761 /** Write a character to the Display 00762 * 00763 * @param c The character to write to the display 00764 */ 00765 int putc(int c); 00766 00767 /** Write a formatted string to the Display 00768 * 00769 * @param format A printf-style format string, followed by the 00770 * variables to use in formatting the string. 00771 */ 00772 int printf(const char* format, ...); 00773 #endif 00774 #endif 00775 00776 /** Locate cursor to a screen column 00777 * 00778 * @param column The horizontal position from the left, indexed from 0 00779 */ 00780 void TM1638_LKM1638::locate(int column) { 00781 //sanity check 00782 if (column < 0) {column = 0;} 00783 if (column > (_columns - 1)) {column = _columns - 1;} 00784 00785 _column = column; 00786 } 00787 00788 00789 /** Number of screen columns 00790 * 00791 * @param none 00792 * @return columns 00793 */ 00794 int TM1638_LKM1638::columns() { 00795 return _columns; 00796 } 00797 00798 00799 /** Clear the screen and locate to 0 00800 * @param bool clrAll Clear Icons also (default = false) 00801 */ 00802 void TM1638_LKM1638::cls(bool clrAll) { 00803 00804 if (clrAll) { 00805 //clear local buffer (including Icons) 00806 for (int idx=0; idx < (LKM1638_NR_GRIDS << 1); idx++) { 00807 _displaybuffer[idx] = 0x00; 00808 } 00809 } 00810 else { 00811 //clear local buffer (preserving Icons) 00812 for (int idx=0; idx < LKM1638_NR_GRIDS; idx++) { 00813 _displaybuffer[(idx<<1)] = _displaybuffer[(idx<<1)] & MASK_ICON_GRID[idx][0]; 00814 _displaybuffer[(idx<<1) + 1] = _displaybuffer[(idx<<1) + 1] & MASK_ICON_GRID[idx][1]; 00815 } 00816 } 00817 00818 writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00819 00820 _column = 0; 00821 } 00822 00823 /** Set Icon 00824 * 00825 * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs 00826 * @return none 00827 */ 00828 void TM1638_LKM1638::setIcon(Icon icon) { 00829 int addr, icn; 00830 00831 icn = icon & 0xFFFF; 00832 addr = (icon >> 24) & 0xFF; 00833 addr = (addr - 1) << 1; // * TM1638_BYTES_PER_GRID 00834 00835 //Save char...and set bits for icon to write 00836 _displaybuffer[addr] = _displaybuffer[addr] | LO(icn); 00837 _displaybuffer[addr+1] = _displaybuffer[addr+1] | HI(icn); 00838 // writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00839 writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr); 00840 } 00841 00842 /** Clr Icon 00843 * 00844 * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs 00845 * @return none 00846 */ 00847 void TM1638_LKM1638::clrIcon(Icon icon) { 00848 int addr, icn; 00849 00850 icn = icon & 0xFFFF; 00851 addr = (icon >> 24) & 0xFF; 00852 addr = (addr - 1) << 1; // * TM1638_BYTES_PER_GRID 00853 00854 //Save char...and clr bits for icon to write 00855 _displaybuffer[addr] = _displaybuffer[addr] & ~LO(icn); 00856 _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~HI(icn); 00857 // writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00858 writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr); 00859 } 00860 00861 00862 /** Set User Defined Characters (UDC) 00863 * 00864 * @param unsigned char udc_idx The Index of the UDC (0..7) 00865 * @param int udc_data The bitpattern for the UDC (8 bits) 00866 */ 00867 void TM1638_LKM1638::setUDC(unsigned char udc_idx, int udc_data) { 00868 00869 //Sanity check 00870 if (udc_idx > (LKM1638_NR_UDC-1)) { 00871 return; 00872 } 00873 // Mask out Icon bits? 00874 00875 _UDC_7S[udc_idx] = LO(udc_data); 00876 } 00877 00878 00879 /** Write a single character (Stream implementation) 00880 */ 00881 int TM1638_LKM1638::_putc(int value) { 00882 int addr; 00883 bool validChar = false; 00884 char pattern = 0x00; 00885 00886 if ((value == '\n') || (value == '\r')) { 00887 //No character to write 00888 validChar = false; 00889 00890 //Update Cursor 00891 _column = 0; 00892 } 00893 else if ((value == '.') || (value == ',')) { 00894 //No character to write 00895 validChar = false; 00896 pattern = S7_DP; // placeholder for all DPs 00897 00898 // Check to see that DP can be shown for current column 00899 if (_column > 0) { 00900 //Translate between _column and displaybuffer entries 00901 //Add DP to bitpattern of digit left of current column. 00902 addr = (_column - 1) << 1; // * TM1638_BYTES_PER_GRID 00903 00904 //Save icons...and set bits for decimal point to write 00905 _displaybuffer[addr] = _displaybuffer[addr] | pattern; 00906 // _displaybuffer[addr+1] = _displaybuffer[addr+1] | pattern; 00907 00908 // writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00909 writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr); 00910 00911 //No Cursor Update 00912 } 00913 } 00914 else if ((value >= 0) && (value < LKM1638_NR_UDC)) { 00915 //Character to write 00916 validChar = true; 00917 pattern = _UDC_7S[value]; 00918 } 00919 00920 #if (SHOW_ASCII == 1) 00921 //display all ASCII characters 00922 else if ((value >= FONT_7S_START) && (value <= FONT_7S_END)) { 00923 //Character to write 00924 validChar = true; 00925 pattern = FONT_7S[value - FONT_7S_START]; 00926 } // else 00927 #else 00928 //display only digits and hex characters 00929 else if (value == '-') { 00930 //Character to write 00931 validChar = true; 00932 pattern = C7_MIN; 00933 } 00934 else if ((value >= (int)'0') && (value <= (int) '9')) { 00935 //Character to write 00936 validChar = true; 00937 pattern = FONT_7S[value - (int) '0']; 00938 } 00939 else if ((value >= (int) 'A') && (value <= (int) 'F')) { 00940 //Character to write 00941 validChar = true; 00942 pattern = FONT_7S[10 + value - (int) 'A']; 00943 } 00944 else if ((value >= (int) 'a') && (value <= (int) 'f')) { 00945 //Character to write 00946 validChar = true; 00947 pattern = FONT_7S[10 + value - (int) 'a']; 00948 } //else 00949 #endif 00950 00951 if (validChar) { 00952 //Character to write 00953 00954 //Translate between _column and displaybuffer entries 00955 addr = _column << 1; // * TM1638_BYTES_PER_GRID 00956 00957 //Save icons...and set bits for character to write 00958 _displaybuffer[addr] = (_displaybuffer[addr] & MASK_ICON_GRID[_column][0]) | pattern; 00959 // _displaybuffer[addr+1] = (_displaybuffer[addr+1] & MASK_ICON_GRID[_column][0]) | pattern; 00960 00961 // writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID)); 00962 writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr); 00963 00964 //Update Cursor 00965 _column++; 00966 if (_column > (LKM1638_NR_DIGITS - 1)) { 00967 _column = 0; 00968 } 00969 00970 } // if validChar 00971 00972 return value; 00973 } 00974 00975 00976 // get a single character (Stream implementation) 00977 int TM1638_LKM1638::_getc() { 00978 return -1; 00979 } 00980 00981 #endif 00982
Generated on Tue Jul 12 2022 19:03:47 by 1.7.2