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

See here for more information.

Files at this revision

API Documentation at this revision

Comitter:
wim
Date:
Sun Jan 31 12:11:06 2016 +0000
Parent:
3:25ddabfadc8c
Commit message:
Added QYF-TM1638 and LKM1638, refactoring of writeData()

Changed in this revision

Font_7Seg.cpp Show annotated file Show diff for this revision Revisions of this file
Font_7Seg.h Show annotated file Show diff for this revision Revisions of this file
TM1638.cpp Show annotated file Show diff for this revision Revisions of this file
TM1638.h Show annotated file Show diff for this revision Revisions of this file
TM1638_Config.h Show annotated file Show diff for this revision Revisions of this file
diff -r 25ddabfadc8c -r b2bbdc58967e Font_7Seg.cpp
--- a/Font_7Seg.cpp	Tue Jan 19 18:58:22 2016 +0000
+++ b/Font_7Seg.cpp	Sun Jan 31 12:11:06 2016 +0000
@@ -1,6 +1,7 @@
 /* mbed LED Font Library, for TM1638 LED controller
  * Copyright (c) 2015, v01: WH, Initial version, Test in LEDKEY8
  *               2016, v02: WH, Added ASCII alphabet, changed fonttable into short
+ *               2016, v03: WH, Added QYF-TM1638 and LKM1638 
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +24,7 @@
 #include "Font_7Seg.h"
 
 // Select one of the testboards for TM1638 LED controller
-#if (LEDKEY8_TEST == 1) 
+#if ((LEDKEY8_TEST == 1) || (QYF_TEST == 1) || (LKM1638_TEST == 1))
 
 //Mask for blending out and restoring Icons
 const char MASK_ICON_GRID[][2] = {
diff -r 25ddabfadc8c -r b2bbdc58967e Font_7Seg.h
--- a/Font_7Seg.h	Tue Jan 19 18:58:22 2016 +0000
+++ b/Font_7Seg.h	Sun Jan 31 12:11:06 2016 +0000
@@ -1,6 +1,7 @@
 /* mbed LED Font Library, for TM1638 LED Controller
  * Copyright (c) 2015, v01: WH, Initial version, Test in LEDKEY8
- *               2016, v02: WH, Added ASCII alphabet, changed fonttable into short 
+ *               2016, v02: WH, Added ASCII alphabet, changed fonttable into short
+ *               2016, v03: WH, Added QYF-TM1638 and LKM1638  
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -109,6 +110,231 @@
 extern const char MASK_ICON_GRID[][2]; 
 #endif
 
+#if (QYF_TEST == 1)
+// Segment bit positions for 7 Segment display using the QYF mapping for TM1638
+// This display module uses a single byte of each grid to drive a specific segment of all digits.
+// So the bits in byte 0 (Grid 1) drive all A-segments, the bits in byte 2 (Grid 2) drive all B-segments etc.
+// Bit0 is for the segment in Digit 8, Bit1 is for the segment in Digit 7 etc.. This bit manipulation is handled in _putc().
+//
+// The ASCII character defines and the FONT_7S const table below will be adapted automatically according to the bit-to-segment mapping.
+//
+//            A
+//          -----
+//         |     |     
+//       F |     | B    
+//         |  G  |     
+//          -----
+//         |     |     
+//       E |     | C    
+//         |     |     
+//          -----   * DP
+//            D  
+//
+//Generic segment placeholders
+#define S7_A    0x0001
+#define S7_B    0x0002
+#define S7_C    0x0004
+#define S7_D    0x0008
+#define S7_E    0x0010
+#define S7_F    0x0020
+#define S7_G    0x0040 
+#define S7_DP   0x0080 
+
+//Mask for blending out and setting 7 segments digits
+//#define MASK_7S_ALL = (S7_A | S7_B | S7_C | S7_D | S7_E | S7_F | S7_G}
+
+//Segments and Icons Grid 1
+#define S7_A1        0x0080
+#define S7_B1        0x0080
+#define S7_C1        0x0080
+#define S7_D1        0x0080
+#define S7_E1        0x0080
+#define S7_F1        0x0080
+#define S7_G1        0x0080
+#define S7_DP1       0x0080
+#define S7_ICON_GR1 (0x0000)
+
+//Segments and Icons Grid 2
+#define S7_A2        0x0040
+#define S7_B2        0x0040
+#define S7_C2        0x0040
+#define S7_D2        0x0040
+#define S7_E2        0x0040
+#define S7_F2        0x0040
+#define S7_G2        0x0040
+#define S7_DP2       0x0040
+#define S7_ICON_GR2 (0x0000)
+
+//Segments and Icons Grid 3
+#define S7_A3        0x0020
+#define S7_B3        0x0020
+#define S7_C3        0x0020
+#define S7_D3        0x0020
+#define S7_E3        0x0020
+#define S7_F3        0x0020
+#define S7_G3        0x0020
+#define S7_DP3       0x0020
+#define S7_ICON_GR3 (0x0000)
+
+//Segments and Icons Grid 4
+#define S7_A4        0x0010
+#define S7_B4        0x0010
+#define S7_C4        0x0010
+#define S7_D4        0x0010
+#define S7_E4        0x0010
+#define S7_F4        0x0010
+#define S7_G4        0x0010
+#define S7_DP4       0x0010
+#define S7_ICON_GR4 (0x0000)
+
+//Segments and Icons Grid 5
+#define S7_A5        0x0008
+#define S7_B5        0x0008
+#define S7_C5        0x0008
+#define S7_D5        0x0008
+#define S7_E5        0x0008
+#define S7_F5        0x0008
+#define S7_G5        0x0008
+#define S7_DP5       0x0008
+#define S7_ICON_GR5 (0x0000)
+
+//Segments and Icons Grid 6
+#define S7_A6        0x0004
+#define S7_B6        0x0004
+#define S7_C6        0x0004
+#define S7_D6        0x0004
+#define S7_E6        0x0004
+#define S7_F6        0x0004
+#define S7_G6        0x0004
+#define S7_DP6       0x0004
+#define S7_ICON_GR6 (0x0000)
+
+//Segments and Icons Grid 7
+#define S7_A7        0x0002
+#define S7_B7        0x0002
+#define S7_C7        0x0002
+#define S7_D7        0x0002
+#define S7_E7        0x0002
+#define S7_F7        0x0002
+#define S7_G7        0x0002
+#define S7_DP7       0x0002
+#define S7_ICON_GR7 (0x0000)
+
+//Segments and Icons Grid 8
+#define S7_A8        0x0001
+#define S7_B8        0x0001
+#define S7_C8        0x0001
+#define S7_D8        0x0001
+#define S7_E8        0x0001
+#define S7_F8        0x0001
+#define S7_G8        0x0001
+#define S7_DP8       0x0001
+#define S7_ICON_GR8 (0x0000)
+
+//Mask for blending out and restoring Icons
+extern const char MASK_ICON_GRID[][2]; 
+#endif
+
+#if (LKM1638_TEST == 1)
+// Segment bit positions for 7 Segment display using the LKM1638 mapping for TM1638
+// Modify this table for different 'bit-to-segment' mappings. The ASCII character defines and the FONT_7S const table below 
+// will be adapted automatically according to the bit-to-segment mapping. Obviously this will only work when the segment
+// mapping is identical for every digit position. This will be the case unless the hardware designer really hates software developers.
+//
+// The ASCII character defines and the FONT_7S const table below will be adapted automatically according to the bit-to-segment mapping.
+//
+//            A
+//          -----
+//         |     |     
+//       F |     | B    
+//         |  G  |     
+//          -----
+//         |     |     
+//       E |     | C    
+//         |     |     
+//          -----   * DP
+//            D  
+//
+//Generic segment placeholders
+#define S7_A    0x0001
+#define S7_B    0x0002
+#define S7_C    0x0004
+#define S7_D    0x0008
+#define S7_E    0x0010
+#define S7_F    0x0020
+#define S7_G    0x0040 
+#define S7_DP   0x0080 
+
+//Mask for blending out and setting 7 segments digits
+//#define MASK_7S_ALL = (S7_A | S7_B | S7_C | S7_D | S7_E | S7_F | S7_G}
+
+//Icons Grid 1
+#define S7_DP1  0x0080
+#define S7_GR1  0x0100
+#define S7_RD1  0x0200
+#define S7_YL1  0x0300
+#define S7_ICON_GR1 (S7_RD1 | S7_GR1 | S7_YL1)
+//#define S7_ICON_GR1 (S7_RD1 | S7_GR1 | S7_YL1 | S7_DP1)
+
+//Icons Grid 2
+#define S7_DP2  0x0080
+#define S7_GR2  0x0100
+#define S7_RD2  0x0200
+#define S7_YL2  0x0300
+#define S7_ICON_GR2 (S7_RD2 | S7_GR2 | S7_YL2)
+//#define S7_ICON_GR2 (S7_RD2 | S7_GR2 | S7_YL2 | S7_DP2)
+
+//Icons Grid 3
+#define S7_DP3  0x0080
+#define S7_GR3  0x0100
+#define S7_RD3  0x0200
+#define S7_YL3  0x0300
+#define S7_ICON_GR3 (S7_RD3 | S7_GR3 | S7_YL3)
+//#define S7_ICON_GR3 (S7_RD3 | S7_GR3 | S7_YL3 | S7_DP3)
+
+//Icons Grid 4
+#define S7_DP4  0x0080
+#define S7_GR4  0x0100
+#define S7_RD4  0x0200
+#define S7_YL4  0x0300
+#define S7_ICON_GR4 (S7_RD4 | S7_GR4 | S7_YL4)
+//#define S7_ICON_GR4 (S7_RD4 | S7_GR4 | S7_YL4 | S7_DP4)
+
+//Icons Grid 5
+#define S7_DP5  0x0080
+#define S7_GR5  0x0100
+#define S7_RD5  0x0200
+#define S7_YL5  0x0300
+#define S7_ICON_GR5 (S7_RD5 | S7_GR5 | S7_YL5)
+//#define S7_ICON_GR5 (S7_RD5 | S7_GR5 | S7_YL5 | S7_DP5)
+
+//Icons Grid 6
+#define S7_DP6  0x0080
+#define S7_GR6  0x0100
+#define S7_RD6  0x0200
+#define S7_YL6  0x0300
+#define S7_ICON_GR6 (S7_RD6 | S7_GR6 | S7_YL6)
+//#define S7_ICON_GR6 (S7_RD6 | S7_GR6 | S7_YL6 | S7_DP6)
+
+//Icons Grid 7
+#define S7_DP7  0x0080
+#define S7_GR7  0x0100
+#define S7_RD7  0x0200
+#define S7_YL7  0x0300
+#define S7_ICON_GR7 (S7_RD7 | S7_GR7 | S7_YL7)
+//#define S7_ICON_GR7 (S7_RD7 | S7_GR7 | S7_YL7 | S7_DP7)
+
+//Icons Grid 8
+#define S7_DP8  0x0080
+#define S7_GR8  0x0100
+#define S7_RD8  0x0200
+#define S7_YL8  0x0300
+#define S7_ICON_GR8 (S7_RD8 | S7_GR8 | S7_YL8)
+//#define S7_ICON_GR8 (S7_RD8 | S7_GR8 | S7_YL8 | S7_DP8)
+
+//Mask for blending out and restoring Icons
+extern const char MASK_ICON_GRID[][2]; 
+#endif
 
 // ASCII Font definitions for segments in each character
 //
diff -r 25ddabfadc8c -r b2bbdc58967e TM1638.cpp
--- a/TM1638.cpp	Tue Jan 19 18:58:22 2016 +0000
+++ b/TM1638.cpp	Sun Jan 31 12:11:06 2016 +0000
@@ -1,6 +1,7 @@
 /* mbed TM1638 Library, for TM1638 LED controller
  * Copyright (c) 2015, v01: WH, Initial version
  *               2016, v02: WH, Added ASCII alphabet display selector, refactored display and keyboard defines 
+ *               2016, v03: WH, Added QYF-TM1638 and LKM1638, refactoring of writeData() 
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -98,12 +99,13 @@
   _writeCmd(TM1638_DSP_CTRL_CMD, _display | _bright );  // Display control cmd, display on/off, brightness   
 }
 
+
 /** Write databyte to TM1638
+  *  @param  char data byte written at given address
   *  @param  int address display memory location to write byte
-  *  @param  char data byte written at given address
   *  @return none
   */ 
-void TM1638::writeData(int address, char data) {
+void TM1638::writeData(char data, int address) {
   _cs=0;
   wait_us(1);    
   _spi.write(_flip(TM1638_ADDR_SET_CMD | (address & TM1638_ADDR_MSK))); // Set Address cmd
@@ -114,23 +116,28 @@
   _cs=1;             
 }
 
+
 /** Write Display datablock to TM1638
-  *  @param  DisplayData_t data Array of TM1638_DISPLAY_MEM (=16) bytes for displaydata (starting at address 0)
-  *  @param  length number bytes to write (valide range 0..TM1638_DISPLAY_MEM (=16), starting at address 0)     
+  *  @param  DisplayData_t data Array of TM1638_DISPLAY_MEM (=16) bytes for displaydata
+  *  @param  length number bytes to write (valid range 0..TM1638_DISPLAY_MEM (=16), when starting at address 0)
+  *  @param  int address display memory location to write bytes (default = 0)   
   *  @return none
   */ 
-void TM1638::writeData(DisplayData_t data, int length) {
+void TM1638::writeData(DisplayData_t data, int length, int address) {
   _cs=0;
   wait_us(1);    
-  _spi.write(_flip(TM1638_ADDR_SET_CMD | 0x00)); // Set Address at 0
-      
+       
 // sanity check
+  address &= TM1638_ADDR_MSK;
   if (length < 0) {length = 0;}
-  if (length > TM1638_DISPLAY_MEM) {length = TM1638_DISPLAY_MEM;}
+  if ((length + address) > TM1638_DISPLAY_MEM) {length = (TM1638_DISPLAY_MEM - address);}
 
-//  for (int idx=0; idx<TM1638_DISPLAY_MEM; idx++) {  
+  // _spi.write(_flip(TM1638_ADDR_SET_CMD | 0x00)); // Set Address at 0
+  _spi.write(_flip(TM1638_ADDR_SET_CMD | address)); // Set Address
+
   for (int idx=0; idx<length; idx++) {    
-    _spi.write(_flip(data[idx])); // data 
+    //_spi.write(_flip(data[idx])); // data 
+    _spi.write(_flip(data[address + idx])); // data 
   }
   
   wait_us(1);
@@ -319,12 +326,13 @@
 
    icn =        icon  & 0xFFFF;
   addr = (icon >> 24) & 0xFF; 
-  addr = (addr - 1) << 1;   // * PT1638_BYTES_PER_GRID
+  addr = (addr - 1) << 1;   // * TM1638_BYTES_PER_GRID
     
   //Save char...and set bits for icon to write
   _displaybuffer[addr]   = _displaybuffer[addr]   | LO(icn);      
   _displaybuffer[addr+1] = _displaybuffer[addr+1] | HI(icn);      
-  writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
+//  writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
+  writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);      
 }
 
 /** Clr Icon
@@ -342,7 +350,8 @@
   //Save char...and clr bits for icon to write
   _displaybuffer[addr]   = _displaybuffer[addr]   & ~LO(icn);      
   _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~HI(icn);      
-  writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
+//  writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
+  writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);      
 }
 
 
@@ -386,14 +395,15 @@
       if (_column > 0) {
         //Translate between _column and displaybuffer entries
         //Add DP to bitpattern of digit left of current column.
-        addr = (_column - 1) << 1; // * PT1638_BYTES_PER_GRID
+        addr = (_column - 1) << 1; // * TM1638_BYTES_PER_GRID
       
         //Save icons...and set bits for decimal point to write
         _displaybuffer[addr]   = _displaybuffer[addr] | pattern;
 //        _displaybuffer[addr+1] = _displaybuffer[addr+1] | pattern;
 
-        writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
-        
+//        writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
+        writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);    
+          
         //No Cursor Update
       }
     }
@@ -444,8 +454,9 @@
       _displaybuffer[addr]   = (_displaybuffer[addr]   & MASK_ICON_GRID[_column][0]) | pattern;
 //      _displaybuffer[addr+1] = (_displaybuffer[addr+1] & MASK_ICON_GRID[_column][0]) | pattern;
 
-      writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
-                                
+//      writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
+      writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);
+      
       //Update Cursor
       _column++;
       if (_column > (LEDKEY8_NR_DIGITS - 1)) {
@@ -464,3 +475,508 @@
 }
 
 #endif
+
+
+#if (QYF_TEST == 1) 
+// Derived class for TM1638 used in QYF-TM1638 display unit
+//
+
+/** Constructor for class for driving TM1638 LED controller as used in QYF
+  *
+  *  @brief Supports 8 Digits of 7 Segments + DP. Also supports a scanned keyboard of 16 keys.
+  *   
+  *  @param  PinName mosi, miso, sclk, cs SPI bus pins
+  */
+TM1638_QYF::TM1638_QYF(PinName mosi, PinName miso, PinName sclk, PinName cs) : TM1638(mosi, miso, sclk, cs) {
+  _column  = 0;
+  _columns = QYF_NR_DIGITS;    
+}  
+
+#if(0)
+#if DOXYGEN_ONLY
+    /** Write a character to the Display
+     *
+     * @param c The character to write to the display
+     */
+    int putc(int c);
+
+    /** Write a formatted string to the Display
+     *
+     * @param format A printf-style format string, followed by the
+     *               variables to use in formatting the string.
+     */
+    int printf(const char* format, ...);   
+#endif
+#endif
+
+/** Locate cursor to a screen column
+  *
+  * @param column  The horizontal position from the left, indexed from 0
+  */
+void TM1638_QYF::locate(int column) {
+  //sanity check
+  if (column < 0) {column = 0;}
+  if (column > (_columns - 1)) {column = _columns - 1;}  
+  
+  _column = column;       
+}
+
+
+/** Number of screen columns
+  *
+  * @param none
+  * @return columns
+  */
+int TM1638_QYF::columns() {
+    return _columns;
+}
+
+    
+/** Clear the screen and locate to 0
+  * @param bool clrAll Clear Icons also (default = false)
+  */ 
+void TM1638_QYF::cls(bool clrAll) {  
+
+  if (clrAll) {
+    //clear local buffer (including Icons)
+    for (int idx=0; idx < (QYF_NR_GRIDS << 1); idx++) {
+      _displaybuffer[idx] = 0x00;  
+    }
+  }  
+  else {
+    //clear local buffer (preserving Icons)
+    for (int idx=0; idx < QYF_NR_GRIDS; idx++) {
+      _displaybuffer[(idx<<1)]     = _displaybuffer[(idx<<1)]     & MASK_ICON_GRID[idx][0];  
+      _displaybuffer[(idx<<1) + 1] = _displaybuffer[(idx<<1) + 1] & MASK_ICON_GRID[idx][1];
+    }  
+  }
+
+  writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID));
+
+  _column = 0;   
+}     
+
+/** Set Icon
+  *
+  * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+  * @return none
+  */
+void TM1638_QYF::setIcon(Icon icon) {
+  int addr, icn;
+
+   icn =        icon  & 0xFFFF;
+  addr = (icon >> 24) & 0xFF; 
+  addr = (addr - 1) << 1;   // * TM1638_BYTES_PER_GRID
+    
+  //Save char...and set bits for icon to write
+  _displaybuffer[addr]   = _displaybuffer[addr]   | LO(icn);      
+  _displaybuffer[addr+1] = _displaybuffer[addr+1] | HI(icn);      
+//  writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID));
+  writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);    
+}
+
+/** Clr Icon
+  *
+  * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+  * @return none
+  */
+void TM1638_QYF::clrIcon(Icon icon) {
+  int addr, icn;
+
+   icn =        icon  & 0xFFFF;
+  addr = (icon >> 24) & 0xFF; 
+  addr = (addr - 1) << 1;   // * TM1638_BYTES_PER_GRID
+    
+  //Save char...and clr bits for icon to write
+  _displaybuffer[addr]   = _displaybuffer[addr]   & ~LO(icn);      
+  _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~HI(icn);      
+//  writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID));
+  writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);  
+}
+
+
+/** Set User Defined Characters (UDC)
+  *
+  * @param unsigned char udc_idx  The Index of the UDC (0..7)
+  * @param int udc_data           The bitpattern for the UDC (8 bits)       
+  */
+void TM1638_QYF::setUDC(unsigned char udc_idx, int udc_data) {
+
+  //Sanity check
+  if (udc_idx > (QYF_NR_UDC-1)) {
+    return;
+  }
+  // Mask out Icon bits?
+
+  _UDC_7S[udc_idx] = LO(udc_data);
+}
+
+
+/** Write a single character (Stream implementation)
+  */
+int TM1638_QYF::_putc(int value) {
+    bool validChar = false;
+    char pattern   = 0x00;
+    char bit       = 0x00;
+        
+    if ((value == '\n') || (value == '\r')) {
+      //No character to write
+      validChar = false;
+      
+      //Update Cursor      
+      _column = 0;
+    }
+    else if ((value == '.') || (value == ',')) {
+      //No character to write
+      validChar = false;
+      pattern = S7_DP; // placeholder for all DPs
+      
+      // Check to see that DP can be shown for current column
+      if (_column > 0) {
+        //Add DP to bitpattern of digit left of current column.
+        bit = 1 << (8 - _column); // bitposition for the previous _column
+
+        _displaybuffer[14] = (_displaybuffer[14] | bit); // set bit
+
+        writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID));
+        
+        //No Cursor Update
+      }
+    }
+    else if ((value >= 0) && (value < QYF_NR_UDC)) {
+      //Character to write
+      validChar = true;
+      pattern = _UDC_7S[value];
+    }  
+    
+#if (SHOW_ASCII == 1)
+    //display all ASCII characters
+    else if ((value >= FONT_7S_START) && (value <= FONT_7S_END)) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[value - FONT_7S_START];
+    } // else
+#else    
+    //display only digits and hex characters      
+    else if (value == '-') {
+      //Character to write
+      validChar = true;
+      pattern = C7_MIN;         
+    }
+    else if ((value >= (int)'0') && (value <= (int) '9')) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[value - (int) '0'];
+    }
+    else if ((value >= (int) 'A') && (value <= (int) 'F')) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[10 + value - (int) 'A'];
+    }
+    else if ((value >= (int) 'a') && (value <= (int) 'f')) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[10 + value - (int) 'a'];
+    } //else
+#endif
+
+    if (validChar) {
+      //Character to write
+
+      // Very annoying bitmapping :(
+      // This display module uses a single byte of each grid to drive a specific segment of all digits.
+      // So the bits in byte 0 (Grid 1) drive all A-segments, the bits in byte 2 (Grid 2) drive all B-segments etc.
+      // Bit0 is for the segment in Digit 8, Bit1 is for the segment in Digit 7 etc.. This bit manipulation is handled in _putc().
+      
+      bit = 1 << (7 - _column); // bitposition for the current _column
+
+      if (pattern & S7_A) {_displaybuffer[0] = (_displaybuffer[0] | bit); } // set bit
+      else                {_displaybuffer[0] = (_displaybuffer[0] & ~bit);} // clr bit       
+
+      if (pattern & S7_B) {_displaybuffer[2] = (_displaybuffer[2] | bit); } // set bit
+      else                {_displaybuffer[2] = (_displaybuffer[2] & ~bit);} // clr bit       
+
+      if (pattern & S7_C) {_displaybuffer[4] = (_displaybuffer[4] | bit); } // set bit
+      else                {_displaybuffer[4] = (_displaybuffer[4] & ~bit);} // clr bit       
+
+      if (pattern & S7_D) {_displaybuffer[6] = (_displaybuffer[6] | bit); } // set bit
+      else                {_displaybuffer[6] = (_displaybuffer[6] & ~bit);} // clr bit       
+
+      if (pattern & S7_E) {_displaybuffer[8] = (_displaybuffer[8] | bit); } // set bit
+      else                {_displaybuffer[8] = (_displaybuffer[8] & ~bit);} // clr bit       
+
+      if (pattern & S7_F) {_displaybuffer[10] = (_displaybuffer[10] | bit); } // set bit
+      else                {_displaybuffer[10] = (_displaybuffer[10] & ~bit);} // clr bit       
+
+      if (pattern & S7_G) {_displaybuffer[12] = (_displaybuffer[12] | bit); } // set bit
+      else                {_displaybuffer[12] = (_displaybuffer[12] & ~bit);} // clr bit       
+
+      if (pattern & S7_DP) {_displaybuffer[14] = (_displaybuffer[14] | bit); } // set bit
+      else                 {_displaybuffer[14] = (_displaybuffer[14] & ~bit);} // clr bit       
+
+      //Save icons...and set bits for character to write
+//      _displaybuffer[addr]   = (_displaybuffer[addr]   & MASK_ICON_GRID[_column][0]) | pattern;
+//      _displaybuffer[addr+1] = (_displaybuffer[addr+1] & MASK_ICON_GRID[_column][0]) | pattern;
+
+      writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID));
+                                
+      //Update Cursor
+      _column++;
+      if (_column > (QYF_NR_DIGITS - 1)) {
+        _column = 0;
+      }
+
+    } // if validChar           
+
+    return value;
+}
+
+
+// get a single character (Stream implementation)
+int TM1638_QYF::_getc() {
+    return -1;
+}
+
+#endif
+
+
+
+#if (LKM1638_TEST == 1) 
+// Derived class for TM1638 used in LMK1638 display unit
+//
+
+/** Constructor for class for driving TM1638 LED controller as used in LKM1638
+  *
+  *  @brief Supports 8 Digits of 7 Segments + DP + Bi-Color LED Icons. Also supports a scanned keyboard of 8.
+  *   
+  *  @param  PinName mosi, miso, sclk, cs SPI bus pins
+  */
+TM1638_LKM1638::TM1638_LKM1638(PinName mosi, PinName miso, PinName sclk, PinName cs) : TM1638(mosi, miso, sclk, cs) {
+  _column  = 0;
+  _columns = LKM1638_NR_DIGITS;    
+}  
+
+#if(0)
+#if DOXYGEN_ONLY
+    /** Write a character to the Display
+     *
+     * @param c The character to write to the display
+     */
+    int putc(int c);
+
+    /** Write a formatted string to the Display
+     *
+     * @param format A printf-style format string, followed by the
+     *               variables to use in formatting the string.
+     */
+    int printf(const char* format, ...);   
+#endif
+#endif
+
+/** Locate cursor to a screen column
+  *
+  * @param column  The horizontal position from the left, indexed from 0
+  */
+void TM1638_LKM1638::locate(int column) {
+  //sanity check
+  if (column < 0) {column = 0;}
+  if (column > (_columns - 1)) {column = _columns - 1;}  
+  
+  _column = column;       
+}
+
+
+/** Number of screen columns
+  *
+  * @param none
+  * @return columns
+  */
+int TM1638_LKM1638::columns() {
+    return _columns;
+}
+
+    
+/** Clear the screen and locate to 0
+  * @param bool clrAll Clear Icons also (default = false)
+  */ 
+void TM1638_LKM1638::cls(bool clrAll) {  
+
+  if (clrAll) {
+    //clear local buffer (including Icons)
+    for (int idx=0; idx < (LKM1638_NR_GRIDS << 1); idx++) {
+      _displaybuffer[idx] = 0x00;  
+    }
+  }  
+  else {
+    //clear local buffer (preserving Icons)
+    for (int idx=0; idx < LKM1638_NR_GRIDS; idx++) {
+      _displaybuffer[(idx<<1)]     = _displaybuffer[(idx<<1)]     & MASK_ICON_GRID[idx][0];  
+      _displaybuffer[(idx<<1) + 1] = _displaybuffer[(idx<<1) + 1] & MASK_ICON_GRID[idx][1];
+    }  
+  }
+
+  writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID));
+
+  _column = 0;   
+}     
+
+/** Set Icon
+  *
+  * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+  * @return none
+  */
+void TM1638_LKM1638::setIcon(Icon icon) {
+  int addr, icn;
+
+   icn =        icon  & 0xFFFF;
+  addr = (icon >> 24) & 0xFF; 
+  addr = (addr - 1) << 1;   // * TM1638_BYTES_PER_GRID
+    
+  //Save char...and set bits for icon to write
+  _displaybuffer[addr]   = _displaybuffer[addr]   | LO(icn);      
+  _displaybuffer[addr+1] = _displaybuffer[addr+1] | HI(icn);      
+//  writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID));
+  writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);      
+}
+
+/** Clr Icon
+  *
+  * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+  * @return none
+  */
+void TM1638_LKM1638::clrIcon(Icon icon) {
+  int addr, icn;
+
+   icn =        icon  & 0xFFFF;
+  addr = (icon >> 24) & 0xFF; 
+  addr = (addr - 1) << 1;   // * TM1638_BYTES_PER_GRID
+    
+  //Save char...and clr bits for icon to write
+  _displaybuffer[addr]   = _displaybuffer[addr]   & ~LO(icn);      
+  _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~HI(icn);      
+//  writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID));
+  writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);      
+}
+
+
+/** Set User Defined Characters (UDC)
+  *
+  * @param unsigned char udc_idx  The Index of the UDC (0..7)
+  * @param int udc_data           The bitpattern for the UDC (8 bits)       
+  */
+void TM1638_LKM1638::setUDC(unsigned char udc_idx, int udc_data) {
+
+  //Sanity check
+  if (udc_idx > (LKM1638_NR_UDC-1)) {
+    return;
+  }
+  // Mask out Icon bits?
+
+  _UDC_7S[udc_idx] = LO(udc_data);
+}
+
+
+/** Write a single character (Stream implementation)
+  */
+int TM1638_LKM1638::_putc(int value) {
+    int addr;
+    bool validChar = false;
+    char pattern   = 0x00;
+    
+    if ((value == '\n') || (value == '\r')) {
+      //No character to write
+      validChar = false;
+      
+      //Update Cursor      
+      _column = 0;
+    }
+    else if ((value == '.') || (value == ',')) {
+      //No character to write
+      validChar = false;
+      pattern = S7_DP; // placeholder for all DPs
+      
+      // Check to see that DP can be shown for current column
+      if (_column > 0) {
+        //Translate between _column and displaybuffer entries
+        //Add DP to bitpattern of digit left of current column.
+        addr = (_column - 1) << 1; // * TM1638_BYTES_PER_GRID
+      
+        //Save icons...and set bits for decimal point to write
+        _displaybuffer[addr]   = _displaybuffer[addr] | pattern;
+//        _displaybuffer[addr+1] = _displaybuffer[addr+1] | pattern;
+
+//        writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID));
+        writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);    
+          
+        //No Cursor Update
+      }
+    }
+    else if ((value >= 0) && (value < LKM1638_NR_UDC)) {
+      //Character to write
+      validChar = true;
+      pattern = _UDC_7S[value];
+    }  
+    
+#if (SHOW_ASCII == 1)
+    //display all ASCII characters
+    else if ((value >= FONT_7S_START) && (value <= FONT_7S_END)) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[value - FONT_7S_START];
+    } // else
+#else    
+    //display only digits and hex characters      
+    else if (value == '-') {
+      //Character to write
+      validChar = true;
+      pattern = C7_MIN;         
+    }
+    else if ((value >= (int)'0') && (value <= (int) '9')) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[value - (int) '0'];
+    }
+    else if ((value >= (int) 'A') && (value <= (int) 'F')) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[10 + value - (int) 'A'];
+    }
+    else if ((value >= (int) 'a') && (value <= (int) 'f')) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[10 + value - (int) 'a'];
+    } //else
+#endif
+
+    if (validChar) {
+      //Character to write
+ 
+      //Translate between _column and displaybuffer entries
+      addr = _column << 1; // * TM1638_BYTES_PER_GRID
+
+      //Save icons...and set bits for character to write
+      _displaybuffer[addr]   = (_displaybuffer[addr]   & MASK_ICON_GRID[_column][0]) | pattern;
+//      _displaybuffer[addr+1] = (_displaybuffer[addr+1] & MASK_ICON_GRID[_column][0]) | pattern;
+
+//      writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID));
+      writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);
+      
+      //Update Cursor
+      _column++;
+      if (_column > (LKM1638_NR_DIGITS - 1)) {
+        _column = 0;
+      }
+
+    } // if validChar           
+
+    return value;
+}
+
+
+// get a single character (Stream implementation)
+int TM1638_LKM1638::_getc() {
+    return -1;
+}
+
+#endif
+
diff -r 25ddabfadc8c -r b2bbdc58967e TM1638.h
--- a/TM1638.h	Tue Jan 19 18:58:22 2016 +0000
+++ b/TM1638.h	Sun Jan 31 12:11:06 2016 +0000
@@ -1,6 +1,7 @@
 /* mbed TM1638 Library, for TM1638 LED controller
  * Copyright (c) 2015, v01: WH, Initial version
  *               2016, v02: WH, refactored display and keyboard defines 
+ *               2016, v03: WH, Added QYF-TM1638 and LKM1638, refactoring of writeData() 
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -119,9 +120,10 @@
  */
 class TM1638 {
  public:
-
-  /** Datatypes for display and keymatrix data */
+  /** Datatype for display data */
   typedef char DisplayData_t[TM1638_DISPLAY_MEM];
+  
+  /** Datatypes for keymatrix data */
   typedef char KeyData_t[TM1638_KEY_MEM];
     
  /** Constructor for class for driving TM1638 LED controller
@@ -139,19 +141,20 @@
   void cls();  
 
   /** Write databyte to TM1638
+   *  @param  char data byte written at given address
    *  @param  int address display memory location to write byte
-   *  @param  char data byte written at given address
    *  @return none
    */ 
-  void writeData(int address, char data); 
+   void writeData(char data, int address); 
+
+   /** Write Display datablock to TM1638
+    *  @param  DisplayData_t data Array of TM1638_DISPLAY_MEM (=16) bytes for displaydata
+    *  @param  length number bytes to write (valid range 0..(TM1638_MAX_NR_GRIDS * TM1638_BYTES_PER_GRID) (=16), when starting at address 0)  
+    *  @param  int address display memory location to write bytes (default = 0) 
+    *  @return none
+    */ 
+    void writeData(DisplayData_t data, int length = (TM1638_MAX_NR_GRIDS * TM1638_BYTES_PER_GRID), int address = 0);
  
- /** Write Display datablock to TM1638
-   *  @param  DisplayData_t data Array of TM1638_DISPLAY_MEM (=16) bytes for displaydata (starting at address 0)
-   *  @param  length number bytes to write (valid range 0..TM1638_DISPLAY_MEM (=16), starting at address 0)   
-   *  @return none
-   */   
-  void writeData(DisplayData_t data, int length = TM1638_DISPLAY_MEM);
-
   /** Read keydata block from TM1638
    *  @param  *keydata Ptr to Array of TM1638_KEY_MEM (=4) bytes for keydata
    *  @return bool keypress True when at least one key was pressed
@@ -164,7 +167,7 @@
 
   /** Set Brightness
     *
-    * @param  char brightness (3 significant bits, valid range 0..7 (1/16 .. 14/14 dutycycle)  
+    * @param  char brightness (3 significant bits, valid range 0..7 (1/16 .. 14/16 dutycycle)  
     * @return none
     */
   void setBrightness(char brightness = TM1638_BRT_DEF);
@@ -243,23 +246,23 @@
   /** Enums for Icons */
   //  Grid encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
   enum Icon {
-    LD1  = (1<<24) | S7_LD1,
-    LD2  = (2<<24) | S7_LD2,
-    LD3  = (3<<24) | S7_LD3,
-    LD4  = (4<<24) | S7_LD4,
-    LD5  = (5<<24) | S7_LD5,
-    LD6  = (6<<24) | S7_LD6,
-    LD7  = (7<<24) | S7_LD7,
-    LD8  = (8<<24) | S7_LD8,
+    LD1  = (1<<24) | S7_LD1, /**<  LED1 */
+    LD2  = (2<<24) | S7_LD2, /**<  LED2 */
+    LD3  = (3<<24) | S7_LD3, /**<  LED3 */
+    LD4  = (4<<24) | S7_LD4, /**<  LED4 */
+    LD5  = (5<<24) | S7_LD5, /**<  LED5 */
+    LD6  = (6<<24) | S7_LD6, /**<  LED6 */
+    LD7  = (7<<24) | S7_LD7, /**<  LED7 */
+    LD8  = (8<<24) | S7_LD8, /**<  LED8 */
                                 
-    DP1  = (1<<24) | S7_DP1,
-    DP2  = (2<<24) | S7_DP2,
-    DP3  = (3<<24) | S7_DP3,
-    DP4  = (4<<24) | S7_DP4,
-    DP5  = (5<<24) | S7_DP5,
-    DP6  = (6<<24) | S7_DP6,
-    DP7  = (7<<24) | S7_DP7,
-    DP8  = (8<<24) | S7_DP8                            
+    DP1  = (1<<24) | S7_DP1, /**<  Decimal Point 1 */
+    DP2  = (2<<24) | S7_DP2, /**<  Decimal Point 2 */
+    DP3  = (3<<24) | S7_DP3, /**<  Decimal Point 3 */
+    DP4  = (4<<24) | S7_DP4, /**<  Decimal Point 4 */
+    DP5  = (5<<24) | S7_DP5, /**<  Decimal Point 5 */
+    DP6  = (6<<24) | S7_DP6, /**<  Decimal Point 6 */
+    DP7  = (7<<24) | S7_DP7, /**<  Decimal Point 7 */
+    DP8  = (8<<24) | S7_DP8  /**<  Decimal Point 8 */  
   };
   
   typedef char UDCData_t[LEDKEY8_NR_UDC];
@@ -328,21 +331,366 @@
     int columns();   
 
    /** Write databyte to TM1638
+     *  @param  char data byte written at given address
      *  @param  int address display memory location to write byte
-     *  @param  char data byte written at given address
      *  @return none
      */ 
-    void writeData(int address, char data){
-      TM1638::writeData(address, data);
+    void writeData(char data, int address){
+      TM1638::writeData(data, address);
+    }        
+
+   /** Write Display datablock to TM1638
+    *  @param  DisplayData_t data Array of TM1638_DISPLAY_MEM (=16) bytes for displaydata
+    *  @param  length number bytes to write (valid range 0..(LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID) (=16), when starting at address 0)  
+    *  @param  int address display memory location to write bytes (default = 0) 
+    *  @return none
+    */   
+    void writeData(DisplayData_t data, int length = (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID), int address = 0) {
+      TM1638::writeData(data, length, address);
+    }  
+
+protected:  
+    // Stream implementation functions
+    virtual int _putc(int value);
+    virtual int _getc();
+
+private:
+    int _column;
+    int _columns;   
+    
+    DisplayData_t _displaybuffer;
+    UDCData_t _UDC_7S; 
+};
+#endif
+
+
+#if (QYF_TEST == 1) 
+// Derived class for TM1638 used in QYF-TM1638 display unit
+//
+
+#include "Font_7Seg.h"
+
+#define QYF_NR_GRIDS  8
+#define QYF_NR_DIGITS 8
+#define QYF_NR_UDC    8
+
+//Access to 16 Switches
+#define QYF_SW1_IDX   0
+#define QYF_SW1_BIT   0x04
+#define QYF_SW2_IDX   0
+#define QYF_SW2_BIT   0x40
+#define QYF_SW3_IDX   1
+#define QYF_SW3_BIT   0x04
+#define QYF_SW4_IDX   1
+#define QYF_SW4_BIT   0x40
+
+#define QYF_SW5_IDX   2
+#define QYF_SW5_BIT   0x04
+#define QYF_SW6_IDX   2
+#define QYF_SW6_BIT   0x40
+#define QYF_SW7_IDX   3
+#define QYF_SW7_BIT   0x04
+#define QYF_SW8_IDX   3
+#define QYF_SW8_BIT   0x40
+
+#define QYF_SW9_IDX    0
+#define QYF_SW9_BIT    0x02
+#define QYF_SW10_IDX   0
+#define QYF_SW10_BIT   0x20
+#define QYF_SW11_IDX   1
+#define QYF_SW11_BIT   0x02
+#define QYF_SW12_IDX   1
+#define QYF_SW12_BIT   0x20
+
+#define QYF_SW13_IDX   2
+#define QYF_SW13_BIT   0x02
+#define QYF_SW14_IDX   2
+#define QYF_SW14_BIT   0x20
+#define QYF_SW15_IDX   3
+#define QYF_SW15_BIT   0x02
+#define QYF_SW16_IDX   3
+#define QYF_SW16_BIT   0x20
+
+/** Constructor for class for driving TM1638 controller as used in QYF
+  *
+  *  @brief Supports 8 Digits of 7 Segments + DP, Also supports a scanned keyboard of 16 keys.
+  *  
+  *  @param  PinName mosi, miso, sclk, cs SPI bus pins
+  */
+class TM1638_QYF : public TM1638, public Stream {
+ public:
+
+  /** Enums for Icons */
+  //  Grid encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+  enum Icon {
+    DP1  = (8<<24) | S7_DP1, /**<  Decimal Point 1 */
+    DP2  = (8<<24) | S7_DP2, /**<  Decimal Point 2 */
+    DP3  = (8<<24) | S7_DP3, /**<  Decimal Point 3 */
+    DP4  = (8<<24) | S7_DP4, /**<  Decimal Point 4 */
+    DP5  = (8<<24) | S7_DP5, /**<  Decimal Point 5 */
+    DP6  = (8<<24) | S7_DP6, /**<  Decimal Point 6 */
+    DP7  = (8<<24) | S7_DP7, /**<  Decimal Point 7 */
+    DP8  = (8<<24) | S7_DP8  /**<  Decimal Point 8 */  
+  };
+  
+  typedef char UDCData_t[QYF_NR_UDC];
+  
+ /** Constructor for class for driving TM1638 LED controller as used in QYF
+   *
+   * @brief Supports 8 Digits of 7 Segments + DP Icons. Also supports a scanned keyboard of 16 keys.
+   *  
+   * @param  PinName mosi, miso, sclk, cs SPI bus pins
+   */
+  TM1638_QYF(PinName mosi, PinName miso, PinName sclk, PinName cs);
+
+#if DOXYGEN_ONLY
+    /** Write a character to the Display
+     *
+     * @param c The character to write to the display
+     */
+    int putc(int c);
+
+    /** Write a formatted string to the Display
+     *
+     * @param format A printf-style format string, followed by the
+     *               variables to use in formatting the string.
+     */
+    int printf(const char* format, ...);   
+#endif
+
+     /** Locate cursor to a screen column
+     *
+     * @param column  The horizontal position from the left, indexed from 0
+     */
+    void locate(int column);
+    
+    /** Clear the screen and locate to 0
+     * @param bool clrAll Clear Icons also (default = false)
+     */
+    void cls(bool clrAll = false);
+
+    /** Set Icon
+     *
+     * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+     * @return none
+     */
+    void setIcon(Icon icon);
+
+    /** Clr Icon
+     *
+     * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+     * @return none
+     */
+    void clrIcon(Icon icon);
+
+   /** Set User Defined Characters (UDC)
+     *
+     * @param unsigned char udc_idx   The Index of the UDC (0..7)
+     * @param int udc_data            The bitpattern for the UDC (16 bits)       
+     */
+    void setUDC(unsigned char udc_idx, int udc_data);
+
+
+   /** Number of screen columns
+    *
+    * @param none
+    * @return columns
+    */
+    int columns();   
+
+   /** Write databyte to TM1638
+     *  @param  char data byte written at given address   
+     *  @param  int address display memory location to write byte
+     *  @return none
+     */ 
+    void writeData(char data, int address){
+      TM1638::writeData(data, address);
     }        
 
    /** Write Display datablock to TM1638
-    *  @param  DisplayData_t data Array of TM1638_DISPLAY_MEM (=16) bytes for displaydata (starting at address 0)
-    *  @param  length number bytes to write (valid range 0..(LEDKEY8_NR_GRIDS*2) (=16), starting at address 0)   
+    *  @param  DisplayData_t data Array of TM1638_DISPLAY_MEM (=16) bytes for displaydata
+    *  @param  length number bytes to write (valid range 0..(QYF_NR_GRIDS * TM1638_BYTES_PER_GRID) (=16), when starting at address 0)  
+    *  @param  int address display memory location to write bytes (default = 0) 
     *  @return none
     */   
-    void writeData(DisplayData_t data, int length = (LEDKEY8_NR_GRIDS*2)) {
-      TM1638::writeData(data, length);
+    void writeData(DisplayData_t data, int length = (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID), int address = 0) {
+      TM1638::writeData(data, length, address);
+    }  
+
+protected:  
+    // Stream implementation functions
+    virtual int _putc(int value);
+    virtual int _getc();
+
+private:
+    int _column;
+    int _columns;   
+    
+    DisplayData_t _displaybuffer;
+    UDCData_t _UDC_7S; 
+};
+#endif
+
+#if (LKM1638_TEST == 1) 
+// Derived class for TM1638 used in LKM1638 TM1638 display unit
+//
+
+#include "Font_7Seg.h"
+
+#define LKM1638_NR_GRIDS  8
+#define LKM1638_NR_DIGITS 8
+#define LKM1638_NR_UDC    8
+
+//Access to 8 Switches
+#define LKM1638_SW1_IDX   0
+#define LKM1638_SW1_BIT   0x01
+#define LKM1638_SW2_IDX   1
+#define LKM1638_SW2_BIT   0x01
+#define LKM1638_SW3_IDX   2
+#define LKM1638_SW3_BIT   0x01
+#define LKM1638_SW4_IDX   3
+#define LKM1638_SW4_BIT   0x01
+
+#define LKM1638_SW5_IDX   0
+#define LKM1638_SW5_BIT   0x10
+#define LKM1638_SW6_IDX   1
+#define LKM1638_SW6_BIT   0x10
+#define LKM1638_SW7_IDX   2
+#define LKM1638_SW7_BIT   0x10
+#define LKM1638_SW8_IDX   3
+#define LKM1638_SW8_BIT   0x10
+
+/** Constructor for class for driving TM1638 controller as used in LKM1638
+  *
+  *  @brief Supports 8 Digits of 7 Segments + DP, Also supports 8 Bi-color LEDs and a scanned keyboard of 8 keys.
+  *  
+  *  @param  PinName mosi, miso, sclk, cs SPI bus pins
+  */
+class TM1638_LKM1638 : public TM1638, public Stream {
+ public:
+
+  /** Enums for Icons */
+  //  Grid encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+  enum Icon {
+    DP1  = (1<<24) | S7_DP1, /**<  Decimal Point 1 */
+    DP2  = (2<<24) | S7_DP2, /**<  Decimal Point 2 */
+    DP3  = (3<<24) | S7_DP3, /**<  Decimal Point 3 */
+    DP4  = (4<<24) | S7_DP4, /**<  Decimal Point 4 */
+    DP5  = (5<<24) | S7_DP5, /**<  Decimal Point 5 */
+    DP6  = (6<<24) | S7_DP6, /**<  Decimal Point 6 */
+    DP7  = (7<<24) | S7_DP7, /**<  Decimal Point 7 */
+    DP8  = (8<<24) | S7_DP8, /**<  Decimal Point 8 */  
+    
+    GR1  = (1<<24) | S7_GR1, /**<  Green LED 1 */
+    GR2  = (2<<24) | S7_GR2, /**<  Green LED 2 */
+    GR3  = (3<<24) | S7_GR3, /**<  Green LED 3 */
+    GR4  = (4<<24) | S7_GR4, /**<  Green LED 4 */
+    GR5  = (5<<24) | S7_GR5, /**<  Green LED 5 */
+    GR6  = (6<<24) | S7_GR6, /**<  Green LED 6 */
+    GR7  = (7<<24) | S7_GR7, /**<  Green LED 7 */
+    GR8  = (8<<24) | S7_GR8, /**<  Green LED 8 */  
+
+    RD1  = (1<<24) | S7_RD1, /**<  Red LED 1 */
+    RD2  = (2<<24) | S7_RD2, /**<  Red LED 2 */
+    RD3  = (3<<24) | S7_RD3, /**<  Red LED 3 */
+    RD4  = (4<<24) | S7_RD4, /**<  Red LED 4 */
+    RD5  = (5<<24) | S7_RD5, /**<  Red LED 5 */
+    RD6  = (6<<24) | S7_RD6, /**<  Red LED 6 */
+    RD7  = (7<<24) | S7_RD7, /**<  Red LED 7 */
+    RD8  = (8<<24) | S7_RD8, /**<  Red LED 8 */  
+    
+    YL1  = (1<<24) | S7_YL1, /**<  Yellow LED 1 */
+    YL2  = (2<<24) | S7_YL2, /**<  Yellow LED 2 */
+    YL3  = (3<<24) | S7_YL3, /**<  Yellow LED 3 */
+    YL4  = (4<<24) | S7_YL4, /**<  Yellow LED 4 */
+    YL5  = (5<<24) | S7_YL5, /**<  Yellow LED 5 */
+    YL6  = (6<<24) | S7_YL6, /**<  Yellow LED 6 */
+    YL7  = (7<<24) | S7_YL7, /**<  Yellow LED 7 */
+    YL8  = (8<<24) | S7_YL8  /**<  Yellow LED 8 */  
+  };
+  
+  typedef char UDCData_t[LKM1638_NR_UDC];
+  
+ /** Constructor for class for driving TM1638 LED controller as used in LKM1638
+   *
+   * @brief Supports 8 Digits of 7 Segments + DP Icons. Also supports 8 Bi-Color LEDs and a scanned keyboard of 8 keys.
+   *  
+   * @param  PinName mosi, miso, sclk, cs SPI bus pins
+   */
+  TM1638_LKM1638(PinName mosi, PinName miso, PinName sclk, PinName cs);
+
+#if DOXYGEN_ONLY
+    /** Write a character to the Display
+     *
+     * @param c The character to write to the display
+     */
+    int putc(int c);
+
+    /** Write a formatted string to the Display
+     *
+     * @param format A printf-style format string, followed by the
+     *               variables to use in formatting the string.
+     */
+    int printf(const char* format, ...);   
+#endif
+
+     /** Locate cursor to a screen column
+     *
+     * @param column  The horizontal position from the left, indexed from 0
+     */
+    void locate(int column);
+    
+    /** Clear the screen and locate to 0
+     * @param bool clrAll Clear Icons also (default = false)
+     */
+    void cls(bool clrAll = false);
+
+    /** Set Icon
+     *
+     * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+     * @return none
+     */
+    void setIcon(Icon icon);
+
+    /** Clr Icon
+     *
+     * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+     * @return none
+     */
+    void clrIcon(Icon icon);
+
+   /** Set User Defined Characters (UDC)
+     *
+     * @param unsigned char udc_idx   The Index of the UDC (0..7)
+     * @param int udc_data            The bitpattern for the UDC (16 bits)       
+     */
+    void setUDC(unsigned char udc_idx, int udc_data);
+
+
+   /** Number of screen columns
+    *
+    * @param none
+    * @return columns
+    */
+    int columns();   
+
+   /** Write databyte to TM1638
+     *  @param  char data byte written at given address   
+     *  @param  int address display memory location to write byte
+     *  @return none
+     */ 
+    void writeData(char data, int address){
+      TM1638::writeData(data, address);
+    }        
+
+   /** Write Display datablock to TM1638
+    *  @param  DisplayData_t data Array of TM1638_DISPLAY_MEM (=16) bytes for displaydata
+    *  @param  length number bytes to write (valid range 0..(LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID) (=16), when starting at address 0)  
+    *  @param  int address display memory location to write bytes (default = 0) 
+    *  @return none
+    */   
+    void writeData(DisplayData_t data, int length = (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID), int address = 0) {
+      TM1638::writeData(data, length, address);
     }  
 
 protected:  
diff -r 25ddabfadc8c -r b2bbdc58967e TM1638_Config.h
--- a/TM1638_Config.h	Tue Jan 19 18:58:22 2016 +0000
+++ b/TM1638_Config.h	Sun Jan 31 12:11:06 2016 +0000
@@ -1,6 +1,7 @@
 /* mbed TM1638 Library, for TM1638 LEDcontroller
  * Copyright (c) 2015, v01: WH, Initial version
  *               2016, v02: WH, Added ASCII alphabet display selector
+ *               2016, v03: WH, Added QYF-TM1638 and LKM1638
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -27,7 +28,9 @@
 // Select one of the testboards for TM1638 LED controller
 #define TM1638_TEST  0
 #define LEDKEY8_TEST 1 
-
+#define QYF_TEST     0 
+#define LKM1638_TEST 0 
+ 
 // Select the display mode: only digits and hex or ASCII
 #define SHOW_ASCII   1