ssd1306: initial implementation

Signed-off-by: Marc Graham <marc@m2ag.net>
Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
This commit is contained in:
Marc Graham 2015-08-27 17:28:15 -07:00 committed by Mihai Tudor Panu
parent 5a62602a11
commit 3159005aa3
10 changed files with 866 additions and 2 deletions

BIN
docs/images/ssd1306.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -19,6 +19,7 @@ add_executable (nrf24l01-receiver-example nrf24l01-receiver.cxx)
add_executable (nrf24l01-broadcast-example nrf24l01-broadcast.cxx)
add_executable (es08a-example es08a.cxx)
add_executable (hcsr04-example hcsr04.cxx)
add_executable (ssd1306-oled-example ssd1306-oled.cxx)
add_executable (ssd1308-oled-example ssd1308-oled.cxx)
add_executable (ssd1327-oled-example ssd1327-oled.cxx)
add_executable (max44000-example max44000.cxx)
@ -270,6 +271,7 @@ target_link_libraries (nrf24l01-receiver-example nrf24l01 ${CMAKE_THREAD_LIBS_IN
target_link_libraries (nrf24l01-broadcast-example nrf24l01 ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries (es08a-example servo ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries (hcsr04-example hcsr04 ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries (ssd1306-oled-example i2clcd ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries (ssd1308-oled-example i2clcd ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries (ssd1327-oled-example i2clcd ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries (max44000-example max44000 ${CMAKE_THREAD_LIBS_INIT})

View File

@ -0,0 +1,149 @@
/*
* Author Marc Graham <marc@m2ag.net>
* Copyright (c) 2015 Intel Corporation.
*
* Adapted from ssd1308 library.
* Author: Yevgeniy Kiveish <yevgeniy.kiveisha@intel.com>
* Copyright (c) 2014 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "ssd1306.h"
#define DEVICE_ADDRESS 0x3C
#define BUS_NUMBER 0x6
static uint8_t intel_logo[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 192, 192, 192, 224,
224, 224, 224, 240, 240, 248, 248, 120, 120, 120, 120, 60, 60, 60, 60, 60,
62, 30, 30, 30, 30, 30, 30, 30, 31, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 31, 31, 31, 31, 31,
30, 62, 62, 62, 62, 126, 126, 124, 124, 252, 252, 248, 248, 240, 240, 240,
224, 224, 224, 192, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128,
128, 0, 56, 56, 28, 30, 14, 15, 15, 7, 7, 7, 7, 3, 3, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, 192, 193, 195, 195,
195, 7, 15, 15, 63, 127, 255, 255, 255, 254, 252, 252, 240, 192, 0, 0, 0,
0, 0, 0, 0, 0, 128, 192, 192, 240, 248, 124, 124, 60, 0, 0, 0, 0, 159, 159,
159, 159, 159, 159, 159, 159, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0,
0, 0, 0, 0, 254, 254, 254, 254, 254, 254, 254, 254, 128, 128, 128, 128,
128, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 192, 192, 192, 192, 192, 192, 128,
128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255,
0, 0, 0, 0, 3, 7, 3, 3, 3, 0, 0, 0, 0, 0, 1, 1, 255, 255, 255, 255, 255,
255, 255, 0, 0, 224, 248, 252, 252, 255, 127, 15, 15, 3, 1, 0, 0, 0, 0, 0,
0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255,
255, 255, 255, 255, 255, 15, 15, 15, 15, 15, 15, 255, 255, 255, 255, 255,
255, 255, 252, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 15, 15,
15, 15, 15, 224, 224, 252, 254, 255, 255, 255, 255, 159, 159, 143, 143,
135, 135, 143, 159, 255, 255, 255, 255, 255, 255, 252, 248, 0, 0, 0, 255,
255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128,
224, 248, 248, 255, 255, 255, 255, 255, 127, 15, 255, 255, 255, 255, 255,
255, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255,
255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255,
255, 255, 255, 255, 255, 192, 192, 192, 192, 192, 31, 31, 255, 255, 255,
255, 255, 255, 231, 231, 199, 199, 199, 199, 199, 199, 199, 199, 231, 231,
231, 231, 199, 135, 0, 0, 0, 63, 255, 255, 255, 255, 255, 255, 255, 0, 0,
0, 0, 224, 240, 248, 248, 252, 254, 255, 255, 255, 127, 63, 63, 31, 15, 7,
7, 1, 0, 0, 63, 63, 255, 255, 255, 255, 255, 240, 192, 192, 128, 0, 0, 0,
0, 0, 0, 0, 0, 1, 3, 3, 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7,
0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 3, 3, 7, 7, 7,
7, 7, 7, 7, 7, 7, 0, 0, 0, 1, 3, 3, 3, 7, 7, 7, 7, 15, 15, 15, 15, 7, 7, 7,
7, 7, 3, 3, 3, 1, 0, 0, 0, 0, 1, 3, 3, 7, 135, 135, 135, 192, 192, 0, 0, 7,
7, 3, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 15, 15,
31, 127, 127, 127, 255, 255, 252, 252, 252, 248, 240, 240, 240, 224, 224,
224, 192, 192, 192, 192, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 192, 192, 192, 192, 192,
224, 224, 224, 224, 240, 240, 240, 240, 248, 248, 248, 248, 252, 252, 252,
254, 254, 255, 255, 255, 255, 255, 255, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
3, 3, 3, 7, 7, 7, 15, 15, 31, 31, 31, 63, 63, 63, 63, 63, 127, 127, 127,
127, 127, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254,
254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
255, 255, 255, 255, 255, 255, 255, 127, 127, 127, 127, 127, 127, 127, 127,
63, 63, 63, 63, 63, 31, 31, 31, 31, 31, 15, 15, 15, 15, 7, 7, 7, 7, 3, 3,
3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0
};
int
main(int argc, char **argv)
{
//! [Interesting]
upm::SSD1306 *lcd = new upm::SSD1306(BUS_NUMBER, DEVICE_ADDRESS);
lcd->clear();
lcd->stopscroll();
lcd->draw(intel_logo, 1024);
sleep(3);
lcd->clear();
lcd->setCursor(2, 0);
lcd->write("Hello");
lcd->setCursor(3,0);
lcd->write("World");
sleep(3);
lcd->invert(true);
sleep(3);
lcd->dim(true);
sleep(3);
lcd->dim(false);
sleep(3);
lcd->invert(false);
lcd->startscrollright(0x00, 0x0F);
sleep(5);
lcd->stopscroll();
lcd->startscrollleft(0x00, 0x0F);
sleep(5);
lcd->stopscroll();
lcd->startscrolldiagleft(0x00,0x0F);
sleep(5);
lcd->stopscroll();
lcd->startscrolldiagright(0x00,0x0F);
sleep(5);
lcd->stopscroll();
delete lcd;
//! [Interesting]
return 0;
}

View File

@ -0,0 +1,151 @@
/*
* Author: Marc Graham <marc@m2ag.net>
* Copyright (c) 2015 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
var intel_logo = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 192, 192, 192, 224,
224, 224, 224, 240, 240, 248, 248, 120, 120, 120, 120, 60, 60, 60, 60, 60,
62, 30, 30, 30, 30, 30, 30, 30, 31, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 31, 31, 31, 31, 31,
30, 62, 62, 62, 62, 126, 126, 124, 124, 252, 252, 248, 248, 240, 240, 240,
224, 224, 224, 192, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128,
128, 0, 56, 56, 28, 30, 14, 15, 15, 7, 7, 7, 7, 3, 3, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, 192, 193, 195, 195,
195, 7, 15, 15, 63, 127, 255, 255, 255, 254, 252, 252, 240, 192, 0, 0, 0,
0, 0, 0, 0, 0, 128, 192, 192, 240, 248, 124, 124, 60, 0, 0, 0, 0, 159, 159,
159, 159, 159, 159, 159, 159, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0,
0, 0, 0, 0, 254, 254, 254, 254, 254, 254, 254, 254, 128, 128, 128, 128,
128, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 192, 192, 192, 192, 192, 192, 128,
128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255,
0, 0, 0, 0, 3, 7, 3, 3, 3, 0, 0, 0, 0, 0, 1, 1, 255, 255, 255, 255, 255,
255, 255, 0, 0, 224, 248, 252, 252, 255, 127, 15, 15, 3, 1, 0, 0, 0, 0, 0,
0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255,
255, 255, 255, 255, 255, 15, 15, 15, 15, 15, 15, 255, 255, 255, 255, 255,
255, 255, 252, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 15, 15,
15, 15, 15, 224, 224, 252, 254, 255, 255, 255, 255, 159, 159, 143, 143,
135, 135, 143, 159, 255, 255, 255, 255, 255, 255, 252, 248, 0, 0, 0, 255,
255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128,
224, 248, 248, 255, 255, 255, 255, 255, 127, 15, 255, 255, 255, 255, 255,
255, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255,
255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255,
255, 255, 255, 255, 255, 192, 192, 192, 192, 192, 31, 31, 255, 255, 255,
255, 255, 255, 231, 231, 199, 199, 199, 199, 199, 199, 199, 199, 231, 231,
231, 231, 199, 135, 0, 0, 0, 63, 255, 255, 255, 255, 255, 255, 255, 0, 0,
0, 0, 224, 240, 248, 248, 252, 254, 255, 255, 255, 127, 63, 63, 31, 15, 7,
7, 1, 0, 0, 63, 63, 255, 255, 255, 255, 255, 240, 192, 192, 128, 0, 0, 0,
0, 0, 0, 0, 0, 1, 3, 3, 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7,
0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 3, 3, 7, 7, 7,
7, 7, 7, 7, 7, 7, 0, 0, 0, 1, 3, 3, 3, 7, 7, 7, 7, 15, 15, 15, 15, 7, 7, 7,
7, 7, 3, 3, 3, 1, 0, 0, 0, 0, 1, 3, 3, 7, 135, 135, 135, 192, 192, 0, 0, 7,
7, 3, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 15, 15,
31, 127, 127, 127, 255, 255, 252, 252, 252, 248, 240, 240, 240, 224, 224,
224, 192, 192, 192, 192, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 192, 192, 192, 192, 192,
224, 224, 224, 224, 240, 240, 240, 240, 248, 248, 248, 248, 252, 252, 252,
254, 254, 255, 255, 255, 255, 255, 255, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
3, 3, 3, 7, 7, 7, 15, 15, 31, 31, 31, 63, 63, 63, 63, 63, 127, 127, 127,
127, 127, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254,
254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
255, 255, 255, 255, 255, 255, 255, 127, 127, 127, 127, 127, 127, 127, 127,
63, 63, 63, 63, 63, 31, 31, 31, 31, 31, 15, 15, 15, 15, 7, 7, 7, 7, 3, 3,
3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0];
function exit()
{
lcd = null;
lcdObj.cleanUp();
lcdObj = null;
process.exit(0);
}
// Load i2clcd module
var lcdObj = require('jsupm_i2clcd');
var lcd = new lcdObj.SSD1306(6, 0x3c);
var next = 0;
lcd.clear();
lcd.setCursor(2, 0);
lcd.write("Hello");
lcd.setCursor(3, 0);
lcd.write("World!");
setInterval(function(){
loop();
},
3000 );
function loop(){
switch(next)
{
case 0:
lcd.invert(true)
break;
case 1:
lcd.dim(true);
break;
case 2:
lcd.invert(false);
break;
case 3:
lcd.startscrollright(0x00, 0x0F);
break;
case 4:
lcd.startscrollleft(0x00, 0x0F);
break;
case 5:
lcd.startscrolldiagleft(0x00, 0x0F)
break;
case 6:
lcd.startscrolldiagright(0x00, 0x0F)
break;
case 7:
var logo = new lcdObj.uint8Array(intel_logo.length);
for(var x = 0 ; x < intel_logo.length ; x++){
logo.setitem(x, intel_logo[x]);
}
lcd.stopscroll();
lcd.clear();
lcd.draw(logo, 1024);
break;
case 8:
default:
lcd.stopscroll();
lcd.clear();
lcd.setCursor(2, 0);
lcd.write("All");
lcd.setCursor(3, 0);
lcd.write("Done!");
exit();
}
next++;
}

4
src/lcd/CMakeLists.txt Normal file → Executable file
View File

@ -1,6 +1,6 @@
set (libname "i2clcd")
set (classname "lcd")
set (libdescription "upm lcd/oled displays")
set (module_src lcd.cxx lcm1602.cxx jhd1313m1.cxx ssd1308.cxx eboled.cxx ssd1327.cxx sainsmartks.cxx)
set (module_h lcd.h lcm1602.h jhd1313m1.h ssd1308.h eboled.h ssd1327.h ssd.h sainsmartks.h)
set (module_src lcd.cxx lcm1602.cxx jhd1313m1.cxx ssd1308.cxx eboled.cxx ssd1327.cxx sainsmartks.cxx ssd1306.cxx)
set (module_h lcd.h lcm1602.h jhd1313m1.h ssd1308.h eboled.h ssd1327.h ssd.h sainsmartks.h ssd1306.h)
upm_module_init()

View File

@ -27,6 +27,7 @@
#include "ssd.h"
#include "ssd1327.h"
#include "ssd1308.h"
#include "ssd1306.h"
#include "eboled.h"
#include "lcm1602.h"
#include "jhd1313m1.h"
@ -37,6 +38,7 @@
%include "ssd.h"
%include "ssd1327.h"
%include "ssd1308.h"
%include "ssd1306.h"
%include "eboled.h"
%include "lcm1602.h"
%include "jhd1313m1.h"

5
src/lcd/jsupm_i2clcd.i Normal file → Executable file
View File

@ -43,3 +43,8 @@
%{
#include "sainsmartks.h"
%}
%include "ssd1306.h"
%{
#include "ssd1306.h"
%}

5
src/lcd/pyupm_i2clcd.i Normal file → Executable file
View File

@ -46,3 +46,8 @@
%{
#include "sainsmartks.h"
%}
%include "ssd1306.h"
%{
#include "ssd1306.h"
%}

320
src/lcd/ssd1306.cxx Normal file
View File

@ -0,0 +1,320 @@
/*
* Author: Marc Graham <marc@m2ag.net>
* Copyright (c) 2015 Intel Corporation
*
* Adapted from ssd1308 library.
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
* Copyright (c) 2014 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string>
#include <unistd.h>
#include "hd44780_bits.h"
#include "ssd1306.h"
using namespace upm;
SSD1306::SSD1306(int bus_in, int addr_in) : m_i2c_lcd_control(bus_in)
{
int vccstate = SSD1306_SWITCHCAPVCC;
_vccstate = vccstate;
int LCD_CMD = 0x00;
m_lcd_control_address = addr_in;
m_name = "SSD1306";
mraa_result_t error = m_i2c_lcd_control.address(m_lcd_control_address);
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
if (error != mraa_SUCCESS) {
fprintf(stderr, "Failed to initialize i2c bus\n");
return;
}
m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_OFF); // display off
usleep(4500);
//ADD 1306 stuff
// Init sequence for 128x64 OLED module // 0xAE
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
m_i2c_lcd_control.writeReg(LCD_CMD, 0x80); // the suggested ratio 0x80
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETMULTIPLEX); // 0xA8
m_i2c_lcd_control.writeReg(LCD_CMD, 0x3F);
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETDISPLAYOFFSET); // 0xD3
m_i2c_lcd_control.writeReg(LCD_CMD, 0x0); // no offset
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETSTARTLINE | 0x0); // line #0
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_CHARGEPUMP); // 0x8D
if (vccstate == SSD1306_EXTERNALVCC) {
m_i2c_lcd_control.writeReg(LCD_CMD, 0x10);
} else {
m_i2c_lcd_control.writeReg(LCD_CMD,0x14);
}
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_MEMORYMODE); // 0x20
m_i2c_lcd_control.writeReg(LCD_CMD, 0x00); // 0x0 act like ks0108
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SEGREMAP | 0x1);
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_COMSCANDEC);
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETCOMPINS); // 0xDA
m_i2c_lcd_control.writeReg(LCD_CMD, 0x12);
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETCONTRAST); // 0x81
if (vccstate == SSD1306_EXTERNALVCC) {
m_i2c_lcd_control.writeReg(LCD_CMD, 0x9F);
} else {
m_i2c_lcd_control.writeReg(LCD_CMD, 0xCF);
}
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETPRECHARGE); // 0xd9
if (vccstate == SSD1306_EXTERNALVCC) {
m_i2c_lcd_control.writeReg(LCD_CMD, 0x22);
} else {
m_i2c_lcd_control.writeReg(LCD_CMD,0xF1);
}
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETVCOMDETECT); // 0xDB
m_i2c_lcd_control.writeReg(LCD_CMD, 0x40);
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_DISPLAYALLON_RESUME); // 0xA4
m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_SET_NORMAL_1306); // 0xA6
//END 1306 Stuff
m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_ON); // display on
usleep(4500);
setNormalDisplay(); // set to normal display '1' is ON
clear();
setAddressingMode(PAGE);
}
SSD1306::~SSD1306()
{
}
mraa_result_t
SSD1306::draw(uint8_t* data, int bytes)
{
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
mraa_result_t error = mraa_SUCCESS;
setAddressingMode(HORIZONTAL);
for (int idx = 0; idx < bytes; idx++) {
m_i2c_lcd_control.writeReg(LCD_DATA, data[idx]);
}
return error;
}
/*
* **************
* virtual area
* **************
*/
mraa_result_t
SSD1306::write(std::string msg)
{
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
mraa_result_t error = mraa_SUCCESS;
setAddressingMode(PAGE);
for (std::string::size_type i = 0; i < msg.size(); ++i) {
writeChar(msg[i]);
}
return error;
}
mraa_result_t
SSD1306::setCursor(int row, int column)
{
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
mraa_result_t error = mraa_SUCCESS;
error = m_i2c_lcd_control.writeReg(LCD_CMD, BASE_PAGE_START_ADDR + row); // set page address
error = m_i2c_lcd_control.writeReg(LCD_CMD,
BASE_LOW_COLUMN_ADDR + (8 * column & 0x0F)); // set column
// lower address
error = m_i2c_lcd_control.writeReg(LCD_CMD,
BASE_HIGH_COLUMN_ADDR +
((8 * column >> 4) & 0x0F)); // set column higher address
return error;
}
mraa_result_t
SSD1306::clear()
{
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
mraa_result_t error = mraa_SUCCESS;
uint8_t columnIdx, rowIdx;
m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_OFF); // display off
for (rowIdx = 0; rowIdx < 8; rowIdx++) {
setCursor(rowIdx, 0);
// clear all columns
for (columnIdx = 0; columnIdx < 16; columnIdx++) {
writeChar(' ');
}
}
m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_ON); // display on
home();
return error;
}
mraa_result_t
SSD1306::home()
{
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
return setCursor(0, 0);
}
/*
* **************
* private area
* **************
*/
mraa_result_t
SSD1306::writeChar(uint8_t value)
{
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
mraa_result_t rv;
if (value < 0x20 || value > 0x7F) {
value = 0x20; // space
}
for (uint8_t idx = 0; idx < 8; idx++) {
rv = m_i2c_lcd_control.writeReg(LCD_DATA, BasicFont[value - 32][idx]);
}
return rv;
}
mraa_result_t
SSD1306::setNormalDisplay()
{
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
return m_i2c_lcd_control.writeReg(LCD_CMD,
DISPLAY_CMD_SET_NORMAL_1306); // set to normal display '1' is
// ON
}
mraa_result_t
SSD1306::setAddressingMode(displayAddressingMode mode)
{
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
mraa_result_t rv;
rv =m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_MEM_ADDR_MODE); // set addressing mode
rv =m_i2c_lcd_control.writeReg(LCD_CMD, mode); // set page addressing mode
return rv;
}
mraa_result_t
SSD1306::invert(bool i)
{
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
mraa_result_t rv;
if(i){
rv = m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_SET_INVERT_1306);
} else {
rv = m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_SET_NORMAL_1306);
}
return rv;
}
void SSD1306::startscrollright(uint8_t start, uint8_t stop){
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
m_i2c_lcd_control.writeReg(LCD_CMD,SSD1306_RIGHT_HORIZONTAL_SCROLL);
m_i2c_lcd_control.writeReg(LCD_CMD,0X00);
m_i2c_lcd_control.writeReg(LCD_CMD,start);
m_i2c_lcd_control.writeReg(LCD_CMD,0X00);
m_i2c_lcd_control.writeReg(LCD_CMD,stop);
m_i2c_lcd_control.writeReg(LCD_CMD,0X00);
m_i2c_lcd_control.writeReg(LCD_CMD,0XFF);
m_i2c_lcd_control.writeReg(LCD_CMD,SSD1306_ACTIVATE_SCROLL);
}
void SSD1306::startscrollleft(uint8_t start, uint8_t stop){
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
m_i2c_lcd_control.writeReg(LCD_CMD,SSD1306_LEFT_HORIZONTAL_SCROLL);
m_i2c_lcd_control.writeReg(LCD_CMD,0X00);
m_i2c_lcd_control.writeReg(LCD_CMD,start);
m_i2c_lcd_control.writeReg(LCD_CMD,0X00);
m_i2c_lcd_control.writeReg(LCD_CMD,stop);
m_i2c_lcd_control.writeReg(LCD_CMD,0X00);
m_i2c_lcd_control.writeReg(LCD_CMD,0XFF);
m_i2c_lcd_control.writeReg(LCD_CMD,SSD1306_ACTIVATE_SCROLL);
}
void SSD1306::startscrolldiagright(uint8_t start, uint8_t stop){
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SET_VERTICAL_SCROLL_AREA);
m_i2c_lcd_control.writeReg(LCD_CMD, 0X00);
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_LCDHEIGHT);
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL);
m_i2c_lcd_control.writeReg(LCD_CMD, 0X00);
m_i2c_lcd_control.writeReg(LCD_CMD, start);
m_i2c_lcd_control.writeReg(LCD_CMD, 0X00);
m_i2c_lcd_control.writeReg(LCD_CMD, stop);
m_i2c_lcd_control.writeReg(LCD_CMD, 0X01);
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_ACTIVATE_SCROLL);
}
void SSD1306::startscrolldiagleft(uint8_t start, uint8_t stop){
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SET_VERTICAL_SCROLL_AREA);
m_i2c_lcd_control.writeReg(LCD_CMD, 0X00);
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_LCDHEIGHT);
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL);
m_i2c_lcd_control.writeReg(LCD_CMD, 0X00);
m_i2c_lcd_control.writeReg(LCD_CMD, start);
m_i2c_lcd_control.writeReg(LCD_CMD, 0X00);
m_i2c_lcd_control.writeReg(LCD_CMD, stop);
m_i2c_lcd_control.writeReg(LCD_CMD, 0X01);
m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_ACTIVATE_SCROLL);
}
void SSD1306::stopscroll(void){
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
m_i2c_lcd_control.writeReg(LCD_CMD,SSD1306_DEACTIVATE_SCROLL);
}
// Dim the display
// dim = true: display is dimmed
// dim = false: display is normal
void SSD1306::dim(bool dim) {
m_i2c_lcd_control.frequency(MRAA_I2C_FAST);
uint8_t contrast;
if (dim) {
contrast = 0; // Dimmed display
} else {
if (_vccstate == SSD1306_EXTERNALVCC) {
contrast = 0x9F;
} else {
contrast = 0xCF;
}
}
// the range of contrast to too small to be really useful
// it is useful to dim the display
m_i2c_lcd_control.writeReg(LCD_CMD,SSD1306_SETCONTRAST);
m_i2c_lcd_control.writeReg(LCD_CMD,contrast);
}

230
src/lcd/ssd1306.h Normal file
View File

@ -0,0 +1,230 @@
/*
* Author: Marc Graham <marc@m2ag.net>
* Copyright (c) 2015 Intel Corporation
*
* Adapted from ssd1308 library.
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
* Copyright (c) 2014 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <string>
#include <mraa/i2c.hpp>
#include "lcd.h"
#include "ssd.h"
namespace upm
{
const uint8_t DISPLAY_CMD_SET_NORMAL_1306 = 0xA6;
const uint8_t SSD1306_SETCONTRAST = 0x81;
const uint8_t SSD1306_DISPLAYALLON_RESUME =0xA4;
const uint8_t SSD1306_DISPLAYALLON = 0xA5;
const uint8_t DISPLAY_CMD_SET_INVERT_1306 = 0xA7;
const uint8_t SSD1306_SETDISPLAYOFFSET =0xD3;
const uint8_t SSD1306_SETCOMPINS = 0xDA;
const uint8_t SSD1306_SETVCOMDETECT = 0xDB;
const uint8_t SSD1306_SETDISPLAYCLOCKDIV = 0xD5;
const uint8_t SSD1306_SETPRECHARGE = 0xD9;
const uint8_t SSD1306_SETMULTIPLEX = 0xA8;
const uint8_t SSD1306_SETLOWCOLUM = 0x00;
const uint8_t SSD1306_SETHIGHCOLUMN = 0x10;
const uint8_t SSD1306_SETSTARTLINE = 0x40;
const uint8_t SSD1306_MEMORYMODE = 0x20;
const uint8_t SSD1306_COLUMNADDR = 0x21;
const uint8_t SSD1306_PAGEADDR = 0x22;
const uint8_t SSD1306_COMSCANINC = 0xC0;
const uint8_t SSD1306_COMSCANDEC = 0xC8;
const uint8_t SSD1306_SEGREMAP = 0xA0;
const uint8_t SSD1306_CHARGEPUMP = 0x8D;
const uint8_t SSD1306_EXTERNALVCC = 0x1;
const uint8_t SSD1306_SWITCHCAPVCC = 0x2;
// Scrolling const uint8_t s
const uint8_t SSD1306_ACTIVATE_SCROLL = 0x2F;
const uint8_t SSD1306_DEACTIVATE_SCROLL = 0x2E;
const uint8_t SSD1306_SET_VERTICAL_SCROLL_AREA = 0xA3;
const uint8_t SSD1306_RIGHT_HORIZONTAL_SCROLL = 0x26;
const uint8_t SSD1306_LEFT_HORIZONTAL_SCROLL = 0x27;
const uint8_t SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL = 0x29;
const uint8_t SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL = 0x2A;
const uint8_t SSD1306_BLACK = 0;
const uint8_t SSD1306_WHITE = 1;
const uint8_t SSD1306_LCDWIDTH = 128;
const uint8_t SSD1306_LCDHEIGHT = 64;
/**
* @library i2clcd
* @sensor ssd1306
* @comname SSD1306 OLED Display
* @altname Adafruit SSD1306 OLED Display 0.96"
* @type display
* @man adafruit
* @web https://www.adafruit.com/datasheets/SSD1306.pdf
* @web http://www.farnell.com/datasheets/609753.pdf
* @con i2c
*
* @brief API for SSD1306 I2C-controlled OLED displays
*
* SSD1306 is a 128x64 dot-matrix OLED/PLED segment driver with a
* controller. This device is available from many suppliers for a
* very low cost. This implementation was tested using a generic
* SSD1306 device from eBay.
*
* @image html ssd1306.jpeg
* @snippet ssd1306-oled.cxx Interesting
*/
class SSD1306 : public LCD
{
public:
/**
* SSD1306 constructor; calls libmraa initialisation functions
*
* @param bus I2C bus to use
* @param address Slave address the LCD is registered on
*/
SSD1306(int bus, int address = 0x3C);
/**
* SSD1306 destructor
*/
~SSD1306();
/**
* Draws an image; see examples/python/make_oled_pic.py for an
* explanation of how pixels are mapped to bytes
*
* @param data Buffer to read
* @param bytes Number of bytes to read from the pointer
* @return Result of the operation
*/
mraa_result_t draw(uint8_t* data, int bytes);
/**
* Writes a string to the LCD
*
* @param msg std::string to write to the display; note: only ASCII
* characters are supported
* @return Result of the operation
*/
mraa_result_t write(std::string msg);
/**
* Sets the cursor to specified coordinates
*
* @param row Row to set the cursor to
* @param column Column to set the cursor to
* @return Result of the operation
*/
mraa_result_t setCursor(int row, int column);
/**
* Clears the display of all characters
*
* @return Result of the operation
*/
mraa_result_t clear();
/**
* Returns to the original coordinates (0,0)
*
* @return Result of the operation
*/
mraa_result_t home();
/**
* Inverts the display
*
* @param i true to invert, false for normal display
* @return Result of the operation
*/
mraa_result_t invert(bool i);
/**
* Activate a scroll to the right for rows start through stop
* The display is 16 rows tall. To scroll the whole display, run:
* display.scrollright(0x00, 0x0F)
*
* @param start First row to scroll
* @param stop Last row to scroll
* @return void
*/
void startscrollright(uint8_t start, uint8_t stop);
/**
* Activate a scroll to the left for rows start through stop
* The display is 16 rows tall. To scroll the whole display, run:
* display.startscrollright(0x00, 0x0F)
*
* @param start First row to scroll
* @param stop Last row to scroll
* @return void
*/
void startscrollleft(uint8_t start, uint8_t stop);
/**
* Activate a scroll to the upper right for rows start through stop
* The display is 16 rows tall. To scroll the whole display, run:
* display.startscrollleft(0x00, 0x0F)
*
* @param start First row to scroll
* @param stop Last row to scroll
* @return void
*/
void startscrolldiagright(uint8_t start, uint8_t stop);
/**
* Activate a scroll to the upper left for rows start through stop
* The display is 16 rows tall. To scroll the whole display, run:
* display.startscrolldiaagright(0x00, 0x0F)
*
* @param start First row to scroll
* @param stop Last row to scroll
* @return void
*/
void startscrolldiagleft(uint8_t start, uint8_t stop);
/**
* Stops display scrolling.
*
* @return void
*/
void stopscroll(void);
/**
* Dims display
*
* @param dim True to dim display, false for max intensity
* @return Result of last operation
*/
void dim(bool dim);
private:
mraa_result_t writeChar(uint8_t value);
mraa_result_t setNormalDisplay();
mraa_result_t setAddressingMode(displayAddressingMode mode);
int m_lcd_control_address;
mraa::I2c m_i2c_lcd_control;
int _vccstate;
};
}