Wim Huiskamp / PT6302

Dependents:   mbed_PT6302 mbed_PT6301

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PT6302.cpp Source File

PT6302.cpp

00001 /* mbed PT6302 Library, for Princeton LC7571X VFD controller
00002  * Note the PT6302 is identical to the OKI ML9208 
00003  *
00004  * Copyright (c) 2017, v01: WH, Initial version
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a copy
00007  * of this software and associated documentation files (the "Software"), to deal
00008  * in the Software without restriction, including without limitation the rights
00009  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00010  * copies of the Software, and to permit persons to whom the Software is
00011  * furnished to do so, subject to the following conditions:
00012  *
00013  * The above copyright notice and this permission notice shall be included in
00014  * all copies or substantial portions of the Software.
00015  *
00016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00019  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00020  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00021  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00022  * THE SOFTWARE.
00023  */
00024 
00025 #include "mbed.h" 
00026 #include "PT6302.h"
00027 #include "PT6302_UDC.inc"
00028 
00029 
00030  /** Constructor for class for driving Princeton PT6302 VFD controller
00031   *
00032   *  @brief Supports upto 16 Grids of 35 matrix segments.
00033   *         Also supports 2 additional segments and 2 port pins.
00034   *         SPI bus interface device. 
00035   *  @param  PinName mosi, sclk, cs SPI bus pins
00036   *  @param  Mode selects number of Grids and Segments (default 16 Grids, 2 additional segments)
00037   */
00038 PT6302::PT6302(PinName mosi, PinName sclk, PinName cs, Mode mode) : _spi(mosi,NC,sclk), _cs(cs), _mode(mode) {
00039 
00040   _init();
00041 }
00042 
00043 /** Init the PT6302 interface and the controller
00044   *
00045   * @param  none
00046   * @return none
00047   */ 
00048 void PT6302::_init(){
00049   
00050 //init SPI
00051   _cs=1;
00052   _spi.format(8,3); //PT6302 uses mode 3 (Clock High on Idle, Data latched on second (=rising) edge)
00053   _spi.frequency(100000);   
00054 //  _spi.frequency(250000);     
00055 
00056 //init controller  
00057   //setPort(0x0);  // Port Off (default at Reset)
00058 
00059   // Set number of Grids
00060   _writeCmd((PT6302_GRID_REG | _mode));      // Command register & value
00061 
00062   setBrightness(PT6302_BRT_DEF); // Default Brightness
00063 
00064   // Clear the DCRAM and ADRAM (undefined at Reset)
00065   cls(); 
00066 
00067   // Clear the UDC RAM (undefined at Reset)
00068   const char udc_none[] = {0x00,0x00,0x00,0x00,0x00}; 
00069   for (int idx=0; idx < PT6302_NR_UDC; idx++) {
00070     setUDC(idx, (char *)udc_none);
00071   }
00072        
00073   setDisplay(true);  // Display On
00074 }   
00075 
00076 
00077 /** Clear the screen
00078   *
00079   * @param none
00080   * @return none  
00081   */  
00082 void PT6302::cls() {
00083 
00084   for (int cnt=0; cnt<PT6302_DSP_MEM; cnt++) {
00085     writeData(char (' '), cnt); // data 
00086 //    writeData(0x00, cnt);       // data     
00087   }
00088 
00089   for (int cnt=0; cnt<PT6302_ADD_MEM; cnt++) {
00090     writeAData(0x00, cnt);      // adata 
00091   }  
00092 }  
00093 
00094 
00095 /** Set Brightness
00096   *
00097   * @param  char brightness (3 significant bits, valid range 0..7)  
00098   * @return none
00099   */
00100 void PT6302::setBrightness(char brightness){
00101   
00102 //Sanity check
00103   brightness = brightness & PT6302_BRT_MSK; // mask invalid bits
00104  
00105   _writeCmd((PT6302_BRT_REG | brightness));  // Command register & value
00106 }
00107 
00108 /** Set the Display mode On/off
00109   *
00110   * @param bool display mode
00111   * @return none  
00112   */
00113 void PT6302::setDisplay(bool on) {
00114   char display;
00115      
00116   if (on) {
00117     display = PT6302_DSPL_NRM; // normal mode, show Display RAM content
00118   }
00119   else {
00120     display = PT6302_DSPL_OFF; // all segments off
00121   }
00122 
00123   _writeCmd((PT6302_DSPL_REG | display));   // Command register & value
00124 }
00125 
00126 /** Set Port
00127   *
00128   * @param  char port (2 least significant bits)  
00129   * @return none
00130   */
00131 void PT6302::setPort (char port){
00132 
00133 //Sanity check
00134   _port = port & PT6302_PDAT_MSK;          // Mask invalid bits
00135  
00136   _writeCmd((PT6302_PDAT_REG | _port));    // Command register & value
00137   _writeCmd((PT6302_PDAT_REG | _port));    // Command register & value (Dummy cmd to show on Latched LEDs)
00138 }
00139 
00140 
00141 /** Set User Defined Characters (UDC)
00142   *
00143   * @param unsigned char udc_idx   The Index of the UDC (0..7)
00144   * @param UDCData_t udc_data      The bitpattern for the UDC (5 bytes)
00145   * @return none  
00146   */
00147 void PT6302::setUDC(unsigned char udc_idx, UDCData_t udc_data) {
00148   
00149 //Sanity check
00150   udc_idx = udc_idx & PT6302_UADR_MSK; // mask invalid bits
00151 
00152   _cs=0; // Send Command & Params 
00153   wait_us(1);  
00154   _spi.write(_flip(PT6302_UDC_REG | udc_idx));     // Command register & address
00155   wait_us(PT6302_CMD_DLY);         // Command Delay
00156     
00157   _spi.write(_flip(udc_data[0] & PT6302_UDC_MSK)); // CD30 CD25 ......  CD0
00158   _spi.write(_flip(udc_data[1] & PT6302_UDC_MSK)); // CD31 CD26 ......  CD1
00159   _spi.write(_flip(udc_data[2] & PT6302_UDC_MSK)); // CD32 CD27 ......  CD2
00160   _spi.write(_flip(udc_data[3] & PT6302_UDC_MSK)); // CD33 CD28 ......  CD3
00161   _spi.write(_flip(udc_data[4] & PT6302_UDC_MSK)); // CD34 CD29 ......  CD4
00162 
00163   wait_us(PT6302_CS_DLY);          // CS Hold Delay  
00164   _cs=1; // Latch Command & Params
00165 
00166   wait_us(PT6302_CMD_DLY);         // Command Delay   
00167 }
00168 
00169 
00170 /** Write Data to PT6302
00171   *
00172   *  @param char data Character code
00173   *  @param char address Parameter for data
00174   *  @return none
00175   */  
00176 void PT6302::writeData(char data, char address){
00177 
00178 //Sanity check
00179   address = address & PT6302_DADR_MSK; // mask invalid bits
00180 
00181   _writeCmd((PT6302_DATA_REG | address), // Command register & address
00182              data);                      // Character code
00183 }  
00184 
00185 /** Write Additional Data to PT6302
00186   *
00187   *  @param char adata Additional code (annunciator)
00188   *  @param char address Parameter for data
00189   *  @return none
00190   */  
00191 void PT6302::writeAData(char adata, char address){
00192 
00193 //Sanity check
00194   address = address & PT6302_AADR_MSK; // mask invalid bits
00195  
00196   _writeCmd((PT6302_ADAT_REG | address), // Command register & ADRAM address
00197              adata);                     // ADATA
00198 }  
00199 
00200 /** Write command and data to PT6302
00201   *
00202   *  @param char cmd Command byte
00203   *  @param char data Parameter for command  
00204   *  @return none
00205   */  
00206 void PT6302::_writeCmd(char cmd, char data){
00207 
00208   _cs=0; // Prepare to send Command and data
00209   wait_us(1);    
00210 
00211   _spi.write(_flip(cmd));          // Command register & value
00212 
00213   wait_us(PT6302_CMD_DLY);         // Command Delay
00214   
00215   _spi.write(_flip(data));         // data
00216 
00217   wait_us(PT6302_CS_DLY);          // CS Hold Delay
00218   _cs=1; // Latch Command and data 
00219 
00220   wait_us(PT6302_CMD_DLY);         // Command Delay
00221 }  
00222 
00223 /** Write command to PT6302
00224   *
00225   *  @param char cmd Command byte
00226   *  @return none
00227   */  
00228 void PT6302::_writeCmd(char cmd){
00229 
00230   _cs=0; // Prepare to send Command
00231   wait_us(1);
00232 
00233   _spi.write(_flip(cmd));          // Command register & value
00234 
00235   wait_us(PT6302_CS_DLY);          // CS Hold Delay  
00236   _cs=1; // Latch Command
00237 
00238   wait_us(PT6302_CMD_DLY);         // Command Delay
00239 }  
00240 
00241 
00242 
00243 /** Helper to reverse all command or databits. The PT6302 expects LSB first, whereas SPI is MSB first
00244   *
00245   *  @param  char data
00246   *  @return bitreversed data
00247   */ 
00248 char PT6302::_flip(char data) {
00249  char value=0;
00250   
00251  if (data & 0x01) {value |= 0x80;} ;  
00252  if (data & 0x02) {value |= 0x40;} ;
00253  if (data & 0x04) {value |= 0x20;} ;
00254  if (data & 0x08) {value |= 0x10;} ;
00255  if (data & 0x10) {value |= 0x08;} ;
00256  if (data & 0x20) {value |= 0x04;} ;
00257  if (data & 0x40) {value |= 0x02;} ;
00258  if (data & 0x80) {value |= 0x01;} ;
00259  return value;       
00260 }
00261 
00262 
00263 #if (HANNSTAR_TEST == 1) 
00264 
00265 /** Constructor for class for Princeton PT6302 VFD controller as used in HANNSTAR
00266   *
00267   *  @brief Supports 16 Grids of 35 Segments without additional Segments.
00268   *  
00269   *  @param  PinName mosi, miso, sclk, cs SPI bus pins
00270   */
00271 PT6302_HANNSTAR::PT6302_HANNSTAR(PinName mosi, PinName sclk, PinName cs) : PT6302(mosi, sclk, cs, Grid16_Add2) {
00272   _column   = 0;
00273   _columns  = HANNSTAR_NR_DIGITS;
00274   
00275   //Enable VGen for VFD Power Supply
00276   setVGen(true);   
00277 }
00278 
00279 /** Locate cursor to a screen column
00280   *
00281   * @param column  The horizontal position from the left, indexed from 0
00282   * @return none  
00283   */
00284 void PT6302_HANNSTAR::locate(int column) {
00285   //sanity check
00286   if (column < 0) {column = 0;}
00287   if (column > (_columns - 1)) {column = _columns - 1;}  
00288   
00289   _column = column;       
00290 }
00291 
00292 
00293 /** Number of screen columns
00294   *
00295   * @param none
00296   * @return columns
00297   */
00298 int PT6302_HANNSTAR::columns() {
00299     return _columns;
00300 }
00301 
00302 
00303 /** Clear the screen and locate to 0
00304   *
00305   * @param bool clrAll Clear Icons also (default = false)
00306   * @return none  
00307   */ 
00308 void PT6302_HANNSTAR::cls(bool clrAll) {  
00309 
00310   for (int cnt=0; cnt<HANNSTAR_NR_DIGITS; cnt++) {
00311     writeData(char (' '), cnt); // data 
00312   }
00313 
00314   if (clrAll) {
00315     //Clear Icons    
00316     for (int cnt=0; cnt<HANNSTAR_NR_DIGITS; cnt++) {
00317       writeAData(0x00, cnt);      // adata 
00318     }   
00319   }  
00320 
00321   _column = 0;   
00322 }    
00323 
00324 
00325 /** Set Port
00326   *
00327   * @param  char port (Only Bit 1 is used)  
00328   * @return none
00329   */
00330 void PT6302_HANNSTAR::setPort (char port){
00331 
00332 //Sanity check
00333   _port &= ~PT6302_HANN_PDAT_MSK;         // Clear valid bits
00334   _port |= (port & PT6302_HANN_PDAT_MSK); // Mask invalid bits
00335  
00336   _writeCmd((PT6302_PDAT_REG | _port));   // Command register & value
00337   _writeCmd((PT6302_PDAT_REG | _port));   // Command register & value (Dummy cmd to show on Latched LEDs)  
00338 }
00339 
00340 
00341 /** Set VFD VGen
00342   *
00343   * @param  bool on
00344   * @return none
00345   */
00346 void PT6302_HANNSTAR::setVGen(bool on){     
00347 
00348   if (on) {
00349     _port = _port | PT6302_HANN_VGEN;  // VGen On
00350   }
00351   else {
00352     _port = _port & ~PT6302_HANN_VGEN; // VGen Off
00353   }
00354 
00355   _writeCmd((PT6302_PDAT_REG | _port));   // Command register & value
00356   _writeCmd((PT6302_PDAT_REG | _port));   // Command register & value (Dummy cmd to show on Latched LEDs)  
00357 }
00358 
00359 
00360 /** Write a single character (Stream implementation)
00361   * 
00362   * @param value char to print
00363   * @return value;
00364   */
00365 int PT6302_HANNSTAR::_putc(int value) {
00366     int addr;
00367     
00368     if ((value == '\n') || (value == '\r')) {
00369       //No character to write
00370      
00371       //Update Cursor      
00372       _column = 0;
00373     }
00374     else if ((value >= 0) && (value < 256)) {
00375       //Character to write
00376 
00377       //Translate between _column and displaybuffer entries
00378       //Note that the HANNSTAR has 1 digit/grid. 
00379       //_column ==  0 => Grid15  => addr = 15
00380       //_column ==  1 => Grid14  => addr = 14
00381       // ....
00382       //_column == 15 => Grid1   => addr = 0            
00383       addr = (15 - _column); // 1 Byte for every Grid;
00384       
00385       writeData(value, addr);
00386                                 
00387       //Update Cursor
00388       _column++;
00389       if (_column > (HANNSTAR_NR_DIGITS - 1)) {        
00390         _column = 0;
00391       }
00392 
00393     } // if validChar           
00394 
00395     return value;
00396 }
00397 
00398 /** Get a single character (Stream implementation)
00399   *
00400   * @param none  
00401   * @return -1
00402   */
00403 int PT6302_HANNSTAR::_getc() {
00404     return -1;
00405 }
00406 #endif