Library for the Princeton PT6312 Vacuum Fluorescent Display (VFD) driver.

Dependents:   mbed_PT6312

This library is documented here.

Committer:
wim
Date:
Mon Aug 24 20:17:14 2015 +0000
Revision:
0:e59142cded2b
Child:
1:c5e247159aa6
First Test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wim 0:e59142cded2b 1 /* mbed PT6312 Library, for Princeton PT6312 VFD controller
wim 0:e59142cded2b 2 * Copyright (c) 2015, v01: WH, Initial version
wim 0:e59142cded2b 3 *
wim 0:e59142cded2b 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
wim 0:e59142cded2b 5 * of this software and associated documentation files (the "Software"), to deal
wim 0:e59142cded2b 6 * in the Software without restriction, including without limitation the rights
wim 0:e59142cded2b 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
wim 0:e59142cded2b 8 * copies of the Software, and to permit persons to whom the Software is
wim 0:e59142cded2b 9 * furnished to do so, subject to the following conditions:
wim 0:e59142cded2b 10 *
wim 0:e59142cded2b 11 * The above copyright notice and this permission notice shall be included in
wim 0:e59142cded2b 12 * all copies or substantial portions of the Software.
wim 0:e59142cded2b 13 *
wim 0:e59142cded2b 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
wim 0:e59142cded2b 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
wim 0:e59142cded2b 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
wim 0:e59142cded2b 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
wim 0:e59142cded2b 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
wim 0:e59142cded2b 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
wim 0:e59142cded2b 20 * THE SOFTWARE.
wim 0:e59142cded2b 21 */
wim 0:e59142cded2b 22 #include "mbed.h"
wim 0:e59142cded2b 23 #include "PT6312.h"
wim 0:e59142cded2b 24
wim 0:e59142cded2b 25 /** Constructor for class for driving Princeton PT6312 VFD controller
wim 0:e59142cded2b 26 *
wim 0:e59142cded2b 27 * @brief Supports 4 Digits of 16 Segments upto 10 Digits of 12 Segments. Also supports a scanned keyboard of upto 24 keys, 4 switches and 4 LEDs.
wim 0:e59142cded2b 28 * SPI bus interface device.
wim 0:e59142cded2b 29 *
wim 0:e59142cded2b 30 * @param PinName mosi, miso, sclk, cs SPI bus pins
wim 0:e59142cded2b 31 * @param Mode selects either number of Digits and Segments
wim 0:e59142cded2b 32 */
wim 0:e59142cded2b 33 PT6312::PT6312(PinName mosi, PinName miso, PinName sclk, PinName cs, Mode mode) : _spi(mosi,miso,sclk), _cs(cs), _mode(mode) {
wim 0:e59142cded2b 34
wim 0:e59142cded2b 35 _init();
wim 0:e59142cded2b 36 }
wim 0:e59142cded2b 37
wim 0:e59142cded2b 38 /** Init the SPI interface and the controller
wim 0:e59142cded2b 39 * @param none
wim 0:e59142cded2b 40 * @return none
wim 0:e59142cded2b 41 */
wim 0:e59142cded2b 42 void PT6312::_init(){
wim 0:e59142cded2b 43
wim 0:e59142cded2b 44 //init SPI
wim 0:e59142cded2b 45 _cs=1;
wim 0:e59142cded2b 46 _spi.format(8,3); //PT6312 uses mode 3 (Clock High on Idle, Data latched on second (=rising) edge)
wim 0:e59142cded2b 47 _spi.frequency(100000);
wim 0:e59142cded2b 48
wim 0:e59142cded2b 49 //init controller
wim 0:e59142cded2b 50 _writeCmd(PT6312_MODE_SET_CMD, _mode); // Mode set command
wim 0:e59142cded2b 51
wim 0:e59142cded2b 52 _display = PT6312_DSP_ON;
wim 0:e59142cded2b 53 _bright = PT6312_BRT_DEF;
wim 0:e59142cded2b 54 _writeCmd(PT6312_DSP_CTRL_CMD, _display | _bright ); // Display control cmd, display on/off, brightness
wim 0:e59142cded2b 55
wim 0:e59142cded2b 56 _writeCmd(PT6312_DATA_SET_CMD, PT6312_DATA_WR | PT6312_ADDR_INC | PT6312_MODE_NORM); // Data set cmd, normal mode, auto incr, write data
wim 0:e59142cded2b 57 }
wim 0:e59142cded2b 58
wim 0:e59142cded2b 59
wim 0:e59142cded2b 60 /** Clear the screen and locate to 0
wim 0:e59142cded2b 61 */
wim 0:e59142cded2b 62 void PT6312::cls() {
wim 0:e59142cded2b 63
wim 0:e59142cded2b 64 _cs=0;
wim 0:e59142cded2b 65 wait_us(1);
wim 0:e59142cded2b 66 _spi.write(_flip(PT6312_ADDR_SET_CMD | 0x00)); // Address set cmd, 0
wim 0:e59142cded2b 67
wim 0:e59142cded2b 68 for (int cnt=0; cnt<PT6312_DISPLAY_MEM; cnt++) {
wim 0:e59142cded2b 69 _spi.write(0x00); // data
wim 0:e59142cded2b 70 }
wim 0:e59142cded2b 71
wim 0:e59142cded2b 72 wait_us(1);
wim 0:e59142cded2b 73 _cs=1;
wim 0:e59142cded2b 74
wim 0:e59142cded2b 75 }
wim 0:e59142cded2b 76
wim 0:e59142cded2b 77 /** Set Brightness
wim 0:e59142cded2b 78 *
wim 0:e59142cded2b 79 * @param char brightness (3 significant bits, valid range 0..7 (1/16 .. 14/14 dutycycle)
wim 0:e59142cded2b 80 * @return none
wim 0:e59142cded2b 81 */
wim 0:e59142cded2b 82 void PT6312::setBrightness(char brightness){
wim 0:e59142cded2b 83
wim 0:e59142cded2b 84 _bright = brightness & PT6312_BRT_MSK; // mask invalid bits
wim 0:e59142cded2b 85
wim 0:e59142cded2b 86 _writeCmd(PT6312_DSP_CTRL_CMD, _display | _bright ); // Display control cmd, display on/off, brightness
wim 0:e59142cded2b 87
wim 0:e59142cded2b 88 }
wim 0:e59142cded2b 89
wim 0:e59142cded2b 90 /** Set the Display mode On/off
wim 0:e59142cded2b 91 *
wim 0:e59142cded2b 92 * @param bool display mode
wim 0:e59142cded2b 93 */
wim 0:e59142cded2b 94 void PT6312::setDisplay(bool on) {
wim 0:e59142cded2b 95
wim 0:e59142cded2b 96 if (on) {
wim 0:e59142cded2b 97 _display = PT6312_DSP_ON;
wim 0:e59142cded2b 98 }
wim 0:e59142cded2b 99 else {
wim 0:e59142cded2b 100 _display = PT6312_DSP_OFF;
wim 0:e59142cded2b 101 }
wim 0:e59142cded2b 102
wim 0:e59142cded2b 103 _writeCmd(PT6312_DSP_CTRL_CMD, _display | _bright ); // Display control cmd, display on/off, brightness
wim 0:e59142cded2b 104 }
wim 0:e59142cded2b 105
wim 0:e59142cded2b 106 /** Write databyte to PT6312
wim 0:e59142cded2b 107 * @param int address display memory location to write byte
wim 0:e59142cded2b 108 * @param char data byte written at given address
wim 0:e59142cded2b 109 * @return none
wim 0:e59142cded2b 110 */
wim 0:e59142cded2b 111 void PT6312::writeData(int address, char data) {
wim 0:e59142cded2b 112 _cs=0;
wim 0:e59142cded2b 113 wait_us(1);
wim 0:e59142cded2b 114 _spi.write(_flip(PT6312_ADDR_SET_CMD | (address & PT6312_ADDR_MSK))); // Set Address cmd
wim 0:e59142cded2b 115
wim 0:e59142cded2b 116 _spi.write(_flip(data)); // data
wim 0:e59142cded2b 117
wim 0:e59142cded2b 118 wait_us(1);
wim 0:e59142cded2b 119 _cs=1;
wim 0:e59142cded2b 120
wim 0:e59142cded2b 121 }
wim 0:e59142cded2b 122
wim 0:e59142cded2b 123 /** Write Display datablock to PT6312
wim 0:e59142cded2b 124 * @param DisplayData_t data Array of PT6312_DISPLAY_MEM (=16) bytes for displaydata (starting at address 0)
wim 0:e59142cded2b 125 * @return none
wim 0:e59142cded2b 126 */
wim 0:e59142cded2b 127 void PT6312::writeData(DisplayData_t data) {
wim 0:e59142cded2b 128 _cs=0;
wim 0:e59142cded2b 129 wait_us(1);
wim 0:e59142cded2b 130 _spi.write(_flip(PT6312_ADDR_SET_CMD | 0x00)); // Set Address at 0
wim 0:e59142cded2b 131
wim 0:e59142cded2b 132 for (int idx=0; idx<PT6312_DISPLAY_MEM; idx++) {
wim 0:e59142cded2b 133 _spi.write(_flip(data[idx])); // data
wim 0:e59142cded2b 134 }
wim 0:e59142cded2b 135
wim 0:e59142cded2b 136 wait_us(1);
wim 0:e59142cded2b 137 _cs=1;
wim 0:e59142cded2b 138
wim 0:e59142cded2b 139 }
wim 0:e59142cded2b 140
wim 0:e59142cded2b 141 /** Read keydata block from PT6312
wim 0:e59142cded2b 142 * @param *keydata Ptr to Array of PT6312_KEY_MEM (=3) bytes for keydata
wim 0:e59142cded2b 143 * @return bool keypress True when at least one key was pressed
wim 0:e59142cded2b 144 *
wim 0:e59142cded2b 145 * Note: Due to the hardware configuration the PT6312 key matrix scanner will detect multiple keys pressed at same time,
wim 0:e59142cded2b 146 * but this may also result in some spurious keys being set in keypress data array.
wim 0:e59142cded2b 147 * It may be best to ignore all keys in those situations. That option is implemented in this method depending on #define setting.
wim 0:e59142cded2b 148 */
wim 0:e59142cded2b 149 bool PT6312::readKeys(KeyData_t *keydata) {
wim 0:e59142cded2b 150 int keypress = 0;
wim 0:e59142cded2b 151 char data;
wim 0:e59142cded2b 152
wim 0:e59142cded2b 153 // Read keys
wim 0:e59142cded2b 154 _cs=0;
wim 0:e59142cded2b 155 wait_us(1);
wim 0:e59142cded2b 156
wim 0:e59142cded2b 157 // Enable Key Read mode
wim 0:e59142cded2b 158 _spi.write(_flip(PT6312_DATA_SET_CMD | PT6312_KEY_RD | PT6312_ADDR_INC | PT6312_MODE_NORM)); // Data set cmd, normal mode, auto incr, read data
wim 0:e59142cded2b 159
wim 0:e59142cded2b 160 for (int idx=0; idx < PT6312_KEY_MEM; idx++) {
wim 0:e59142cded2b 161 data = _flip(_spi.write(0xFF)); // read keys and correct bitorder
wim 0:e59142cded2b 162
wim 0:e59142cded2b 163 if (data != 0) { // Check for any pressed key
wim 0:e59142cded2b 164 for (int bit=0; bit < PT6312_KEY_BITS; bit++) {
wim 0:e59142cded2b 165 if (data & (1 << bit)) {keypress++;} // Test all significant bits
wim 0:e59142cded2b 166 }
wim 0:e59142cded2b 167 }
wim 0:e59142cded2b 168
wim 0:e59142cded2b 169 (*keydata)[idx] = data; // Store keydata after correcting bitorder
wim 0:e59142cded2b 170 }
wim 0:e59142cded2b 171
wim 0:e59142cded2b 172 wait_us(1);
wim 0:e59142cded2b 173 _cs=1;
wim 0:e59142cded2b 174
wim 0:e59142cded2b 175 // Restore Data Write mode
wim 0:e59142cded2b 176 _writeCmd(PT6312_DATA_SET_CMD, PT6312_DATA_WR | PT6312_ADDR_INC | PT6312_MODE_NORM); // Data set cmd, normal mode, auto incr, write data
wim 0:e59142cded2b 177
wim 0:e59142cded2b 178 #if(1)
wim 0:e59142cded2b 179 // Dismiss multiple keypresses at same time
wim 0:e59142cded2b 180 return (keypress == 1);
wim 0:e59142cded2b 181 #else
wim 0:e59142cded2b 182 // Allow multiple keypress and accept possible spurious keys
wim 0:e59142cded2b 183 return (keypress > 0);
wim 0:e59142cded2b 184 #endif
wim 0:e59142cded2b 185 }
wim 0:e59142cded2b 186
wim 0:e59142cded2b 187
wim 0:e59142cded2b 188 /** Read switches from PT6312
wim 0:e59142cded2b 189 *
wim 0:e59142cded2b 190 * @param none
wim 0:e59142cded2b 191 * @return char for switch data (4 least significant bits)
wim 0:e59142cded2b 192 *
wim 0:e59142cded2b 193 */
wim 0:e59142cded2b 194 char PT6312::readSwitches() {
wim 0:e59142cded2b 195 char data;
wim 0:e59142cded2b 196
wim 0:e59142cded2b 197 // Read switches
wim 0:e59142cded2b 198 _cs=0;
wim 0:e59142cded2b 199 wait_us(1);
wim 0:e59142cded2b 200
wim 0:e59142cded2b 201 // Enable Switch Read mode
wim 0:e59142cded2b 202 _spi.write(_flip(PT6312_DATA_SET_CMD | PT6312_SW_RD | PT6312_ADDR_INC | PT6312_MODE_NORM)); // Data set cmd, normal mode, auto incr, read data
wim 0:e59142cded2b 203
wim 0:e59142cded2b 204 data = _flip(_spi.write(0xFF)) & PT6312_SW_MSK; // read switches and correct bitorder
wim 0:e59142cded2b 205
wim 0:e59142cded2b 206 wait_us(1);
wim 0:e59142cded2b 207 _cs=1;
wim 0:e59142cded2b 208
wim 0:e59142cded2b 209 // Restore Data Write mode
wim 0:e59142cded2b 210 _writeCmd(PT6312_DATA_SET_CMD, PT6312_DATA_WR | PT6312_ADDR_INC | PT6312_MODE_NORM); // Data set cmd, normal mode, auto incr, write data
wim 0:e59142cded2b 211
wim 0:e59142cded2b 212 return data;
wim 0:e59142cded2b 213 }
wim 0:e59142cded2b 214
wim 0:e59142cded2b 215
wim 0:e59142cded2b 216 /** Set LEDs
wim 0:e59142cded2b 217 *
wim 0:e59142cded2b 218 * @param char leds (4 least significant bits)
wim 0:e59142cded2b 219 * @return none
wim 0:e59142cded2b 220 */
wim 0:e59142cded2b 221 void PT6312::setLED (char leds) {
wim 0:e59142cded2b 222
wim 0:e59142cded2b 223 // Set LEDs
wim 0:e59142cded2b 224 _cs=0;
wim 0:e59142cded2b 225 wait_us(1);
wim 0:e59142cded2b 226
wim 0:e59142cded2b 227 // Enable LED Write mode
wim 0:e59142cded2b 228 _spi.write(_flip(PT6312_DATA_SET_CMD | PT6312_LED_WR | PT6312_ADDR_INC | PT6312_MODE_NORM)); // Data set cmd, normal mode, auto incr, write data
wim 0:e59142cded2b 229
wim 0:e59142cded2b 230 _spi.write(_flip(leds & PT6312_LED_MSK)); // write LEDs in correct bitorder
wim 0:e59142cded2b 231
wim 0:e59142cded2b 232 wait_us(1);
wim 0:e59142cded2b 233 _cs=1;
wim 0:e59142cded2b 234
wim 0:e59142cded2b 235 // Restore Data Write mode
wim 0:e59142cded2b 236 _writeCmd(PT6312_DATA_SET_CMD, PT6312_DATA_WR | PT6312_ADDR_INC | PT6312_MODE_NORM); // Data set cmd, normal mode, auto incr, write data
wim 0:e59142cded2b 237 }
wim 0:e59142cded2b 238
wim 0:e59142cded2b 239
wim 0:e59142cded2b 240
wim 0:e59142cded2b 241 /** Helper to reverse all command or databits. The PT6312 expects LSB first, whereas SPI is MSB first
wim 0:e59142cded2b 242 * @param char data
wim 0:e59142cded2b 243 * @return bitreversed data
wim 0:e59142cded2b 244 */
wim 0:e59142cded2b 245 char PT6312::_flip(char data) {
wim 0:e59142cded2b 246 char value=0;
wim 0:e59142cded2b 247
wim 0:e59142cded2b 248 if (data & 0x01) {value |= 0x80;} ;
wim 0:e59142cded2b 249 if (data & 0x02) {value |= 0x40;} ;
wim 0:e59142cded2b 250 if (data & 0x04) {value |= 0x20;} ;
wim 0:e59142cded2b 251 if (data & 0x08) {value |= 0x10;} ;
wim 0:e59142cded2b 252 if (data & 0x10) {value |= 0x08;} ;
wim 0:e59142cded2b 253 if (data & 0x20) {value |= 0x04;} ;
wim 0:e59142cded2b 254 if (data & 0x40) {value |= 0x02;} ;
wim 0:e59142cded2b 255 if (data & 0x80) {value |= 0x01;} ;
wim 0:e59142cded2b 256 return value;
wim 0:e59142cded2b 257 }
wim 0:e59142cded2b 258
wim 0:e59142cded2b 259
wim 0:e59142cded2b 260 /** Write command and parameter to PT6312
wim 0:e59142cded2b 261 * @param int cmd Command byte
wim 0:e59142cded2b 262 * &Param int data Parameters for command
wim 0:e59142cded2b 263 * @return none
wim 0:e59142cded2b 264 */
wim 0:e59142cded2b 265 void PT6312::_writeCmd(int cmd, int data){
wim 0:e59142cded2b 266
wim 0:e59142cded2b 267 _cs=0;
wim 0:e59142cded2b 268 wait_us(1);
wim 0:e59142cded2b 269 // _spi.write(_flip( (cmd & 0xF0) | (data & 0x0F)));
wim 0:e59142cded2b 270 _spi.write(_flip( (cmd & PT6312_CMD_MSK) | (data & ~PT6312_CMD_MSK)));
wim 0:e59142cded2b 271
wim 0:e59142cded2b 272 wait_us(1);
wim 0:e59142cded2b 273 _cs=1;
wim 0:e59142cded2b 274
wim 0:e59142cded2b 275 };
wim 0:e59142cded2b 276
wim 0:e59142cded2b 277