Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated support for 64x48 displays #188

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
77 changes: 50 additions & 27 deletions Adafruit_SSD1306.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,16 +463,20 @@ void Adafruit_SSD1306::ssd1306_command(uint8_t c) {
bool Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, bool reset,
bool periphBegin) {

if ((!buffer) && !(buffer = (uint8_t *)malloc(WIDTH * ((HEIGHT + 7) / 8))))
if ((!buffer) &&
!(buffer = (uint8_t *)malloc(SSD1306_SEGMENTS * ((HEIGHT + 7) / 8))))
return false;

clearDisplay();
if (HEIGHT > 32) {
if (WIDTH > 64 && HEIGHT > 32) {
drawBitmap((WIDTH - splash1_width) / 2, (HEIGHT - splash1_height) / 2,
splash1_data, splash1_width, splash1_height, 1);
} else {
} else if (WIDTH > 64) {
drawBitmap((WIDTH - splash2_width) / 2, (HEIGHT - splash2_height) / 2,
splash2_data, splash2_width, splash2_height, 1);
} else {
drawBitmap((WIDTH - splash3_width) / 2, (HEIGHT - splash3_height) / 2,
splash3_data, splash3_width, splash3_height, 1);
}

vccstate = vcs;
Expand Down Expand Up @@ -538,11 +542,17 @@ bool Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, bool reset,
ssd1306_command1(HEIGHT - 1);

static const uint8_t PROGMEM init2[] = {SSD1306_SETDISPLAYOFFSET, // 0xD3
0x0, // no offset
SSD1306_SETSTARTLINE | 0x0, // line #0
SSD1306_CHARGEPUMP}; // 0x8D
0x0}; // no offset
ssd1306_commandList(init2, sizeof(init2));

if ((WIDTH == 64) && (HEIGHT == 32)) {
ssd1306_command1(0x00); // line #0
} else {
ssd1306_command1(SSD1306_SETSTARTLINE); // 0x40
}

ssd1306_command1(SSD1306_CHARGEPUMP); // 0x8D

ssd1306_command1((vccstate == SSD1306_EXTERNALVCC) ? 0x10 : 0x14);

static const uint8_t PROGMEM init3[] = {SSD1306_MEMORYMODE, // 0x20
Expand All @@ -563,6 +573,9 @@ bool Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, bool reset,
} else if ((WIDTH == 96) && (HEIGHT == 16)) {
comPins = 0x2; // ada x12
contrast = (vccstate == SSD1306_EXTERNALVCC) ? 0x10 : 0xAF;
} else if ((WIDTH == 64) && ((HEIGHT == 48) || (HEIGHT == 32))) {
comPins = 0x12;
contrast = (vccstate == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF;
} else {
// Other screen varieties -- TBD
}
Expand Down Expand Up @@ -622,15 +635,17 @@ void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color) {
y = HEIGHT - y - 1;
break;
}
if ((WIDTH == 64) && (HEIGHT == 48))
x += 32;
switch (color) {
case SSD1306_WHITE:
buffer[x + (y / 8) * WIDTH] |= (1 << (y & 7));
buffer[x + (y / 8) * SSD1306_SEGMENTS] |= (1 << (y & 7));
break;
case SSD1306_BLACK:
buffer[x + (y / 8) * WIDTH] &= ~(1 << (y & 7));
buffer[x + (y / 8) * SSD1306_SEGMENTS] &= ~(1 << (y & 7));
break;
case SSD1306_INVERSE:
buffer[x + (y / 8) * WIDTH] ^= (1 << (y & 7));
buffer[x + (y / 8) * SSD1306_SEGMENTS] ^= (1 << (y & 7));
break;
}
}
Expand All @@ -644,7 +659,7 @@ void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color) {
commands as needed by one's own application.
*/
void Adafruit_SSD1306::clearDisplay(void) {
memset(buffer, 0, WIDTH * ((HEIGHT + 7) / 8));
memset(buffer, 0, SSD1306_SEGMENTS * ((HEIGHT + 7) / 8));
}

/*!
Expand Down Expand Up @@ -707,7 +722,10 @@ void Adafruit_SSD1306::drawFastHLineInternal(int16_t x, int16_t y, int16_t w,
w = (WIDTH - x);
}
if (w > 0) { // Proceed only if width is positive
uint8_t *pBuf = &buffer[(y / 8) * WIDTH + x], mask = 1 << (y & 7);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only s/WIDTH/SSD1306_SEGMENTS/ needed to change on this line.

if ((WIDTH == 64) && (HEIGHT == 48))
x += 32;
uint8_t *pBuf = &buffer[x + (y / 8) * SSD1306_SEGMENTS];
uint8_t mask = 1 << (y & 7);
switch (color) {
case SSD1306_WHITE:
while (w--) {
Expand Down Expand Up @@ -793,7 +811,9 @@ void Adafruit_SSD1306::drawFastVLineInternal(int16_t x, int16_t __y,
// this display doesn't need ints for coordinates,
// use local byte registers for faster juggling
uint8_t y = __y, h = __h;
uint8_t *pBuf = &buffer[(y / 8) * WIDTH + x];
if ((WIDTH == 64) && (HEIGHT == 48))
x += 32;
uint8_t *pBuf = &buffer[x + (y / 8) * SSD1306_SEGMENTS];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only s/WIDTH/SSD1306_SEGMENTS/ needed to change on this line.


// do the first partial byte, if necessary - this requires some masking
uint8_t mod = (y & 7);
Expand Down Expand Up @@ -821,7 +841,7 @@ void Adafruit_SSD1306::drawFastVLineInternal(int16_t x, int16_t __y,
*pBuf ^= mask;
break;
}
pBuf += WIDTH;
pBuf += SSD1306_SEGMENTS;
}

if (h >= mod) { // More to go?
Expand All @@ -832,17 +852,17 @@ void Adafruit_SSD1306::drawFastVLineInternal(int16_t x, int16_t __y,
// separate copy of the code so we don't impact performance of
// black/white write version with an extra comparison per loop
do {
*pBuf ^= 0xFF; // Invert byte
pBuf += WIDTH; // Advance pointer 8 rows
h -= 8; // Subtract 8 rows from height
*pBuf ^= 0xFF; // Invert byte
pBuf += SSD1306_SEGMENTS; // Advance pointer 8 rows
h -= 8; // Subtract 8 rows from height
} while (h >= 8);
} else {
// store a local value to work with
uint8_t val = (color != SSD1306_BLACK) ? 255 : 0;
do {
*pBuf = val; // Set byte
pBuf += WIDTH; // Advance pointer 8 rows
h -= 8; // Subtract 8 rows from height
*pBuf = val; // Set byte
pBuf += SSD1306_SEGMENTS; // Advance pointer 8 rows
h -= 8; // Subtract 8 rows from height
} while (h >= 8);
}
}
Expand Down Expand Up @@ -902,7 +922,9 @@ bool Adafruit_SSD1306::getPixel(int16_t x, int16_t y) {
y = HEIGHT - y - 1;
break;
}
return (buffer[x + (y / 8) * WIDTH] & (1 << (y & 7)));
if ((WIDTH == 64) && (HEIGHT == 48))
x += 32;
return (buffer[x + (y / 8) * SSD1306_SEGMENTS] & (1 << (y & 7)));
}
return false; // Pixel out of bounds
}
Expand All @@ -925,13 +947,14 @@ uint8_t *Adafruit_SSD1306::getBuffer(void) { return buffer; }
*/
void Adafruit_SSD1306::display(void) {
TRANSACTION_START
static const uint8_t PROGMEM dlist1[] = {
SSD1306_PAGEADDR,
0, // Page start address
0xFF, // Page end (not really, but works here)
SSD1306_COLUMNADDR, 0}; // Column start address
static const uint8_t PROGMEM dlist1[] = {SSD1306_PAGEADDR,
0}; // Page start address
ssd1306_commandList(dlist1, sizeof(dlist1));
ssd1306_command1(WIDTH - 1); // Column end address
ssd1306_command1((HEIGHT + 7) / 8 - 1); // Page end address
static const uint8_t PROGMEM dlist2[] = {SSD1306_COLUMNADDR,
0}; // Column start address
ssd1306_commandList(dlist2, sizeof(dlist2));
ssd1306_command1(SSD1306_SEGMENTS - 1); // Column end address

#if defined(ESP8266)
// ESP8266 needs a periodic yield() call to avoid watchdog reset.
Expand All @@ -942,7 +965,7 @@ void Adafruit_SSD1306::display(void) {
// 32-byte transfer condition below.
yield();
#endif
uint16_t count = WIDTH * ((HEIGHT + 7) / 8);
uint16_t count = SSD1306_SEGMENTS * ((HEIGHT + 7) / 8);
uint8_t *ptr = buffer;
if (wire) { // I2C
wire->beginTransmission(i2caddr);
Expand Down
14 changes: 13 additions & 1 deletion Adafruit_SSD1306.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
#ifndef _Adafruit_SSD1306_H_
#define _Adafruit_SSD1306_H_

// ONE of the following three lines must be #defined:
// ONE of the following lines must be #defined:
//#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen
#define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen
//#define SSD1306_96_16 ///< DEPRECATED: old way to specify 96x16 screen
//#define SSD1306_64_48 ///< DEPRECATED: old way to specify 64x48 screen
//#define SSD1306_64_32 ///< DEPRECATED: old way to specify 64x32 screen
// This establishes the screen dimensions in old Adafruit_SSD1306 sketches
// (NEW CODE SHOULD IGNORE THIS, USE THE CONSTRUCTORS THAT ACCEPT WIDTH
// AND HEIGHT ARGUMENTS).
Expand Down Expand Up @@ -105,6 +107,8 @@ typedef uint32_t PortMask;
#define SSD1306_ACTIVATE_SCROLL 0x2F ///< Start scroll
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3 ///< Set scroll range

#define SSD1306_SEGMENTS 128 ///< See datasheet

// Deprecated size stuff for backwards compatibility with old sketches
#if defined SSD1306_128_64
#define SSD1306_LCDWIDTH 128 ///< DEPRECATED: width w/SSD1306_128_64 defined
Expand All @@ -118,6 +122,14 @@ typedef uint32_t PortMask;
#define SSD1306_LCDWIDTH 96 ///< DEPRECATED: width w/SSD1306_96_16 defined
#define SSD1306_LCDHEIGHT 16 ///< DEPRECATED: height w/SSD1306_96_16 defined
#endif
#if defined SSD1306_64_48
#define SSD1306_LCDWIDTH 64 ///< DEPRECATED: width w/SSD1306_64_48 defined
#define SSD1306_LCDHEIGHT 48 ///< DEPRECATED: height w/SSD1306_64_48 defined
#endif
#if defined SSD1306_64_32
#define SSD1306_LCDWIDTH 64 ///< DEPRECATED: width w/SSD1306_64_32 defined
#define SSD1306_LCDHEIGHT 32 ///< DEPRECATED: height w/SSD1306_64_32 defined
#endif

/*!
@brief Class that stores state and functions for interacting with
Expand Down
Loading