Oliver Broad / Adafruit-GP9002-Grayscale-VFD-Library

Dependencies:   bitreversetable256

Dependents:   GP9002af_gray

Fork of Adafruit-GP9002-Graphic-VFD-Library by Oliver Broad

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Adafruit_GP9002.cpp Source File

Adafruit_GP9002.cpp

00001 /*#include <avr/pgmspace.h>
00002 #include <util/delay.h>
00003 #include <stdlib.h>*/
00004 
00005 #include "Adafruit_GFX.h"
00006 #include "Adafruit_GP9002.h"
00007 #include "glcdfont.c"
00008 #include "bitreversetable256.h"
00009 
00010 
00011 
00012 /*
00013 Adafruit_GP9002::Adafruit_GP9002(int8_t SCLK, int8_t MISO, int8_t MOSI, 
00014     int8_t CS, int8_t DC) : Adafruit_GFX(128, 64) {
00015   _sclk = SCLK;
00016   _miso = MISO;
00017   _mosi = MOSI;
00018   _cs = CS;
00019   _dc = DC;
00020   hwSPI = false;
00021 }
00022 
00023 Adafruit_GP9002::Adafruit_GP9002(int8_t CS, int8_t DC) :
00024     Adafruit_GFX(128, 64) {
00025   _sclk = -1;
00026   _miso = -1;
00027   _mosi = -1;
00028   _cs = CS;
00029   _dc = DC;
00030   hwSPI = true;
00031 }
00032 */
00033 Adafruit_GP9002::Adafruit_GP9002(SPI &SPIport, PinName CS, PinName DC): Adafruit_GFX(128, 64), _spi(SPIport), _dc(DC), _cs(CS,1){}  ;
00034 
00035 
00036 void Adafruit_GP9002::begin(void) {
00037   // set pin directions
00038 //  pinMode(_dc, OUTPUT);
00039 //  pinMode(_cs, OUTPUT);
00040 
00041 /*  if (! hwSPI) {
00042     pinMode(_mosi, OUTPUT);
00043     pinMode(_miso, INPUT);
00044     pinMode(_sclk, OUTPUT);
00045     
00046     clkport     = portOutputRegister(digitalPinToPort(_sclk));
00047     clkpinmask  = digitalPinToBitMask(_sclk);
00048     mosiport    = portOutputRegister(digitalPinToPort(_mosi));
00049     mosipinmask = digitalPinToBitMask(_mosi);
00050     misopin = portInputRegister(digitalPinToPort(_miso));
00051     misopinmask = digitalPinToBitMask(_miso);
00052   } else {
00053   */  
00054     //SPI.begin();
00055    // SPI.setClockDivider(SPI_CLOCK_DIV4);
00056    // SPI.setBitOrder(MSBFIRST);
00057     //SPI.setDataMode(SPI_MODE0);
00058      _spi.format(8,3); // I'm sure this is a mode 3 device
00059      _spi.frequency(2000000); //
00060  // }
00061  /*
00062   csport    = portOutputRegister(digitalPinToPort(_cs));
00063   cspinmask = digitalPinToBitMask(_cs);
00064   dcport    = portOutputRegister(digitalPinToPort(_dc));
00065   dcpinmask = digitalPinToBitMask(_dc);
00066   */
00067 
00068   command(GP9002_DISPLAYSOFF);
00069  // command(GP9002_DISPLAY1ON); //defer till display clear
00070   command(GP9002_DISPLAY);
00071   dataWrite(GP9002_DISPLAY_GRAYSCALE);
00072   command(GP9002_LOWERADDR1);
00073   dataWrite(0x0);
00074   command(GP9002_HIGHERADDR1);
00075   dataWrite(0x0);
00076 //  command(GP9002_LOWERADDR2);
00077 //  dataWrite(0x0);
00078  // command(GP9002_HIGHERADDR2);
00079 //  dataWrite(0x4);
00080  // command(GP9002_OR);  //contradicted by display1on, so no
00081   command(GP9002_CLEARSCREEN);
00082   wait_us(500);
00083   command(GP9002_DISPLAY1ON);
00084 
00085   // hold the address so we can read and then write
00086   command(GP9002_ADDRHELD);
00087   addrcache=-1; //address OK but cmd not set
00088   bytecache=0; //known because display cleared
00089 }
00090 
00091 
00092 
00093 // updated high speed drawing!
00094 void Adafruit_GP9002::drawFastVLine(int16_t x, int16_t orig_y, int16_t h, uint16_t color) {
00095   if ((x < 0) || (x >= width()) || (orig_y >= height())) return;
00096   //if ((orig_y+h) >= height()) 
00097   //  h = height() - orig_y -1;
00098 
00099   //drawLine(x, orig_y, x, orig_y+h, color); return;
00100 
00101   while (h) {
00102     if ((h >= 4) && ((orig_y) % 4 == 0)) 
00103       break;
00104     drawPixel(x, orig_y, color);
00105     orig_y++;
00106     h--;
00107   }
00108 
00109   if (h >= 4) {
00110       // calculate addr
00111       uint16_t addr = 0;
00112       addr = x*16;
00113   //    uint16_t y = orig_y+h-8;
00114        uint16_t y=orig_y;
00115   //    y = 63 - y;                 //why?
00116       addr += y/4;
00117 
00118   //    Serial.println(addr, HEX);  ///debug line ?
00119       addrcache=-1; //invalidate the cache
00120       command(GP9002_ADDRINCR);
00121       command(GP9002_ADDRL);
00122       dataWrite(addr & 0xFF);
00123       command(GP9002_ADDRH);
00124       dataWrite(addr >> 8);
00125       command(GP9002_DATAWRITE);
00126 
00127       while (h >= 4) {
00128     // draw 8 pixels at once!
00129     if (color) 
00130       dataWrite(0b01010101 * (color & 3));
00131     else 
00132       dataWrite(0x00);
00133     h -= 4;
00134     orig_y += 4;
00135       }
00136   }
00137   while (h+1) {
00138     drawPixel(x, orig_y-1, color);
00139     orig_y++;
00140     h--;
00141   }
00142 
00143 }
00144 
00145 // the most basic function, set a single pixel
00146 void Adafruit_GP9002::drawPixel(int16_t x, int16_t y, uint16_t color) {
00147   if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
00148     return;
00149 
00150   //uint8_t p;
00151   
00152   // calculate addr
00153   uint16_t addr = 0;
00154   addr = x*16;
00155  // y = 63 - y;                //why
00156   addr += y/4;
00157   if (addr != addrcache)
00158   {
00159     addrcache=addr;
00160     command(GP9002_ADDRHELD);
00161     command(GP9002_ADDRL);
00162     dataWrite(addr & 0xFF);
00163     command(GP9002_ADDRH);
00164     dataWrite(addr >> 8);
00165     command(GP9002_DATAREAD);
00166     dataRead();
00167     bytecache = dataRead();
00168     command(GP9002_DATAWRITE); //warning: subsequent drawpixel ops will assume this
00169   }
00170   y=0xc0>>((y & 3) <<1);
00171   color*=0b01010101;
00172   //Serial.println(p, HEX);
00173   bytecache &= ~y;
00174 
00175   bytecache |= color&y;
00176   
00177   dataWrite(bytecache);
00178 }
00179 
00180   
00181 /* forbidden
00182 void Adafruit_GP9002::invert(bool i) {
00183   // This is kinda clumsy but it does work
00184   // fill the opposite screen with all on pixels so we can invert!
00185   uint16_t addr = 0x400;
00186 
00187   command(GP9002_ADDRINCR);
00188   command(GP9002_ADDRL);
00189   dataWrite(addr & 0xFF);
00190   command(GP9002_ADDRH);
00191   dataWrite(addr >> 8);
00192   command(GP9002_DATAWRITE);
00193 
00194   if (i) {
00195     while (addr < 0x0800) {
00196       dataWrite(0xFF);
00197       addr++;
00198     }
00199     command(GP9002_XOR);
00200   } else {
00201     while (addr < 0x0800) {
00202       dataWrite(0x00);
00203       addr++;
00204     }
00205     command(GP9002_OR);
00206   }
00207   command(GP9002_ADDRHELD);
00208 
00209 }
00210 */
00211 /*
00212 void Adafruit_GP9002::slowSPIwrite(uint8_t d) {
00213  for (uint8_t i=0; i<8; i++) {
00214    digitalWrite(_sclk, LOW);
00215    if (d & _BV(i)) {
00216      digitalWrite(_mosi, HIGH);
00217    } else {
00218      digitalWrite(_mosi, LOW);
00219    }
00220    digitalWrite(_sclk, HIGH);
00221  }
00222 }
00223 */
00224 /*
00225 inline void Adafruit_GP9002::fastSPIwrite(uint8_t d) {
00226   if (hwSPI) {
00227     SPDR = d;
00228     while(!(SPSR & _BV(SPIF)));
00229     return;
00230   }
00231   for(uint8_t bit = 0x1; bit != 0x00; bit <<= 1) {
00232     *clkport &= ~clkpinmask;
00233     if(d & bit) *mosiport |=  mosipinmask;
00234     else        *mosiport &= ~mosipinmask;
00235     *clkport |=  clkpinmask;
00236   }
00237 }
00238 */
00239 /*
00240 uint8_t Adafruit_GP9002::slowSPIread(void) {
00241  uint8_t reply = 0;
00242  for (uint8_t i=0; i<8; i++) {
00243    digitalWrite(_sclk, LOW);
00244 
00245    digitalWrite(_sclk, HIGH);
00246    if (digitalRead(_miso)) 
00247      reply |= _BV(i);
00248  }
00249  return reply;
00250 }
00251 
00252 inline uint8_t Adafruit_GP9002::fastSPIread(void) {
00253  uint8_t reply = 0;
00254  for (uint8_t i=0; i<8; i++) {
00255    *clkport &= ~clkpinmask;
00256    
00257    *clkport |=  clkpinmask;
00258    if ((*misopin) & misopinmask)
00259      reply |= _BV(i);
00260  }
00261  return reply;
00262 }
00263 */
00264 
00265 void Adafruit_GP9002::command(uint8_t d) { 
00266 /*
00267   *dcport |= dcpinmask;
00268   *csport &= ~cspinmask;
00269   fastSPIwrite(d);
00270   *csport |= cspinmask;
00271   delayMicroseconds(1); // should be 400ns actually
00272 */
00273 _dc=1;
00274 _cs=0;
00275 _spi.write(BitReverseTable256[d]);
00276 _cs=1;
00277 wait_us(1);
00278 }
00279 
00280 inline void Adafruit_GP9002::dataWrite(uint8_t d) {
00281 /*
00282   *dcport &= ~dcpinmask;
00283   *csport &= ~cspinmask;
00284 
00285   fastSPIwrite(d);
00286 
00287   *csport |= cspinmask;
00288   delayMicroseconds(1); // should be 600ns actually
00289 */
00290 _dc=0;
00291 _cs=0;
00292 _spi.write(BitReverseTable256[d]);
00293 _cs=1;
00294 wait_us(1);
00295 }
00296 
00297 inline uint8_t Adafruit_GP9002::dataRead() {
00298   uint8_t r;
00299 /*
00300   *dcport &= ~dcpinmask;
00301   *csport &= ~cspinmask;
00302 
00303   r = fastSPIread();
00304 
00305   *csport |= cspinmask;
00306   delayMicroseconds(1); 
00307   */
00308 
00309 _dc=0;
00310 _cs=0;
00311 r=BitReverseTable256[_spi.write(0)&0xFF];
00312 _cs=1;
00313 wait_us(1);
00314 
00315 
00316  return r;
00317 }
00318 
00319 void Adafruit_GP9002::setBrightness(uint8_t val) {
00320   
00321 }
00322 
00323 // clear everything
00324 void Adafruit_GP9002::clearDisplay(void) {
00325   command(GP9002_CLEARSCREEN);
00326 
00327   wait_us(500);
00328   addrcache=-1; //address OK but cmd not set
00329 }
00330 
00331 void Adafruit_GP9002::displayOff(void) {
00332   command(GP9002_DISPLAYSOFF); 
00333   addrcache=-1; //address OK but cmd not set
00334 }
00335 void Adafruit_GP9002::displayOn(void) {
00336    command(GP9002_DISPLAY1ON);
00337   addrcache=-1; //address OK but cmd not set
00338 }
00339 
00340