/* * Copyright 2021 Daniel Friesel * * SPDX-License-Identifier: BSD-2-Clause * * Driver for Solomon Systech SSD1306 OLED controller. Tested with * 128x64 and 128x32 Displays. */ #ifndef SSD1306_H #define SSD1306_H #define SSD1306_SET_CONTRAST 0x81 #define SSD1306_SET_ENTIRE_ON 0xa4 #define SSD1306_SET_NORM_INV 0xa6 #define SSD1306_SET_DISP 0xae #define SSD1306_SET_MEM_ADDR 0x20 #define SSD1306_SET_COL_ADDR 0x21 #define SSD1306_SET_PAGE_ADDR 0x22 #define SSD1306_SET_DISP_START_LINE 0x40 #define SSD1306_SET_SEG_REMAP 0xa0 #define SSD1306_SET_MUX_RATIO 0xa8 #define SSD1306_SET_COM_OUT_DIR 0xc0 #define SSD1306_SET_DISP_OFFSET 0xd3 #define SSD1306_SET_COM_PIN_CFG 0xda #define SSD1306_SET_DISP_CLK_DIV 0xd5 #define SSD1306_SET_PRECHARGE 0xd9 #define SSD1306_SET_VCOM_DESEL 0xdb #define SSD1306_SET_CHARGE_PUMP 0x8d #include #include class SSD1306 { private: const uint8_t width = SSD1306_WIDTH; const uint8_t height = SSD1306_HEIGHT; SSD1306(const SSD1306 ©); unsigned char const address = 0x3c; unsigned char txbuf[130]; unsigned char rxbuf[2]; /* * Adjust both SSD1306_SET_SEG_REMAP and SSD1306_SET_COM_OUT_DIR for * 180° rotation. */ const unsigned char init1[6] = { // Turn off power for configuration SSD1306_SET_DISP | 0x00, #ifdef CONFIG_driver_ssd1306_mode_horizontal /* * Enable Horizontal Addressing Mode. Assuming image data is {A, B, C, * ..., a, b, c, ...}, each byte corresponds to a 1x8 column, starting * at the top left corner and proceeding to the right and then down: * * A7 B7 C7 ... * .. .. .. ... * A0 B0 C0 ... * a7 b7 c7 ... * .. .. .. ... * a0 b0 c0 ... */ SSD1306_SET_MEM_ADDR, 0x00, #endif #ifdef CONFIG_driver_ssd1306_mode_vertical /* * Enable Vertical Addressing Mode. Assuming image data is {A, B, C, * ..., a, b, c, ...}, each byte corresponds to a 1x8 column, starting * at the top left corner and proceeding down and then to the right: * * A7 a7 ... * .. .. ... * A0 a0 ... * B7 b7 ... * .. .. ... * B0 b0 ... * .. .. ... */ SSD1306_SET_MEM_ADDR, 0x01, #endif // RAM line 0 == display line 0 SSD1306_SET_DISP_START_LINE | 0x00, /* * Horizontal Layout: Column 127 is SEG0. * This depends on the connection between SSD1306 and OLED. * Use 0x00 if your content is horizontally mirrored. */ SSD1306_SET_SEG_REMAP | 0x01, /* * Multiplex ratio is the number of display lines * (i.e., the display height) */ SSD1306_SET_MUX_RATIO }; // height-1 sent by init() const unsigned char init2[4] = { /* * Vertical Layout: Scan from COM63 to COM0. * This depends on the connection between SSD1306 and OLED. * Use 0x00 if your content is vertically mirrored. */ SSD1306_SET_COM_OUT_DIR | 0x08, // No vertical display offset SSD1306_SET_DISP_OFFSET, 0x00, /* * COM PIN layout depends on display height and type. See * datasheet and init(). */ SSD1306_SET_COM_PIN_CFG }; // height == 32? 0x02 : 0x12 const unsigned char init3[19] = { /* * Set clock to recommended values: 370 kHz (bits 7..4), * no divider (bits 3..0). Increase divider for glitchy effects. * The datasheet is unclear on the clock frequency range. */ SSD1306_SET_DISP_CLK_DIV, 0x80, /* * Set line (multiplex) precharge times. * phase 1 (discharge pixels to avoid effects from the previous line): 8 cycles * phase 2 (charge pixels for next line): 8 cycles * decrease phase 1 time for glitchy effects. */ SSD1306_SET_PRECHARGE, 0x88, /* * VCOM deselect level. Unknown. * 0x00: ~0.65 VCC * 0x20: ~0.77 VCC * 0x30: ~0.85 VCC */ SSD1306_SET_VCOM_DESEL, 0x30, // start with medium contrast SSD1306_SET_CONTRAST, 0x80, // display content == RAM content SSD1306_SET_ENTIRE_ON, // regular (uninverted) display SSD1306_SET_NORM_INV | 0x00, // Enable charge pump (provide power to the display) SSD1306_SET_CHARGE_PUMP, 0x14, // turn on display SSD1306_SET_DISP | 0x01, // reset column pointer SSD1306_SET_COL_ADDR, 0, 127, // reset page pointer SSD1306_SET_PAGE_ADDR, 0, 7 }; void writeCommand(uint8_t command); void writeData(unsigned char* data); public: SSD1306() {} void init(); void setContrast(unsigned char contrast); void setInvert(bool invert); void showImage(unsigned char* data, uint16_t length); }; extern SSD1306 ssd1306; #endif