Princeton PT6964 LED controller supports 4 Digits @ 13 Segments, 5 Digits @ 12 Segments, 6 Digits @ 11 Segments or 7 Digits @ 10 Segments. Also supports a scanned keyboard of upto 20 keys. SPI bus interface.

Dependents:   mbed_PT6964

Princeton PT6964 LED controller supports 4 Digits @ 13 Segments, 5 Digits @ 12 Segments, 6 Digits @ 11 Segments or 7 Digits @ 10 Segments. Also supports a scanned keyboard of upto 20 keys. SPI bus interface.

See Component page here.

Files at this revision

API Documentation at this revision

Comitter:
wim
Date:
Sat Nov 21 16:43:15 2015 +0000
Child:
1:1adf993a3e34
Commit message:
First version

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
PT6964.cpp Show annotated file Show diff for this revision Revisions of this file
PT6964.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Font_7Seg.cpp	Sat Nov 21 16:43:15 2015 +0000
@@ -0,0 +1,49 @@
+/* mbed LED Font Library, for Princeton PT6964 controller as used in DVD538A
+ * Copyright (c) 2015, v01: WH, Initial version
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "Font_7Seg.h"
+
+// ASCII Font definition table for transmission to PT6964
+//
+//#define FONT_7S_START     0x20
+//#define FONT_7S_END       0x7F
+//#define FONT_7S_NR_CHARS (FONT_7_END - FONT_7S_START + 1)
+ 
+const char FONT_7S[][2] = { 
+                             {LO(C_0), HI(C_0)}, //48 0x30
+                             {LO(C_1), HI(C_1)},
+                             {LO(C_2), HI(C_2)},
+                             {LO(C_3), HI(C_3)},
+                             {LO(C_4), HI(C_4)},                   
+                             {LO(C_5), HI(C_5)},
+                             {LO(C_6), HI(C_6)},
+                             {LO(C_7), HI(C_7)},
+                             {LO(C_8), HI(C_8)},
+                             {LO(C_9), HI(C_9)},
+                             {LO(C_A), HI(C_A)}, //65 0x41, A
+                             {LO(C_B), HI(C_B)},
+                             {LO(C_C), HI(C_C)},
+                             {LO(C_D), HI(C_D)},
+                             {LO(C_E), HI(C_E)},
+                             {LO(C_F), HI(C_F)}
+                                                 };// 127                             
+  
+ 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Font_7Seg.h	Sat Nov 21 16:43:15 2015 +0000
@@ -0,0 +1,93 @@
+/* mbed LED Font Library, for Princeton PT6964 controller as used in DVD538A
+ * Copyright (c) 2015, v01: WH, Initial version
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef MBED_FONT_7SEG_H
+#define MBED_FONT_7SEG_H
+
+// Segment bit positions for 7 Segment display using the DVD538A mapping for PT6964
+// 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.
+//
+#define S_D    0x0008 
+#define S_C    0x0010
+#define S_B    0x0020
+#define S_A    0x0040 
+#define S_E    0x0080
+#define S_F    0x0100
+#define S_G    0x0200
+
+#define S_LD2  0x0001
+#define S_LD1  0x0002
+#define S_CD   0x0008
+#define S_DVD  0x0010
+#define S_PSE  0x0020
+#define S_PLY  0x0040
+#define S_COL  0x0080
+#define S_MP4  0x0100
+#define S_MP3  0x0200
+
+//Mask for blending out and restoring Icons
+//One mask pattern will be sufficient assuming that all digits use the same mapping.
+#define S_ICON_MSK (0x0000)
+
+
+// ASCII Font definitions for segments in each character
+//
+//48 0x30 digits
+#define C_0    (S_A | S_B | S_C | S_D | S_E | S_F)
+#define C_1    (S_B | S_C)
+#define C_2    (S_A | S_B | S_D | S_E | S_G)
+#define C_3    (S_A | S_B | S_C | S_D | S_G)
+#define C_4    (S_B | S_C | S_F | S_G)
+#define C_5    (S_A | S_C | S_D | S_F | S_G)
+#define C_6    (S_A | S_C | S_D | S_E | S_F | S_G)
+#define C_7    (S_A | S_B | S_C)
+#define C_8    (S_A | S_B | S_C | S_D | S_E | S_F | S_G)
+#define C_9    (S_A | S_B | S_C | S_D | S_F | S_G)
+//64 0x40
+#define C_A    (S_A | S_B | S_C | S_E | S_F | S_G )  // Upper case alphabet
+#define C_B    (S_C | S_D | S_E | S_F | S_G)
+#define C_C    (S_A | S_D | S_E | S_F)
+#define C_D    (S_B | S_C | S_D | S_E | S_G)
+#define C_E    (S_A | S_D | S_E | S_F | S_G)
+#define C_F    (S_A | S_E | S_F | S_G)
+//97 0x61
+#define C_a    (S_A | S_B | S_C | S_E | S_F | S_G )  // Lower case alphabet
+#define C_b    (S_C | S_D | S_E | S_F | S_G)
+#define C_c    (S_A | S_D | S_E | S_F)
+#define C_d    (S_B | S_C | S_D | S_E | S_G)
+#define C_e    (S_A | S_D | S_E | S_F | S_G)
+#define C_f    (S_A | S_E | S_F | S_G)
+
+// Font data selection for transmission to PT6964 memory
+#define LO(x)  ( x & 0xFF)
+#define HI(x)  ((x >> 8) & 0xFF)
+
+
+// ASCII Font definition table
+//
+//#define FONT_7S_START     0x20
+//#define FONT_7S_END       0x7F
+//#define FONT_7S_NR_CHARS (FONT_7S_END - FONT_7S_START + 1)
+extern const char FONT_7S[][2]; 
+
+#endif 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PT6964.cpp	Sat Nov 21 16:43:15 2015 +0000
@@ -0,0 +1,439 @@
+/* mbed PT6964 Library, for PT6964 LED controller
+ * Copyright (c) 2015, v01: WH, Initial version
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "mbed.h" 
+#include "PT6964.h"
+#include "Font_7Seg.h"
+
+/** Constructor for class for driving PT6964 LED controller with SPI bus interface device. 
+ *  Note: the PT6964 is also available from other chipvendors eg AIP1628, HT1628, CM1628, SM1628
+ *  @brief Supports 4 digits @ 13 segments or 5 digits @ 12 segments or 6 Digits @ 11 Segments or 7 Digits @ 10 Segments. 
+ *         Also supports a scanned keyboard of upto 20 keys.
+ *   
+ *  @param  PinName mosi, miso, sclk, cs SPI bus pins
+ *  @param  Mode selects either 6 Digits of 12 Segments or 7 Digits of 10 Segments (default) 
+*/
+PT6964::PT6964(PinName mosi, PinName miso, PinName sclk, PinName cs, Mode mode) : _spi(mosi,miso,sclk), _cs(cs), _mode(mode) {
+
+  _init();
+}
+
+/** Init the SPI interface and the controller
+  * @param  none
+  * @return none
+  */ 
+void PT6964::_init(){
+  
+//init SPI
+  _cs=1;
+  _spi.format(8,3); //PT6964 uses mode 3 (Clock High on Idle, Data latched on second (=rising) edge)
+  _spi.frequency(500000);   
+
+//init controller  
+  _writeCmd(PT6964_MODE_SET_CMD, _mode);                                               // Mode set command 
+
+  _display = PT6964_DSP_ON;
+  _bright  = PT6964_BRT_DEF; 
+  _writeCmd(PT6964_DSP_CTRL_CMD, _display | _bright );                                 // Display control cmd, display on/off, brightness   
+  
+  _writeCmd(PT6964_DATA_SET_CMD, PT6964_DATA_WR | PT6964_ADDR_INC | PT6964_MODE_NORM); // Data set cmd, normal mode, auto incr, write data  
+}   
+
+
+/** Clear the screen and locate to 0
+ */  
+void PT6964::cls() {
+  
+  _cs=0;
+  wait_us(1);    
+  _spi.write(_flip(PT6964_ADDR_SET_CMD | 0x00)); // Address set cmd, 0
+      
+  for (int cnt=0; cnt<PT6964_DISPLAY_MEM; cnt++) {
+    _spi.write(0x00); // data 
+  }
+  
+  wait_us(1);
+  _cs=1;      
+}  
+
+/** Set Brightness
+  *
+  * @param  char brightness (3 significant bits, valid range 0..7 (1/16 .. 14/14 dutycycle)  
+  * @return none
+  */
+void PT6964::setBrightness(char brightness){
+
+  _bright = brightness & PT6964_BRT_MSK; // mask invalid bits
+  
+  _writeCmd(PT6964_DSP_CTRL_CMD, _display | _bright );  // Display control cmd, display on/off, brightness  
+}
+
+/** Set the Display mode On/off
+  *
+  * @param bool display mode
+  */
+void PT6964::setDisplay(bool on) {
+  
+  if (on) {
+    _display = PT6964_DSP_ON;
+  }
+  else {
+   _display = PT6964_DSP_OFF;
+  }
+  
+  _writeCmd(PT6964_DSP_CTRL_CMD, _display | _bright );  // Display control cmd, display on/off, brightness   
+}
+
+/** Write databyte to PT6964
+  *  @param  int address display memory location to write byte
+  *  @param  char data byte written at given address
+  *  @return none
+  */ 
+void PT6964::writeData(int address, char data) {
+  _cs=0;
+  wait_us(1);    
+  _spi.write(_flip(PT6964_ADDR_SET_CMD | (address & PT6964_ADDR_MSK))); // Set Address cmd
+      
+  _spi.write(_flip(data)); // data 
+  
+  wait_us(1);
+  _cs=1;             
+}
+
+/** Write Display datablock to PT6964
+  *  @param  DisplayData_t data Array of PT6964_DISPLAY_MEM (=14) bytes for displaydata (starting at address 0)
+  *  @param  length number bytes to write (valide range 0..PT6964_DISPLAY_MEM (=14), starting at address 0)     
+  *  @return none
+  */ 
+void PT6964::writeData(DisplayData_t data, int length) {
+  _cs=0;
+  wait_us(1);    
+  _spi.write(_flip(PT6964_ADDR_SET_CMD | 0x00)); // Set Address at 0
+      
+// sanity check
+  if (length < 0) {length = 0;}
+  if (length > PT6964_DISPLAY_MEM) {length = PT6964_DISPLAY_MEM;}
+
+//  for (int idx=0; idx<PT6964_DISPLAY_MEM; idx++) {  
+  for (int idx=0; idx<length; idx++) {    
+    _spi.write(_flip(data[idx])); // data 
+  }
+  
+  wait_us(1);
+  _cs=1;             
+}
+
+
+/** Read keydata block from PT6964
+  *  @param  *keydata Ptr to Array of PT6964_KEY_MEM (=5) bytes for keydata
+  *  @return bool keypress True when at least one key was pressed
+  *
+  * Note: Due to the hardware configuration the PT6964 key matrix scanner will detect multiple keys pressed at same time,
+  *       but this may also result in some spurious keys being set in keypress data array.
+  *       It may be best to ignore all keys in those situations. That option is implemented in this method depending on #define setting.  
+  */ 
+bool PT6964::getKeys(KeyData_t *keydata) {
+  int keypress = 0;
+  char data;
+
+  // Read keys
+  _cs=0;
+  wait_us(1);    
+  
+  // Enable Key Read mode
+  _spi.write(_flip(PT6964_DATA_SET_CMD | PT6964_KEY_RD | PT6964_ADDR_INC | PT6964_MODE_NORM)); // Data set cmd, normal mode, auto incr, read data
+
+  for (int idx=0; idx < PT6964_KEY_MEM; idx++) {
+    data = _flip(_spi.write(0xFF));    // read keys and correct bitorder
+
+    if (data != 0) {  // Check for any pressed key
+      for (int bit=0; bit < PT6964_KEY_BITS; bit++) {
+        if (data & (1 << bit)) {keypress++;} // Test all significant bits
+      }
+    }  
+
+    (*keydata)[idx] = data;            // Store keydata after correcting bitorder
+  }
+
+  wait_us(1);
+  _cs=1;    
+
+  // Restore Data Write mode
+  _writeCmd(PT6964_DATA_SET_CMD, PT6964_DATA_WR | PT6964_ADDR_INC | PT6964_MODE_NORM); // Data set cmd, normal mode, auto incr, write data  
+      
+#if(1)
+// Dismiss multiple keypresses at same time
+  return (keypress == 1);    
+#else
+// Allow multiple keypress and accept possible spurious keys
+  return (keypress > 0);
+#endif  
+}
+    
+
+/** Helper to reverse all command or databits. The PT6964 expects LSB first, whereas SPI is MSB first
+  *  @param  char data
+  *  @return bitreversed data
+  */ 
+char PT6964::_flip(char data) {
+ char value=0;
+  
+ if (data & 0x01) {value |= 0x80;} ;  
+ if (data & 0x02) {value |= 0x40;} ;
+ if (data & 0x04) {value |= 0x20;} ;
+ if (data & 0x08) {value |= 0x10;} ;
+ if (data & 0x10) {value |= 0x08;} ;
+ if (data & 0x20) {value |= 0x04;} ;
+ if (data & 0x40) {value |= 0x02;} ;
+ if (data & 0x80) {value |= 0x01;} ;
+ return value;       
+}
+
+
+/** Write command and parameter to PT6964
+  *  @param  int cmd Command byte
+  *  &Param  int data Parameters for command
+  *  @return none
+  */  
+void PT6964::_writeCmd(int cmd, int data){
+    
+  _cs=0;
+  wait_us(1);    
+//  _spi.write(_flip( (cmd & 0xF0) | (data & 0x0F)));  
+  _spi.write(_flip( (cmd & PT6964_CMD_MSK) | (data & ~PT6964_CMD_MSK)));   
+ 
+  wait_us(1);
+  _cs=1;          
+}  
+
+
+
+
+/** Constructor for class for driving Princeton PT6964 controller as used in DVD538A
+  *
+  *  @brief Supports 4 Digits of 7 Segments, 1 Grid of 9 Icons. Also supports a scanned keyboard of 4.
+  *   
+  *  @param  PinName mosi, miso, sclk, cs SPI bus pins
+  */
+PT6964_DVD538A::PT6964_DVD538A(PinName mosi, PinName miso, PinName sclk, PinName cs) : PT6964(mosi, miso, sclk, cs, Grid7_Seg10) {
+  _column  = 0;
+  _columns = DVD538A_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 PT6964_DVD538A::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 PT6964_DVD538A::columns() {
+    return _columns;
+}
+
+    
+/** Clear the screen and locate to 0
+  */
+void PT6964_DVD538A::cls() {
+  
+#if(0)
+  //clear local buffer (including Icons)
+  for (int idx = 0; idx < DVD538A_NR_GRIDS; idx++) {
+    _displaybuffer[(idx<<1)]     = 0x00;  
+    _displaybuffer[(idx<<1) + 1] = 0x00;      
+  }
+#else
+  //clear local buffer (preserving Icons)
+  for (int idx = DVD538A_DIG1_IDX; idx < (DVD538A_DIG1_IDX + DVD538A_NR_DIGITS); idx++) {    
+    _displaybuffer[(idx<<1)]     = _displaybuffer[(idx<<1)]     & LO(S_ICON_MSK);  
+    _displaybuffer[(idx<<1) + 1] = _displaybuffer[(idx<<1) + 1] & HI(S_ICON_MSK);      
+  }
+#endif  
+
+  writeData(_displaybuffer, (DVD538A_NR_GRIDS*2));
+
+  _column = 0;   
+}    
+
+/** Set Icon
+  *
+  * @param Icon icon Enums Icon has Grid position encoded in 16 MSBs, Icon pattern encoded in 16 LSBs
+  * @return none
+  */
+void PT6964_DVD538A::setIcon(Icon icon) {
+  int addr, icn;
+
+   icn =         icon  & 0xFFFF;
+  addr = ((icon >> 16) & 0xFFFF) - 1; 
+    
+  //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, (DVD538A_NR_GRIDS*2));
+}
+
+/** Clr Icon
+  *
+  * @param Icon icon Enums Icon has Grid position encoded in 16 MSBs, Icon pattern encoded in 16 LSBs
+  * @return none
+  */
+void PT6964_DVD538A::clrIcon(Icon icon) {
+  int addr, icn;
+
+   icn =         icon  & 0xFFFF;
+  addr = ((icon >> 16) & 0xFFFF) - 1; 
+    
+  //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, (DVD538A_NR_GRIDS*2));
+}
+
+
+/** 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 PT6964_DVD538A::setUDC(unsigned char udc_idx, int udc_data) {
+
+  //Sanity check
+  if (udc_idx > (DVD538A_NR_UDC-1)) {
+    return;
+  }
+  // Mask out Icon bits?
+
+  _UDC_16S[udc_idx][0] = LO(udc_data);
+  _UDC_16S[udc_idx][1] = HI(udc_data);
+}
+
+/** Write a single character (Stream implementation)
+  */
+int PT6964_DVD538A::_putc(int value) {
+  int addr;
+    
+    if ((value == '\n') || (value == '\r')) {
+      //No character to write
+      
+      //Update Cursor      
+      _column = 0;
+    }
+    else if ((value >= 0) && (value < DVD538A_NR_UDC)) {
+      //Character to write
+      addr = (DVD538A_DIG1_IDX + ((DVD538A_NR_DIGITS - 1) - _column)) << 1; 
+      
+      //Save icons...and set bits for character to write
+      _displaybuffer[addr]   = (_displaybuffer[addr]   & LO(S_ICON_MSK)) | _UDC_16S[value][0];      
+      _displaybuffer[addr+1] = (_displaybuffer[addr+1] & HI(S_ICON_MSK)) | _UDC_16S[value][1];      
+      writeData(_displaybuffer, (DVD538A_NR_GRIDS*2));
+               
+      //Update Cursor
+      _column++;
+      if (_column > (DVD538A_NR_DIGITS - 1)) {
+        _column = 0;
+      }          
+    }  
+    else if ((value >= (int)'0') && (value <= (int) '9')) {   
+      //Character to write
+      value = value - (int) '0';
+      addr = (DVD538A_DIG1_IDX + ((DVD538A_NR_DIGITS - 1) - _column)) << 1; 
+      
+      //Save icons...and set bits for character to write
+      _displaybuffer[addr]   = (_displaybuffer[addr]   & LO(S_ICON_MSK)) | FONT_7S[value][0];      
+      _displaybuffer[addr+1] = (_displaybuffer[addr+1] & HI(S_ICON_MSK)) | FONT_7S[value][1];      
+      writeData(_displaybuffer, (DVD538A_NR_GRIDS*2));
+               
+      //Update Cursor
+      _column++;
+      if (_column > (DVD538A_NR_DIGITS - 1)) {
+        _column = 0;
+      }
+    }            
+    else if ((value >= (int) 'A') && (value <= (int) 'F')) {   
+      //Character to write
+      value = 10 + value - (int) 'A';
+      addr = (DVD538A_DIG1_IDX + ((DVD538A_NR_DIGITS - 1) - _column)) << 1; 
+      
+      //Save icons...and set bits for character to write
+      _displaybuffer[addr]   = (_displaybuffer[addr]   & LO(S_ICON_MSK)) | FONT_7S[value][0];      
+      _displaybuffer[addr+1] = (_displaybuffer[addr+1] & HI(S_ICON_MSK)) | FONT_7S[value][1];      
+      writeData(_displaybuffer, (DVD538A_NR_GRIDS*2));
+               
+      //Update Cursor
+      _column++;
+      if (_column > (DVD538A_NR_DIGITS - 1)) {
+        _column = 0;
+      }
+    }  
+    else if ((value >= (int) 'a') && (value <= (int) 'f')) {   
+      //Character to write
+      value = 10 + value - (int) 'a';
+      addr = (DVD538A_DIG1_IDX + ((DVD538A_NR_DIGITS - 1) - _column)) << 1; 
+      
+      //Save icons...and set bits for character to write
+      _displaybuffer[addr]   = (_displaybuffer[addr]   & LO(S_ICON_MSK)) | FONT_7S[value][0];      
+      _displaybuffer[addr+1] = (_displaybuffer[addr+1] & HI(S_ICON_MSK)) | FONT_7S[value][1];      
+      writeData(_displaybuffer, (DVD538A_NR_GRIDS*2));
+               
+      //Update Cursor
+      _column++;
+      if (_column > (DVD538A_NR_DIGITS - 1)) {
+        _column = 0;
+      }          
+
+    } //else
+
+    return value;
+}
+
+
+// get a single character (Stream implementation)
+int PT6964_DVD538A::_getc() {
+    return -1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PT6964.h	Sat Nov 21 16:43:15 2015 +0000
@@ -0,0 +1,338 @@
+/* mbed PT6964 Library, for PT6964 LED controller
+ * Copyright (c) 2015, v01: WH, Initial version
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef PT6964_H
+#define PT6964_H
+
+#include "Font_7Seg.h"
+
+/** An interface for driving PT6964 LED controller
+ *
+ * @code
+ * #include "mbed.h"
+ * #include "PT6964.h" 
+ * 
+ * DisplayData_t size is  8 bytes (4 grids @ 13 segments) OR 10 bytes (5 grids @ 12 segments) OR
+ *                       12 bytes (6 grids @ 11 segments) OR 14 bytes (7 grids @ 10 segments) 
+ * PT6964::DisplayData_t mbed_str = {0xDA,0x00, 0x7C,0x00, 0x3C,0x01, 0xF6,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00};  
+ * PT6964::DisplayData_t all_str  = {0xFF,0x0F, 0xFF,0x0F, 0xFF,0x0F, 0xFF,0x0F, 0xFF,0x0F, 0xFF,0x0F, 0xFF,0x0F};  
+ *
+ * // KeyData_t size is 5 bytes  
+ * PT6964::KeyData_t keydata; 
+ *
+ * // PT6964 declaration, Default setting 7 Grids @ 10 Segments
+ * PT6964 PT6964(p5,p6,p7, p8);
+ *
+ * int main() {
+ *   PT6964.cls(); 
+ *   PT6964.writeData(all_str);
+ *   wait(4);
+ *   PT6964.writeData(mbed_str);    
+ *   wait(1);
+ *   PT6964.setBrightness(PT6964_BRT0);
+ *   wait(1);
+ *   PT6964.setBrightness(PT6964_BRT3);
+ *
+ *   while (1) {
+ *    // Check and read keydata
+ *    if (PT6964.getKeys(&keydata)) {
+ *      pc.printf("Keydata 0..4 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\r\n", keydata[0], keydata[1], keydata[2], keydata[3], keydata[4]);
+ *
+ *      if (keydata[0] == 0x10) { //sw2   
+ *        PT6964.cls(); 
+ *        PT6964.writeData(all_str);
+ *      }  
+ *    } 
+ *   }   
+ * }
+ * @endcode
+ */
+
+//Memory size in bytes for Display and Keymatrix
+#define PT6964_DISPLAY_MEM    14
+#define PT6964_KEY_MEM         5
+//Significant bits Keymatrix data
+#define PT6964_KEY_BITS        5 
+
+//Reserved bits for commands
+#define PT6964_CMD_MSK      0xC0
+
+//Mode setting command
+#define PT6964_MODE_SET_CMD 0x00
+#define PT6964_GR4_SEG13    0x00
+#define PT6964_GR5_SEG12    0x01
+#define PT6964_GR6_SEG11    0x02
+#define PT6964_GR7_SEG10    0x03 //default
+
+//Data setting commands
+#define PT6964_DATA_SET_CMD 0x40
+#define PT6964_DATA_WR      0x00
+#define PT6964_KEY_RD       0x02
+#define PT6964_ADDR_INC     0x00
+#define PT6964_ADDR_FIXED   0x04
+#define PT6964_MODE_NORM    0x00
+#define PT6964_MODE_TEST    0x08
+
+//Address setting commands
+#define PT6964_ADDR_SET_CMD 0xC0
+#define PT6964_ADDR_MSK     0x0F
+
+//Display control commands
+#define PT6964_DSP_CTRL_CMD 0x80
+#define PT6964_BRT_MSK      0x07
+#define PT6964_BRT0         0x00 //Pulsewidth 1/16
+#define PT6964_BRT1         0x01
+#define PT6964_BRT2         0x02
+#define PT6964_BRT3         0x03
+#define PT6964_BRT4         0x04
+#define PT6964_BRT5         0x05
+#define PT6964_BRT6         0x06
+#define PT6964_BRT7         0x07 //Pulsewidth 14/16
+
+#define PT6964_BRT_DEF      PT6964_BRT3
+
+#define PT6964_DSP_OFF      0x00
+#define PT6964_DSP_ON       0x08
+
+
+/** A class for driving Princeton PT6964 LED controller
+ *  Note: the PT6964 is also available from other chipvendors eg AIP1628, HT1628, CM1628, SM1628
+ *
+ * @brief Supports 4 Grids @ 13 Segments or 5 Grids @ 12 Segments or 6 Grids @ 11 Segments or 7 Grids @ 10 Segments. 
+ *        Also supports a scanned keyboard of upto 20 keys.
+ *        SPI bus interface device. 
+ */
+class PT6964 {
+ public:
+
+  /** Enums for display mode */
+  enum Mode {
+    Grid4_Seg13 = PT6964_GR4_SEG13,
+    Grid5_Seg12 = PT6964_GR5_SEG12,   
+    Grid6_Seg11 = PT6964_GR6_SEG11,
+    Grid7_Seg10 = PT6964_GR7_SEG10
+  };
+  
+  /** Datatypes for display and keymatrix data */
+  typedef char DisplayData_t[PT6964_DISPLAY_MEM];
+  typedef char KeyData_t[PT6964_KEY_MEM];
+    
+ /** Constructor for class for driving Princeton PT6964 LED controller
+  *
+  * @brief Supports 4 Grids @ 13 segments or 5 Grids @ 12 segments or 6 Grids @ 11 Segments or 7 Grids @ 10 Segments. 
+  *        Also supports a scanned keyboard of upto 20 keys.
+  *        SPI bus interface device. 
+  *
+  *  @param  PinName mosi, miso, sclk, cs SPI bus pins
+  *  @param  Mode selects either Grids/Segments (default 7 Grids @ 10 Segments)
+  */
+  PT6964(PinName mosi, PinName miso, PinName sclk, PinName cs, Mode mode=Grid7_Seg10);
+      
+  /** Clear the screen and locate to 0
+   */ 
+  void cls();  
+
+  /** Write databyte to PT6964
+   *  @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); 
+ 
+ /** Write Display datablock to PT6964
+   *  @param  DisplayData_t data Array of PT6964_DISPLAY_MEM (=14) bytes for displaydata (starting at address 0)
+   *  @param  length number bytes to write (valid range 0..PT6964_DISPLAY_MEM (=14), starting at address 0)   
+   *  @return none
+   */   
+  void writeData(DisplayData_t data, int length = PT6964_DISPLAY_MEM);
+
+  /** Read keydata block from PT6964
+   *  @param  *keydata Ptr to Array of PT6964_KEY_MEM (=5) bytes for keydata
+   *  @return bool keypress True when at least one key was pressed
+   *
+   * Note: Due to the hardware configuration the PT6964 key matrix scanner will detect multiple keys pressed at same time,
+   *       but this may result in some spurious keys also being set in keypress data array.
+   *       It may be best to ignore all keys in those situations. That option is implemented in this method depending on #define setting.
+   */   
+  bool getKeys(KeyData_t *keydata);
+
+  /** Set Brightness
+    *
+    * @param  char brightness (3 significant bits, valid range 0..7 (1/16 .. 14/14 dutycycle)  
+    * @return none
+    */
+  void setBrightness(char brightness = PT6964_BRT_DEF);
+  
+  /** Set the Display mode On/off
+    *
+    * @param bool display mode
+    */
+  void setDisplay(bool on);
+  
+ private:  
+  SPI _spi;
+  DigitalOut _cs;
+  Mode _mode;
+  char _display;
+  char _bright; 
+  
+  /** Init the SPI interface and the controller
+    * @param  none
+    * @return none
+    */ 
+  void _init();
+
+  /** Helper to reverse all command or databits. The PT6964 expects LSB first, whereas SPI is MSB first
+    *  @param  char data
+    *  @return bitreversed data
+    */ 
+  char _flip(char data);
+
+  /** Write command and parameter to PT6964
+    *  @param  int cmd Command byte
+    *  &Param  int data Parameters for command
+    *  @return none
+    */ 
+  void _writeCmd(int cmd, int data);  
+};
+
+
+
+// Derived class for PT6964 used in DVD-538A front display unit
+//
+
+#define DVD538A_NR_GRIDS  5
+#define DVD538A_NR_DIGITS 4
+#define DVD538A_DIG1_IDX  1
+#define DVD538A_NR_UDC    8
+
+/** Constructor for class for driving Princeton PT6964 controller as used in DVD538A
+  *
+  *  @brief Supports 4 Digits of 7 Segments, 1 Grid of 9 Icons. Also supports a scanned keyboard of 4 keys.
+  *  
+  *  @param  PinName mosi, miso, sclk, cs SPI bus pins
+  */
+class PT6964_DVD538A : public PT6964, public Stream {
+ public:
+
+  /** Enums for Icons */
+  //  Grid encoded in 16 MSBs, Icon pattern encoded in 16 LSBs
+  enum Icon {
+    Grid1_LD1  = (1<<16) | S_LD1,
+    Grid1_LD2  = (1<<16) | S_LD2,
+    Grid1_CD   = (1<<16) | S_CD,
+    Grid1_DVD  = (1<<16) | S_DVD,
+    Grid1_PSE  = (1<<16) | S_PSE,
+    Grid1_PLY  = (1<<16) | S_PLY,    
+    Grid1_COL  = (1<<16) | S_COL,
+    Grid1_MP4  = (1<<16) | S_MP4,
+    Grid1_MP3  = (1<<16) | S_MP3    
+  };
+  
+  typedef char UDCData_t[DVD538A_NR_UDC][2];
+  
+ /** Constructor for class for driving Princeton PT6964 VFD controller as used in DVD538A
+   *
+   * @brief Supports 4 Digits of 7 Segments, 1 Grid of 9 Icons. Also supports a scanned keyboard of 4 keys.
+   *  
+   * @param  PinName mosi, miso, sclk, cs SPI bus pins
+   */
+  PT6964_DVD538A(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
+     */
+    void cls();
+
+    /** Set Icon
+     *
+     * @param Icon icon Enums Icon has Grid position encoded in 16 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 16 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 Display datablock to PT6964
+    *  @param  DisplayData_t data Array of PT6964_DISPLAY_MEM (=14) bytes for displaydata (starting at address 0)
+    *  @param  length number bytes to write (valid range 0..(DVD538A_NR_GRIDS*2) (=14), starting at address 0)   
+    *  @return none
+    */   
+    void writeData(DisplayData_t data, int length = (DVD538A_NR_GRIDS*2)) {
+      PT6964::writeData(data, length);
+    }  
+
+protected:  
+    // Stream implementation functions
+    virtual int _putc(int value);
+    virtual int _getc();
+
+private:
+    int _column;
+    int _columns;   
+    
+    DisplayData_t _displaybuffer;
+    UDCData_t _UDC_16S; 
+};
+
+
+#endif
\ No newline at end of file