Modified Adafruit GFX library with support for selecting displays using an 74HC4067 Analog Multiplexer

Dependents:   mbed_oled

Fork of Adafruit_GFX by Neal Horman

Committer:
jimconner
Date:
Thu Feb 05 22:07:19 2015 +0000
Revision:
19:f393e67ed0b5
Parent:
17:bf0e4072b06d
Child:
20:5fa5c734e5f2
Support for 74HC4067 4-to-16 analog Mux now complete. We now use a PortOut pointer to specify the four control pins connected to the MUX and the mux value to write to the pins before an I2C command is executed.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nkhorman 0:c3dcd4c4983a 1 /*********************************************************************
nkhorman 0:c3dcd4c4983a 2 This is a library for our Monochrome OLEDs based on SSD1306 drivers
nkhorman 0:c3dcd4c4983a 3
nkhorman 0:c3dcd4c4983a 4 Pick one up today in the adafruit shop!
nkhorman 0:c3dcd4c4983a 5 ------> http://www.adafruit.com/category/63_98
nkhorman 0:c3dcd4c4983a 6
nkhorman 0:c3dcd4c4983a 7 These displays use SPI to communicate, 4 or 5 pins are required to
nkhorman 0:c3dcd4c4983a 8 interface
nkhorman 0:c3dcd4c4983a 9
nkhorman 0:c3dcd4c4983a 10 Adafruit invests time and resources providing this open source code,
nkhorman 0:c3dcd4c4983a 11 please support Adafruit and open-source hardware by purchasing
nkhorman 0:c3dcd4c4983a 12 products from Adafruit!
nkhorman 0:c3dcd4c4983a 13
nkhorman 0:c3dcd4c4983a 14 Written by Limor Fried/Ladyada for Adafruit Industries.
nkhorman 0:c3dcd4c4983a 15 BSD license, check license.txt for more information
nkhorman 0:c3dcd4c4983a 16 All text above, and the splash screen must be included in any redistribution
nkhorman 0:c3dcd4c4983a 17 *********************************************************************/
nkhorman 0:c3dcd4c4983a 18
nkhorman 0:c3dcd4c4983a 19 /*
nkhorman 9:ddb97c9850a2 20 * Modified by Neal Horman 7/14/2012 for use in mbed
nkhorman 0:c3dcd4c4983a 21 */
nkhorman 0:c3dcd4c4983a 22
nkhorman 0:c3dcd4c4983a 23 #ifndef _ADAFRUIT_SSD1306_H_
nkhorman 0:c3dcd4c4983a 24 #define _ADAFRUIT_SSD1306_H_
nkhorman 0:c3dcd4c4983a 25
nkhorman 0:c3dcd4c4983a 26 #include "mbed.h"
nkhorman 0:c3dcd4c4983a 27 #include "Adafruit_GFX.h"
nkhorman 0:c3dcd4c4983a 28
nkhorman 9:ddb97c9850a2 29 #include <vector>
nkhorman 9:ddb97c9850a2 30 #include <algorithm>
nkhorman 0:c3dcd4c4983a 31
nkhorman 9:ddb97c9850a2 32 // A DigitalOut sub-class that provides a constructed default state
nkhorman 9:ddb97c9850a2 33 class DigitalOut2 : public DigitalOut
nkhorman 9:ddb97c9850a2 34 {
nkhorman 9:ddb97c9850a2 35 public:
nkhorman 9:ddb97c9850a2 36 DigitalOut2(PinName pin, bool active = false) : DigitalOut(pin) { write(active); };
nkhorman 9:ddb97c9850a2 37 DigitalOut2& operator= (int value) { write(value); return *this; };
nkhorman 9:ddb97c9850a2 38 DigitalOut2& operator= (DigitalOut2& rhs) { write(rhs.read()); return *this; };
nkhorman 9:ddb97c9850a2 39 operator int() { return read(); };
nkhorman 9:ddb97c9850a2 40 };
Neal Horman 6:1be3e3b46eb7 41
nkhorman 0:c3dcd4c4983a 42 #define SSD1306_EXTERNALVCC 0x1
nkhorman 0:c3dcd4c4983a 43 #define SSD1306_SWITCHCAPVCC 0x2
nkhorman 0:c3dcd4c4983a 44
nkhorman 11:86909e6db3c8 45 /** The pure base class for the SSD1306 display driver.
nkhorman 11:86909e6db3c8 46 *
nkhorman 11:86909e6db3c8 47 * You should derive from this for a new transport interface type,
nkhorman 11:86909e6db3c8 48 * such as the SPI and I2C drivers.
nkhorman 11:86909e6db3c8 49 */
nkhorman 0:c3dcd4c4983a 50 class Adafruit_SSD1306 : public Adafruit_GFX
nkhorman 0:c3dcd4c4983a 51 {
nkhorman 9:ddb97c9850a2 52 public:
nkhorman 9:ddb97c9850a2 53 Adafruit_SSD1306(PinName RST, uint8_t rawHeight = 32, uint8_t rawWidth = 128)
nkhorman 9:ddb97c9850a2 54 : Adafruit_GFX(rawWidth,rawHeight)
nkhorman 9:ddb97c9850a2 55 , rst(RST,false)
nkhorman 11:86909e6db3c8 56 {
nkhorman 11:86909e6db3c8 57 buffer.resize(rawHeight * rawWidth / 8);
nkhorman 11:86909e6db3c8 58 };
nkhorman 9:ddb97c9850a2 59
nkhorman 9:ddb97c9850a2 60 void begin(uint8_t switchvcc = SSD1306_SWITCHCAPVCC);
nkhorman 11:86909e6db3c8 61
nkhorman 11:86909e6db3c8 62 // These must be implemented in the derived transport driver
nkhorman 9:ddb97c9850a2 63 virtual void command(uint8_t c) = 0;
nkhorman 9:ddb97c9850a2 64 virtual void data(uint8_t c) = 0;
nkhorman 11:86909e6db3c8 65 virtual void drawPixel(int16_t x, int16_t y, uint16_t color);
nkhorman 11:86909e6db3c8 66
nkhorman 11:86909e6db3c8 67 /// Clear the display buffer
nkhorman 9:ddb97c9850a2 68 void clearDisplay(void);
nkhorman 9:ddb97c9850a2 69 virtual void invertDisplay(bool i);
nkhorman 11:86909e6db3c8 70
nkhorman 11:86909e6db3c8 71 /// Cause the display to be updated with the buffer content.
nkhorman 9:ddb97c9850a2 72 void display();
nkhorman 11:86909e6db3c8 73 /// Fill the buffer with the AdaFruit splash screen.
nkhorman 9:ddb97c9850a2 74 virtual void splash();
nkhorman 9:ddb97c9850a2 75
nkhorman 9:ddb97c9850a2 76 protected:
nkhorman 9:ddb97c9850a2 77 virtual void sendDisplayBuffer() = 0;
nkhorman 9:ddb97c9850a2 78 DigitalOut2 rst;
nkhorman 9:ddb97c9850a2 79
nkhorman 9:ddb97c9850a2 80 // the memory buffer for the LCD
nkhorman 9:ddb97c9850a2 81 std::vector<uint8_t> buffer;
nkhorman 9:ddb97c9850a2 82 };
nkhorman 9:ddb97c9850a2 83
nkhorman 11:86909e6db3c8 84
nkhorman 11:86909e6db3c8 85 /** This is the SPI SSD1306 display driver transport class
nkhorman 11:86909e6db3c8 86 *
nkhorman 11:86909e6db3c8 87 */
nkhorman 9:ddb97c9850a2 88 class Adafruit_SSD1306_Spi : public Adafruit_SSD1306
nkhorman 9:ddb97c9850a2 89 {
nkhorman 9:ddb97c9850a2 90 public:
nkhorman 11:86909e6db3c8 91 /** Create a SSD1306 SPI transport display driver instance with the specified DC, RST, and CS pins, as well as the display dimentions
nkhorman 11:86909e6db3c8 92 *
nkhorman 11:86909e6db3c8 93 * Required parameters
nkhorman 11:86909e6db3c8 94 * @param spi - a reference to an initialized SPI object
nkhorman 11:86909e6db3c8 95 * @param DC (Data/Command) pin name
nkhorman 11:86909e6db3c8 96 * @param RST (Reset) pin name
nkhorman 11:86909e6db3c8 97 * @param CS (Chip Select) pin name
nkhorman 11:86909e6db3c8 98 *
nkhorman 11:86909e6db3c8 99 * Optional parameters
nkhorman 11:86909e6db3c8 100 * @param rawHeight - the vertical number of pixels for the display, defaults to 32
nkhorman 11:86909e6db3c8 101 * @param rawWidth - the horizonal number of pixels for the display, defaults to 128
nkhorman 11:86909e6db3c8 102 */
nkhorman 9:ddb97c9850a2 103 Adafruit_SSD1306_Spi(SPI &spi, PinName DC, PinName RST, PinName CS, uint8_t rawHieght = 32, uint8_t rawWidth = 128)
nkhorman 9:ddb97c9850a2 104 : Adafruit_SSD1306(RST, rawHieght, rawWidth)
nkhorman 9:ddb97c9850a2 105 , cs(CS,true)
nkhorman 9:ddb97c9850a2 106 , dc(DC,false)
nkhorman 9:ddb97c9850a2 107 , mspi(spi)
nkhorman 9:ddb97c9850a2 108 {
nkhorman 9:ddb97c9850a2 109 begin();
nkhorman 9:ddb97c9850a2 110 splash();
nkhorman 9:ddb97c9850a2 111 display();
nkhorman 9:ddb97c9850a2 112 };
nkhorman 9:ddb97c9850a2 113
nkhorman 9:ddb97c9850a2 114 virtual void command(uint8_t c)
nkhorman 9:ddb97c9850a2 115 {
nkhorman 9:ddb97c9850a2 116 cs = 1;
nkhorman 9:ddb97c9850a2 117 dc = 0;
nkhorman 9:ddb97c9850a2 118 cs = 0;
nkhorman 9:ddb97c9850a2 119 mspi.write(c);
nkhorman 9:ddb97c9850a2 120 cs = 1;
nkhorman 9:ddb97c9850a2 121 };
nkhorman 9:ddb97c9850a2 122
nkhorman 9:ddb97c9850a2 123 virtual void data(uint8_t c)
nkhorman 9:ddb97c9850a2 124 {
nkhorman 9:ddb97c9850a2 125 cs = 1;
nkhorman 9:ddb97c9850a2 126 dc = 1;
nkhorman 9:ddb97c9850a2 127 cs = 0;
nkhorman 9:ddb97c9850a2 128 mspi.write(c);
nkhorman 9:ddb97c9850a2 129 cs = 1;
nkhorman 9:ddb97c9850a2 130 };
nkhorman 9:ddb97c9850a2 131
nkhorman 9:ddb97c9850a2 132 protected:
nkhorman 9:ddb97c9850a2 133 virtual void sendDisplayBuffer()
nkhorman 9:ddb97c9850a2 134 {
nkhorman 9:ddb97c9850a2 135 cs = 1;
nkhorman 9:ddb97c9850a2 136 dc = 1;
nkhorman 9:ddb97c9850a2 137 cs = 0;
nkhorman 9:ddb97c9850a2 138
nkhorman 9:ddb97c9850a2 139 for(uint16_t i=0, q=buffer.size(); i<q; i++)
nkhorman 9:ddb97c9850a2 140 mspi.write(buffer[i]);
nkhorman 9:ddb97c9850a2 141
nkhorman 11:86909e6db3c8 142 if(height() == 32)
nkhorman 11:86909e6db3c8 143 {
nkhorman 11:86909e6db3c8 144 for(uint16_t i=0, q=buffer.size(); i<q; i++)
nkhorman 11:86909e6db3c8 145 mspi.write(0);
nkhorman 11:86909e6db3c8 146 }
nkhorman 11:86909e6db3c8 147
nkhorman 9:ddb97c9850a2 148 cs = 1;
nkhorman 9:ddb97c9850a2 149 };
nkhorman 9:ddb97c9850a2 150
nkhorman 9:ddb97c9850a2 151 DigitalOut2 cs, dc;
nkhorman 9:ddb97c9850a2 152 SPI &mspi;
nkhorman 9:ddb97c9850a2 153 };
nkhorman 9:ddb97c9850a2 154
nkhorman 11:86909e6db3c8 155 /** This is the I2C SSD1306 display driver transport class
nkhorman 11:86909e6db3c8 156 *
nkhorman 11:86909e6db3c8 157 */
nkhorman 9:ddb97c9850a2 158 class Adafruit_SSD1306_I2c : public Adafruit_SSD1306
nkhorman 9:ddb97c9850a2 159 {
nkhorman 9:ddb97c9850a2 160 public:
nkhorman 9:ddb97c9850a2 161 #define SSD_I2C_ADDRESS 0x78
nkhorman 11:86909e6db3c8 162 /** Create a SSD1306 I2C transport display driver instance with the specified RST pin name, the I2C address, as well as the display dimensions
nkhorman 11:86909e6db3c8 163 *
nkhorman 11:86909e6db3c8 164 * Required parameters
nkhorman 11:86909e6db3c8 165 * @param i2c - A reference to an initialized I2C object
nkhorman 11:86909e6db3c8 166 * @param RST - The Reset pin name
nkhorman 11:86909e6db3c8 167 *
nkhorman 11:86909e6db3c8 168 * Optional parameters
nkhorman 11:86909e6db3c8 169 * @param i2cAddress - The i2c address of the display
nkhorman 11:86909e6db3c8 170 * @param rawHeight - The vertical number of pixels for the display, defaults to 32
nkhorman 11:86909e6db3c8 171 * @param rawWidth - The horizonal number of pixels for the display, defaults to 128
nkhorman 11:86909e6db3c8 172 */
nkhorman 9:ddb97c9850a2 173 Adafruit_SSD1306_I2c(I2C &i2c, PinName RST, uint8_t i2cAddress = SSD_I2C_ADDRESS, uint8_t rawHeight = 32, uint8_t rawWidth = 128)
nkhorman 9:ddb97c9850a2 174 : Adafruit_SSD1306(RST, rawHeight, rawWidth)
nkhorman 9:ddb97c9850a2 175 , mi2c(i2c)
nkhorman 9:ddb97c9850a2 176 , mi2cAddress(i2cAddress)
nkhorman 9:ddb97c9850a2 177 {
nkhorman 9:ddb97c9850a2 178 begin();
nkhorman 9:ddb97c9850a2 179 splash();
nkhorman 9:ddb97c9850a2 180 display();
nkhorman 9:ddb97c9850a2 181 };
nkhorman 9:ddb97c9850a2 182
nkhorman 9:ddb97c9850a2 183 virtual void command(uint8_t c)
nkhorman 9:ddb97c9850a2 184 {
nkhorman 9:ddb97c9850a2 185 char buff[2];
nkhorman 9:ddb97c9850a2 186 buff[0] = 0; // Command Mode
nkhorman 9:ddb97c9850a2 187 buff[1] = c;
nkhorman 9:ddb97c9850a2 188 mi2c.write(mi2cAddress, buff, sizeof(buff));
nkhorman 9:ddb97c9850a2 189 }
nkhorman 9:ddb97c9850a2 190
nkhorman 9:ddb97c9850a2 191 virtual void data(uint8_t c)
nkhorman 9:ddb97c9850a2 192 {
nkhorman 9:ddb97c9850a2 193 char buff[2];
nkhorman 9:ddb97c9850a2 194 buff[0] = 0x40; // Data Mode
nkhorman 9:ddb97c9850a2 195 buff[1] = c;
nkhorman 9:ddb97c9850a2 196 mi2c.write(mi2cAddress, buff, sizeof(buff));
nkhorman 9:ddb97c9850a2 197 };
nkhorman 9:ddb97c9850a2 198
nkhorman 9:ddb97c9850a2 199 protected:
nkhorman 9:ddb97c9850a2 200 virtual void sendDisplayBuffer()
nkhorman 9:ddb97c9850a2 201 {
nkhorman 9:ddb97c9850a2 202 char buff[17];
nkhorman 9:ddb97c9850a2 203 buff[0] = 0x40; // Data Mode
nkhorman 9:ddb97c9850a2 204
nkhorman 9:ddb97c9850a2 205 // send display buffer in 16 byte chunks
nkhorman 9:ddb97c9850a2 206 for(uint16_t i=0, q=buffer.size(); i<q; i+=16 )
nkhorman 9:ddb97c9850a2 207 { uint8_t x ;
nkhorman 9:ddb97c9850a2 208
nkhorman 9:ddb97c9850a2 209 // TODO - this will segfault if buffer.size() % 16 != 0
nkhorman 9:ddb97c9850a2 210 for(x=1; x<sizeof(buff); x++)
JojoS 15:77feec1c0684 211 buff[x] = buffer[i+x-1];
nkhorman 9:ddb97c9850a2 212 mi2c.write(mi2cAddress, buff, sizeof(buff));
nkhorman 9:ddb97c9850a2 213 }
nkhorman 9:ddb97c9850a2 214 };
nkhorman 9:ddb97c9850a2 215
nkhorman 9:ddb97c9850a2 216 I2C &mi2c;
nkhorman 9:ddb97c9850a2 217 uint8_t mi2cAddress;
jimconner 17:bf0e4072b06d 218
jimconner 17:bf0e4072b06d 219 };
jimconner 17:bf0e4072b06d 220
jimconner 17:bf0e4072b06d 221 /** Jim's modified I2C SSD1306 display driver transport class
jimconner 17:bf0e4072b06d 222 * which also toggles some gpio lines to control an CD4067 analog mux
jimconner 17:bf0e4072b06d 223 */
jimconner 17:bf0e4072b06d 224 class mux_SSD1306_I2c : public Adafruit_SSD1306
jimconner 17:bf0e4072b06d 225 {
jimconner 17:bf0e4072b06d 226 public:
jimconner 17:bf0e4072b06d 227 #define SSD_I2C_ADDRESS 0x78
jimconner 17:bf0e4072b06d 228 /** Create a SSD1306 I2C transport display driver instance with the specified RST pin name, the I2C address, as well as the display dimensions
jimconner 17:bf0e4072b06d 229 *
jimconner 17:bf0e4072b06d 230 * Required parameters
jimconner 17:bf0e4072b06d 231 * @param i2c - A reference to an initialized I2C object
jimconner 17:bf0e4072b06d 232 * @param RST - The Reset pin name
jimconner 17:bf0e4072b06d 233 * @param MUX - The pin for controlling the CD4067 multiplier
jimconner 17:bf0e4072b06d 234 * @param MUXVal - The value that the MUX pin should be set to for a given display
jimconner 17:bf0e4072b06d 235 *
jimconner 17:bf0e4072b06d 236 * Optional parameters
jimconner 17:bf0e4072b06d 237 * @param i2cAddress - The i2c address of the display
jimconner 17:bf0e4072b06d 238 * @param rawHeight - The vertical number of pixels for the display, defaults to 32
jimconner 17:bf0e4072b06d 239 * @param rawWidth - The horizonal number of pixels for the display, defaults to 128
jimconner 17:bf0e4072b06d 240 */
jimconner 19:f393e67ed0b5 241 mux_SSD1306_I2c(I2C &i2c, PinName RST, PortOut &mux, uint8_t MUXval = 1, uint8_t i2cAddress = SSD_I2C_ADDRESS, uint8_t rawHeight = 32, uint8_t rawWidth = 128)
jimconner 17:bf0e4072b06d 242 : Adafruit_SSD1306(RST, rawHeight, rawWidth)
jimconner 17:bf0e4072b06d 243 , mi2c(i2c)
jimconner 17:bf0e4072b06d 244 , mi2cAddress(i2cAddress)
jimconner 19:f393e67ed0b5 245 , mmux(mux)
jimconner 17:bf0e4072b06d 246 , muxval(MUXval)
jimconner 17:bf0e4072b06d 247 {
jimconner 17:bf0e4072b06d 248 begin();
jimconner 17:bf0e4072b06d 249 splash();
jimconner 17:bf0e4072b06d 250 display();
jimconner 17:bf0e4072b06d 251 };
jimconner 17:bf0e4072b06d 252
jimconner 17:bf0e4072b06d 253 virtual void command(uint8_t c)
jimconner 17:bf0e4072b06d 254 {
jimconner 17:bf0e4072b06d 255 char buff[2];
jimconner 17:bf0e4072b06d 256 buff[0] = 0; // Command Mode
jimconner 17:bf0e4072b06d 257 buff[1] = c;
jimconner 19:f393e67ed0b5 258 mmux = muxval;
jimconner 17:bf0e4072b06d 259 mi2c.write(mi2cAddress, buff, sizeof(buff));
jimconner 17:bf0e4072b06d 260 }
jimconner 17:bf0e4072b06d 261
jimconner 17:bf0e4072b06d 262 virtual void data(uint8_t c)
jimconner 17:bf0e4072b06d 263 {
jimconner 17:bf0e4072b06d 264 char buff[2];
jimconner 17:bf0e4072b06d 265 buff[0] = 0x40; // Data Mode
jimconner 17:bf0e4072b06d 266 buff[1] = c;
jimconner 19:f393e67ed0b5 267 mmux = muxval;
jimconner 17:bf0e4072b06d 268 mi2c.write(mi2cAddress, buff, sizeof(buff));
jimconner 17:bf0e4072b06d 269 };
jimconner 17:bf0e4072b06d 270
jimconner 17:bf0e4072b06d 271 protected:
jimconner 17:bf0e4072b06d 272 virtual void sendDisplayBuffer()
jimconner 17:bf0e4072b06d 273 {
jimconner 17:bf0e4072b06d 274 char buff[17];
jimconner 17:bf0e4072b06d 275 buff[0] = 0x40; // Data Mode
jimconner 17:bf0e4072b06d 276
jimconner 17:bf0e4072b06d 277 // send display buffer in 16 byte chunks
jimconner 17:bf0e4072b06d 278 for(uint16_t i=0, q=buffer.size(); i<q; i+=16 )
jimconner 17:bf0e4072b06d 279 { uint8_t x ;
jimconner 17:bf0e4072b06d 280
jimconner 17:bf0e4072b06d 281 // TODO - this will segfault if buffer.size() % 16 != 0
jimconner 17:bf0e4072b06d 282 for(x=1; x<sizeof(buff); x++)
jimconner 17:bf0e4072b06d 283 buff[x] = buffer[i+x-1];
jimconner 19:f393e67ed0b5 284 mmux = muxval;
jimconner 17:bf0e4072b06d 285 mi2c.write(mi2cAddress, buff, sizeof(buff));
jimconner 17:bf0e4072b06d 286 }
jimconner 17:bf0e4072b06d 287 };
jimconner 17:bf0e4072b06d 288
jimconner 17:bf0e4072b06d 289 I2C &mi2c;
jimconner 17:bf0e4072b06d 290 uint8_t mi2cAddress;
jimconner 19:f393e67ed0b5 291 PortOut &mmux;
jimconner 17:bf0e4072b06d 292 uint8_t muxval;
nkhorman 0:c3dcd4c4983a 293 };
nkhorman 0:c3dcd4c4983a 294
nkhorman 0:c3dcd4c4983a 295 #endif