Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of L152RE_OLED_SSD1306 by
ssd1306.cpp
00001 00002 #include "mbed.h" 00003 #include "ssd1306.h" 00004 00005 #include <stdarg.h> 00006 00007 #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 00008 00009 SSD1306::SSD1306(PinName cs, PinName rs, PinName dc, PinName clk, PinName data) 00010 : _spi(data, NC, clk), 00011 _cs(cs), 00012 _reset(rs), 00013 _dc(dc), 00014 _cursor_x(0), 00015 _cursor_y(0) 00016 { 00017 } 00018 00019 void SSD1306::off() 00020 { 00021 _send_command(0xAE); 00022 } 00023 00024 void SSD1306::on() 00025 { 00026 _send_command(0xAF); 00027 } 00028 00029 void SSD1306::sleep() 00030 { 00031 _send_command(0xAE); 00032 } 00033 00034 void SSD1306::wake() 00035 { 00036 _send_command(0xAF); 00037 } 00038 00039 void SSD1306::set_inverse(unsigned char value) 00040 { 00041 _send_command(value ? 0xA7 : 0xA6); 00042 } 00043 00044 void SSD1306::set_display_offset(unsigned char value) 00045 { 00046 _send_command(0xD3); 00047 _send_command(value & 0x3F); 00048 } 00049 00050 void SSD1306::set_contrast(unsigned char value) 00051 { 00052 _send_command(0x81); 00053 _send_command(value); 00054 } 00055 00056 void SSD1306::set_display_start_line(unsigned char value) 00057 { 00058 _send_command(0x40 | value); 00059 } 00060 00061 void SSD1306::set_segment_remap(unsigned char value) 00062 { 00063 _send_command(value ? 0xA1 : 0xA0); 00064 } 00065 00066 void SSD1306::set_multiplex_ratio(unsigned char value) 00067 { 00068 _send_command(0xA8); 00069 _send_command(value & 0x3F); 00070 } 00071 00072 void SSD1306::set_com_output_scan_direction(unsigned char value) 00073 { 00074 _send_command(value ? 0xC8 : 0xC0); 00075 } 00076 00077 void SSD1306::set_com_pins_hardware_configuration(unsigned char sequential, unsigned char lr_remap) 00078 { 00079 _send_command(0xDA); 00080 _send_command(0x02 | ((sequential & 1) << 4) | ((lr_remap & 1) << 5)); 00081 } 00082 00083 void SSD1306::start_horizontal_scroll(unsigned char direction, unsigned char start, unsigned char end, unsigned char interval) 00084 { 00085 _send_command(direction ? 0x27 : 0x26); 00086 _send_command(0x00); 00087 _send_command(start & 0x07); 00088 switch (interval) { 00089 case 2: _send_command(0x07); break; // 111b 00090 case 3: _send_command(0x04); break; // 100b 00091 case 4: _send_command(0x05); break; // 101b 00092 case 5: _send_command(0x00); break; // 000b 00093 case 25: _send_command(0x06); break; // 110b 00094 case 64: _send_command(0x01); break; // 001b 00095 case 128: _send_command(0x02); break; // 010b 00096 case 256: _send_command(0x03); break; // 011b 00097 default: 00098 // default to 2 frame interval 00099 _send_command(0x07); break; 00100 } 00101 _send_command(end & 0x07); 00102 _send_command(0x00); 00103 _send_command(0xFF); 00104 00105 // activate scroll 00106 _send_command(0x2F); 00107 } 00108 00109 void SSD1306::start_vertical_and_horizontal_scroll(unsigned char direction, unsigned char start, unsigned char end, unsigned char interval, unsigned char vertical_offset) 00110 { 00111 _send_command(direction ? 0x2A : 0x29); 00112 _send_command(0x00); 00113 _send_command(start & 0x07); 00114 switch (interval) { 00115 case 2: _send_command(0x07); break; // 111b 00116 case 3: _send_command(0x04); break; // 100b 00117 case 4: _send_command(0x05); break; // 101b 00118 case 5: _send_command(0x00); break; // 000b 00119 case 25: _send_command(0x06); break; // 110b 00120 case 64: _send_command(0x01); break; // 001b 00121 case 128: _send_command(0x02); break; // 010b 00122 case 256: _send_command(0x03); break; // 011b 00123 default: 00124 // default to 2 frame interval 00125 _send_command(0x07); break; 00126 } 00127 _send_command(end & 0x07); 00128 _send_command(vertical_offset); 00129 00130 // activate scroll 00131 _send_command(0x2F); 00132 } 00133 00134 void SSD1306::stop_scroll() 00135 { 00136 // all scroll configurations are removed from the display when executing this command. 00137 _send_command(0x2E); 00138 } 00139 00140 void SSD1306::pam_set_start_address(unsigned char address) 00141 { 00142 // "Set Lower Column Start Address for Page Addressing Mode" 00143 _send_command(address & 0x0F); 00144 00145 // "Set Higher Column Start Address for Page Addressing Mode" 00146 _send_command((address << 4) & 0x0F); 00147 } 00148 00149 void SSD1306::set_memory_addressing_mode(unsigned char mode) 00150 { 00151 _send_command(0x20); 00152 _send_command(mode & 0x3); 00153 } 00154 00155 void SSD1306::hv_set_column_address(unsigned char start, unsigned char end) 00156 { 00157 _send_command(0x21); 00158 _send_command(start & 0x7F); 00159 _send_command(end & 0x7F); 00160 } 00161 00162 void SSD1306::hv_set_page_address(unsigned char start, unsigned char end) 00163 { 00164 _send_command(0x22); 00165 _send_command(start & 0x07); 00166 _send_command(end & 0x07); 00167 } 00168 00169 void SSD1306::pam_set_page_start(unsigned char address) 00170 { 00171 _send_command(0xB0 | (address & 0x07)); 00172 } 00173 00174 void SSD1306::set_display_clock_ratio_and_frequency(unsigned char ratio, unsigned char frequency) 00175 { 00176 _send_command(0xD5); 00177 _send_command((ratio & 0x0F) | ((frequency & 0x0F) << 4)); 00178 } 00179 00180 void SSD1306::set_precharge_period(unsigned char phase1, unsigned char phase2) 00181 { 00182 _send_command(0xD9); 00183 _send_command((phase1 & 0x0F) | ((phase2 & 0x0F ) << 4)); 00184 } 00185 00186 void SSD1306::set_vcomh_deselect_level(unsigned char level) 00187 { 00188 _send_command(0xDB); 00189 _send_command((level & 0x03) << 4); 00190 } 00191 00192 void SSD1306::nop() 00193 { 00194 _send_command(0xE3); 00195 } 00196 00197 void SSD1306::set_charge_pump_enable(unsigned char enable) 00198 { 00199 _send_command(0x8D); 00200 _send_command(enable ? 0x14 : 0x10); 00201 } 00202 00203 void SSD1306::initialise() 00204 { 00205 // Init 00206 _reset = 1; 00207 wait(0.01); 00208 _reset = 0; 00209 wait(0.10); 00210 _reset = 1; 00211 00212 off(); 00213 00214 set_display_clock_ratio_and_frequency(0, 8); 00215 set_multiplex_ratio(0x3F); // 1/64 duty 00216 set_precharge_period(0xF, 0x01); 00217 set_display_offset(0); 00218 set_display_start_line(0); 00219 set_charge_pump_enable(1); 00220 set_memory_addressing_mode(0); // horizontal addressing mode; across then down 00221 set_segment_remap(1); 00222 set_com_output_scan_direction(1); 00223 set_com_pins_hardware_configuration(1, 0); 00224 set_contrast(0xFF); 00225 set_vcomh_deselect_level(1); 00226 00227 wake(); 00228 set_inverse(0); 00229 00230 hv_set_column_address(0, 127); 00231 hv_set_page_address(0, 7); 00232 00233 pam_set_start_address(0); 00234 pam_set_page_start(0); 00235 00236 // set_precharge_period(2, 2); 00237 } 00238 00239 void SSD1306::update() 00240 { 00241 hv_set_column_address(0, 127); 00242 hv_set_page_address(0, 7); 00243 00244 for (int i = 0; i < 1024; i++) 00245 _send_data(_screen[i]); 00246 } 00247 00248 void SSD1306::drawBitmap(int x, int y, 00249 const unsigned char *bitmap, int w, int h, int color) { 00250 int16_t i, j, byteWidth = (w + 7) / 8; 00251 00252 for(j=0; j<h; j++) { 00253 for(i=0; i<w; i++ ) { 00254 if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) { 00255 color? set_pixel(x+i, y+j): clear_pixel(x+i, y+j); 00256 } 00257 } 00258 } 00259 } 00260 00261 void SSD1306::set_pixel(int x, int y) 00262 { 00263 if (x >= SSD1306_LCDWIDTH || y >= SSD1306_LCDHEIGHT) return; 00264 00265 _screen[x + (y / 8) * 128] |= 1 << (y % 8); 00266 } 00267 00268 void SSD1306::clear_pixel(int x, int y) 00269 { 00270 if (x >= SSD1306_LCDWIDTH || y >= SSD1306_LCDHEIGHT) return; 00271 00272 _screen[x + (y / 8) * 128] &= ~(1 << (y % 8)); 00273 } 00274 00275 void SSD1306::line(int x0, int y0, int x1, int y1) { 00276 int steep = abs(y1 - y0) > abs(x1 - x0); 00277 int t; 00278 00279 if (steep) { 00280 t = x0; x0 = y0; y0 = t; 00281 t = x1; x1 = y1; y1 = t; 00282 } 00283 00284 if (x0 > x1) { 00285 t = x0; x0 = x1; x1 = t; 00286 t = y0; y0 = y1; y1 = t; 00287 } 00288 00289 int dx, dy; 00290 00291 dx = x1 - x0; 00292 dy = abs(y1 - y0); 00293 00294 int err = dx / 2; 00295 int ystep; 00296 00297 if (y0 < y1) { 00298 ystep = 1; 00299 } else { 00300 ystep = -1;} 00301 00302 for (; x0<x1; x0++) { 00303 if (steep) { 00304 set_pixel(y0, x0); 00305 } else { 00306 set_pixel(x0, y0); 00307 } 00308 err -= dy; 00309 if (err < 0) { 00310 y0 += ystep; 00311 err += dx; 00312 } 00313 } 00314 } 00315 00316 void SSD1306::set_font(unsigned char *font, unsigned int width) 00317 { 00318 _console_font_data = font; 00319 _console_font_width = width; 00320 } 00321 00322 void SSD1306::set_double_height_text(unsigned int double_height) 00323 { 00324 _double_height_text = double_height; 00325 } 00326 00327 void SSD1306::putc(unsigned char c) 00328 { 00329 while (_cursor_x >= (128 / _console_font_width)) 00330 { 00331 _cursor_x -= (128 / _console_font_width); 00332 _cursor_y++; 00333 } 00334 00335 while (_cursor_y > 7) 00336 { 00337 scroll_up(); 00338 } 00339 00340 switch (c) 00341 { 00342 case '\n': 00343 _cursor_y++; 00344 break; 00345 00346 case '\r': 00347 _cursor_x = 0; 00348 break; 00349 00350 case '\t': 00351 _cursor_x = (_cursor_x + 4) % 4; 00352 break; 00353 00354 default: 00355 for (int b = 0; b < _console_font_width; b++) 00356 { 00357 _screen[_cursor_x * _console_font_width + _cursor_y * 128 + b] = _console_font_data[(c - FONT_START) * _console_font_width + b]; 00358 } 00359 00360 _cursor_x++; 00361 } 00362 } 00363 00364 void SSD1306::scroll_up() 00365 { 00366 for (int y = 1; y <= 7; y++) 00367 { 00368 for (int x = 0; x < 128; x++) 00369 { 00370 _screen[x + 128 * (y - 1)] = _screen[x + 128 * y]; 00371 } 00372 } 00373 00374 for (int x = 0; x < 128; x++) 00375 { 00376 _screen[x + 128 * 7] = 0; 00377 } 00378 00379 _cursor_y--; 00380 } 00381 00382 void SSD1306::printf(const char *format, ...) 00383 { 00384 static char buffer[128]; 00385 00386 va_list args; 00387 va_start(args, format); 00388 vsprintf(buffer, format, args); 00389 va_end(args); 00390 00391 char *c = (char *)&buffer; 00392 while (*c != 0) 00393 { 00394 putc(*c++); 00395 } 00396 } 00397 00398 void SSD1306::clear() 00399 { 00400 for (int i = 0; i < 1024; i++) 00401 _screen[i] = 0; 00402 00403 _cursor_x = 0; 00404 _cursor_y = 0; 00405 } 00406 00407 void SSD1306::_send_command(unsigned char code) 00408 { 00409 _cs = 1; 00410 _dc = 0; 00411 _cs = 0; 00412 _spi.write(code); 00413 _cs = 1; 00414 } 00415 00416 void SSD1306::_send_data(unsigned char value) 00417 { 00418 _cs = 1; 00419 _dc = 1; 00420 _cs = 0; 00421 _spi.write(value); 00422 _cs = 1; 00423 }
Generated on Wed Jul 13 2022 03:43:57 by
1.7.2
