Wim Huiskamp / PT6318
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PT6318.cpp Source File

PT6318.cpp

00001 /* mbed PT6318 Library, for Princeton PT6318 VFD controller
00002  * Copyright (c) 2016, v01: WH, Initial version, for KUH8300 code
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to deal
00006  * in the Software without restriction, including without limitation the rights
00007  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008  * copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020  * THE SOFTWARE.
00021  */
00022 #include "mbed.h" 
00023 #include "PT6318.h"
00024 
00025 /** Constructor for class for driving Princeton PT6318 VFD controller
00026  *
00027  *  @brief Supports 8 Grids of 20 Segments upto 16 Grids of 12 Segments. Also supports a scanned keyboard of upto 48 keys, 4 switches and 5 LEDs.
00028  *         SPI bus interface device. 
00029  *   
00030  *  @param PinName mosi, miso, sclk, cs SPI bus pins
00031  *  @param Mode selects either number of Digits and Segments
00032 */
00033 PT6318::PT6318(PinName mosi, PinName miso, PinName sclk, PinName cs, Mode mode) : _spi(mosi,miso,sclk), _cs(cs), _mode(mode) {
00034 
00035   _init();
00036 }
00037 
00038 /** Init the SPI interface and the controller
00039   * @param  none
00040   * @return none
00041   */ 
00042 void PT6318::_init(){
00043   
00044 //init SPI
00045   _cs=1;
00046   _spi.format(8,3); //PT6318 uses mode 3 (Clock High on Idle, Data latched on second (=rising) edge)
00047 //  _spi.frequency(100000);   
00048   _spi.frequency(500000);     
00049 
00050 //init controller  
00051   _writeCmd(PT6318_MODE_SET_CMD, _mode);                                               // Mode set command
00052 
00053   _display = PT6318_DSP_ON;
00054   _bright  = PT6318_BRT_DEF; 
00055   _writeCmd(PT6318_DSP_CTRL_CMD, _display | _bright );                                 // Display control cmd, display on/off, brightness   
00056   
00057   _writeCmd(PT6318_DATA_SET_CMD, PT6318_DATA_WR | PT6318_ADDR_INC | PT6318_MODE_NORM); // Data set cmd, normal mode, auto incr, write data  
00058 }   
00059 
00060 
00061 /** Clear the screen and locate to 0
00062  */  
00063 void PT6318::cls() {
00064   
00065   _cs=0;
00066   wait_us(1);    
00067   _spi.write(_flip(PT6318_ADDR_SET_CMD | 0x00)); // Address set cmd, 0
00068       
00069   for (int cnt=0; cnt<PT6318_DISPLAY_MEM; cnt++) {
00070     _spi.write(0x00); // data 
00071   }
00072   
00073   wait_us(1);
00074   _cs=1;      
00075   
00076 }  
00077 
00078 /** Set Brightness
00079   *
00080   * @param  char brightness (3 significant bits, valid range 0..7 (1/16 .. 14/16 dutycycle)  
00081   * @return none
00082   */
00083 void PT6318::setBrightness(char brightness){
00084 
00085   _bright = brightness & PT6318_BRT_MSK; // mask invalid bits
00086   
00087   _writeCmd(PT6318_DSP_CTRL_CMD, _display | _bright );  // Display control cmd, display on/off, brightness  
00088 
00089 }
00090 
00091 /** Set the Display mode On/off
00092   *
00093   * @param bool display mode
00094   */
00095 void PT6318::setDisplay(bool on) {
00096   
00097   if (on) {
00098     _display = PT6318_DSP_ON;
00099   }
00100   else {
00101    _display = PT6318_DSP_OFF;
00102   }
00103   
00104   _writeCmd(PT6318_DSP_CTRL_CMD, _display | _bright );  // Display control cmd, display on/off, brightness   
00105 }
00106 
00107 /** Write databyte to PT6318
00108   *  @param  char data byte written at given address
00109   *  @param  int address display memory location to write byte  
00110   *  @return none
00111   */ 
00112 void PT6318::writeData(char data, int address) {
00113   _cs=0;
00114   wait_us(1);    
00115   _spi.write(_flip(PT6318_ADDR_SET_CMD | (address & PT6318_ADDR_MSK))); // Set Address cmd
00116       
00117   _spi.write(_flip(data)); // data 
00118   
00119   wait_us(1);
00120   _cs=1;         
00121     
00122 }
00123 
00124 /** Write Display datablock to PT6318
00125   *  @param  DisplayData_t data Array of PT6318_DISPLAY_MEM (=48) bytes for displaydata (starting at address)
00126   *  @param  length number bytes to write (valid range 0..PT6318_DISPLAY_MEM (=48), starting at address)   
00127   *  @param  int address display memory location to write byte    
00128   *  @return none
00129   */    
00130 void PT6318::writeData(DisplayData_t data, int length, int address) {
00131   _cs=0;
00132   wait_us(1);    
00133      
00134 // sanity check
00135   address &= PT6318_ADDR_MSK;
00136   if (length < 0) {length = 0;}
00137 //  if (length > PT6318_DISPLAY_MEM) {length = PT6318_DISPLAY_MEM;}
00138   if ((address + length) > PT6318_DISPLAY_MEM) {length = PT6318_DISPLAY_MEM - address;}
00139   
00140 //  _spi.write(_flip(PT6318_ADDR_SET_CMD | 0x00)); // Set Address at 0
00141   _spi.write(_flip(PT6318_ADDR_SET_CMD | address)); // Set Address
00142     
00143 //  for (int idx=0; idx<PT6318_DISPLAY_MEM; idx++) {  
00144   for (int idx=0; idx<length; idx++) {    
00145 //    _spi.write(_flip(data[idx])); // data 
00146     _spi.write(_flip(data[address + idx])); // data    
00147   }
00148   
00149   wait_us(1);
00150   _cs=1;
00151 }
00152 
00153 /** Read keydata block from PT6318
00154   *  @param  *keydata Ptr to Array of PT6318_KEY_MEM (=6) bytes for keydata
00155   *  @return bool keypress True when at least one key was pressed
00156   *
00157   * Note: Due to the hardware configuration the PT6318 key matrix scanner will detect multiple keys pressed at same time,
00158   *       but this may also result in some spurious keys being set in keypress data array.
00159   *       It may be best to ignore all keys in those situations. That option is implemented in this method depending on #define setting.  
00160   */ 
00161 bool PT6318::getKeys(KeyData_t *keydata) {
00162   int keypress = 0;
00163   char data;
00164 
00165   // Read keys
00166   _cs=0;
00167   wait_us(1);    
00168   
00169   // Enable Key Read mode
00170   _spi.write(_flip(PT6318_DATA_SET_CMD | PT6318_KEY_RD | PT6318_ADDR_INC | PT6318_MODE_NORM)); // Data set cmd, normal mode, auto incr, read data
00171 
00172   for (int idx=0; idx < PT6318_KEY_MEM; idx++) {
00173     data = _flip(_spi.write(0xFF));    // read keys and correct bitorder
00174     
00175     data = data & PT6318_KEY_MSK; // Mask valid bits
00176     if (data != 0) {  // Check for any pressed key
00177       for (int bit=0; bit < 8; bit++) {
00178         if (data & (1 << bit)) {keypress++;} // Test all significant bits
00179       }
00180     }  
00181 
00182     (*keydata)[idx] = data;            // Store keydata after correcting bitorder
00183   }
00184 
00185   wait_us(1);
00186   _cs=1;    
00187 
00188   // Restore Data Write mode
00189   _writeCmd(PT6318_DATA_SET_CMD, PT6318_DATA_WR | PT6318_ADDR_INC | PT6318_MODE_NORM); // Data set cmd, normal mode, auto incr, write data  
00190       
00191 #if(1)
00192 // Dismiss multiple keypresses at same time
00193   return (keypress == 1);    
00194 #else
00195 // Allow multiple keypress and accept possible spurious keys
00196   return (keypress > 0);
00197 #endif  
00198 }
00199 
00200 /** Read switches from PT6318
00201   *
00202   *  @param  none
00203   *  @return char for switch data (4 least significant bits) 
00204   *
00205   */   
00206 char PT6318::getSwitches() {
00207   char data;
00208 
00209   // Read switches
00210   _cs=0;
00211   wait_us(1);    
00212   
00213   // Enable Switch Read mode
00214   _spi.write(_flip(PT6318_DATA_SET_CMD | PT6318_SW_RD | PT6318_ADDR_INC | PT6318_MODE_NORM)); // Data set cmd, normal mode, auto incr, read data
00215 
00216   data = _flip(_spi.write(0xFF)) & PT6318_SW_MSK;   // read switches and correct bitorder
00217 
00218   wait_us(1);
00219   _cs=1;    
00220 
00221   // Restore Data Write mode
00222   _writeCmd(PT6318_DATA_SET_CMD, PT6318_DATA_WR | PT6318_ADDR_INC | PT6318_MODE_NORM); // Data set cmd, normal mode, auto incr, write data  
00223       
00224   return data;       
00225 }
00226    
00227 
00228 /** Set LEDs
00229   *
00230   * @param  char leds (4 least significant bits)  
00231   * @return none
00232   */
00233 void  PT6318::setLED (char leds) {
00234 
00235   // Set LEDs
00236   _cs=0;
00237   wait_us(1);    
00238   
00239   // Enable LED Write mode
00240   _spi.write(_flip(PT6318_DATA_SET_CMD | PT6318_LED_WR | PT6318_ADDR_INC | PT6318_MODE_NORM)); // Data set cmd, normal mode, auto incr, write data
00241 
00242   _spi.write(_flip(leds & PT6318_LED_MSK));    // write LEDs in correct bitorder
00243 
00244   wait_us(1);
00245   _cs=1;    
00246 
00247   // Restore Data Write mode
00248   _writeCmd(PT6318_DATA_SET_CMD, PT6318_DATA_WR | PT6318_ADDR_INC | PT6318_MODE_NORM); // Data set cmd, normal mode, auto incr, write data  
00249 }
00250 
00251 
00252 
00253 /** Helper to reverse all command or databits. The PT6318 expects LSB first, whereas SPI is MSB first
00254   *  @param  char data
00255   *  @return bitreversed data
00256   */ 
00257 char PT6318::_flip(char data) {
00258  char value=0;
00259   
00260  if (data & 0x01) {value |= 0x80;} ;  
00261  if (data & 0x02) {value |= 0x40;} ;
00262  if (data & 0x04) {value |= 0x20;} ;
00263  if (data & 0x08) {value |= 0x10;} ;
00264  if (data & 0x10) {value |= 0x08;} ;
00265  if (data & 0x20) {value |= 0x04;} ;
00266  if (data & 0x40) {value |= 0x02;} ;
00267  if (data & 0x80) {value |= 0x01;} ;
00268  return value;       
00269 }
00270 
00271 
00272 /** Write command and parameter to PT6318
00273   *  @param  int cmd Command byte
00274   *  &Param  int data Parameters for command
00275   *  @return none
00276   */  
00277 void PT6318::_writeCmd(int cmd, int data){
00278     
00279   _cs=0;
00280   wait_us(1);    
00281  
00282   _spi.write(_flip( (cmd & PT6318_CMD_MSK) | (data & ~PT6318_CMD_MSK)));   
00283  
00284   wait_us(1);
00285   _cs=1;      
00286     
00287 };  
00288 
00289 
00290 
00291 #if (KUH8300_TEST == 1)
00292 /** Constructor for class for driving Princeton PT6318 VFD controller as used in KUH8300
00293   *
00294   *  @brief Supports 8 Grids of 20 Segments and Icons (8 1/2 digits of 14 Segments plus some icons).  
00295   *         Also supports a scanned keyboard of 12 keys and 1 LED.
00296   *  
00297   *  @param  PinName mosi, miso, sclk, cs SPI bus pins
00298   */  
00299 PT6318_KUH8300::PT6318_KUH8300(PinName mosi, PinName miso, PinName sclk, PinName cs) : PT6318(mosi, miso, sclk, cs, Grid8_Seg20) {
00300   _column  = 0;
00301   _columns = KUH8300_NR_DIGITS;    
00302 }  
00303 
00304 #if(0)
00305 #if DOXYGEN_ONLY
00306     /** Write a character to the Display
00307      *
00308      * @param c The character to write to the display
00309      */
00310     int putc(int c);
00311 
00312     /** Write a formatted string to the Display
00313      *
00314      * @param format A printf-style format string, followed by the
00315      *               variables to use in formatting the string.
00316      */
00317     int printf(const char* format, ...);   
00318 #endif
00319 #endif
00320 
00321 /** Locate cursor to a screen column
00322   *
00323   * @param column  The horizontal position from the left, indexed from 0
00324   */
00325 void PT6318_KUH8300::locate(int column) {
00326   //sanity check
00327   if (column < 0) {column = 0;}
00328   if (column > (_columns - 1)) {column = _columns - 1;}  
00329   
00330   _column = column;       
00331 }
00332 
00333 
00334 /** Number of screen columns
00335   *
00336   * @param none
00337   * @return columns
00338   */
00339 int PT6318_KUH8300::columns() {
00340     return _columns;
00341 }
00342 
00343     
00344 /** Clear the screen and locate to 0
00345   * @param bool clrAll Clear Icons also (default = false)
00346   */ 
00347 void PT6318_KUH8300::cls(bool clrAll) {  
00348   int idx;
00349   
00350   if (clrAll) {
00351     //clear local buffer (including Icons)
00352     for (idx=0; idx < (KUH8300_NR_GRIDS * PT6318_BYTES_PER_GRID); idx++) {
00353       _displaybuffer[idx] = 0x00;  
00354     }
00355   }  
00356   else {
00357     //clear local buffer (preserving Icons)
00358     for (int grd=0; grd < KUH8300_NR_GRIDS; grd++) {
00359       idx = grd * PT6318_BYTES_PER_GRID; // 3 bytes for every Grid
00360       _displaybuffer[idx    ] = _displaybuffer[idx    ] & MASK_ICON_GRID[grd][0];  
00361       _displaybuffer[idx + 1] = _displaybuffer[idx + 1] & MASK_ICON_GRID[grd][1];
00362       _displaybuffer[idx + 2] = _displaybuffer[idx + 2] & MASK_ICON_GRID[grd][2];      
00363     }  
00364   }
00365 
00366   writeData(_displaybuffer, (KUH8300_NR_GRIDS * PT6318_BYTES_PER_GRID));
00367 
00368   _column = 0;   
00369 }    
00370 
00371 /** Set Icon
00372   *
00373   * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 24 LSBs
00374   * @return none
00375   */
00376 void PT6318_KUH8300::setIcon(Icon icon) {
00377   int addr, icn;
00378 
00379    icn =        icon  & 0xFFFFFF;
00380   addr = (icon >> 24) & 0xFF; 
00381   addr = (addr - 1) * PT6318_BYTES_PER_GRID;  // 3 Bytes for every Grid
00382     
00383   //Save char...and set bits for icon to write
00384   _displaybuffer[addr    ] = _displaybuffer[addr    ] | LO(icn);      
00385   _displaybuffer[addr + 1] = _displaybuffer[addr + 1] | MD(icn);      
00386   _displaybuffer[addr + 2] = _displaybuffer[addr + 2] | HI(icn);        
00387   writeData(_displaybuffer, (KUH8300_NR_GRIDS * PT6318_BYTES_PER_GRID));
00388 }
00389 
00390 /** Clr Icon
00391   *
00392   * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 24 LSBs
00393   * @return none
00394   */
00395 void PT6318_KUH8300::clrIcon(Icon icon) {
00396   int addr, icn;
00397 
00398    icn =        icon  & 0xFFFFFF;
00399   addr = (icon >> 24) & 0xFF; 
00400   addr = (addr - 1) * PT6318_BYTES_PER_GRID;   // 3 Bytes for every Grid
00401     
00402   //Save char...and clr bits for icon to write
00403   _displaybuffer[addr    ] = _displaybuffer[addr    ] & ~LO(icn);      
00404   _displaybuffer[addr + 1] = _displaybuffer[addr + 1] & ~MD(icn);      
00405   _displaybuffer[addr + 2] = _displaybuffer[addr + 2] & ~HI(icn);        
00406   writeData(_displaybuffer, (KUH8300_NR_GRIDS * PT6318_BYTES_PER_GRID));
00407 }
00408 
00409 
00410 /** Set User Defined Characters (UDC)
00411   *
00412   * @param unsigned char udc_idx  The Index of the UDC (0..7)
00413   * @param int udc_data           The bitpattern for the UDC (16 bits)       
00414   */
00415 void PT6318_KUH8300::setUDC(unsigned char udc_idx, int udc_data) {
00416 
00417   //Sanity check
00418   if (udc_idx > (KUH8300_NR_UDC-1)) {
00419     return;
00420   }
00421 
00422   // Mask out Icon bits?
00423   _UDC_7S[udc_idx] = udc_data & 0xFF;
00424 }
00425 
00426 /** Write a single character (Stream implementation)
00427   */
00428 int PT6318_KUH8300::_putc(int value) {
00429     bool validChar = false;
00430     bool even = false;
00431     char pattern  = 0x00;
00432     int addr;
00433     
00434     if ((value == '\n') || (value == '\r')) {
00435       //No character to write
00436       validChar = false;
00437       
00438       //Update Cursor      
00439       _column = 0;
00440     }
00441     else if ((value >= 0) && (value < KUH8300_NR_UDC)) {
00442       //Character to write
00443       validChar = true;
00444       pattern = _UDC_7S[value];
00445     }  
00446 #if (SHOW_ASCII == 1)
00447     //display all ASCII characters
00448     else if ((value >= FONT_7S_START) && (value <= FONT_7S_END)) {   
00449       //Character to write
00450       validChar = true;
00451       pattern = FONT_7S[value - FONT_7S_START];
00452     } // else
00453 #else
00454     //display only digits and hex characters
00455     else if (value == '-') {
00456       //Character to write
00457       validChar = true;
00458       pattern = C7_MIN;         
00459     }
00460     else if ((value >= (int)'0') && (value <= (int) '9')) {   
00461       //Character to write
00462       validChar = true;
00463       pattern = FONT_7S[value - (int) '0'];
00464     }
00465     else if ((value >= (int) 'A') && (value <= (int) 'F')) {   
00466       //Character to write
00467       validChar = true;
00468       pattern = FONT_7S[10 + value - (int) 'A'];
00469     }
00470     else if ((value >= (int) 'a') && (value <= (int) 'f')) {   
00471       //Character to write
00472       validChar = true;
00473       pattern = FONT_7S[10 + value - (int) 'a'];
00474     } //else
00475 #endif
00476     if (validChar) {
00477       //Character to write
00478  
00479       //Translate between _column and displaybuffer entries
00480       //Note that the KUH8300 has 8 7-Segment digits using 4 Grids. 
00481       //Some of these Grids also have icons that need to be preserved
00482       //_column ==  0 => Grid5 => addr = 12..14
00483       //_column ==  1 => Grid5 => addr = 12..14
00484       // ....
00485       //_column ==  6 => Grid2 => addr =  3..5            
00486       //_column ==  7 => Grid2 => addr =  3..5            
00487       addr = 12 - ((_column >> 1) * PT6318_BYTES_PER_GRID); // 3 Bytes for every Grid;
00488       even = ((_column & 0x01) == 0x00);                    // Odd or Even column
00489       
00490       // pattern is a placeholder, test pattern and set the actual segment depending on the odd or even _column for this Grid
00491       if (pattern & S7_A) {
00492         //Set Segment
00493         if (even) {
00494           _displaybuffer[addr]   = _displaybuffer[addr]   | LO(S7_A0);
00495         }
00496         else {
00497           _displaybuffer[addr+1] = _displaybuffer[addr+1] | MD(S7_A1);
00498         }
00499       }
00500       else {
00501         //Clear Segment
00502         if (even) {
00503           _displaybuffer[addr]   = _displaybuffer[addr]   & ~LO(S7_A0);
00504         }
00505         else {
00506           _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~MD(S7_A1);
00507         }
00508       }
00509 
00510       if (pattern & S7_B) {
00511         //Set Segment
00512         if (even) {
00513           _displaybuffer[addr]   = _displaybuffer[addr]   | LO(S7_B0);
00514         }
00515         else {
00516           _displaybuffer[addr+1] = _displaybuffer[addr+1] | MD(S7_B1);
00517         }
00518       }
00519       else {
00520         //Clear Segment
00521         if (even) {
00522           _displaybuffer[addr]   = _displaybuffer[addr]   & ~LO(S7_B0);
00523         }
00524         else {
00525           _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~MD(S7_B1);
00526         }
00527       }
00528 
00529       if (pattern & S7_C) {
00530         //Set Segment
00531         if (even) {
00532           _displaybuffer[addr]   = _displaybuffer[addr]   | LO(S7_C0);
00533         }
00534         else {
00535           _displaybuffer[addr+1] = _displaybuffer[addr+1] | MD(S7_C1);
00536         }
00537       }
00538       else {
00539         //Clear Segment
00540         if (even) {
00541           _displaybuffer[addr]   = _displaybuffer[addr]   & ~LO(S7_C0);
00542         }
00543         else {
00544           _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~MD(S7_C1);
00545         }
00546       }
00547 
00548       if (pattern & S7_D) {
00549         //Set Segment
00550         if (even) {
00551           _displaybuffer[addr]   = _displaybuffer[addr]   | LO(S7_D0);
00552         }
00553         else {
00554           _displaybuffer[addr+2] = _displaybuffer[addr+2] | HI(S7_D1);
00555         }
00556       }
00557       else {
00558         //Clear Segment
00559         if (even) {
00560           _displaybuffer[addr]   = _displaybuffer[addr]   & ~LO(S7_D0);
00561         }
00562         else {
00563           _displaybuffer[addr+2] = _displaybuffer[addr+2] & ~HI(S7_D1);
00564         }
00565       }
00566 
00567       if (pattern & S7_E) {
00568         //Set Segment
00569         if (even) {
00570           _displaybuffer[addr]   = _displaybuffer[addr]   | LO(S7_E0);
00571         }
00572         else {
00573           _displaybuffer[addr+2] = _displaybuffer[addr+2] | HI(S7_E1);
00574         }
00575       }
00576       else {
00577         //Clear Segment
00578         if (even) {
00579           _displaybuffer[addr]   = _displaybuffer[addr]   & ~LO(S7_E0);
00580         }
00581         else {
00582           _displaybuffer[addr+2] = _displaybuffer[addr+2] & ~HI(S7_E1);
00583         }
00584       }
00585 
00586       if (pattern & S7_F) {
00587         //Set Segment
00588         if (even) {
00589           _displaybuffer[addr]   = _displaybuffer[addr]   | LO(S7_F0);
00590         }
00591         else {
00592           _displaybuffer[addr+1] = _displaybuffer[addr+1] | MD(S7_F1);
00593         }
00594       }
00595       else {
00596         //Clear Segment
00597         if (even) {
00598           _displaybuffer[addr]   = _displaybuffer[addr]   & ~LO(S7_F0);
00599         }
00600         else {
00601           _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~MD(S7_F1);
00602         }
00603       }
00604 
00605       if (pattern & S7_G) {
00606         //Set Segment
00607         if (even) {
00608           _displaybuffer[addr]   = _displaybuffer[addr]   | LO(S7_G0);
00609         }
00610         else {
00611           _displaybuffer[addr+1] = _displaybuffer[addr+1] | MD(S7_G1);
00612         }
00613       }
00614       else {
00615         //Clear Segment
00616         if (even) {
00617           _displaybuffer[addr]   = _displaybuffer[addr]   & ~LO(S7_G0);
00618         }
00619         else {
00620           _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~MD(S7_G1);
00621         }
00622       }
00623 
00624 //      //Save icons...and set bits for character to write
00625 //      _displaybuffer[addr]   = (_displaybuffer[addr]   & MASK_ICON_GRID[_column][0]) | LO(pattern);
00626 //      _displaybuffer[addr+1] = (_displaybuffer[addr+1] & MASK_ICON_GRID[_column][1]) | MD(pattern);
00627 //      _displaybuffer[addr+2] = (_displaybuffer[addr+2] & MASK_ICON_GRID[_column][2]) | HI(pattern);
00628 
00629 //      writeData(_displaybuffer, (KUH8300_NR_GRIDS * PT6318_BYTES_PER_GRID));
00630       writeData(_displaybuffer, PT6318_BYTES_PER_GRID, addr);      
00631                                 
00632       //Update Cursor
00633       _column++;
00634       if (_column > (KUH8300_NR_DIGITS - 1)) {
00635         _column = 0;
00636       }
00637 
00638     } // if validChar           
00639 
00640     return value;
00641 }
00642 
00643 // get a single character (Stream implementation)
00644 int PT6318_KUH8300::_getc() {
00645     return -1;
00646 }
00647 #endif