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