Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Major changes

Major code reorganization for init for easier use of the library by
client
Added bargraph functions
Bugs Fix
Begin support of other OLED such SeeeStudio
  • Loading branch information...
commit 857de7faad86b174f4af4dc341e0229eddd2fd67 1 parent 6e986fa
@hallard authored
View
324 Adafruit_GFX.cpp
@@ -17,6 +17,9 @@
LCD size and connection are now passed as arguments on
the command line (no more #define on compilation needed)
ArduiPi project documentation http://hallard.me/arduipi
+07/01/2013 Charles-Henri Hallard (http://hallard.me)
+ Created Draw Bargraph feature
+ Added printf feature
******************************************************************/
@@ -24,7 +27,8 @@
#include "./Adafruit_GFX.h"
#include "./glcdfont.c"
-void Adafruit_GFX::constructor(int16_t w, int16_t h) {
+void Adafruit_GFX::constructor(int16_t w, int16_t h)
+{
_width = WIDTH = w;
_height = HEIGHT = h;
@@ -36,9 +40,10 @@ void Adafruit_GFX::constructor(int16_t w, int16_t h) {
}
// the printf function
-void Adafruit_GFX::printf( const char * format, ...) {
+void Adafruit_GFX::printf( const char * format, ...)
+{
- char buffer[256];
+ char buffer[64];
char * p = buffer;
int n;
va_list args;
@@ -55,7 +60,8 @@ void Adafruit_GFX::printf( const char * format, ...) {
}
// the print function
-void Adafruit_GFX::print( const char * string) {
+void Adafruit_GFX::print( const char * string)
+{
const char * p = string;
int n = strlen(string);
@@ -69,8 +75,8 @@ void Adafruit_GFX::print( const char * string) {
// draw a circle outline
-void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r,
- uint16_t color) {
+void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)
+{
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
@@ -82,12 +88,15 @@ void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r,
drawPixel(x0+r, y0, color);
drawPixel(x0-r, y0, color);
- while (x<y) {
- if (f >= 0) {
+ while (x<y)
+ {
+ if (f >= 0)
+ {
y--;
ddF_y += 2;
f += ddF_y;
}
+
x++;
ddF_x += 2;
f += ddF_x;
@@ -104,73 +113,85 @@ void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r,
}
}
-void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0,
- int16_t r, uint8_t cornername, uint16_t color) {
+void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color)
+{
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
int16_t x = 0;
int16_t y = r;
- while (x<y) {
- if (f >= 0) {
+ while (x<y)
+ {
+ if (f >= 0)
+ {
y--;
ddF_y += 2;
f += ddF_y;
}
+
x++;
ddF_x += 2;
f += ddF_x;
- if (cornername & 0x4) {
+ if (cornername & 0x4)
+ {
drawPixel(x0 + x, y0 + y, color);
drawPixel(x0 + y, y0 + x, color);
}
- if (cornername & 0x2) {
+ if (cornername & 0x2)
+ {
drawPixel(x0 + x, y0 - y, color);
drawPixel(x0 + y, y0 - x, color);
}
- if (cornername & 0x8) {
+ if (cornername & 0x8)
+ {
drawPixel(x0 - y, y0 + x, color);
drawPixel(x0 - x, y0 + y, color);
}
- if (cornername & 0x1) {
+ if (cornername & 0x1)
+ {
drawPixel(x0 - y, y0 - x, color);
drawPixel(x0 - x, y0 - y, color);
}
}
}
-void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r,
- uint16_t color) {
+void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)
+{
drawFastVLine(x0, y0-r, 2*r+1, color);
fillCircleHelper(x0, y0, r, 3, 0, color);
}
// used to do circles and roundrects!
-void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
- uint8_t cornername, int16_t delta, uint16_t color) {
-
+void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color)
+{
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
int16_t x = 0;
int16_t y = r;
- while (x<y) {
- if (f >= 0) {
+ while (x<y)
+ {
+ if (f >= 0)
+ {
y--;
ddF_y += 2;
f += ddF_y;
}
+
x++;
ddF_x += 2;
f += ddF_x;
- if (cornername & 0x1) {
+ if (cornername & 0x1)
+ {
drawFastVLine(x0+x, y0-y, 2*y+1+delta, color);
drawFastVLine(x0+y, y0-x, 2*x+1+delta, color);
}
- if (cornername & 0x2) {
+
+ if (cornername & 0x2)
+ {
drawFastVLine(x0-x, y0-y, 2*y+1+delta, color);
drawFastVLine(x0-y, y0-x, 2*x+1+delta, color);
}
@@ -178,16 +199,18 @@ void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
}
// bresenham's algorithm - thx wikpedia
-void Adafruit_GFX::drawLine(int16_t x0, int16_t y0,
- int16_t x1, int16_t y1,
- uint16_t color) {
+void Adafruit_GFX::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color)
+{
int16_t steep = abs(y1 - y0) > abs(x1 - x0);
- if (steep) {
+
+ if (steep)
+ {
swap(x0, y0);
swap(x1, y1);
}
- if (x0 > x1) {
+ if (x0 > x1)
+ {
swap(x0, x1);
swap(y0, y1);
}
@@ -199,20 +222,29 @@ void Adafruit_GFX::drawLine(int16_t x0, int16_t y0,
int16_t err = dx / 2;
int16_t ystep;
- if (y0 < y1) {
+ if (y0 < y1)
+ {
ystep = 1;
- } else {
+ }
+ else
+ {
ystep = -1;
}
- for (; x0<=x1; x0++) {
- if (steep) {
+ for (; x0<=x1; x0++)
+ {
+ if (steep)
+ {
drawPixel(y0, x0, color);
- } else {
- drawPixel(x0, y0, color);
}
+ else
+ {
+ drawPixel(x0, y0, color);
+ }
err -= dy;
- if (err < 0) {
+
+ if (err < 0)
+ {
y0 += ystep;
err += dx;
}
@@ -221,49 +253,90 @@ void Adafruit_GFX::drawLine(int16_t x0, int16_t y0,
// draw a rectangle
-void Adafruit_GFX::drawRect(int16_t x, int16_t y,
- int16_t w, int16_t h,
- uint16_t color) {
+void Adafruit_GFX::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
+{
drawFastHLine(x, y, w, color);
drawFastHLine(x, y+h-1, w, color);
drawFastVLine(x, y, h, color);
drawFastVLine(x+w-1, y, h, color);
}
-void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y,
- int16_t h, uint16_t color) {
+void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)
+{
// stupidest version - update in subclasses if desired!
drawLine(x, y, x, y+h-1, color);
}
-void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y,
- int16_t w, uint16_t color) {
+void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color)
+{
// stupidest version - update in subclasses if desired!
drawLine(x, y, x+w-1, y, color);
}
-void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
- uint16_t color) {
+void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
+{
// stupidest version - update in subclasses if desired!
- for (int16_t i=x; i<x+w; i++) {
+ for (int16_t i=x; i<x+w; i++)
+ {
drawFastVLine(i, y, h, color);
}
}
+// draw a vertical bargraph and fill it with percent value (0%..100%)
+void Adafruit_GFX::drawVerticalBargraph(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color, uint16_t percent)
+{
+ uint16_t vsize;
+
+ // Create rectangle
+ drawRect(x,y, w, h, color) ;
+
+ // Do not do stupid job
+ if ( h>2 && w>2 )
+ {
+ // calculate pixel size of bargraph
+ vsize = ( ( h - 2) * percent ) / 100 ;
+
+ // Fill it from bottom (0%) to top (100%)
+ fillRect(x+1,y+1 + (( h-2)-vsize), w - 2, vsize, color);
+ }
+}
+
+// draw a horizontal bargraph and fill it with percent value (0%..100%)
+void Adafruit_GFX::drawHorizontalBargraph(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color, uint16_t percent)
+{
+ uint16_t hsize;
+
+ // Create rectangle
+ drawRect(x,y, w, h, color) ;
+
+ // Do not do stupid job
+ if ( h>2 && w>2 )
+ {
+ // calculate pixel size of bargraph
+ hsize = ( ( w - 2) * percent ) / 100 ;
+
+ // Fill it from left (0%) to right (100%)
+ fillRect(x+1 , y+1 , hsize, h - 2, color);
+ }
+}
-void Adafruit_GFX::fillScreen(uint16_t color) {
+
+void Adafruit_GFX::fillScreen(uint16_t color)
+{
fillRect(0, 0, _width, _height, color);
}
// draw a rounded rectangle!
-void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w,
- int16_t h, int16_t r, uint16_t color) {
+void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color)
+{
+
// smarter version
drawFastHLine(x+r , y , w-2*r, color); // Top
drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom
drawFastVLine( x , y+r , h-2*r, color); // Left
drawFastVLine( x+w-1, y+r , h-2*r, color); // Right
+
// draw four corners
drawCircleHelper(x+r , y+r , r, 1, color);
drawCircleHelper(x+w-r-1, y+r , r, 2, color);
@@ -272,8 +345,8 @@ void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w,
}
// fill a rounded rectangle!
-void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w,
- int16_t h, int16_t r, uint16_t color) {
+void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color)
+{
// smarter version
fillRect(x+r, y, w-2*r, h, color);
@@ -283,33 +356,35 @@ void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w,
}
// draw a triangle!
-void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0,
- int16_t x1, int16_t y1,
- int16_t x2, int16_t y2, uint16_t color) {
+void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)
+{
drawLine(x0, y0, x1, y1, color);
drawLine(x1, y1, x2, y2, color);
drawLine(x2, y2, x0, y0, color);
}
// fill a triangle!
-void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0,
- int16_t x1, int16_t y1,
- int16_t x2, int16_t y2, uint16_t color) {
+void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)
+{
int16_t a, b, y, last;
// Sort coordinates by Y order (y2 >= y1 >= y0)
- if (y0 > y1) {
+ if (y0 > y1)
+ {
swap(y0, y1); swap(x0, x1);
}
- if (y1 > y2) {
+ if (y1 > y2)
+ {
swap(y2, y1); swap(x2, x1);
}
- if (y0 > y1) {
+ if (y0 > y1)
+ {
swap(y0, y1); swap(x0, x1);
}
- if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing
+ if(y0 == y2)
+ { // Handle awkward all-on-same-line case as its own thing
a = b = x0;
if(x1 < a) a = x1;
else if(x1 > b) b = x1;
@@ -335,10 +410,13 @@ void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0,
// error there), otherwise scanline y1 is skipped here and handled
// in the second loop...which also avoids a /0 error here if y0=y1
// (flat-topped triangle).
- if(y1 == y2) last = y1; // Include y1 scanline
- else last = y1-1; // Skip it
+ if(y1 == y2)
+ last = y1; // Include y1 scanline
+ else
+ last = y1-1; // Skip it
- for(y=y0; y<=last; y++) {
+ for(y=y0; y<=last; y++)
+ {
a = x0 + sa / dy01;
b = x0 + sb / dy02;
sa += dx01;
@@ -347,7 +425,9 @@ void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0,
a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
- if(a > b) swap(a,b);
+ if(a > b)
+ swap(a,b);
+
drawFastHLine(a, y, b-a+1, color);
}
@@ -355,7 +435,8 @@ void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0,
// 0-2 and 1-2. This loop is skipped if y1=y2.
sa = dx12 * (y - y1);
sb = dx02 * (y - y0);
- for(; y<=y2; y++) {
+ for(; y<=y2; y++)
+ {
a = x1 + sa / dy12;
b = x0 + sb / dy02;
sa += dx12;
@@ -364,19 +445,22 @@ void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0,
a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
- if(a > b) swap(a,b);
+ if(a > b)
+ swap(a,b);
+
drawFastHLine(a, y, b-a+1, color);
}
}
-void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
- const uint8_t *bitmap, int16_t w, int16_t h,
- uint16_t color) {
+void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color)
+{
int16_t i, j, byteWidth = (w + 7) / 8;
- for(j=0; j<h; j++) {
- for(i=0; i<w; i++ ) {
+ for(j=0; j<h; j++)
+ {
+ for(i=0; i<w; i++ )
+ {
if( *(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7)))
{
drawPixel(x+i, y+j, color);
@@ -386,16 +470,24 @@ void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
}
-size_t Adafruit_GFX::write(uint8_t c) {
- if (c == '\n') {
+size_t Adafruit_GFX::write(uint8_t c)
+{
+ if (c == '\n')
+ {
cursor_y += textsize*8;
cursor_x = 0;
- } else if (c == '\r') {
+ }
+ else if (c == '\r')
+ {
// skip em
- } else {
+ }
+ else
+ {
drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
cursor_x += textsize*6;
- if (wrap && (cursor_x > (_width - textsize*6))) {
+
+ if (wrap && (cursor_x > (_width - textsize*6)))
+ {
cursor_y += textsize*8;
cursor_x = 0;
}
@@ -404,8 +496,8 @@ size_t Adafruit_GFX::write(uint8_t c) {
}
// draw a character
-void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
- uint16_t color, uint16_t bg, uint8_t size) {
+void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size)
+{
if((x >= _width) || // Clip right
(y >= _height) || // Clip bottom
@@ -413,91 +505,111 @@ void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
((y + 8 * size - 1) < 0)) // Clip top
return;
- for (int8_t i=0; i<6; i++ ) {
+ for (int8_t i=0; i<6; i++ )
+ {
uint8_t line;
if (i == 5)
line = 0x0;
else
//line = pgm_read_byte(font+(c*5)+i);
line = font[(c*5)+i];
- for (int8_t j = 0; j<8; j++) {
- if (line & 0x1) {
+ for (int8_t j = 0; j<8; j++)
+ {
+ if (line & 0x1)
+ {
if (size == 1) // default size
drawPixel(x+i, y+j, color);
- else { // big size
+ else
+ { // big size
fillRect(x+(i*size), y+(j*size), size, size, color);
- }
- } else if (bg != color) {
+ }
+ }
+ else if (bg != color)
+ {
if (size == 1) // default size
drawPixel(x+i, y+j, bg);
- else { // big size
+ else
+ { // big size
fillRect(x+i*size, y+j*size, size, size, bg);
}
}
+
line >>= 1;
}
}
}
-void Adafruit_GFX::setCursor(int16_t x, int16_t y) {
+void Adafruit_GFX::setCursor(int16_t x, int16_t y)
+{
cursor_x = x;
cursor_y = y;
}
-void Adafruit_GFX::setTextSize(uint8_t s) {
+void Adafruit_GFX::setTextSize(uint8_t s)
+{
textsize = (s > 0) ? s : 1;
}
-void Adafruit_GFX::setTextColor(uint16_t c) {
+void Adafruit_GFX::setTextColor(uint16_t c)
+{
textcolor = c;
textbgcolor = c;
// for 'transparent' background, we'll set the bg
// to the same as fg instead of using a flag
}
- void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) {
+void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b)
+{
textcolor = c;
textbgcolor = b;
}
-void Adafruit_GFX::setTextWrap(boolean w) {
+void Adafruit_GFX::setTextWrap(boolean w)
+{
wrap = w;
}
-uint8_t Adafruit_GFX::getRotation(void) {
+uint8_t Adafruit_GFX::getRotation(void)
+{
rotation %= 4;
return rotation;
}
-void Adafruit_GFX::setRotation(uint8_t x) {
+void Adafruit_GFX::setRotation(uint8_t x)
+{
x %= 4; // cant be higher than 3
rotation = x;
- switch (x) {
- case 0:
- case 2:
- _width = WIDTH;
- _height = HEIGHT;
+ switch (x)
+ {
+ case 0:
+ case 2:
+ _width = WIDTH;
+ _height = HEIGHT;
break;
- case 1:
- case 3:
- _width = HEIGHT;
- _height = WIDTH;
+
+ case 1:
+ case 3:
+ _width = HEIGHT;
+ _height = WIDTH;
break;
}
}
-void Adafruit_GFX::invertDisplay(boolean i) {
+void Adafruit_GFX::invertDisplay(boolean i)
+{
// do nothing, can be subclassed
}
// return the size of the display which depends on the rotation!
-int16_t Adafruit_GFX::width(void) {
+int16_t Adafruit_GFX::width(void)
+{
return _width;
}
-int16_t Adafruit_GFX::height(void) {
+int16_t Adafruit_GFX::height(void)
+{
return _height;
}
View
5 Adafruit_GFX.h
@@ -51,6 +51,11 @@ class Adafruit_GFX {
uint16_t color);
virtual void fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
uint16_t color);
+
+ void drawVerticalBargraph(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color, uint16_t percent) ;
+ void drawHorizontalBargraph(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color, uint16_t percent) ;
+
+
virtual void fillScreen(uint16_t color);
void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
View
606 Adafruit_SSD1306.cpp
@@ -20,175 +20,239 @@ All text above, and the splash screen below must be included in any redistributi
LCD size and connection are now passed as arguments on
the command line (no more #define on compilation needed)
ArduiPi project documentation http://hallard.me/arduipi
+07/01/2013 Charles-Henri Hallard
+ Reduced code size removed the Adafruit Logo (sorry guys)
+ Buffer for OLED is now dynamic to LCD size
+ Added support of Seeed OLED 64x64 Display
*********************************************************************/
-
-
-#include "./ArduiPi_SSD1306.h"
+#include "./ArduiPi_SSD1306.h"
#include "./Adafruit_GFX.h"
#include "./Adafruit_SSD1306.h"
-//#include "glcdfont.c"
-
-// a 5x7 font table
-//extern uint8_t font[];
-
-// the memory buffer for the LCD
-
-//static uint8_t buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = {
-// Buffer to max size of LCD
-static uint8_t buffer[64 * 128 / 8] = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF,
-0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
-0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84, 0x00, 0x00, 0x80, 0xF8,
-0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80,
-0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0x01, 0x01,
-0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF,
-0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7, 0xFF, 0xFF, 0x00, 0x00,
-0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x7F, 0xFF,
-0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF,
-0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x8F,
-0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC,
-0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x01, 0x03, 0x03, 0x03,
-0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01,
-0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00,
-0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03,
-0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-//#if (SSD1306_LCDHEIGHT == 64)
-0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x0F,
-0x87, 0xC7, 0xF7, 0xFF, 0xFF, 0x1F, 0x1F, 0x3D, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0x7C, 0x7D, 0xFF,
-0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x00, 0x30, 0x30, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F,
-0x0F, 0x07, 0x1F, 0x7F, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xE0,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00,
-0x00, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xF0, 0xF8, 0x1C, 0x0E,
-0x06, 0x06, 0x06, 0x0C, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFC,
-0xFE, 0xFC, 0x00, 0x18, 0x3C, 0x7E, 0x66, 0xE6, 0xCE, 0x84, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x06,
-0x06, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xC0, 0xF8,
-0xFC, 0x4E, 0x46, 0x46, 0x46, 0x4E, 0x7C, 0x78, 0x40, 0x18, 0x3C, 0x76, 0xE6, 0xCE, 0xCC, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x03,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00,
-0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x03, 0x07, 0x0E, 0x0C,
-0x18, 0x18, 0x0C, 0x06, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0E, 0x0C, 0x18, 0x0C, 0x0F,
-0x07, 0x01, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00,
-0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x07,
-0x07, 0x0C, 0x0C, 0x18, 0x1C, 0x0C, 0x06, 0x06, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-//#endif
-};
-
-
+
+inline boolean Adafruit_SSD1306::isSPI(void) {
+ return (cs != -1 ? true : false);
+}
+inline boolean Adafruit_SSD1306::isI2C(void) {
+ return (cs == -1 ? true : false);
+}
+// Low level I2C and SPI Write function
+inline void Adafruit_SSD1306::fastSPIwrite(uint8_t d) {
+ bcm2835_spi_transfer(d);
+}
+inline void Adafruit_SSD1306::fastI2Cwrite(uint8_t d) {
+ bcm2835_spi_transfer(d);
+}
+inline void Adafruit_SSD1306::fastSPIwrite(char* tbuf, uint32_t len) {
+ bcm2835_spi_writenb(tbuf, len);
+}
+inline void Adafruit_SSD1306::fastI2Cwrite(char* tbuf, uint32_t len) {
+ bcm2835_i2c_write(tbuf, len);
+}
// the most basic function, set a single pixel
-void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color) {
+void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color)
+{
+ uint8_t * p = poledbuff ;
+
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
return;
- // check rotation, move pixel around if necessary
- switch (getRotation()) {
- case 1:
- swap(x, y);
- x = WIDTH - x - 1;
- break;
- case 2:
- x = WIDTH - x - 1;
- y = HEIGHT - y - 1;
- break;
- case 3:
- swap(x, y);
- y = HEIGHT - y - 1;
- break;
- }
-
- // x is which column
- if (color == WHITE)
- buffer[x+ (y/8)*ssd1306_lcdwidth] |= _BV((y%8));
- else
- buffer[x+ (y/8)*ssd1306_lcdwidth] &= ~_BV((y%8));
+ // check rotation, move pixel around if necessary
+ switch (getRotation())
+ {
+ case 1:
+ swap(x, y);
+ x = WIDTH - x - 1;
+ break;
+
+ case 2:
+ x = WIDTH - x - 1;
+ y = HEIGHT - y - 1;
+ break;
+
+ case 3:
+ swap(x, y);
+ y = HEIGHT - y - 1;
+ break;
+ }
+
+ // Get where to do the change in the buffer
+ p = poledbuff + (x + (y/8)*ssd1306_lcdwidth );
+
+ // x is which column
+ if (color == WHITE)
+ *p |= _BV((y%8));
+ else
+ *p &= ~_BV((y%8));
+}
+
+// Display instantiation
+Adafruit_SSD1306::Adafruit_SSD1306()
+{
+ // Init all var, and clean
+ // Command I/O
+ rst = 0 ;
+ dc = 0 ;
+ cs = 0 ;
+
+ // Lcd size
+ ssd1306_lcdwidth = 0;
+ ssd1306_lcdheight = 0;
+
+ // Empty pointer to OLED buffer
+ poledbuff = NULL;
}
-Adafruit_SSD1306::Adafruit_SSD1306() {
- rst = dc = cs = ssd1306_lcdwidth = ssd1306_lcdheight = 0;
+// When not initialized program using this library may
+// know protocol for correct init call, he could just know
+// oled number in driver list
+boolean Adafruit_SSD1306::oled_is_spi_proto(uint8_t OLED_TYPE)
+{
+ switch (OLED_TYPE)
+ {
+ case OLED_ADAFRUIT_SPI_128x32:
+ case OLED_ADAFRUIT_SPI_128x64:
+ return true;
+ break;
+ }
+
+ // default
+ return false;
+
}
-// initializer for SPI - we indicate the pins used and LCD size
-boolean Adafruit_SSD1306::init(int8_t DC, int8_t RST, int8_t CS, int16_t SSD1306_LCDWIDTH, int16_t SSD1306_LCDHEIGHT) {
- rst = RST;
- dc = DC; // Data / command Pin
- cs = CS ; // Raspberry SPI chip Enable (may be CE0 or CE1)
- ssd1306_lcdwidth = SSD1306_LCDWIDTH;
- ssd1306_lcdheight = SSD1306_LCDHEIGHT;
+// initializer for OLED Type
+boolean Adafruit_SSD1306::select_oled(uint8_t OLED_TYPE)
+{
+ // Default type
+ ssd1306_lcdwidth = 128;
+ ssd1306_lcdheight = 64;
+ _i2c_addr = 0x00;
+
+ // default OLED are using internal boost VCC converter
+ vcc_type = SSD_Internal_Vcc;
+
+ // Oled supported display
+ // Setup size and I2C address
+ switch (OLED_TYPE)
+ {
+ case OLED_ADAFRUIT_SPI_128x32:
+ ssd1306_lcdheight = 32;
+ break;
+
+ case OLED_ADAFRUIT_SPI_128x64:
+ ;
+ break;
+
+ case OLED_ADAFRUIT_I2C_128x32:
+ ssd1306_lcdheight = 32;
+ _i2c_addr = ADAFRUIT_I2C_ADDRESS;
+ break;
+
+ case OLED_ADAFRUIT_I2C_128x64:
+ _i2c_addr = ADAFRUIT_I2C_ADDRESS;
+ break;
+
+ case OLED_SEEED_I2C_128x64:
+ _i2c_addr = SEEEED_I2C_ADDRESS ;
+ vcc_type = SSD_External_Vcc;
+ break;
+
+ case OLED_SEEED_I2C_96x96:
+ ssd1306_lcdwidth = 96;
+ ssd1306_lcdheight = 96;
+ _i2c_addr = SEEEED_I2C_ADDRESS ;
+ break;
+
+ // houston, we have a problem
+ default:
+ return false;
+ break;
+ }
+
+ // De-Allocate memory for OLED buffer if any
+ if (poledbuff)
+ free(poledbuff);
+
+ // Allocate memory for OLED buffer
+ poledbuff = (uint8_t *) malloc ( (ssd1306_lcdwidth * ssd1306_lcdheight / 8 ));
+ if (!poledbuff)
+ return false;
- // Use for testing
- // bcm2835_set_debug(1);
// Init Raspberry PI GPIO
if (!bcm2835_init())
return false;
+
+ return true;
+
+}
+
+// initializer for SPI - we indicate the pins used and OLED type
+//
+boolean Adafruit_SSD1306::init(int8_t DC, int8_t RST, int8_t CS, uint8_t OLED_TYPE)
+{
+ rst = RST; // Reset Pin
+ dc = DC; // Data / command Pin
+ cs = CS ; // Raspberry SPI chip Enable (may be CE0 or CE1)
+
+ // Select OLED parameters
+ if (!select_oled(OLED_TYPE))
+ return false;
- // Init Raspberry PI SPI
+ // Init & Configure Raspberry PI SPI
bcm2835_spi_begin(cs);
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
// 16 MHz SPI bus, but Worked at 62 MHz also
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_16);
-
+
+ // Set the pin that will control DC as output
+ bcm2835_gpio_fsel(dc, BCM2835_GPIO_FSEL_OUTP);
+
+ // Setup reset pin direction as output
+ bcm2835_gpio_fsel(rst, BCM2835_GPIO_FSEL_OUTP);
+
return ( true);
}
-// initializer for I2C - we only indicate the reset pin and LCD size !
-boolean Adafruit_SSD1306::init(int8_t RST,int16_t SSD1306_LCDWIDTH, int16_t SSD1306_LCDHEIGHT) {
- dc = cs = -1;
+// initializer for I2C - we only indicate the reset pin and OLED type !
+boolean Adafruit_SSD1306::init(int8_t RST, uint8_t OLED_TYPE)
+{
+ dc = cs = -1; // DC and chip Select do not exist in I2C
rst = RST;
- ssd1306_lcdwidth = SSD1306_LCDWIDTH;
- ssd1306_lcdheight = SSD1306_LCDHEIGHT;
- // Use for testing
- // bcm2835_set_debug(1);
- // Init Raspberry PI GPIO
- if (!bcm2835_init())
- return false;
+ // Select OLED parameters
+ if (!select_oled(OLED_TYPE))
+ return false;
- // Init Raspberry PI I2C
+ // Init & Configure Raspberry PI I2C
if (bcm2835_i2c_begin()==0)
return false;
+
+ bcm2835_i2c_setSlaveAddress(_i2c_addr) ;
+
+ // Set clock to 400 KHz
+ // does not seem to work, will check this later
+ // bcm2835_i2c_set_baudrate(400000);
+ // Setup reset pin direction as output
+ bcm2835_gpio_fsel(rst, BCM2835_GPIO_FSEL_OUTP);
+
return ( true);
}
-void Adafruit_SSD1306::close(void) {
-
+void Adafruit_SSD1306::close(void)
+{
+ // De-Allocate memory for OLED buffer if any
+ if (poledbuff)
+ free(poledbuff);
+
+ poledbuff = NULL;
// Release Raspberry SPI
if ( isSPI() )
@@ -202,37 +266,16 @@ void Adafruit_SSD1306::close(void) {
bcm2835_close();
}
-
-inline boolean Adafruit_SSD1306::isSPI(void) {
- return (cs != -1 ? true : false);
-}
-
-inline boolean Adafruit_SSD1306::isI2C(void) {
- return (cs == -1 ? true : false);
-}
-void Adafruit_SSD1306::begin(uint8_t vccstate, uint8_t i2caddr) {
-
- constructor(ssd1306_lcdwidth, ssd1306_lcdheight);
- _i2caddr = i2caddr;
+void Adafruit_SSD1306::begin( void )
+{
+ uint8_t multiplex;
+ uint8_t chargepump;
+ uint8_t compins;
+ uint8_t contrast;
+ uint8_t precharge;
- // CS pin only setup for SPI
- if ( isSPI() )
- {
- // SPI
- // Set the pin that will control DC as output
- bcm2835_gpio_fsel(dc, BCM2835_GPIO_FSEL_OUTP);
- }
- else
- {
- // I2C Init
- bcm2835_i2c_setSlaveAddress(i2caddr) ;
-
- // Set clock to 400 KHz
- // does not seem to work, will check this later
- // bcm2835_i2c_set_baudrate(400000);
- }
-
+ constructor(ssd1306_lcdwidth, ssd1306_lcdheight);
// Setup reset pin direction (used by both SPI and I2C)
bcm2835_gpio_fsel(rst, BCM2835_GPIO_FSEL_OUTP);
@@ -249,102 +292,90 @@ void Adafruit_SSD1306::begin(uint8_t vccstate, uint8_t i2caddr) {
// bring out of reset
bcm2835_gpio_write(rst, HIGH);
-
- // SPI oled does not seem to work with spi multiple byte command, I need to check that later
- if (isSPI())
+
+ // depends on OLED type configuration
+ if (ssd1306_lcdheight == 32)
{
- // Init sequence for OLED module
- ssd1306_command(SSD1306_DISPLAYOFF); // 0xAE
- ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
- ssd1306_command(0x80); // the suggested ratio 0x80
- ssd1306_command(SSD1306_SETMULTIPLEX); // 0xA8
-
- ssd1306_command(ssd1306_lcdheight==32?0x1F:0x3F);
-
- ssd1306_command(SSD1306_SETDISPLAYOFFSET); // 0xD3
- ssd1306_command(0x0); // no offset
- ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0
- ssd1306_command(SSD1306_CHARGEPUMP); // 0x8D
- ssd1306_command(vccstate==SSD1306_EXTERNALVCC?0x10:0x14);
- ssd1306_command(SSD1306_MEMORYMODE); // 0x20
- ssd1306_command(0x00); // 0x0 act like ks0108
- ssd1306_command(SSD1306_SEGREMAP | 0x1);
- ssd1306_command(SSD1306_COMSCANDEC);
- ssd1306_command(SSD1306_SETCOMPINS); // 0xDA
- ssd1306_command(ssd1306_lcdheight==32?0x02:0x12);
- ssd1306_command(SSD1306_SETCONTRAST); // 0x81
-
- if (ssd1306_lcdheight == 32)
- ssd1306_command(0x8F);
- else
- ssd1306_command(vccstate==SSD1306_EXTERNALVCC?0x9F:0xCF);
-
- ssd1306_command(SSD1306_SETPRECHARGE); // 0xd9
- ssd1306_command(vccstate==SSD1306_EXTERNALVCC?0x22:0xF1);
- ssd1306_command(SSD1306_SETVCOMDETECT); // 0xDB
- ssd1306_command(0x40);
- ssd1306_command(SSD1306_DISPLAYALLON_RESUME); // 0xA4
- ssd1306_command(SSD1306_NORMALDISPLAY); // 0xA6
- ssd1306_command(SSD1306_DISPLAYON);
+ multiplex = 0x1F;
+ compins = 0x02;
+ contrast = 0x8F;
}
else
{
- ssd1306_command(SSD1306_DISPLAYOFF); // 0xAE
- ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV, 0x80); // 0xD5 + the suggested ratio 0x80
- ssd1306_command(SSD1306_SETMULTIPLEX, ssd1306_lcdheight==32?0x1F:0x3F); // 0xA8 +
- ssd1306_command(SSD1306_SETDISPLAYOFFSET, 0x00); // 0xD3 + no offset
- ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0
- ssd1306_command(SSD1306_CHARGEPUMP, vccstate==SSD1306_EXTERNALVCC?0x10:0x14); // 0x8D
- ssd1306_command(SSD1306_MEMORYMODE, 0x00); // 0x20 0x0 act like ks0108
- ssd1306_command(SSD1306_SEGREMAP | 0x1);
- ssd1306_command(SSD1306_COMSCANDEC);
- ssd1306_command(SSD1306_SETCOMPINS, ssd1306_lcdheight==32?0x02:0x12); // 0xDA
-
- if (ssd1306_lcdheight == 32)
- ssd1306_command(SSD1306_SETCONTRAST, 0x8F);
- else
- ssd1306_command(SSD1306_SETCONTRAST, vccstate==SSD1306_EXTERNALVCC?0x9F:0xCF);
-
- ssd1306_command(SSD1306_SETPRECHARGE, vccstate==SSD1306_EXTERNALVCC?0x22:0xF1); // 0xd9
- ssd1306_command(SSD1306_SETVCOMDETECT, 0x40); // 0xDB
- ssd1306_command(SSD1306_DISPLAYALLON_RESUME); // 0xA4
- ssd1306_command(SSD1306_NORMALDISPLAY); // 0xA6
- ssd1306_command(0x21, 0x00, 0x7F); // Set column address; start 0, end 127
- ssd1306_command(0x22, 0x00, 0x03); // Set row address; start 0, end 3
- stopscroll();
- ssd1306_command(SSD1306_DISPLAYON); //--turn on oled panel
+ multiplex = 0x3F;
+ compins = 0x12;
+ contrast = (vcc_type==SSD_External_Vcc?0x9F:0xCF);
}
+ if (vcc_type == SSD_External_Vcc)
+ {
+ chargepump = 0x10;
+ precharge = 0x22;
+ }
+ else
+ {
+ chargepump = 0x14;
+ precharge = 0xF1;
+ }
+
+ ssd1306_command(SSD_Display_Off); // 0xAE
+ ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV, 0x80); // 0xD5 + the suggested ratio 0x80
+ ssd1306_command(SSD1306_SETMULTIPLEX, multiplex);
+ ssd1306_command(SSD1306_SETDISPLAYOFFSET, 0x00); // 0xD3 + no offset
+ ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0
+ ssd1306_command(SSD1306_CHARGEPUMP, chargepump);
+ ssd1306_command(SSD1306_MEMORYMODE, 0x00); // 0x20 0x0 act like ks0108
+ ssd1306_command(SSD1306_SEGREMAP | 0x1);
+ ssd1306_command(SSD1306_COMSCANDEC);
+ ssd1306_command(SSD1306_SETCOMPINS, compins); // 0xDA
+ ssd1306_command(SSD_Set_ContrastLevel, contrast);
+ ssd1306_command(SSD1306_SETPRECHARGE, precharge); // 0xd9
+ ssd1306_command(SSD1306_SETVCOMDETECT, 0x40); // 0xDB
+ ssd1306_command(SSD1306_DISPLAYALLON_RESUME); // 0xA4
+ ssd1306_command(SSD1306_Normal_Display); // 0xA6
+
+ // Reset to default value in case of
+ // no reset pin available on OLED
+ ssd1306_command( 0x21, 0, 127 );
+ ssd1306_command( 0x22, 0, 7 );
+ stopscroll();
+
+ // Empty uninitialized buffer
+ clearDisplay();
+ ssd1306_command(SSD_Display_On); //--turn on oled panel
}
-void Adafruit_SSD1306::invertDisplay(uint8_t i) {
- if (i) {
- ssd1306_command(SSD1306_INVERTDISPLAY);
- } else {
- ssd1306_command(SSD1306_NORMALDISPLAY);
- }
+void Adafruit_SSD1306::invertDisplay(uint8_t i)
+{
+ if (i)
+ ssd1306_command(SSD_Inverse_Display);
+ else
+ ssd1306_command(SSD1306_Normal_Display);
}
-void Adafruit_SSD1306::ssd1306_command(uint8_t c) {
+void Adafruit_SSD1306::ssd1306_command(uint8_t c)
+{
// Is SPI
if (isSPI())
{
- // SPI
- // Setup D/C line to low
+ // Setup D/C line to low to switch to command mode
bcm2835_gpio_write(dc, LOW);
- // Write Data
+ // Write Data on SPI
fastSPIwrite(c);
}
+ // so I2C
else
{
- // I2C
char buff[2] ;
- buff[0] = 0x00 ; // Co = 0, D/C = 0
+ // Clear D/C to switch to command mode
+ buff[0] = SSD_Command_Mode ;
buff[1] = c;
- bcm2835_i2c_write(buff, sizeof(buff)) ;
+
+ // Write Data on I2C
+ fastI2Cwrite(buff, sizeof(buff)) ;
}
}
@@ -357,17 +388,20 @@ void Adafruit_SSD1306::ssd1306_command(uint8_t c0, uint8_t c1)
// Is SPI
if (isSPI())
{
- // Setup D/C line to low
+ // Setup D/C line to low to switch to command mode
bcm2835_gpio_write(dc, LOW);
// Write Data
fastSPIwrite(&buff[1], 2);
}
+ // I2C
else
{
- // I2C
- buff[0] = 0x00 ; // Co = 0, D/C = 0
- bcm2835_i2c_write(buff, 3) ;
+ // Clear D/C to switch to command mode
+ buff[0] = SSD_Command_Mode ;
+
+ // Write Data on I2C
+ fastI2Cwrite(buff, 3) ;
}
}
@@ -382,18 +416,20 @@ void Adafruit_SSD1306::ssd1306_command(uint8_t c0, uint8_t c1, uint8_t c2)
// Is SPI
if (isSPI())
{
- // SPI
- // Setup D/C line to low
+ // Setup D/C line to low to switch to command mode
bcm2835_gpio_write(dc, LOW);
// Write Data
fastSPIwrite(&buff[1], 3);
}
+ // I2C
else
{
- // I2C
- buff[0] = 0x00; // Co = 0, D/C = 0;
- bcm2835_i2c_write(buff, sizeof(buff)) ;
+ // Clear D/C to switch to command mode
+ buff[0] = SSD_Command_Mode;
+
+ // Write Data on I2C
+ fastI2Cwrite(buff, sizeof(buff)) ;
}
}
@@ -402,7 +438,8 @@ void Adafruit_SSD1306::ssd1306_command(uint8_t c0, uint8_t c1, uint8_t c2)
// Activate a right handed scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// display.scrollright(0x00, 0x0F)
-void Adafruit_SSD1306::startscrollright(uint8_t start, uint8_t stop){
+void Adafruit_SSD1306::startscrollright(uint8_t start, uint8_t stop)
+{
ssd1306_command(SSD1306_RIGHT_HORIZONTAL_SCROLL);
ssd1306_command(0X00);
ssd1306_command(start);
@@ -410,14 +447,15 @@ void Adafruit_SSD1306::startscrollright(uint8_t start, uint8_t stop){
ssd1306_command(stop);
ssd1306_command(0X01);
ssd1306_command(0XFF);
- ssd1306_command(SSD1306_ACTIVATE_SCROLL);
+ ssd1306_command(SSD_Activate_Scroll);
}
// startscrollleft
// Activate a right handed scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// display.scrollright(0x00, 0x0F)
-void Adafruit_SSD1306::startscrollleft(uint8_t start, uint8_t stop){
+void Adafruit_SSD1306::startscrollleft(uint8_t start, uint8_t stop)
+{
ssd1306_command(SSD1306_LEFT_HORIZONTAL_SCROLL);
ssd1306_command(0X00);
ssd1306_command(start);
@@ -425,14 +463,15 @@ void Adafruit_SSD1306::startscrollleft(uint8_t start, uint8_t stop){
ssd1306_command(stop);
ssd1306_command(0X01);
ssd1306_command(0XFF);
- ssd1306_command(SSD1306_ACTIVATE_SCROLL);
+ ssd1306_command(SSD_Activate_Scroll);
}
// startscrolldiagright
// Activate a diagonal scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// display.scrollright(0x00, 0x0F)
-void Adafruit_SSD1306::startscrolldiagright(uint8_t start, uint8_t stop){
+void Adafruit_SSD1306::startscrolldiagright(uint8_t start, uint8_t stop)
+{
ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA);
ssd1306_command(0X00);
ssd1306_command(ssd1306_lcdheight);
@@ -442,14 +481,15 @@ void Adafruit_SSD1306::startscrolldiagright(uint8_t start, uint8_t stop){
ssd1306_command(0X00);
ssd1306_command(stop);
ssd1306_command(0X01);
- ssd1306_command(SSD1306_ACTIVATE_SCROLL);
+ ssd1306_command(SSD_Activate_Scroll);
}
// startscrolldiagleft
// Activate a diagonal scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// display.scrollright(0x00, 0x0F)
-void Adafruit_SSD1306::startscrolldiagleft(uint8_t start, uint8_t stop){
+void Adafruit_SSD1306::startscrolldiagleft(uint8_t start, uint8_t stop)
+{
ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA);
ssd1306_command(0X00);
ssd1306_command(ssd1306_lcdheight);
@@ -459,34 +499,37 @@ void Adafruit_SSD1306::startscrolldiagleft(uint8_t start, uint8_t stop){
ssd1306_command(0X00);
ssd1306_command(stop);
ssd1306_command(0X01);
- ssd1306_command(SSD1306_ACTIVATE_SCROLL);
+ ssd1306_command(SSD_Activate_Scroll);
}
-void Adafruit_SSD1306::stopscroll(void){
- ssd1306_command(SSD1306_DEACTIVATE_SCROLL);
+void Adafruit_SSD1306::stopscroll(void)
+{
+ ssd1306_command(SSD_Deactivate_Scroll);
}
-void Adafruit_SSD1306::ssd1306_data(uint8_t c) {
-
+void Adafruit_SSD1306::ssd1306_data(uint8_t c)
+{
// SPI
if ( isSPI())
{
// SPI
- // Set D/C pin high
+ // Setup D/C line to high to switch to data mode
bcm2835_gpio_write(dc, HIGH);
// write value
fastSPIwrite(c);
}
+ // I2C
else
{
- // I2C
char buff[2] ;
- uint8_t control = 0x40; // Co = 0, D/C = 1
- buff[0] = control;
+
+ // Setup D/C to switch to data mode
+ buff[0] = SSD_Data_Mode;
buff[1] = c;
- bcm2835_i2c_write ( buff, sizeof(buff)) ;
+ // Write on i2c
+ fastI2Cwrite( buff, sizeof(buff)) ;
}
}
@@ -497,16 +540,20 @@ void Adafruit_SSD1306::display(void)
ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0
uint16_t i=0 ;
+
+ // pointer to OLED data buffer
+ uint8_t * p = poledbuff;
// SPI
if ( isSPI())
{
- // set D/C line to High
+ // Setup D/C line to high to switch to data mode
bcm2835_gpio_write(dc, HIGH);
+ // Send all data to OLED
for ( i=0; i<(ssd1306_lcdwidth*ssd1306_lcdheight/8); i++)
{
- fastSPIwrite(buffer[i]);
+ fastSPIwrite(*p++);
}
// i wonder why we have to do this (check datasheet)
@@ -517,6 +564,7 @@ void Adafruit_SSD1306::display(void)
fastSPIwrite(0);
}
}
+
}
// I2C
else
@@ -524,34 +572,24 @@ void Adafruit_SSD1306::display(void)
char buff[17] ;
uint8_t x ;
- /// loop trought all buffer
- for ( i=0; i<(ssd1306_lcdwidth*ssd1306_lcdheight/8); i++ )
+ // Setup D/C to switch to data mode
+ buff[0] = SSD_Data_Mode;
+
+ // loop trough all OLED buffer and
+ // send a bunch of 16 data byte in one xmission
+ for ( i=0; i<(ssd1306_lcdwidth*ssd1306_lcdheight/8); i+=16 )
{
- buff[0] = 0x40; // Co = 0; D/C# = 1 for data
-
- // send a bunch of 16 data byte in one xmission
- for (x=0; x<16; x++)
- buff[x+1] = buffer[i++];
-
- bcm2835_i2c_write ( buff, sizeof(buff));
- i--;
+ for (x=1; x<=16; x++)
+ buff[x] = *p++;
+
+ fastI2Cwrite( buff, 17);
}
}
}
-// clear everything
-void Adafruit_SSD1306::clearDisplay(void) {
- memset(buffer, 0, (ssd1306_lcdwidth*ssd1306_lcdheight/8));
-}
-
-
-inline void Adafruit_SSD1306::fastSPIwrite(uint8_t d) {
-
- bcm2835_spi_transfer(d);
-}
-
-inline void Adafruit_SSD1306::fastSPIwrite(char* tbuf, uint32_t len) {
-
- bcm2835_spi_writenb(tbuf, len);
+// clear everything (in the buffer)
+void Adafruit_SSD1306::clearDisplay(void)
+{
+ memset(poledbuff, 0, (ssd1306_lcdwidth*ssd1306_lcdheight/8));
}
View
143 Adafruit_SSD1306.h
@@ -28,73 +28,112 @@ All text above, and the splash screen must be included in any redistribution
#define BLACK 0
#define WHITE 1
-#define SSD1306_I2C_ADDRESS 0x3C // 011110+SA0+RW - 0x3C or 0x3D
-// Address for 128x32 is 0x3C
-// Address for 128x32 is 0x3D (default) or 0x3C (if SA0 is grounded)
/*=========================================================================
- SSD1306 Displays
+ SSDxxxx Common Displays
-----------------------------------------------------------------------
- The driver is used in multiple displays (128x64, 128x32, etc.).
- The appropriate display is defined in the code using this library
+ Common values to all displays
=========================================================================*/
-#define SSD1306_SETCONTRAST 0x81
-#define SSD1306_DISPLAYALLON_RESUME 0xA4
-#define SSD1306_DISPLAYALLON 0xA5
-#define SSD1306_NORMALDISPLAY 0xA6
-#define SSD1306_INVERTDISPLAY 0xA7
-#define SSD1306_DISPLAYOFF 0xAE
-#define SSD1306_DISPLAYON 0xAF
+//#define SSD_Command_Mode 0x80 /* DC bit is 0 */ Seeed set C0 to 1 why ?
+#define SSD_Command_Mode 0x00 /* C0 and DC bit are 0 */
+#define SSD_Data_Mode 0x40 /* C0 bit is 0 and DC bit is 1 */
-#define SSD1306_SETDISPLAYOFFSET 0xD3
-#define SSD1306_SETCOMPINS 0xDA
+#define SSD_Inverse_Display 0xA7
-#define SSD1306_SETVCOMDETECT 0xDB
+#define SSD_Display_Off 0xAE
+#define SSD_Display_On 0xAF
-#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
-#define SSD1306_SETPRECHARGE 0xD9
+#define SSD_Set_ContrastLevel 0x81
-#define SSD1306_SETMULTIPLEX 0xA8
+#define SSD_External_Vcc 0x01
+#define SSD_Internal_Vcc 0x02
-#define SSD1306_SETLOWCOLUMN 0x00
-#define SSD1306_SETHIGHCOLUMN 0x10
-#define SSD1306_SETSTARTLINE 0x40
+#define SSD_Activate_Scroll 0x2F
+#define SSD_Deactivate_Scroll 0x2E
-#define SSD1306_MEMORYMODE 0x20
+#define Scroll_Left 0x00
+#define Scroll_Right 0x01
-#define SSD1306_COMSCANINC 0xC0
-#define SSD1306_COMSCANDEC 0xC8
+#define Scroll_2Frames 0x07
+#define Scroll_3Frames 0x04
+#define Scroll_4Frames 0x05
+#define Scroll_5Frames 0x00
+#define Scroll_25Frames 0x06
+#define Scroll_64Frames 0x01
+#define Scroll_128Frames 0x02
+#define Scroll_256Frames 0x03
-#define SSD1306_SEGREMAP 0xA0
+#define VERTICAL_MODE 01
+#define PAGE_MODE 01
+#define HORIZONTAL_MODE 02
-#define SSD1306_CHARGEPUMP 0x8D
-#define SSD1306_EXTERNALVCC 0x1
-#define SSD1306_SWITCHCAPVCC 0x2
+/*=========================================================================
+ SSD1306 Displays
+ -----------------------------------------------------------------------
+ The driver is used in multiple displays (128x64, 128x32, etc.).
+=========================================================================*/
+#define SSD1306_DISPLAYALLON_RESUME 0xA4
+#define SSD1306_DISPLAYALLON 0xA5
+
+#define SSD1306_Normal_Display 0xA6
+
+#define SSD1306_SETDISPLAYOFFSET 0xD3
+#define SSD1306_SETCOMPINS 0xDA
+#define SSD1306_SETVCOMDETECT 0xDB
+#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
+#define SSD1306_SETPRECHARGE 0xD9
+#define SSD1306_SETMULTIPLEX 0xA8
+#define SSD1306_SETLOWCOLUMN 0x00
+#define SSD1306_SETHIGHCOLUMN 0x10
+#define SSD1306_SETSTARTLINE 0x40
+#define SSD1306_MEMORYMODE 0x20
+#define SSD1306_COMSCANINC 0xC0
+#define SSD1306_COMSCANDEC 0xC8
+#define SSD1306_SEGREMAP 0xA0
+#define SSD1306_CHARGEPUMP 0x8D
// Scrolling #defines
-#define SSD1306_ACTIVATE_SCROLL 0x2F
-#define SSD1306_DEACTIVATE_SCROLL 0x2E
-#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
-#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
-#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
-#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
-#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
-
-class Adafruit_SSD1306 : public Adafruit_GFX {
- public:
-// Adafruit_SSD1306(int8_t DC, int8_t RST);
-// Adafruit_SSD1306(int8_t RST);
+#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
+#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
+#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
+#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
+#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
+
+/*=========================================================================
+ SSD1308 Displays
+ -----------------------------------------------------------------------
+ The driver is used in multiple displays (128x64, 128x32, etc.).
+=========================================================================*/
+#define SSD1308_Normal_Display 0xA6
+/*=========================================================================
+ SSD1327 Displays
+ -----------------------------------------------------------------------
+ The driver is used in Seeed 96x96 display
+=========================================================================*/
+#define SSD1327_Normal_Display 0xA4
+
+
+class Adafruit_SSD1306 : public Adafruit_GFX
+{
+ public:
Adafruit_SSD1306();
- boolean init(int8_t DC, int8_t RST, int8_t CS, int16_t SSD1306_LCDWIDTH, int16_t SSD1306_LCDHEIGHT);
- boolean init(int8_t RST,int16_t SSD1306_LCDWIDTH, int16_t SSD1306_LCDHEIGHT);
+ // SPI Init
+ boolean init(int8_t DC, int8_t RST, int8_t CS, uint8_t OLED_TYPE);
+
+ // I2C Init
+ boolean init(int8_t RST, uint8_t OLED_TYPE);
+
+ boolean oled_is_spi_proto(uint8_t OLED_TYPE); /* to know protocol before init */
+ boolean select_oled(uint8_t OLED_TYPE) ;
+
+ void begin(void);
void close(void);
- void begin(uint8_t switchvcc = SSD1306_SWITCHCAPVCC, uint8_t i2caddr = SSD1306_I2C_ADDRESS);
void ssd1306_command(uint8_t c);
void ssd1306_command(uint8_t c0, uint8_t c1);
void ssd1306_command(uint8_t c0, uint8_t c1, uint8_t c2);
@@ -112,17 +151,21 @@ class Adafruit_SSD1306 : public Adafruit_GFX {
void stopscroll(void);
void drawPixel(int16_t x, int16_t y, uint16_t color);
+
+ private:
+ uint8_t *poledbuff; // Pointer to OLED data buffer in memory
+ int8_t _i2c_addr, dc, rst, cs;
+ int16_t ssd1306_lcdwidth, ssd1306_lcdheight;
+ uint8_t vcc_type;
inline boolean isI2C(void);
inline boolean isSPI(void);
-
- private:
- int8_t _i2caddr, dc, rst, cs;
- int16_t ssd1306_lcdwidth, ssd1306_lcdheight;
void fastSPIwrite(uint8_t c);
void fastSPIwrite(char* tbuf, uint32_t len);
+ void fastI2Cwrite(uint8_t c);
+ void fastI2Cwrite(char* tbuf, uint32_t len);
void slowSPIwrite(uint8_t c);
- volatile uint8_t *dcport;
- uint8_t dcpinmask;
+ //volatile uint8_t *dcport;
+ //uint8_t dcpinmask;
};
View
31 ArduiPi_SSD1306.h
@@ -20,7 +20,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include "./bcm2835.h"
+#include "bcm2835.h"
// Configuration Pin for ArduiPi board
#define OLED_SPI_RESET RPI_V2_GPIO_P1_22 /* GPIO 25 pin 22 */
@@ -30,6 +30,33 @@
#define OLED_SPI_CS BCM2835_SPI_CS1 /* Default Chip Select */
#define OLED_I2C_RESET RPI_V2_GPIO_P1_22 /* GPIO 25 pin 12 */
+// OLED type I2C Address
+#define ADAFRUIT_I2C_ADDRESS 0x3C /* 011110+SA0+RW - 0x3C or 0x3D */
+// Address for 128x32 is 0x3C
+// Address for 128x32 is 0x3D (default) or 0x3C (if SA0 is grounded)
+
+#define SEEEED_I2C_ADDRESS 0x3C /* 011110+SA0+RW - 0x3C or 0x3D */
+
+// Oled supported display
+#define OLED_ADAFRUIT_SPI_128x32 0
+#define OLED_ADAFRUIT_SPI_128x64 1
+#define OLED_ADAFRUIT_I2C_128x32 2
+#define OLED_ADAFRUIT_I2C_128x64 3
+#define OLED_SEEED_I2C_128x64 4
+#define OLED_SEEED_I2C_96x96 5
+
+#define OLED_LAST_OLED 6 /* always last type, used in code to end array */
+
+
+static const char * oled_type_str[] = {
+ "Adafruit SPI 128x32",
+ "Adafruit SPI 128x64",
+ "Adafruit I2C 128x32",
+ "Adafruit I2C 128x64",
+ "Seeed I2C 128x64",
+ "Seeed I2C 96x96"
+};
+
// Arduino Compatible type
typedef uint8_t boolean;
typedef uint8_t byte;
@@ -41,4 +68,4 @@ typedef uint8_t byte;
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
-#endif
+#endif
View
27 Makefile
@@ -30,8 +30,6 @@ all: libssd1306 install
# Make the library
libssd1306: Adafruit_SSD1306.o Adafruit_GFX.o bcm2835.o
g++ -shared -Wl,-soname,$@.so.1 ${CCFLAGS} -o ${LIBNAME} $^
- #ar -rcs $@.a $^
- #ranlib $@.a
# Library parts (use -fno-rtti flag to avoid link problem)
Adafruit_SSD1306.o: Adafruit_SSD1306.cpp
@@ -45,20 +43,33 @@ bcm2835.o: bcm2835.c
# Install the library to LIBPATH
install:
- @echo "[Install]"
+ @echo "[Install Library]"
@if ( test ! -d $(PREFIX)/lib ) ; then mkdir -p $(PREFIX)/lib ; fi
- #@install -m 0755 ${LIB}.a ${LIBDIR}
@install -m 0755 ${LIBNAME} ${LIBDIR}
@ln -sf ${LIBDIR}/${LIBNAME} ${LIBDIR}/${LIB}.so.1
@ln -sf ${LIBDIR}/${LIBNAME} ${LIBDIR}/${LIB}.so
@ldconfig
+ @rm -rf ${LIB}.*
- # if you need it
- #cp -f *.h $(PREFIX)/include
- #chmod ugo-x $(PREFIX)/include/*.h
+ @echo "[Install Headers]"
+ @if ( test ! -d $(PREFIX)/include ) ; then mkdir -p $(PREFIX)/include ; fi
+ @cp -f Adafruit_*.h $(PREFIX)/include
+ @cp -f ArduiPi_*.h $(PREFIX)/include
+ @cp -f bcm2835.h $(PREFIX)/include
+
+
+# Uninstall the library
+uninstall:
+ @echo "[Uninstall Library]"
+ @rm -f ${LIBDIR}/${LIB}.*
+
+ @echo "[Uninstall Headers]"
+ @rm -rf $(PREFIX)/include/Adafruit_SSD1306*
+ @rm -rf $(PREFIX)/include/ArduiPi_SSD1306*
+ @rm -rf $(PREFIX)/include/bcm2835.h
# clear build files
clean:
- rm -rf *.o ${LIB}.*
+ rm -rf *.o ${LIB}.* ${LIBDIR}/${LIB}.*
View
5 bcm2835.c
@@ -55,7 +55,7 @@ volatile uint32_t *bcm2835_st = MAP_FAILED;
static uint8_t debug = 0;
// I2C The time needed to transmit one byte. In microseconds.
-static int i2c_byte_wait_us = 0;
+//static int i2c_byte_wait_us = 0;
// i2c file descriptor for opeping i2c device
static int i2c_fd = 0;
@@ -159,6 +159,7 @@ uint32_t bcm2835_peri_read(volatile uint32_t* paddr)
// if subsequent code changes to a different peripheral
uint32_t ret = *paddr;
uint32_t dummy = *paddr;
+ dummy=dummy; // avoid compiler warning
return ret;
}
}
@@ -750,7 +751,7 @@ void bcm2835_spi_writenb(char* tbuf, uint32_t len)
bcm2835_spi_setChipSelect(LOW);
// This is Polled transfer as per section 10.6.1
- // BUG ALERT: what happens if we get interupted in this section, and someone else
+ // BUG ALERT: what happens if we get interrupted in this section, and someone else
// accesses a different peripheral?
// Clear TX and RX fifos
View
2  examples/Makefile
@@ -22,7 +22,7 @@ SOURCES = ${PROGRAMS:=.cpp}
all: ${PROGRAMS}
${PROGRAMS}: ${SOURCES}
- g++ ${CCFLAGS} -Wall -I../ -L../ -lssd1306 $@.cpp -o $@
+ g++ ${CCFLAGS} -Wall -lssd1306 $@.cpp -o $@
clean:
rm -rf $(PROGRAMS)
View
133 examples/ssd1306_demo.cpp
@@ -21,6 +21,7 @@ All text above, and the splash screen must be included in any redistribution
the command line (no more #define on compilation needed)
ArduiPi project documentation http://hallard.me/arduipi
+
*********************************************************************/
#include "ArduiPi_SSD1306.h"
@@ -30,31 +31,22 @@ All text above, and the splash screen must be included in any redistribution
#include <getopt.h>
#define PRG_NAME "ssd1306_demo"
-#define PRG_VERSION "1.0"
-#define DEF_WIDTH 128 /* default OLED width */
-#define DEF_HEIGHT 32 /* default OLED height */
+#define PRG_VERSION "1.1"
// Instantiate the display
Adafruit_SSD1306 display;
-
-enum bus_e { MODE_SPI, MODE_I2C };
-
// Config Option
struct s_opts
{
- int mode;
- int width;
- int height;
+ int oled;
int verbose;
} ;
// default options values
s_opts opts = {
- MODE_SPI, // SPI by default
- DEF_WIDTH, // 128 pixels width
- DEF_HEIGHT, // 32 pixels height
- false // Not verbose
+ OLED_ADAFRUIT_SPI_128x32, // Default oled
+ false // Not verbose
};
#define NUMFLAKES 10
@@ -277,19 +269,19 @@ Output : -
void usage( char * name)
{
printf("%s\n", name );
- printf("Usage is: %s --i2c|spi --witdh --height [options]\n", name);
- printf(" --<i>2c : OLED is i2c\n");
- printf(" --<s>pi : OLED is SPI\n");
- printf(" --<width> : OLED width\n");
- printf(" --heigh<t> : OLED height\n");
+ printf("Usage is: %s --oled type [options]\n", name);
+ printf(" --<o>led type\nOLED type are:\n");
+ for (int i=0; i<OLED_LAST_OLED;i++)
+ printf(" %1d %s\n", i, oled_type_str[i]);
+
printf("Options are:\n");
printf(" --<v>erbose : speak more to user\n");
printf(" --<h>elp\n");
printf("<?> indicates the equivalent short option.\n");
printf("Short options are prefixed by \"-\" instead of by \"--\".\n");
printf("Example :\n");
- printf( "%s -s -w 128 -t 32 use a SPI 128x32 OLED\n\n", name);
- printf( "%s -i -w 128 -t 64 use a I2C 128x64 OLED\n", name);
+ printf( "%s -o 1 use a %s OLED\n\n", name, oled_type_str[1]);
+ printf( "%s -o 4 -v use a %s OLED being verbose\n", name, oled_type_str[4]);
}
@@ -304,11 +296,8 @@ void parse_args(int argc, char *argv[])
{
static struct option longOptions[] =
{
- {"i2c" , no_argument, 0, 'i'},
- {"spi" , no_argument, 0, 's'},
+ {"oled" , required_argument,0, 'o'},
{"verbose", no_argument, 0, 'v'},
- {"width" , required_argument,0, 'w'},
- {"height" , required_argument,0, 't'},
{"help" , no_argument, 0, 'h'},
{0, 0, 0, 0}
};
@@ -321,7 +310,7 @@ void parse_args(int argc, char *argv[])
/* no default error messages printed. */
opterr = 0;
- c = getopt_long(argc, argv, "isvhw:t:", longOptions, &optionIndex);
+ c = getopt_long(argc, argv, "vho:", longOptions, &optionIndex);
if (c < 0)
break;
@@ -329,34 +318,23 @@ void parse_args(int argc, char *argv[])
switch (c)
{
case 'v': opts.verbose = true ; break;
- case 'i': opts.mode = MODE_I2C ; break;
- case 's': opts.mode = MODE_SPI ; break;
-
- case 'w':
- opts.width = (int) atoi(optarg);
-
- if (opts.width != DEF_WIDTH )
- {
- fprintf(stderr, "--width '%d' ignored.\n", opts.width);
- fprintf(stderr, "--width must be 128 for now\n");
- opts.width = DEF_WIDTH;
- }
- break;
- case 't':
- opts.height = (int) atoi(optarg);
+ case 'o':
+ opts.oled = (int) atoi(optarg);
- if (opts.height != 32 && opts.height != 63 )
+ if (opts.oled < 0 || opts.oled >= OLED_LAST_OLED )
{
- fprintf(stderr, "--height '%d' ignored.\n", opts.height);
- fprintf(stderr, "--height must be 32 or 64 for now\n");
- opts.height = DEF_HEIGHT;
+ fprintf(stderr, "--oled %d ignored must be 0 to %d.\n", opts.oled, OLED_LAST_OLED-1);
+ fprintf(stderr, "--oled set to 0 now\n");
+ opts.oled = 0;
}
break;
case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
+ break;
+
case '?':
default:
fprintf(stderr, "Unrecognized option.\n");
@@ -369,9 +347,7 @@ void parse_args(int argc, char *argv[])
{
printf("%s v%s\n", PRG_NAME, PRG_VERSION);
printf("-- OLED params -- \n");
- printf("mode is : %s\n", opts.mode == MODE_SPI ? "SPI" : "I2C");
- printf("width is : %d\n", opts.width);
- printf("height is : %d\n", opts.height);
+ printf("Oled is : %s\n", oled_type_str[opts.oled]);
printf("-- Other Stuff -- \n");
printf("verbose is : %s\n", opts.verbose? "yes" : "no");
printf("\n");
@@ -388,40 +364,30 @@ Output : -
====================================================================== */
int main(int argc, char **argv)
{
+ int i;
+
+
+ // Oled supported display in ArduiPi_SSD1306.h
// Get OLED type
parse_args(argc, argv);
// SPI
- if (opts.mode == MODE_SPI )
+ if (display.oled_is_spi_proto(opts.oled))
{
- // SPI LCD 128x32 size, change parameters to fit to your LCD
- if ( !display.init(OLED_SPI_DC,OLED_SPI_RESET,OLED_SPI_CS, opts.width, opts.height) )
+ // SPI change parameters to fit to your LCD
+ if ( !display.init(OLED_SPI_DC,OLED_SPI_RESET,OLED_SPI_CS, opts.oled) )
exit(EXIT_FAILURE);
-
- // SPI start : by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
- display.begin(SSD1306_SWITCHCAPVCC);
}
-
- // I2C
- if (opts.mode == MODE_I2C )
+ else
{
- // SPI LCD 128x32 size, change parameters to fit to your LCD
- if ( !display.init(OLED_I2C_RESET,opts.width, opts.height) )
+ // I2C change parameters to fit to your LCD
+ if ( !display.init(OLED_I2C_RESET,opts.oled) )
exit(EXIT_FAILURE);
-
- // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
- if (opts.height == 32 )
- // initialize with the I2C addr 0x3C (for the 128x32)
- display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
- else
- // initialize with the I2C addr 0x3D (for the 128x64)
- display.begin(SSD1306_SWITCHCAPVCC, 0x3D);
}
+ display.begin();
// init done
- display.display(); // show splashscreen
- sleep(2);
display.clearDisplay(); // clears the screen and buffer
@@ -496,6 +462,37 @@ int main(int argc, char **argv)
display.display();
sleep(2);
+
+ // horizontal bargraph tests
+ display.clearDisplay();
+ display.setTextSize(1);
+ display.setTextColor(WHITE);
+ for ( i =0 ; i<=100 ; i++)
+ {
+ display.clearDisplay();
+ display.setCursor(0,0);
+ display.print("Gauge Graph!\n");
+ display.printf(" %03d %%", i);
+ display.drawHorizontalBargraph(0,16,128,16,1, i);
+ display.display();
+ usleep(25000);
+ }
+
+ // vertical bargraph tests
+ display.clearDisplay();
+ display.setTextSize(1);
+ display.setTextColor(WHITE);
+ for ( i =0 ; i<=100 ; i++)
+ {
+ display.clearDisplay();
+ display.setCursor(0,0);
+ display.print("Gauge !\n");
+ display.printf("%03d %%", i);
+ display.drawVerticalBargraph(114,0,8,32,1, i);
+ display.display();
+ usleep(25000);
+ }
+
// draw scrolling text
testscrolltext();
sleep(2);
View
109 examples/teleinfo-oled.cpp
@@ -41,7 +41,7 @@ Comments: some code grabbed from picocom and other from teleinfo
#define false 0
#define PRG_NAME "teleinfo-oled"
-#define PRG_VERSION "1.0"
+#define PRG_VERSION "1.1"
#define PRG_DIR "/usr/local/bin" // Directory where we are when in daemon mode
// Define teleinfo mode, device or network
@@ -61,6 +61,10 @@ enum flowcntrl_e { FC_NONE, FC_RTSCTS, FC_XONXOFF };
enum mode_e { MODE_NET, MODE_SERIAL };
enum ptec_e { PTEC_HP, PTEC_HC };
+// Oled protocol
+enum oled_e { OLED_I2C, OLED_SPI };
+
+
// Config Option
struct s_opts
{
@@ -73,6 +77,9 @@ struct s_opts
int databits;
int mode;
char mode_str[32];
+ int address; // i2c slave address
+ int oled; // protocol used for OLED
+ char oled_str[8]; // protocol mode functionnality human readable
int netport;
int verbose;
int daemon;
@@ -88,11 +95,15 @@ s_opts opts = {
7,
MODE_SERIAL,
"Serial",
+ 0,
+ OLED_I2C,
+ "i2c",
TELEINFO_PORT,
false,
false
};
+
// ======================================================================
// Global vars
// ======================================================================
@@ -643,9 +654,13 @@ void usage( char * name)
{
printf("%s\n", PRG_NAME );
- printf("Usage is: %s --net|serial [options] <tty device>\n", PRG_NAME);
+ printf("Usage is: %s --net|serial [oled] [-a address] [options] <tty device>\n", PRG_NAME);
printf(" --<s>erial : receive teleinfo frame from network\n");
printf(" --<n>net : receive teleinfo frame from serial\n");
+ printf(" --<a>ddress: i2c device address (default 0x2A)\n");
+ printf("oled is:\n");
+ printf(" --<I>2c : set protocol to i2c (default)\n");
+ printf(" --<S>pi : set protocol to spi\n");
printf("Options are:\n");
printf(" --<v>erbose : speak more to user\n");
printf(" --<d>aemon : daemonize the process\n");
@@ -672,14 +687,18 @@ void parse_args(int argc, char *argv[])
{"verbose", no_argument, 0, 'v'},
{"net" , no_argument, 0, 'n'},
{"serial" , no_argument, 0, 's'},
- {"port", required_argument,0, 'p'},
- {"daemon", no_argument, 0, 'd'},
- {"help", no_argument, 0, 'h'},
+ {"address",required_argument, 0, 'a' },
+ {"i2c" ,no_argument , 0, 'I' },
+ {"spi" ,no_argument ,0, 'S' },
+ {"port" , required_argument,0, 'p'},
+ {"daemon" , no_argument, 0, 'd'},
+ {"help" , no_argument, 0, 'h'},
{0, 0, 0, 0}
};
int optionIndex = 0;
int c;
+ char * pEnd;
while (1)
{
@@ -693,13 +712,12 @@ void parse_args(int argc, char *argv[])
switch (c)
{
- case 'v':
- opts.verbose = true;
- break;
-
- case 'd':
- opts.daemon = true;
- break;
+
+ case 'I': opts.oled= OLED_I2C; strcpy(opts.oled_str, "i2c") ; break;
+ case 'S': opts.oled= OLED_SPI; strcpy(opts.oled_str, "spi") ; break;
+
+ case 'v':opts.verbose = true; break;
+ case 'd':opts.daemon = true; break;
case 'n':
opts.mode = MODE_NET;
@@ -710,6 +728,20 @@ void parse_args(int argc, char *argv[])
opts.mode = MODE_SERIAL;
strcpy(opts.mode_str,"Serial");
break;
+
+ // i2c slave address
+ case 'a':
+ opts.address = strtol(optarg,&pEnd,0);
+
+ if ( !*pEnd || opts.address < 1 || opts.address > 0x7F )
+ {
+ fprintf(stderr, "--address %d (0x%02x) ignored.\n", opts.address, opts.address);
+ fprintf(stderr, "--address must be between 1 and 255 or 0x01 and 0xff\n");
+ opts.address = 0;
+ fprintf(stderr, "--setting slave to default 0x%02x\n", opts.address);
+ }
+ break;
+
case 'p':
opts.netport = (int) atoi(optarg);
@@ -750,6 +782,19 @@ void parse_args(int argc, char *argv[])
{
printf("%s v%s\n", PRG_NAME, PRG_VERSION);
+ if ( opts.oled == OLED_I2C )
+ {
+ printf("-- i2c OLED -- \n");
+ printf("slave address : 0x%02X\n", opts.address);
+ }
+
+ if ( opts.oled == OLED_SPI )
+ {
+ printf("-- Spi OLED -- \n");
+ printf("Spi CS : CE0\n");
+ }
+
+
if (opts.mode == MODE_NET )
{
printf("-- Network Stuff -- \n");
@@ -764,6 +809,7 @@ void parse_args(int argc, char *argv[])
printf("parity is : %s\n", opts.parity_str);
printf("databits are : %d\n", opts.databits);
}
+
printf("-- Other Stuff -- \n");
printf("verbose is : %s\n", opts.verbose? "yes" : "no");
printf("\n");
@@ -853,14 +899,22 @@ int main(int argc, char **argv)
}
}
- // SPI Init
- if ( !display.init(OLED_SPI_DC,OLED_SPI_RESET,OLED_SPI_CS, 128, 32) )
- fatal("Unable to init SPI OLED");
-
- // SPI start : by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
- display.begin(SSD1306_SWITCHCAPVCC);
+ if (opts.oled == OLED_SPI )
+ {
+ // SPI OLED Init
+ if ( !display.init(OLED_SPI_DC,OLED_SPI_RESET,OLED_SPI_CS, OLED_ADAFRUIT_SPI_128x32) )
+ fatal("Unable to init SPI OLED");
+ }
+ else
+ {
+ // I2C OLED Init
+ if ( !display.init(OLED_I2C_RESET,OLED_ADAFRUIT_I2C_128x32) )
+ fatal("Unable to init I2C OLED");
+ }
- // show splashscreen
+ display.begin();
+
+ // show
display.display();
log_syslog(stdout, "Inits succeded, entering Main loop\n");
@@ -969,7 +1023,6 @@ int main(int argc, char **argv)
{
//char oled_buff[1024];
int percent=0;
- int hsize=0;
t = time(NULL);
tmp = localtime(&t);
@@ -981,12 +1034,6 @@ int main(int argc, char **argv)
}
}
- // Percent of total power
- percent = (100 * g_values.iinst) / g_values.isousc ;
-
- // calculate pixel size
- hsize = 30 / (percent);
-
// good full frame received, do whatever you want here
//fprintf(stdout, "==========================\nTeleinfo Frame of %d char\n%s\n==========================%s\n",
// strlen(rcv_buff), time_str, rcv_buff );
@@ -1012,13 +1059,19 @@ int main(int argc, char **argv)
display.print("Creuses ");
display.printf("%09ld\n", g_values.hchc);
display.setTextColor(WHITE); // normaltext
+
+ // Calculate Bargraph display
+
+ // Percent of total power
+ percent = (100 * g_values.iinst) / g_values.isousc ;
//display.setTextColor(BLACK, WHITE); // 'inverted' text
display.printf("%d W %d%% %3d A\n%s", g_values.papp, percent, g_values.iinst, time_str);
//display.setTextSize(2);
//display.setTextColor(WHITE);
- display.drawRect(114,0, 12,32, 1) ;
- display.fillRect(115,31 - hsize, 10, hsize, 1);
+ display.drawVerticalBargraph(114,0,12,32,1, percent);
+ //display.drawRect(114,0, 12,32, 1) ;
+ //display.fillRect(115,31 - hsize, 10, hsize, 1);
display.display();
display.setTextColor(BLACK, WHITE); // 'inverted' text