derived from Aidafruit SSD1306 library
Dependents: Test_SSD1306 L152RE_OLED_SSD1306 EcranZumo
Fork of 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 Fri Jul 15 2022 22:48:28 by 1.7.2