derived from Aidafruit SSD1306 library

Dependents:   Test_SSD1306 L152RE_OLED_SSD1306 EcranZumo

Fork of SSD1306 by Jonathan Gaul

Committer:
Byrn
Date:
Tue Feb 05 21:21:22 2013 +0000
Revision:
2:e479b0296757
Parent:
1:1d58d378221c
Child:
3:1d9df877c90a
commit before initial publish

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::off()
Byrn 0:21cb91208386 14 {
Byrn 2:e479b0296757 15 _send_command(0xAE);
Byrn 0:21cb91208386 16 }
Byrn 0:21cb91208386 17
Byrn 0:21cb91208386 18 void SSD1306::on()
Byrn 0:21cb91208386 19 {
Byrn 2:e479b0296757 20 _send_command(0xAF);
Byrn 0:21cb91208386 21 }
Byrn 0:21cb91208386 22
Byrn 1:1d58d378221c 23 void SSD1306::sleep()
Byrn 1:1d58d378221c 24 {
Byrn 1:1d58d378221c 25 _send_command(0xAE);
Byrn 1:1d58d378221c 26 }
Byrn 1:1d58d378221c 27
Byrn 1:1d58d378221c 28 void SSD1306::wake()
Byrn 0:21cb91208386 29 {
Byrn 1:1d58d378221c 30 _send_command(0xAF);
Byrn 1:1d58d378221c 31 }
Byrn 1:1d58d378221c 32
Byrn 1:1d58d378221c 33 void SSD1306::set_inverse(unsigned char value)
Byrn 1:1d58d378221c 34 {
Byrn 1:1d58d378221c 35 _send_command(value ? 0xA7 : 0xA6);
Byrn 1:1d58d378221c 36 }
Byrn 1:1d58d378221c 37
Byrn 1:1d58d378221c 38 void SSD1306::set_display_offset(unsigned char value)
Byrn 1:1d58d378221c 39 {
Byrn 1:1d58d378221c 40 _send_command(0xD3);
Byrn 2:e479b0296757 41 _send_command(value & 0x3F);
Byrn 0:21cb91208386 42 }
Byrn 0:21cb91208386 43
Byrn 1:1d58d378221c 44 void SSD1306::set_contrast(unsigned char value)
Byrn 1:1d58d378221c 45 {
Byrn 1:1d58d378221c 46 _send_command(0x81);
Byrn 1:1d58d378221c 47 _send_command(value);
Byrn 1:1d58d378221c 48 }
Byrn 1:1d58d378221c 49
Byrn 1:1d58d378221c 50 void SSD1306::set_display_start_line(unsigned char value)
Byrn 1:1d58d378221c 51 {
Byrn 1:1d58d378221c 52 _send_command(0x40 | value);
Byrn 1:1d58d378221c 53 }
Byrn 1:1d58d378221c 54
Byrn 2:e479b0296757 55 void SSD1306::set_segment_remap(unsigned char value)
Byrn 0:21cb91208386 56 {
Byrn 1:1d58d378221c 57 _send_command(value ? 0xA1 : 0xA0);
Byrn 1:1d58d378221c 58 }
Byrn 1:1d58d378221c 59
Byrn 1:1d58d378221c 60 void SSD1306::set_multiplex_ratio(unsigned char value)
Byrn 1:1d58d378221c 61 {
Byrn 2:e479b0296757 62 _send_command(0xA8);
Byrn 2:e479b0296757 63 _send_command(value & 0x3F);
Byrn 1:1d58d378221c 64 }
Byrn 1:1d58d378221c 65
Byrn 1:1d58d378221c 66 void SSD1306::set_com_output_scan_direction(unsigned char value)
Byrn 1:1d58d378221c 67 {
Byrn 1:1d58d378221c 68 _send_command(value ? 0xC8 : 0xC0);
Byrn 1:1d58d378221c 69 }
Byrn 1:1d58d378221c 70
Byrn 1:1d58d378221c 71 void SSD1306::set_com_pins_hardware_configuration(unsigned char sequential, unsigned char lr_remap)
Byrn 1:1d58d378221c 72 {
Byrn 1:1d58d378221c 73 _send_command(0xDA);
Byrn 2:e479b0296757 74 _send_command(0x02 | ((sequential & 1) << 4) | ((lr_remap & 1) << 5));
Byrn 2:e479b0296757 75 }
Byrn 2:e479b0296757 76
Byrn 2:e479b0296757 77 void SSD1306::start_horizontal_scroll(unsigned char direction, unsigned char start, unsigned char end, unsigned char interval)
Byrn 2:e479b0296757 78 {
Byrn 2:e479b0296757 79 _send_command(direction ? 0x27 : 0x26);
Byrn 2:e479b0296757 80 _send_command(0x00);
Byrn 2:e479b0296757 81 _send_command(start & 0x07);
Byrn 2:e479b0296757 82 switch (interval) {
Byrn 2:e479b0296757 83 case 2: _send_command(0x07); break; // 111b
Byrn 2:e479b0296757 84 case 3: _send_command(0x04); break; // 100b
Byrn 2:e479b0296757 85 case 4: _send_command(0x05); break; // 101b
Byrn 2:e479b0296757 86 case 5: _send_command(0x00); break; // 000b
Byrn 2:e479b0296757 87 case 25: _send_command(0x06); break; // 110b
Byrn 2:e479b0296757 88 case 64: _send_command(0x01); break; // 001b
Byrn 2:e479b0296757 89 case 128: _send_command(0x02); break; // 010b
Byrn 2:e479b0296757 90 case 256: _send_command(0x03); break; // 011b
Byrn 2:e479b0296757 91 default:
Byrn 2:e479b0296757 92 // default to 2 frame interval
Byrn 2:e479b0296757 93 _send_command(0x07); break;
Byrn 2:e479b0296757 94 }
Byrn 2:e479b0296757 95 _send_command(end & 0x07);
Byrn 2:e479b0296757 96 _send_command(0x00);
Byrn 2:e479b0296757 97 _send_command(0xFF);
Byrn 2:e479b0296757 98
Byrn 2:e479b0296757 99 // activate scroll
Byrn 2:e479b0296757 100 _send_command(0x2F);
Byrn 2:e479b0296757 101 }
Byrn 2:e479b0296757 102
Byrn 2:e479b0296757 103 void SSD1306::start_vertical_and_horizontal_scroll(unsigned char direction, unsigned char start, unsigned char end, unsigned char interval, unsigned char vertical_offset)
Byrn 2:e479b0296757 104 {
Byrn 2:e479b0296757 105 _send_command(direction ? 0x2A : 0x29);
Byrn 2:e479b0296757 106 _send_command(0x00);
Byrn 2:e479b0296757 107 _send_command(start & 0x07);
Byrn 2:e479b0296757 108 switch (interval) {
Byrn 2:e479b0296757 109 case 2: _send_command(0x07); break; // 111b
Byrn 2:e479b0296757 110 case 3: _send_command(0x04); break; // 100b
Byrn 2:e479b0296757 111 case 4: _send_command(0x05); break; // 101b
Byrn 2:e479b0296757 112 case 5: _send_command(0x00); break; // 000b
Byrn 2:e479b0296757 113 case 25: _send_command(0x06); break; // 110b
Byrn 2:e479b0296757 114 case 64: _send_command(0x01); break; // 001b
Byrn 2:e479b0296757 115 case 128: _send_command(0x02); break; // 010b
Byrn 2:e479b0296757 116 case 256: _send_command(0x03); break; // 011b
Byrn 2:e479b0296757 117 default:
Byrn 2:e479b0296757 118 // default to 2 frame interval
Byrn 2:e479b0296757 119 _send_command(0x07); break;
Byrn 2:e479b0296757 120 }
Byrn 2:e479b0296757 121 _send_command(end & 0x07);
Byrn 2:e479b0296757 122 _send_command(vertical_offset);
Byrn 2:e479b0296757 123
Byrn 2:e479b0296757 124 // activate scroll
Byrn 2:e479b0296757 125 _send_command(0x2F);
Byrn 2:e479b0296757 126 }
Byrn 2:e479b0296757 127
Byrn 2:e479b0296757 128 void SSD1306::stop_scroll()
Byrn 2:e479b0296757 129 {
Byrn 2:e479b0296757 130 // all scroll configurations are removed from the display when executing this command.
Byrn 2:e479b0296757 131 _send_command(0x2E);
Byrn 2:e479b0296757 132 }
Byrn 2:e479b0296757 133
Byrn 2:e479b0296757 134 void SSD1306::pam_set_start_address(unsigned char address)
Byrn 2:e479b0296757 135 {
Byrn 2:e479b0296757 136 // "Set Lower Column Start Address for Page Addressing Mode"
Byrn 2:e479b0296757 137 _send_command(address & 0x0F);
Byrn 2:e479b0296757 138
Byrn 2:e479b0296757 139 // "Set Higher Column Start Address for Page Addressing Mode"
Byrn 2:e479b0296757 140 _send_command((address << 4) & 0x0F);
Byrn 2:e479b0296757 141 }
Byrn 2:e479b0296757 142
Byrn 2:e479b0296757 143 void SSD1306::set_memory_addressing_mode(unsigned char mode)
Byrn 2:e479b0296757 144 {
Byrn 2:e479b0296757 145 _send_command(0x20);
Byrn 2:e479b0296757 146 _send_command(mode & 0x3);
Byrn 2:e479b0296757 147 }
Byrn 2:e479b0296757 148
Byrn 2:e479b0296757 149 void SSD1306::hv_set_column_address(unsigned char start, unsigned char end)
Byrn 2:e479b0296757 150 {
Byrn 2:e479b0296757 151 _send_command(0x21);
Byrn 2:e479b0296757 152 _send_command(start & 0x7F);
Byrn 2:e479b0296757 153 _send_command(end & 0x7F);
Byrn 2:e479b0296757 154 }
Byrn 2:e479b0296757 155
Byrn 2:e479b0296757 156 void SSD1306::hv_set_page_address(unsigned char start, unsigned char end)
Byrn 2:e479b0296757 157 {
Byrn 2:e479b0296757 158 _send_command(0x22);
Byrn 2:e479b0296757 159 _send_command(start & 0x07);
Byrn 2:e479b0296757 160 _send_command(end & 0x07);
Byrn 2:e479b0296757 161 }
Byrn 2:e479b0296757 162
Byrn 2:e479b0296757 163 void SSD1306::pam_set_page_start(unsigned char address)
Byrn 2:e479b0296757 164 {
Byrn 2:e479b0296757 165 _send_command(0xB0 | (address & 0x07));
Byrn 2:e479b0296757 166 }
Byrn 2:e479b0296757 167
Byrn 2:e479b0296757 168 void SSD1306::set_display_clock_ratio_and_frequency(unsigned char ratio, unsigned char frequency)
Byrn 2:e479b0296757 169 {
Byrn 2:e479b0296757 170 _send_command(0xD5);
Byrn 2:e479b0296757 171 _send_command((ratio & 0x0F) | ((frequency & 0x0F) << 4));
Byrn 2:e479b0296757 172 }
Byrn 2:e479b0296757 173
Byrn 2:e479b0296757 174 void SSD1306::set_precharge_period(unsigned char phase1, unsigned char phase2)
Byrn 2:e479b0296757 175 {
Byrn 2:e479b0296757 176 _send_command(0xD9);
Byrn 2:e479b0296757 177 _send_command((phase1 & 0x0F) | ((phase2 & 0x0F ) << 4));
Byrn 2:e479b0296757 178 }
Byrn 2:e479b0296757 179
Byrn 2:e479b0296757 180 void SSD1306::set_vcomh_deselect_level(unsigned char level)
Byrn 2:e479b0296757 181 {
Byrn 2:e479b0296757 182 _send_command(0xDB);
Byrn 2:e479b0296757 183 _send_command((level & 0x03) << 4);
Byrn 2:e479b0296757 184 }
Byrn 2:e479b0296757 185
Byrn 2:e479b0296757 186 void SSD1306::nop()
Byrn 2:e479b0296757 187 {
Byrn 2:e479b0296757 188 _send_command(0xE3);
Byrn 2:e479b0296757 189 }
Byrn 2:e479b0296757 190
Byrn 2:e479b0296757 191 void SSD1306::set_charge_pump_enable(unsigned char enable)
Byrn 2:e479b0296757 192 {
Byrn 2:e479b0296757 193 _send_command(0x8D);
Byrn 2:e479b0296757 194 _send_command(enable ? 0x14 : 0x10);
Byrn 0:21cb91208386 195 }
Byrn 0:21cb91208386 196
Byrn 0:21cb91208386 197 void SSD1306::initialise()
Byrn 0:21cb91208386 198 {
Byrn 1:1d58d378221c 199 // Init
Byrn 0:21cb91208386 200 _reset = 1;
Byrn 0:21cb91208386 201 wait(0.01);
Byrn 0:21cb91208386 202 _reset = 0;
Byrn 0:21cb91208386 203 wait(0.10);
Byrn 0:21cb91208386 204 _reset = 1;
Byrn 0:21cb91208386 205
Byrn 0:21cb91208386 206 off();
Byrn 2:e479b0296757 207
Byrn 2:e479b0296757 208 set_display_clock_ratio_and_frequency(0, 8);
Byrn 2:e479b0296757 209 set_multiplex_ratio(0x3F); // 1/64 duty
Byrn 2:e479b0296757 210 set_precharge_period(0xF, 0x01);
Byrn 2:e479b0296757 211 set_display_offset(0);
Byrn 2:e479b0296757 212 set_display_start_line(0);
Byrn 2:e479b0296757 213 set_charge_pump_enable(1);
Byrn 2:e479b0296757 214 set_memory_addressing_mode(0); // horizontal addressing mode
Byrn 2:e479b0296757 215 set_segment_remap(1);
Byrn 2:e479b0296757 216 set_com_output_scan_direction(1);
Byrn 2:e479b0296757 217 set_com_pins_hardware_configuration(1, 0);
Byrn 1:1d58d378221c 218 set_contrast(0xFF);
Byrn 2:e479b0296757 219 set_vcomh_deselect_level(1);
Byrn 1:1d58d378221c 220
Byrn 2:e479b0296757 221 wake();
Byrn 2:e479b0296757 222 set_inverse(0);
Byrn 0:21cb91208386 223
Byrn 2:e479b0296757 224 hv_set_column_address(0, 127);
Byrn 2:e479b0296757 225 hv_set_page_address(0, 7);
Byrn 0:21cb91208386 226
Byrn 2:e479b0296757 227 pam_set_start_address(0);
Byrn 2:e479b0296757 228 pam_set_page_start(0);
Byrn 2:e479b0296757 229
Byrn 2:e479b0296757 230 // set_precharge_period(2, 2);
Byrn 0:21cb91208386 231 }
Byrn 0:21cb91208386 232
Byrn 0:21cb91208386 233 void SSD1306::update()
Byrn 0:21cb91208386 234 {
Byrn 2:e479b0296757 235 hv_set_column_address(0, 127);
Byrn 2:e479b0296757 236 hv_set_page_address(0, 7);
Byrn 0:21cb91208386 237
Byrn 0:21cb91208386 238 for (int i = 0; i < 1024; i++)
Byrn 0:21cb91208386 239 _send_data(_screen[i]);
Byrn 0:21cb91208386 240 }
Byrn 0:21cb91208386 241
Byrn 0:21cb91208386 242 void SSD1306::set_pixel(int x, int y)
Byrn 0:21cb91208386 243 {
Byrn 0:21cb91208386 244 if (x >= SSD1306_LCDWIDTH || y >= SSD1306_LCDHEIGHT) return;
Byrn 0:21cb91208386 245
Byrn 0:21cb91208386 246 _screen[x + (y / 8) * 128] |= 1 << (y % 8);
Byrn 0:21cb91208386 247 }
Byrn 0:21cb91208386 248
Byrn 0:21cb91208386 249 void SSD1306::clear_pixel(int x, int y)
Byrn 0:21cb91208386 250 {
Byrn 0:21cb91208386 251 if (x >= SSD1306_LCDWIDTH || y >= SSD1306_LCDHEIGHT) return;
Byrn 0:21cb91208386 252
Byrn 0:21cb91208386 253 _screen[x + (y / 8) * 128] &= ~(1 << (y % 8));
Byrn 0:21cb91208386 254 }
Byrn 0:21cb91208386 255
Byrn 0:21cb91208386 256 void SSD1306::line(int x0, int y0, int x1, int y1) {
Byrn 0:21cb91208386 257 int steep = abs(y1 - y0) > abs(x1 - x0);
Byrn 0:21cb91208386 258 int t;
Byrn 0:21cb91208386 259
Byrn 0:21cb91208386 260 if (steep) {
Byrn 0:21cb91208386 261 t = x0; x0 = y0; y0 = t;
Byrn 0:21cb91208386 262 t = x1; x1 = y1; y1 = t;
Byrn 0:21cb91208386 263 }
Byrn 0:21cb91208386 264
Byrn 0:21cb91208386 265 if (x0 > x1) {
Byrn 0:21cb91208386 266 t = x0; x0 = x1; x1 = t;
Byrn 0:21cb91208386 267 t = y0; y0 = y1; y1 = t;
Byrn 0:21cb91208386 268 }
Byrn 0:21cb91208386 269
Byrn 0:21cb91208386 270 int dx, dy;
Byrn 0:21cb91208386 271
Byrn 0:21cb91208386 272 dx = x1 - x0;
Byrn 0:21cb91208386 273 dy = abs(y1 - y0);
Byrn 0:21cb91208386 274
Byrn 0:21cb91208386 275 int err = dx / 2;
Byrn 0:21cb91208386 276 int ystep;
Byrn 0:21cb91208386 277
Byrn 0:21cb91208386 278 if (y0 < y1) {
Byrn 0:21cb91208386 279 ystep = 1;
Byrn 0:21cb91208386 280 } else {
Byrn 0:21cb91208386 281 ystep = -1;}
Byrn 0:21cb91208386 282
Byrn 0:21cb91208386 283 for (; x0<x1; x0++) {
Byrn 0:21cb91208386 284 if (steep) {
Byrn 0:21cb91208386 285 set_pixel(y0, x0);
Byrn 0:21cb91208386 286 } else {
Byrn 0:21cb91208386 287 set_pixel(x0, y0);
Byrn 0:21cb91208386 288 }
Byrn 0:21cb91208386 289 err -= dy;
Byrn 0:21cb91208386 290 if (err < 0) {
Byrn 0:21cb91208386 291 y0 += ystep;
Byrn 0:21cb91208386 292 err += dx;
Byrn 0:21cb91208386 293 }
Byrn 0:21cb91208386 294 }
Byrn 0:21cb91208386 295 }
Byrn 0:21cb91208386 296
Byrn 0:21cb91208386 297 void SSD1306::draw_string(char *font, int x, int y, const char *string)
Byrn 0:21cb91208386 298 {
Byrn 0:21cb91208386 299 _cursor_x = x;
Byrn 0:21cb91208386 300 _cursor_y = y;
Byrn 0:21cb91208386 301
Byrn 0:21cb91208386 302 for (int i = 0; i < strlen(string); i++)
Byrn 0:21cb91208386 303 draw_char(font, _cursor_x, _cursor_y, string[i]);
Byrn 0:21cb91208386 304 }
Byrn 0:21cb91208386 305
Byrn 0:21cb91208386 306 void SSD1306::draw_char(char *font, int x, int y, char c)
Byrn 0:21cb91208386 307 {
Byrn 0:21cb91208386 308 int height = font[FONT_HEIGHT_OFFSET];
Byrn 0:21cb91208386 309 int max_width = font[FONT_SIZE_OFFSET];
Byrn 0:21cb91208386 310 int char_size_bytes = max_width * height + 1;
Byrn 0:21cb91208386 311 int char_width = font[(c - FONT_START) * char_size_bytes + FONT_DATA_OFFSET];
Byrn 0:21cb91208386 312 for (int i = 0; i < char_width; i++)
Byrn 0:21cb91208386 313 _screen[(x + i) + (y * SSD1306_LCDWIDTH)] = font[(c - FONT_START) * (char_size_bytes) + i + FONT_DATA_OFFSET + 1];
Byrn 0:21cb91208386 314
Byrn 0:21cb91208386 315 _cursor_x = x + char_width;
Byrn 0:21cb91208386 316 _cursor_y = y;
Byrn 0:21cb91208386 317 }
Byrn 0:21cb91208386 318
Byrn 0:21cb91208386 319 void SSD1306::clear()
Byrn 0:21cb91208386 320 {
Byrn 0:21cb91208386 321 for (int i = 0; i < 1024; i++)
Byrn 0:21cb91208386 322 _screen[i] = 0;
Byrn 0:21cb91208386 323 }
Byrn 0:21cb91208386 324
Byrn 1:1d58d378221c 325 void SSD1306::_send_command(unsigned char code)
Byrn 0:21cb91208386 326 {
Byrn 0:21cb91208386 327 _cs = 1;
Byrn 0:21cb91208386 328 _dc = 0;
Byrn 0:21cb91208386 329 _cs = 0;
Byrn 0:21cb91208386 330 _spi.write(code);
Byrn 0:21cb91208386 331 _cs = 1;
Byrn 0:21cb91208386 332 }
Byrn 0:21cb91208386 333
Byrn 1:1d58d378221c 334 void SSD1306::_send_data(unsigned char value)
Byrn 0:21cb91208386 335 {
Byrn 0:21cb91208386 336 _cs = 1;
Byrn 0:21cb91208386 337 _dc = 1;
Byrn 0:21cb91208386 338 _cs = 0;
Byrn 0:21cb91208386 339 _spi.write(value);
Byrn 0:21cb91208386 340 _cs = 1;
Byrn 0:21cb91208386 341 }