A buffered display driver for the SSD1306 OLED controller. Please note that this is a work-in-progress; only very rudimentary drawing support is provided.

Dependents:   Projetv0 greenhouse_proj ProjetLong_Serre_V3 ProjetLong_Serre_V3_1 ... more

Example of use:

#include "mbed.h"

#include "ssd1306.h"
#include "standard_font.h"
#include "bold_font.h"

SSD1306 oled(p8 /* cs */, p9 /* reset */, p14 /* dc */,
             p13 /* clock */, p11 /* data */);

int main()
{
    oled.initialise();
    oled.clear();
    oled.set_contrast(255); // max contrast

    oled.set_font(bold_font, 8);
    oled.printf("Heading\r\n");

    oled.set_font(standard_font, 6);
    oled.printf("Hello World!\r\n");
    oled.printf("Some more text here...");

    oled.update();

    while (1)
    {
        wait(2);
        oled.scroll_up();
        oled.update();
    }
}
Committer:
Byrn
Date:
Tue Feb 05 17:18:23 2013 +0000
Revision:
1:1d58d378221c
Parent:
0:21cb91208386
Child:
2:e479b0296757
intiial commit;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Byrn 0:21cb91208386 1
Byrn 0:21cb91208386 2 #include "mbed.h"
Byrn 0:21cb91208386 3 #include "ssd1306.h"
Byrn 0:21cb91208386 4
Byrn 0:21cb91208386 5 SSD1306::SSD1306(PinName cs, PinName rs, PinName dc, PinName clk, PinName data)
Byrn 1:1d58d378221c 6 : _spi(data, NC, clk),
Byrn 1:1d58d378221c 7 _cs(cs),
Byrn 1:1d58d378221c 8 _reset(rs),
Byrn 1:1d58d378221c 9 _dc(dc)
Byrn 0:21cb91208386 10 {
Byrn 0:21cb91208386 11 }
Byrn 0:21cb91208386 12
Byrn 0:21cb91208386 13 void SSD1306::set_low_column(int v)
Byrn 0:21cb91208386 14 {
Byrn 0:21cb91208386 15 _send_command(SSD1306_SETLOWCOLUMN | v);
Byrn 0:21cb91208386 16 }
Byrn 0:21cb91208386 17
Byrn 0:21cb91208386 18 void SSD1306::set_high_column(int v)
Byrn 0:21cb91208386 19 {
Byrn 0:21cb91208386 20 _send_command(SSD1306_SETHIGHCOLUMN | v);
Byrn 0:21cb91208386 21 }
Byrn 0:21cb91208386 22
Byrn 0:21cb91208386 23 void SSD1306::set_start_line(int v)
Byrn 0:21cb91208386 24 {
Byrn 0:21cb91208386 25 _send_command(SSD1306_SETSTARTLINE | v);
Byrn 0:21cb91208386 26 }
Byrn 0:21cb91208386 27
Byrn 0:21cb91208386 28 void SSD1306::off()
Byrn 0:21cb91208386 29 {
Byrn 0:21cb91208386 30 _send_command(SSD1306_DISPLAYOFF);
Byrn 0:21cb91208386 31 }
Byrn 0:21cb91208386 32
Byrn 0:21cb91208386 33 void SSD1306::on()
Byrn 0:21cb91208386 34 {
Byrn 0:21cb91208386 35 _send_command(SSD1306_DISPLAYON);
Byrn 0:21cb91208386 36 }
Byrn 0:21cb91208386 37
Byrn 1:1d58d378221c 38 void SSD1306::sleep()
Byrn 1:1d58d378221c 39 {
Byrn 1:1d58d378221c 40 _send_command(0xAE);
Byrn 1:1d58d378221c 41 }
Byrn 1:1d58d378221c 42
Byrn 1:1d58d378221c 43 void SSD1306::wake()
Byrn 0:21cb91208386 44 {
Byrn 1:1d58d378221c 45 _send_command(0xAF);
Byrn 1:1d58d378221c 46 }
Byrn 1:1d58d378221c 47
Byrn 1:1d58d378221c 48 void SSD1306::set_inverse(unsigned char value)
Byrn 1:1d58d378221c 49 {
Byrn 1:1d58d378221c 50 _send_command(value ? 0xA7 : 0xA6);
Byrn 1:1d58d378221c 51 }
Byrn 1:1d58d378221c 52
Byrn 1:1d58d378221c 53 void SSD1306::set_display_offset(unsigned char value)
Byrn 1:1d58d378221c 54 {
Byrn 1:1d58d378221c 55 _send_command(0xD3);
Byrn 1:1d58d378221c 56 _send_command(value);
Byrn 0:21cb91208386 57 }
Byrn 0:21cb91208386 58
Byrn 1:1d58d378221c 59 void SSD1306::set_contrast(unsigned char value)
Byrn 1:1d58d378221c 60 {
Byrn 1:1d58d378221c 61 _send_command(0x81);
Byrn 1:1d58d378221c 62 _send_command(value);
Byrn 1:1d58d378221c 63 }
Byrn 1:1d58d378221c 64
Byrn 1:1d58d378221c 65 void SSD1306::set_display_start_line(unsigned char value)
Byrn 1:1d58d378221c 66 {
Byrn 1:1d58d378221c 67 _send_command(0x40 | value);
Byrn 1:1d58d378221c 68 }
Byrn 1:1d58d378221c 69
Byrn 1:1d58d378221c 70 void SSD1306::set_horizontal_flip(unsigned char value)
Byrn 0:21cb91208386 71 {
Byrn 1:1d58d378221c 72 _send_command(value ? 0xA1 : 0xA0);
Byrn 1:1d58d378221c 73 }
Byrn 1:1d58d378221c 74
Byrn 1:1d58d378221c 75 void SSD1306::set_multiplex_ratio(unsigned char value)
Byrn 1:1d58d378221c 76 {
Byrn 1:1d58d378221c 77 _send_command(0xA8 | value);
Byrn 1:1d58d378221c 78 }
Byrn 1:1d58d378221c 79
Byrn 1:1d58d378221c 80 void SSD1306::set_com_output_scan_direction(unsigned char value)
Byrn 1:1d58d378221c 81 {
Byrn 1:1d58d378221c 82 _send_command(value ? 0xC8 : 0xC0);
Byrn 1:1d58d378221c 83 }
Byrn 1:1d58d378221c 84
Byrn 1:1d58d378221c 85 void SSD1306::set_com_pins_hardware_configuration(unsigned char sequential, unsigned char lr_remap)
Byrn 1:1d58d378221c 86 {
Byrn 1:1d58d378221c 87 _send_command(0xDA);
Byrn 1:1d58d378221c 88 _send_command(0x02 | ((sequential & 1) << 5) | ((lr_remap & 1) << 6));
Byrn 0:21cb91208386 89 }
Byrn 0:21cb91208386 90
Byrn 0:21cb91208386 91 void SSD1306::initialise()
Byrn 0:21cb91208386 92 {
Byrn 1:1d58d378221c 93 // Init
Byrn 0:21cb91208386 94 _reset = 1;
Byrn 0:21cb91208386 95 wait(0.01);
Byrn 0:21cb91208386 96 _reset = 0;
Byrn 0:21cb91208386 97 wait(0.10);
Byrn 0:21cb91208386 98 _reset = 1;
Byrn 0:21cb91208386 99
Byrn 0:21cb91208386 100 off();
Byrn 0:21cb91208386 101
Byrn 0:21cb91208386 102 set_low_column(0);
Byrn 0:21cb91208386 103 set_high_column(0);
Byrn 0:21cb91208386 104 set_start_line(0);
Byrn 0:21cb91208386 105
Byrn 1:1d58d378221c 106 _send_command(0xAE); // turn off
Byrn 1:1d58d378221c 107 _send_command(0x00); // set low column address
Byrn 1:1d58d378221c 108 _send_command(0x10); // set high column address
Byrn 1:1d58d378221c 109 _send_command(0x40); // set start line address
Byrn 1:1d58d378221c 110
Byrn 1:1d58d378221c 111 set_contrast(0xFF);
Byrn 1:1d58d378221c 112
Byrn 1:1d58d378221c 113 _send_command(0xA1); // set segment re-map 95 to 0
Byrn 1:1d58d378221c 114 _send_command(0xA6); // set normal display
Byrn 1:1d58d378221c 115 _send_command(0xA8); // set multiplex ratio (1-64);
Byrn 1:1d58d378221c 116 _send_command(0x3F); // 1/64 duty
Byrn 1:1d58d378221c 117 _send_command(0xD3); // set display offset
Byrn 1:1d58d378221c 118 _send_command(0x00); // -- no offset
Byrn 1:1d58d378221c 119 _send_command(0xD5); // set display clock divide ratio/oscillator frequency
Byrn 1:1d58d378221c 120 _send_command(0x80); // -- set divide ratio
Byrn 1:1d58d378221c 121 _send_command(0xD9); // set precharge period;
Byrn 1:1d58d378221c 122 _send_command(0xF1);
Byrn 1:1d58d378221c 123 _send_command(0xDA); // set com pins hardware config
Byrn 1:1d58d378221c 124 _send_command(0x12);
Byrn 1:1d58d378221c 125 _send_command(0xDB); // set vcomh
Byrn 1:1d58d378221c 126 _send_command(0x40);
Byrn 1:1d58d378221c 127 _send_command(0x8D); // set charge pump enable/disable
Byrn 1:1d58d378221c 128 _send_command(0x14); // enable (0x10 disable)
Byrn 1:1d58d378221c 129 _send_command(0xAF); // switch panel on
Byrn 1:1d58d378221c 130
Byrn 1:1d58d378221c 131 set_inverse(1);
Byrn 1:1d58d378221c 132
Byrn 1:1d58d378221c 133 /*
Byrn 0:21cb91208386 134 _send_command(SSD1306_SETCONTRAST);
Byrn 0:21cb91208386 135 _send_command(0xCF); // chargepump, could be 0x9F for external 9V
Byrn 0:21cb91208386 136
Byrn 0:21cb91208386 137 _send_command(0xA1); // setment remap 95 to 0 (??)
Byrn 0:21cb91208386 138
Byrn 0:21cb91208386 139 invert(0);
Byrn 0:21cb91208386 140
Byrn 0:21cb91208386 141 _send_command(SSD1306_DISPLAYALLON_RESUME);
Byrn 0:21cb91208386 142 _send_command(SSD1306_SETMULTIPLEX);
Byrn 0:21cb91208386 143 _send_command(0x3F); // 1/64 duty
Byrn 0:21cb91208386 144
Byrn 0:21cb91208386 145 set_display_offset(0);
Byrn 0:21cb91208386 146
Byrn 0:21cb91208386 147 _send_command(SSD1306_SETDISPLAYCLOCKDIV);
Byrn 0:21cb91208386 148 _send_command(0x80); // suggested value = 0x80
Byrn 0:21cb91208386 149 _send_command(SSD1306_SETPRECHARGE);
Byrn 0:21cb91208386 150 _send_command(0xF1); // dc/dc, could be 0x22 for external 9V
Byrn 0:21cb91208386 151 _send_command(SSD1306_SETCOMPINS);
Byrn 0:21cb91208386 152 _send_command(0x12); // disable COM left/right remap
Byrn 0:21cb91208386 153 _send_command(SSD1306_SETVCOMDETECT);
Byrn 0:21cb91208386 154 _send_command(0x40); // apparently, 0x20 is default...
Byrn 0:21cb91208386 155 _send_command(SSD1306_MEMORYMODE);
Byrn 0:21cb91208386 156 _send_command(0x0); // act like KS0108
Byrn 0:21cb91208386 157
Byrn 0:21cb91208386 158 // left-to-right scan
Byrn 0:21cb91208386 159 _send_command(SSD1306_SEGREMAP | 0x1);
Byrn 0:21cb91208386 160 _send_command(SSD1306_COMSCANDEC);
Byrn 0:21cb91208386 161 _send_command(SSD1306_CHARGEPUMP);
Byrn 0:21cb91208386 162 _send_command(0x14); // disable, for external 9v 0x10 disable
Byrn 1:1d58d378221c 163 */
Byrn 0:21cb91208386 164 // turn it on
Byrn 1:1d58d378221c 165 // on();
Byrn 0:21cb91208386 166 }
Byrn 0:21cb91208386 167
Byrn 0:21cb91208386 168 void SSD1306::update()
Byrn 0:21cb91208386 169 {
Byrn 0:21cb91208386 170 set_low_column(0);
Byrn 0:21cb91208386 171 set_high_column(0);
Byrn 0:21cb91208386 172 set_start_line(0);
Byrn 0:21cb91208386 173
Byrn 0:21cb91208386 174 for (int i = 0; i < 1024; i++)
Byrn 0:21cb91208386 175 _send_data(_screen[i]);
Byrn 0:21cb91208386 176 }
Byrn 0:21cb91208386 177
Byrn 0:21cb91208386 178 void SSD1306::set_pixel(int x, int y)
Byrn 0:21cb91208386 179 {
Byrn 0:21cb91208386 180 if (x >= SSD1306_LCDWIDTH || y >= SSD1306_LCDHEIGHT) return;
Byrn 0:21cb91208386 181
Byrn 0:21cb91208386 182 _screen[x + (y / 8) * 128] |= 1 << (y % 8);
Byrn 0:21cb91208386 183 }
Byrn 0:21cb91208386 184
Byrn 0:21cb91208386 185 void SSD1306::clear_pixel(int x, int y)
Byrn 0:21cb91208386 186 {
Byrn 0:21cb91208386 187 if (x >= SSD1306_LCDWIDTH || y >= SSD1306_LCDHEIGHT) return;
Byrn 0:21cb91208386 188
Byrn 0:21cb91208386 189 _screen[x + (y / 8) * 128] &= ~(1 << (y % 8));
Byrn 0:21cb91208386 190 }
Byrn 0:21cb91208386 191
Byrn 0:21cb91208386 192 void SSD1306::line(int x0, int y0, int x1, int y1) {
Byrn 0:21cb91208386 193 int steep = abs(y1 - y0) > abs(x1 - x0);
Byrn 0:21cb91208386 194 int t;
Byrn 0:21cb91208386 195
Byrn 0:21cb91208386 196 if (steep) {
Byrn 0:21cb91208386 197 t = x0; x0 = y0; y0 = t;
Byrn 0:21cb91208386 198 t = x1; x1 = y1; y1 = t;
Byrn 0:21cb91208386 199 }
Byrn 0:21cb91208386 200
Byrn 0:21cb91208386 201 if (x0 > x1) {
Byrn 0:21cb91208386 202 t = x0; x0 = x1; x1 = t;
Byrn 0:21cb91208386 203 t = y0; y0 = y1; y1 = t;
Byrn 0:21cb91208386 204 }
Byrn 0:21cb91208386 205
Byrn 0:21cb91208386 206 int dx, dy;
Byrn 0:21cb91208386 207
Byrn 0:21cb91208386 208 dx = x1 - x0;
Byrn 0:21cb91208386 209 dy = abs(y1 - y0);
Byrn 0:21cb91208386 210
Byrn 0:21cb91208386 211 int err = dx / 2;
Byrn 0:21cb91208386 212 int ystep;
Byrn 0:21cb91208386 213
Byrn 0:21cb91208386 214 if (y0 < y1) {
Byrn 0:21cb91208386 215 ystep = 1;
Byrn 0:21cb91208386 216 } else {
Byrn 0:21cb91208386 217 ystep = -1;}
Byrn 0:21cb91208386 218
Byrn 0:21cb91208386 219 for (; x0<x1; x0++) {
Byrn 0:21cb91208386 220 if (steep) {
Byrn 0:21cb91208386 221 set_pixel(y0, x0);
Byrn 0:21cb91208386 222 } else {
Byrn 0:21cb91208386 223 set_pixel(x0, y0);
Byrn 0:21cb91208386 224 }
Byrn 0:21cb91208386 225 err -= dy;
Byrn 0:21cb91208386 226 if (err < 0) {
Byrn 0:21cb91208386 227 y0 += ystep;
Byrn 0:21cb91208386 228 err += dx;
Byrn 0:21cb91208386 229 }
Byrn 0:21cb91208386 230 }
Byrn 0:21cb91208386 231 }
Byrn 0:21cb91208386 232
Byrn 0:21cb91208386 233 void SSD1306::draw_string(char *font, int x, int y, const char *string)
Byrn 0:21cb91208386 234 {
Byrn 0:21cb91208386 235 _cursor_x = x;
Byrn 0:21cb91208386 236 _cursor_y = y;
Byrn 0:21cb91208386 237
Byrn 0:21cb91208386 238 for (int i = 0; i < strlen(string); i++)
Byrn 0:21cb91208386 239 draw_char(font, _cursor_x, _cursor_y, string[i]);
Byrn 0:21cb91208386 240 }
Byrn 0:21cb91208386 241
Byrn 0:21cb91208386 242 void SSD1306::draw_char(char *font, int x, int y, char c)
Byrn 0:21cb91208386 243 {
Byrn 0:21cb91208386 244 int height = font[FONT_HEIGHT_OFFSET];
Byrn 0:21cb91208386 245 int max_width = font[FONT_SIZE_OFFSET];
Byrn 0:21cb91208386 246 int char_size_bytes = max_width * height + 1;
Byrn 0:21cb91208386 247 int char_width = font[(c - FONT_START) * char_size_bytes + FONT_DATA_OFFSET];
Byrn 0:21cb91208386 248 for (int i = 0; i < char_width; i++)
Byrn 0:21cb91208386 249 _screen[(x + i) + (y * SSD1306_LCDWIDTH)] = font[(c - FONT_START) * (char_size_bytes) + i + FONT_DATA_OFFSET + 1];
Byrn 0:21cb91208386 250
Byrn 0:21cb91208386 251 _cursor_x = x + char_width;
Byrn 0:21cb91208386 252 _cursor_y = y;
Byrn 0:21cb91208386 253 }
Byrn 0:21cb91208386 254
Byrn 0:21cb91208386 255 void SSD1306::clear()
Byrn 0:21cb91208386 256 {
Byrn 0:21cb91208386 257 for (int i = 0; i < 1024; i++)
Byrn 0:21cb91208386 258 _screen[i] = 0;
Byrn 0:21cb91208386 259 }
Byrn 0:21cb91208386 260
Byrn 1:1d58d378221c 261 void SSD1306::_send_command(unsigned char code)
Byrn 0:21cb91208386 262 {
Byrn 0:21cb91208386 263 _cs = 1;
Byrn 0:21cb91208386 264 _dc = 0;
Byrn 0:21cb91208386 265 _cs = 0;
Byrn 0:21cb91208386 266 _spi.write(code);
Byrn 0:21cb91208386 267 _cs = 1;
Byrn 0:21cb91208386 268 }
Byrn 0:21cb91208386 269
Byrn 1:1d58d378221c 270 void SSD1306::_send_data(unsigned char value)
Byrn 0:21cb91208386 271 {
Byrn 0:21cb91208386 272 _cs = 1;
Byrn 0:21cb91208386 273 _dc = 1;
Byrn 0:21cb91208386 274 _cs = 0;
Byrn 0:21cb91208386 275 _spi.write(value);
Byrn 0:21cb91208386 276 _cs = 1;
Byrn 0:21cb91208386 277 }
Byrn 0:21cb91208386 278