derived from Aidafruit SSD1306 library
Dependents: Test_SSD1306 L152RE_OLED_SSD1306 EcranZumo
Fork of SSD1306 by
Diff: ssd1306.cpp
- Revision:
- 0:21cb91208386
- Child:
- 1:1d58d378221c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ssd1306.cpp Tue Feb 05 09:46:58 2013 +0000 @@ -0,0 +1,207 @@ + +#include "mbed.h" +#include "ssd1306.h" + +SSD1306::SSD1306(PinName cs, PinName rs, PinName dc, PinName clk, PinName data) + : _spi(data, NC, clk), _cs(cs), _reset(rs), _dc(dc) +{ +} + +void SSD1306::set_low_column(int v) +{ + _send_command(SSD1306_SETLOWCOLUMN | v); +} + +void SSD1306::set_high_column(int v) +{ + _send_command(SSD1306_SETHIGHCOLUMN | v); +} + +void SSD1306::set_start_line(int v) +{ + _send_command(SSD1306_SETSTARTLINE | v); +} + +void SSD1306::off() +{ + _send_command(SSD1306_DISPLAYOFF); +} + +void SSD1306::on() +{ + _send_command(SSD1306_DISPLAYON); +} + +void SSD1306::invert(int i) +{ + _send_command(i ? + SSD1306_INVERTDISPLAY : + SSD1306_NORMALDISPLAY); +} + +void SSD1306::set_display_offset(int v) +{ + _send_command(SSD1306_SETDISPLAYOFFSET); + _send_command(v); +} + +void SSD1306::initialise() +{ + // Init + _reset = 1; + wait(0.01); + _reset = 0; + wait(0.10); + _reset = 1; + + off(); + + set_low_column(0); + set_high_column(0); + set_start_line(0); + + _send_command(SSD1306_SETCONTRAST); + _send_command(0xCF); // chargepump, could be 0x9F for external 9V + + _send_command(0xA1); // setment remap 95 to 0 (??) + + invert(0); + + _send_command(SSD1306_DISPLAYALLON_RESUME); + _send_command(SSD1306_SETMULTIPLEX); + _send_command(0x3F); // 1/64 duty + + set_display_offset(0); + + _send_command(SSD1306_SETDISPLAYCLOCKDIV); + _send_command(0x80); // suggested value = 0x80 + _send_command(SSD1306_SETPRECHARGE); + _send_command(0xF1); // dc/dc, could be 0x22 for external 9V + _send_command(SSD1306_SETCOMPINS); + _send_command(0x12); // disable COM left/right remap + _send_command(SSD1306_SETVCOMDETECT); + _send_command(0x40); // apparently, 0x20 is default... + _send_command(SSD1306_MEMORYMODE); + _send_command(0x0); // act like KS0108 + + // left-to-right scan + _send_command(SSD1306_SEGREMAP | 0x1); + _send_command(SSD1306_COMSCANDEC); + _send_command(SSD1306_CHARGEPUMP); + _send_command(0x14); // disable, for external 9v 0x10 disable + + // turn it on + on(); +} + +void SSD1306::update() +{ + set_low_column(0); + set_high_column(0); + set_start_line(0); + + for (int i = 0; i < 1024; i++) + _send_data(_screen[i]); +} + +void SSD1306::set_pixel(int x, int y) +{ + if (x >= SSD1306_LCDWIDTH || y >= SSD1306_LCDHEIGHT) return; + + _screen[x + (y / 8) * 128] |= 1 << (y % 8); +} + +void SSD1306::clear_pixel(int x, int y) +{ + if (x >= SSD1306_LCDWIDTH || y >= SSD1306_LCDHEIGHT) return; + + _screen[x + (y / 8) * 128] &= ~(1 << (y % 8)); +} + +void SSD1306::line(int x0, int y0, int x1, int y1) { + int steep = abs(y1 - y0) > abs(x1 - x0); + int t; + + if (steep) { + t = x0; x0 = y0; y0 = t; + t = x1; x1 = y1; y1 = t; + } + + if (x0 > x1) { + t = x0; x0 = x1; x1 = t; + t = y0; y0 = y1; y1 = t; + } + + int dx, dy; + + dx = x1 - x0; + dy = abs(y1 - y0); + + int err = dx / 2; + int ystep; + + if (y0 < y1) { + ystep = 1; + } else { + ystep = -1;} + + for (; x0<x1; x0++) { + if (steep) { + set_pixel(y0, x0); + } else { + set_pixel(x0, y0); + } + err -= dy; + if (err < 0) { + y0 += ystep; + err += dx; + } + } +} + +void SSD1306::draw_string(char *font, int x, int y, const char *string) +{ + _cursor_x = x; + _cursor_y = y; + + for (int i = 0; i < strlen(string); i++) + draw_char(font, _cursor_x, _cursor_y, string[i]); +} + +void SSD1306::draw_char(char *font, int x, int y, char c) +{ + int height = font[FONT_HEIGHT_OFFSET]; + int max_width = font[FONT_SIZE_OFFSET]; + int char_size_bytes = max_width * height + 1; + int char_width = font[(c - FONT_START) * char_size_bytes + FONT_DATA_OFFSET]; + for (int i = 0; i < char_width; i++) + _screen[(x + i) + (y * SSD1306_LCDWIDTH)] = font[(c - FONT_START) * (char_size_bytes) + i + FONT_DATA_OFFSET + 1]; + + _cursor_x = x + char_width; + _cursor_y = y; +} + +void SSD1306::clear() +{ + for (int i = 0; i < 1024; i++) + _screen[i] = 0; +} + +void SSD1306::_send_command(int code) +{ + _cs = 1; + _dc = 0; + _cs = 0; + _spi.write(code); + _cs = 1; +} + +void SSD1306::_send_data(int value) +{ + _cs = 1; + _dc = 1; + _cs = 0; + _spi.write(value); + _cs = 1; +} +