Library for Princeton PT6961 LED driver. Supports 6 digits @ 12 segments or 7 digits @ 11 segments. Also supports keyboard scanning of upto 30 keys. SPI interface.

Dependents:   mbed_PT6961

This LED driver is found in frontpanel controllers of consumer electronics such as DVD players. The added features such as the matrix keyboard scanning are useful in these applications.

Additional information is available on the component page here

PT6961.h

Committer:
wim
Date:
2016-01-14
Revision:
2:c6883ede8d8b
Parent:
1:eb4758bba68a

File content as of revision 2:c6883ede8d8b:

/* mbed PT6961 Library, for Princeton PT6961 LED controller
 * Copyright (c) 2015, v01: WH, Initial version (HR734)
 *               2015, v02: WH, rename Digit/Grid
 *               2016, v02: WH, Added V56S, Added Stream support
 *               2016, v03: WH, Refactored display and keyboard defines  
 *
 * 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 PT6961_H
#define PT6961_H

// Select one of the testboards for Princeton PT6312 VFD controller
#include "PT6961_Config.h"

/** An interface for driving Princeton PT6961 LED controller
 *  Note: Also available are derived Classes for V56S and HR734 displays that have added Stream support.
 *
 * @code
 * #include "mbed.h"
 * #include "PT6961.h" 
 * 
 * // DisplayData_t size is 12 bytes (6 Grids max 12 Segments) OR 14 bytes (7 Grids at max 11 Segments) 
 * PT6961::DisplayData_t mbed_str = {0xDA,0x00, 0x7C,0x00, 0x3C,0x01, 0xF6,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00};  
 * PT6961::DisplayData_t all_str  = {0xFF,0x0F, 0xFF,0x0F, 0xFF,0x0F, 0xFF,0x0F, 0xFF,0x0F, 0xFF,0x0F, 0xFF,0x0F};  
 *
 * // KeyData_t size is 5 bytes  
 * PT6961::KeyData_t keydata; 
 *
 * // PT6191 declaration, Default setting 7 Grids, 11 Segments
 * PT6961 pt6961(p5,p6,p7, p8);
 *
 * int main() {
 *   pt6961.cls(); 
 *   pt6961.writeData(all_str);
 *   wait(4);
 *   pt6961.writeData(mbed_str);    
 *   wait(1);
 *   pt6961.setBrightness(PT6961_BRT0);
 *   wait(1);
 *   pt6961.setBrightness(PT6961_BRT3);
 *
 *   while (1) {
 *    // Check and read keydata
 *    if (pt6961.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   
 *        pt6961.cls(); 
 *        pt6961.writeData(all_str);
 *      }  
 *    } 
 *   }   
 * }
 * @endcode
 */


//PT6961 Display and Keymatrix data
#define PT6961_MAX_NR_GRIDS    7
#define PT6961_BYTES_PER_GRID  2
//Significant bits Keymatrix data
#define PT6961_KEY_MSK      0x3F 

//Memory size in bytes for Display and Keymatrix
#define PT6961_DISPLAY_MEM  (PT6961_MAX_NR_GRIDS * PT6961_BYTES_PER_GRID)
#define PT6961_KEY_MEM         5


//Reserved bits for commands
#define PT6961_CMD_MSK      0xE0

//Mode setting command
#define PT6961_MODE_SET_CMD 0x00
#define PT6961_GR6_SEG12    0x02
#define PT6961_GR7_SEG11    0x03 //default

//Data setting commands
#define PT6961_DATA_SET_CMD 0x40
#define PT6961_DATA_WR      0x00
#define PT6961_KEY_RD       0x02
#define PT6961_ADDR_INC     0x00
#define PT6961_ADDR_FIXED   0x04
#define PT6961_MODE_NORM    0x00
#define PT6961_MODE_TEST    0x08

//Address setting commands
#define PT6961_ADDR_SET_CMD 0xC0
#define PT6961_ADDR_MSK     0x0F

//Display control commands
#define PT6961_DSP_CTRL_CMD 0x80
#define PT6961_BRT_MSK      0x07
#define PT6961_BRT0         0x00 //Pulsewidth 1/16
#define PT6961_BRT1         0x01
#define PT6961_BRT2         0x02
#define PT6961_BRT3         0x03
#define PT6961_BRT4         0x04
#define PT6961_BRT5         0x05
#define PT6961_BRT6         0x06
#define PT6961_BRT7         0x07 //Pulsewidth 14/16

#define PT6961_BRT_DEF      PT6961_BRT3

#define PT6961_DSP_OFF      0x00
#define PT6961_DSP_ON       0x08


/** A class for driving Princeton PT6961 LED controller
 *
 * @brief Supports 6 Grids of 12 Segments or 7 Grids of 11 Segments. Also supports a scanned keyboard of upto 30 keys.
 *        SPI bus interface device. 
 */
class PT6961 {
 public:

  /** Enums for display mode */
  enum Mode {
    Grid6_Seg12 = PT6961_GR6_SEG12,
    Grid7_Seg11 = PT6961_GR7_SEG11
  };
  
  /** Datatypes for display and keymatrix data */
  typedef char DisplayData_t[PT6961_DISPLAY_MEM];
  typedef char KeyData_t[PT6961_KEY_MEM];
    
 /** Constructor for class for driving Princeton PT6961 LED controller
  *
  * @brief Supports 6 Grids @ 12 Segments or 7 Grids @ 11 Segments. Also supports a scanned keyboard of upto 30 keys.
  *        SPI bus interface device. 
  *  @param  PinName mosi, miso, sclk, cs SPI bus pins
  *  @param  Mode selects either 6 Grids @ 12 Segments or 7 Grids @ 11 Segments (default 7 Grids @ 11 Segments)
  */
  PT6961(PinName mosi, PinName miso, PinName sclk, PinName cs, Mode mode=Grid7_Seg11);
      
  /** Clear the screen and locate to 0
   */ 
  void cls();  

  /** Write databyte to PT6961
   *  @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 PT6961
   *  @param  DisplayData_t data Array of PT6961_DISPLAY_MEM (=14) bytes for displaydata (starting at address 0)
   *  @param  length number bytes to write (valid range 0..PT6961_DISPLAY_MEM (=14), starting at address 0)   
   *  @return none
   */   
  void writeData(DisplayData_t data, int length = PT6961_DISPLAY_MEM);

  /** Read keydata block from PT6961
   *  @param  *keydata Ptr to Array of PT6961_KEY_MEM (=5) bytes for keydata
   *  @return bool keypress True when at least one key was pressed
   *
   * Note: Due to the hardware configuration the PT6961 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 = PT6961_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 PT6961 expects LSB first, whereas SPI is MSB first
    *  @param  char data
    *  @return bitreversed data
    */ 
  char _flip(char data);

  /** Write command and parameter to PT6961
    *  @param  int cmd Command byte
    *  &Param  int data Parameters for command
    *  @return none
    */ 
  void _writeCmd(int cmd, int data);  
};


#if(HR734_TEST == 1)
// Derived class for PT6961 used in DVD-HR734 front display unit
//
#include "Font_7Seg.h"

#define HR734_NR_GRIDS    7
#define HR734_NR_DIGITS   5
//#define HR734_DIG1_IDX    0
#define HR734_NR_UDC      8

//Access to 8 Switches
//#define HR734_SW1_IDX   0
//#define HR734_SW1_BIT   0x01

/** A class for driving Princeton PT6961 LED controller as used in HR734 display
 *
 * @brief Supports 5 Digits of 7 Segments + some additional segments + Icons. Also supports a scanned keyboard of 10 keys.
 *    
 *        SPI bus interface device. 
 */
class PT6961_HR734 : public PT6961, public Stream {
 public:
 
   /** Enums for Icons */
  //  Grid encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
 enum Icon {
    RA    = (1<<24) | S7_RA,
    M     = (2<<24) | S7_M,
    ARW   = (3<<24) | S7_ARW,    
    HDDDVD_HD = (4<<24) | S7_HDDVD_HD,
    HDDDVD_D  = (5<<24) | S7_HDDVD_D,
    HDDDVD_VD = (6<<24) | S7_HDDVD_VD,    
    DP2   = (6<<24) | S7_DP2,
    DP1   = (6<<24) | S7_DP1,
    R     = (7<<24) | S7_R,
    W     = (7<<24) | S7_W,
    SO    = (7<<24) | S7_SO,
    P     = (7<<24) | S7_P,
    CLK   = (7<<24) | S7_CLK,
    BRK   = (7<<24) | S7_BRK,
    DP4   = (7<<24) | S7_DP4,
    DP3   = (7<<24) | S7_DP3, 
  };
  
  /** Datatypes for display */
  typedef short UDCData_t[HR734_NR_UDC];
    
 /** Constructor for class for driving Princeton PT6961 LED controller as used in HR734 display
  *
  * @brief Supports 5 Digits of 7 Segments + some additional segments + Icons. Also supports a scanned keyboard of 10 keys.
  *        SPI bus interface device. 
  *  @param  PinName mosi, miso, sclk, cs SPI bus pins
  */
  PT6961_HR734(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 PT6961
     *  @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){
      PT6961::writeData(address, data);
    }        

   /** Write Display datablock to PT6961
    *  @param  DisplayData_t data Array of PT6961_DISPLAY_MEM (=16) bytes for displaydata (starting at address 0)
    *  @param  length number bytes to write (valid range 0..(HR734_NR_GRIDS*2) (=14), starting at address 0)   
    *  @return none
    */   
    void writeData(DisplayData_t data, int length = (HR734_NR_GRIDS*2)) {
      PT6961::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_7S;
};
#endif



#if(V56S_TEST == 1)
// Derived class for PT6961 used in V56S front display unit
//
#include "Font_7Seg.h"

#define V56S_NR_GRIDS    7
#define V56S_NR_DIGITS   5
//#define V56S_DIG1_IDX    0
#define V56S_NR_UDC      8

//Access to 5 Switches
//#define V56S_SW1_IDX   0
//#define V56S_SW1_BIT   0x01

/** A class for driving Princeton PT6961 LED controller as used in V56S display
 *
 * @brief Supports 5 Digits of 7 Segments + some additional segments + Icons. Also supports a scanned keyboard of 5 keys.
 *    
 *        SPI bus interface device. 
 */
class PT6961_V56S : public PT6961, public Stream {
 public:
 
   /** Enums for Icons */
  //  Grid encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
 enum Icon {
    RED   = (1<<24) | S7_RED,
    GRN   = (1<<24) | S7_GRN,
    YEL   = (1<<24) | S7_YEL,    
    DVD   = (6<<24) | S7_DVD,
    COL1  = (6<<24) | S7_COL1,
    DP3   = (6<<24) | S7_DP3,    
    PSE   = (6<<24) | S7_PSE,
    MP3   = (6<<24) | S7_MP3,
    PLY   = (6<<24) | S7_PLY,
    CD    = (6<<24) | S7_CD,
    COL3  = (6<<24) | S7_COL3,
    ARW   = (7<<24) | S7_ARW,
    ANT   = (7<<24) | S7_ANT,
    DTS   = (7<<24) | S7_DTS,
    MHZ   = (7<<24) | S7_MHZ,
    DDD   = (7<<24) | S7_DDD, 
    KHZ   = (7<<24) | S7_KHZ,
    RDS   = (7<<24) | S7_RDS   
  };
  
  /** Datatypes for display */
  typedef short UDCData_t[V56S_NR_UDC];
    
 /** Constructor for class for driving Princeton PT6961 LED controller as used in V56S display
  *
  * @brief Supports 5 Digits of 7 Segments + some additional segments + Icons. Also supports a scanned keyboard of 5 keys.
  *        SPI bus interface device. 
  *  @param  PinName mosi, miso, sclk, cs SPI bus pins
  */
  PT6961_V56S(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 PT6961
     *  @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){
      PT6961::writeData(address, data);
    }        

   /** Write Display datablock to PT6961
    *  @param  DisplayData_t data Array of PT6961_DISPLAY_MEM (=16) bytes for displaydata (starting at address 0)
    *  @param  length number bytes to write (valid range 0..(V56S_NR_GRIDS*2) (=14), starting at address 0)   
    *  @return none
    */   
    void writeData(DisplayData_t data, int length = (V56S_NR_GRIDS*2)) {
      PT6961::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_7S;
};
#endif


#endif