ADAFRUIT GP9002 VFD Driver, requires GFX-Library

Dependents:   GP9002adafruit

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 
00009 extern const unsigned char BitReverseTable256[] = 
00010 {
00011   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 
00012   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 
00013   0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 
00014   0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 
00015   0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 
00016   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
00017   0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 
00018   0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
00019   0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
00020   0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 
00021   0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
00022   0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
00023   0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 
00024   0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
00025   0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 
00026   0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
00027 };
00028 
00029 
00030 /*
00031 Adafruit_GP9002::Adafruit_GP9002(int8_t SCLK, int8_t MISO, int8_t MOSI, 
00032     int8_t CS, int8_t DC) : Adafruit_GFX(128, 64) {
00033   _sclk = SCLK;
00034   _miso = MISO;
00035   _mosi = MOSI;
00036   _cs = CS;
00037   _dc = DC;
00038   hwSPI = false;
00039 }
00040 
00041 Adafruit_GP9002::Adafruit_GP9002(int8_t CS, int8_t DC) :
00042     Adafruit_GFX(128, 64) {
00043   _sclk = -1;
00044   _miso = -1;
00045   _mosi = -1;
00046   _cs = CS;
00047   _dc = DC;
00048   hwSPI = true;
00049 }
00050 */
00051 Adafruit_GP9002::Adafruit_GP9002(SPI &SPIport, PinName CS, PinName DC): Adafruit_GFX(128, 64), _spi(SPIport), _dc(DC), _cs(CS,1){}  ;
00052 
00053 
00054 void Adafruit_GP9002::begin(void) {
00055   // set pin directions
00056 //  pinMode(_dc, OUTPUT);
00057 //  pinMode(_cs, OUTPUT);
00058 
00059 /*  if (! hwSPI) {
00060     pinMode(_mosi, OUTPUT);
00061     pinMode(_miso, INPUT);
00062     pinMode(_sclk, OUTPUT);
00063     
00064     clkport     = portOutputRegister(digitalPinToPort(_sclk));
00065     clkpinmask  = digitalPinToBitMask(_sclk);
00066     mosiport    = portOutputRegister(digitalPinToPort(_mosi));
00067     mosipinmask = digitalPinToBitMask(_mosi);
00068     misopin = portInputRegister(digitalPinToPort(_miso));
00069     misopinmask = digitalPinToBitMask(_miso);
00070   } else {
00071   */  
00072     //SPI.begin();
00073    // SPI.setClockDivider(SPI_CLOCK_DIV4);
00074    // SPI.setBitOrder(MSBFIRST);
00075     //SPI.setDataMode(SPI_MODE0);
00076      _spi.format(8,3); // I'm sure this is a mode 3 device
00077      _spi.frequency(2000000); //
00078  // }
00079  /*
00080   csport    = portOutputRegister(digitalPinToPort(_cs));
00081   cspinmask = digitalPinToBitMask(_cs);
00082   dcport    = portOutputRegister(digitalPinToPort(_dc));
00083   dcpinmask = digitalPinToBitMask(_dc);
00084   */
00085 
00086   command(GP9002_DISPLAY);
00087   dataWrite(GP9002_DISPLAY_MONOCHROME);
00088   command(GP9002_LOWERADDR1);
00089   dataWrite(0x0);
00090   command(GP9002_HIGHERADDR1);
00091   dataWrite(0x0);
00092   command(GP9002_LOWERADDR2);
00093   dataWrite(0x0);
00094   command(GP9002_HIGHERADDR2);
00095   dataWrite(0x4);
00096   command(GP9002_OR);
00097   command(GP9002_CLEARSCREEN);
00098   command(GP9002_DISPLAY1ON);
00099 
00100   // hold the address so we can read and then write
00101   command(GP9002_ADDRHELD);
00102 }
00103 
00104 
00105 
00106 // updated high speed drawing!
00107 void Adafruit_GP9002::drawFastVLine(int16_t x, int16_t orig_y, int16_t h, uint16_t color) {
00108   if ((x < 0) || (x >= width()) || (orig_y >= height())) return;
00109   //if ((orig_y+h) >= height()) 
00110   //  h = height() - orig_y -1;
00111 
00112   //drawLine(x, orig_y, x, orig_y+h, color); return;
00113 
00114   while (h) {
00115     if ((h >= 8) && ((orig_y) % 8 == 0)) 
00116       break;
00117     drawPixel(x, orig_y, color);
00118     orig_y++;
00119     h--;
00120   }
00121 
00122   if (h >= 8) {
00123       // calculate addr
00124       uint16_t addr = 0;
00125       addr = x*8;
00126   //    uint16_t y = orig_y+h-8;
00127        uint16_t y=orig_y;
00128   //    y = 63 - y;                 //why?
00129       addr += y/8;
00130 
00131   //    Serial.println(addr, HEX);  ///debug line ?
00132       command(GP9002_ADDRINCR);
00133       command(GP9002_ADDRL);
00134       dataWrite(addr & 0xFF);
00135       command(GP9002_ADDRH);
00136       dataWrite(addr >> 8);
00137       command(GP9002_DATAWRITE);
00138 
00139       while (h >= 8) {
00140     // draw 8 pixels at once!
00141     if (color) 
00142       dataWrite(0xFF);
00143     else 
00144       dataWrite(0x00);
00145     h -= 8;
00146     orig_y += 8;
00147       }
00148   }
00149   while (h+1) {
00150     drawPixel(x, orig_y-1, color);
00151     orig_y++;
00152     h--;
00153   }
00154 
00155 }
00156 
00157 // the most basic function, set a single pixel
00158 void Adafruit_GP9002::drawPixel(int16_t x, int16_t y, uint16_t color) {
00159   if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
00160     return;
00161 
00162   uint8_t p;
00163   
00164   // calculate addr
00165   uint16_t addr = 0;
00166   addr = x*8;
00167  // y = 63 - y;                //why
00168   addr += y/8;
00169 
00170   command(GP9002_ADDRHELD);
00171   command(GP9002_ADDRL);
00172   dataWrite(addr & 0xFF);
00173   command(GP9002_ADDRH);
00174   dataWrite(addr >> 8);
00175   command(GP9002_DATAREAD);
00176   dataRead();
00177   p = dataRead();
00178 
00179   //Serial.println(p, HEX);
00180 
00181   if (color)
00182     p |= (1 << (7-(y % 8)));
00183   else
00184     p &= ~(1 << (7-(y % 8)));
00185   command(GP9002_DATAWRITE);
00186   dataWrite(p);
00187 }
00188 
00189   
00190 
00191 void Adafruit_GP9002::invert(bool i) {
00192   // This is kinda clumsy but it does work
00193   // fill the opposite screen with all on pixels so we can invert!
00194   uint16_t addr = 0x400;
00195 
00196   command(GP9002_ADDRINCR);
00197   command(GP9002_ADDRL);
00198   dataWrite(addr & 0xFF);
00199   command(GP9002_ADDRH);
00200   dataWrite(addr >> 8);
00201   command(GP9002_DATAWRITE);
00202 
00203   if (i) {
00204     while (addr < 0x0800) {
00205       dataWrite(0xFF);
00206       addr++;
00207     }
00208     command(GP9002_XOR);
00209   } else {
00210     while (addr < 0x0800) {
00211       dataWrite(0x00);
00212       addr++;
00213     }
00214     command(GP9002_OR);
00215   }
00216   command(GP9002_ADDRHELD);
00217 
00218 }
00219 /*
00220 void Adafruit_GP9002::slowSPIwrite(uint8_t d) {
00221  for (uint8_t i=0; i<8; i++) {
00222    digitalWrite(_sclk, LOW);
00223    if (d & _BV(i)) {
00224      digitalWrite(_mosi, HIGH);
00225    } else {
00226      digitalWrite(_mosi, LOW);
00227    }
00228    digitalWrite(_sclk, HIGH);
00229  }
00230 }
00231 */
00232 /*
00233 inline void Adafruit_GP9002::fastSPIwrite(uint8_t d) {
00234   if (hwSPI) {
00235     SPDR = d;
00236     while(!(SPSR & _BV(SPIF)));
00237     return;
00238   }
00239   for(uint8_t bit = 0x1; bit != 0x00; bit <<= 1) {
00240     *clkport &= ~clkpinmask;
00241     if(d & bit) *mosiport |=  mosipinmask;
00242     else        *mosiport &= ~mosipinmask;
00243     *clkport |=  clkpinmask;
00244   }
00245 }
00246 */
00247 /*
00248 uint8_t Adafruit_GP9002::slowSPIread(void) {
00249  uint8_t reply = 0;
00250  for (uint8_t i=0; i<8; i++) {
00251    digitalWrite(_sclk, LOW);
00252 
00253    digitalWrite(_sclk, HIGH);
00254    if (digitalRead(_miso)) 
00255      reply |= _BV(i);
00256  }
00257  return reply;
00258 }
00259 
00260 inline uint8_t Adafruit_GP9002::fastSPIread(void) {
00261  uint8_t reply = 0;
00262  for (uint8_t i=0; i<8; i++) {
00263    *clkport &= ~clkpinmask;
00264    
00265    *clkport |=  clkpinmask;
00266    if ((*misopin) & misopinmask)
00267      reply |= _BV(i);
00268  }
00269  return reply;
00270 }
00271 */
00272 
00273 void Adafruit_GP9002::command(uint8_t d) { 
00274 /*
00275   *dcport |= dcpinmask;
00276   *csport &= ~cspinmask;
00277   fastSPIwrite(d);
00278   *csport |= cspinmask;
00279   delayMicroseconds(1); // should be 400ns actually
00280 */
00281 _dc=1;
00282 _cs=0;
00283 _spi.write(BitReverseTable256[d]);
00284 _cs=1;
00285 wait_us(1);
00286 }
00287 
00288 inline void Adafruit_GP9002::dataWrite(uint8_t d) {
00289 /*
00290   *dcport &= ~dcpinmask;
00291   *csport &= ~cspinmask;
00292 
00293   fastSPIwrite(d);
00294 
00295   *csport |= cspinmask;
00296   delayMicroseconds(1); // should be 600ns actually
00297 */
00298 _dc=0;
00299 _cs=0;
00300 _spi.write(BitReverseTable256[d]);
00301 _cs=1;
00302 wait_us(1);
00303 }
00304 
00305 inline uint8_t Adafruit_GP9002::dataRead() {
00306   uint8_t r;
00307 /*
00308   *dcport &= ~dcpinmask;
00309   *csport &= ~cspinmask;
00310 
00311   r = fastSPIread();
00312 
00313   *csport |= cspinmask;
00314   delayMicroseconds(1); 
00315   */
00316 
00317 _dc=0;
00318 _cs=0;
00319 r=BitReverseTable256[_spi.write(0)&0xFF];
00320 _cs=1;
00321 wait_us(1);
00322 
00323 
00324  return r;
00325 }
00326 
00327 void Adafruit_GP9002::setBrightness(uint8_t val) {
00328   
00329 }
00330 
00331 // clear everything
00332 void Adafruit_GP9002::clearDisplay(void) {
00333   command(GP9002_CLEARSCREEN);
00334 
00335   wait_ms(1);
00336 }
00337 
00338 void Adafruit_GP9002::displayOff(void) {
00339   command(GP9002_DISPLAYSOFF); 
00340 }
00341 void Adafruit_GP9002::displayOn(void) {
00342    command(GP9002_DISPLAY1ON);
00343 }
00344 
00345