#ifndef PICO1541_SSD1306_H #define PICO1541_SSD1306_H #include #include /* ------------------------------------------------------------------ */ /* I2C addressing and control bytes */ /* ------------------------------------------------------------------ */ #define SSD1306_I2C_ADDR 0x3C /* 7-bit, SA0 = 0 (D/C# pin low) */ #define SSD1306_I2C_ADDR_ALT 0x3D /* 7-bit, SA0 = 1 */ #define SSD1306_CTRL_CMD 0x00 /* following bytes are commands */ #define SSD1306_CTRL_DATA 0x40 /* following bytes are GDDRAM */ #define SSD1306_CTRL_CMD_SINGLE 0x80 /* one command byte follows */ #define SSD1306_CTRL_DATA_SINGLE 0xC0 /* one data byte follows */ /* ------------------------------------------------------------------ */ /* Fundamental commands */ /* ------------------------------------------------------------------ */ #define SSD1306_SET_CONTRAST 0x81 /* 1 arg: 0x00..0xFF, reset 0x7F */ #define SSD1306_ENTIRE_DISPLAY_RESUME 0xA4 /* output follows RAM (reset) */ #define SSD1306_ENTIRE_DISPLAY_ON 0xA5 /* all pixels on, ignores RAM */ #define SSD1306_NORMAL_DISPLAY 0xA6 /* 1 = pixel on */ #define SSD1306_INVERSE_DISPLAY 0xA7 /* 1 = pixel off */ #define SSD1306_DISPLAY_OFF 0xAE /* sleep mode */ #define SSD1306_DISPLAY_ON 0xAF /* ------------------------------------------------------------------ */ /* Scrolling commands */ /* ------------------------------------------------------------------ */ #define SSD1306_SCROLL_RIGHT 0x26 /* 6 args: continuous, right */ #define SSD1306_SCROLL_LEFT 0x27 /* 6 args: continuous, left */ #define SSD1306_SCROLL_VERT_RIGHT 0x29 /* 5 args: vertical + horizontal */ #define SSD1306_SCROLL_VERT_LEFT 0x2A /* 5 args: vertical + horizontal */ #define SSD1306_SCROLL_DEACTIVATE 0x2E #define SSD1306_SCROLL_ACTIVATE 0x2F #define SSD1306_SET_VERT_SCROLL_AREA 0xA3 /* 2 args: top fixed, scroll rows */ /* Argument layout, 0x26 / 0x27: * dummy 0x00, start page, frame interval, end page, dummy 0x00, dummy 0xFF * Argument layout, 0x29 / 0x2A: * dummy 0x00, start page, frame interval, end page, vertical offset */ /* ------------------------------------------------------------------ */ /* Addressing commands */ /* ------------------------------------------------------------------ */ #define SSD1306_SET_MEMORY_MODE 0x20 /* 1 arg, see MODE_* below */ #define SSD1306_SET_COL_ADDR 0x21 /* 2 args: column start, end */ #define SSD1306_SET_PAGE_ADDR 0x22 /* 2 args: page start, end */ /* Page addressing mode only: start address is split across two commands. */ #define SSD1306_SET_LOWER_COL_START 0x00 /* 0x00..0x0F = low nibble */ #define SSD1306_SET_HIGHER_COL_START 0x10 /* 0x10..0x1F = high nibble */ #define SSD1306_SET_PAGE_START 0xB0 /* 0xB0..0xB7 = page 0..7 */ /* ------------------------------------------------------------------ */ /* Hardware configuration */ /* ------------------------------------------------------------------ */ #define SSD1306_SET_START_LINE 0x40 /* 0x40..0x7F, line 0..63 */ #define SSD1306_SEG_REMAP_COL0 0xA0 /* column 0 -> SEG0 (reset) */ #define SSD1306_SEG_REMAP_COL127 0xA1 /* column 127 -> SEG0 (mirror X) */ #define SSD1306_SET_MULTIPLEX 0xA8 /* 1 arg: N+1 rows, 0x0F..0x3F */ #define SSD1306_COM_SCAN_NORMAL 0xC0 /* COM0 -> COM[N-1] */ #define SSD1306_COM_SCAN_REMAP 0xC8 /* COM[N-1] -> COM0 (mirror Y) */ #define SSD1306_SET_DISPLAY_OFFSET 0xD3 /* 1 arg: shift 0..63 by COM */ #define SSD1306_SET_COM_PINS 0xDA /* 1 arg, see COM_PINS_* below */ /* ------------------------------------------------------------------ */ /* Timing and driving scheme */ /* ------------------------------------------------------------------ */ #define SSD1306_SET_CLOCK_DIV 0xD5 /* 1 arg: lo = div-1, hi = freq */ /* reset 0x80 */ #define SSD1306_SET_PRECHARGE 0xD9 /* 1 arg: phase2/phase1 */ /* reset 0x22, 0xF1 for ext VCC*/ #define SSD1306_SET_VCOMH 0xDB /* 1 arg, see VCOMH_* below */ #define SSD1306_NOP 0xE3 #define SSD1306_SET_CHARGE_PUMP 0x8D /* 1 arg: 0x14 on, 0x10 off */ /* (SSD1306B / modules only) */ /* ------------------------------------------------------------------ */ /* Parameter constants */ /* ------------------------------------------------------------------ */ #define SSD1306_MEM_MODE_HORIZONTAL 0x00 #define SSD1306_MEM_MODE_VERTICAL 0x01 #define SSD1306_MEM_MODE_PAGE 0x02 /* reset default */ #define SSD1306_COM_PINS_SEQUENTIAL 0x02 #define SSD1306_COM_PINS_ALTERNATIVE 0x12 /* 128x64 default */ #define SSD1306_COM_PINS_SEQ_REMAP 0x22 #define SSD1306_COM_PINS_ALT_REMAP 0x32 #define SSD1306_VCOMH_0_65 0x00 /* ~0.65 x VCC */ #define SSD1306_VCOMH_0_77 0x20 /* ~0.77 x VCC, reset */ #define SSD1306_VCOMH_0_83 0x30 /* ~0.83 x VCC */ #define SSD1306_CHARGE_PUMP_ON 0x14 #define SSD1306_CHARGE_PUMP_OFF 0x10 #define SSD1306_SCROLL_5_FRAMES 0x00 /* 5 frames per step */ #define SSD1306_SCROLL_64_FRAMES 0x01 #define SSD1306_SCROLL_128_FRAMES 0x02 #define SSD1306_SCROLL_256_FRAMES 0x03 #define SSD1306_SCROLL_3_FRAMES 0x04 #define SSD1306_SCROLL_4_FRAMES 0x05 #define SSD1306_SCROLL_25_FRAMES 0x06 #define SSD1306_SCROLL_2_FRAMES 0x07 /* ------------------------------------------------------------------ */ /* Helper macros for building command bytes */ /* ------------------------------------------------------------------ */ #define SSD1306_COL_ADDR_LO(c) (uint8_t)(SSD1306_SET_LOWER_COL_START | ((c) & 0x0F)) #define SSD1306_COL_ADDR_HI(c) (uint8_t)(SSD1306_SET_HIGHER_COL_START | (((c) >> 4) & 0x0F)) #define SSD1306_PAGE(c) (uint8_t)(SSD1306_SET_PAGE_START | ((c) & 0x07)) #define SSD1306_START_LINE(l) (uint8_t)(SSD1306_SET_START_LINE | ((l) & 0x3F)) #define SSD1306_CONTRAST(v) (uint8_t)(v) #define SSD1306_MUX_RATIO(rows) (uint8_t)((rows) - 1) /* rows = 16..64 */ #define SSD1306_CLOCK(div, freq) (uint8_t)((((freq) & 0x0F) << 4) | (((div) - 1) & 0x0F)) #define SSD1306_BUFFER_LEN 256 typedef struct ssd1306 { i2c_inst_t *i2c; uint8_t addr; uint8_t buf[SSD1306_BUFFER_LEN]; size_t len; } ssd1306_t; int ssd_init(ssd1306_t *display, i2c_inst_t *i2c, uint8_t addr); int ssd_push(ssd1306_t *display, uint8_t byte); int ssd_send(ssd1306_t *display); int ssd_power_on(ssd1306_t *display); int ssd_push_char(ssd1306_t *display, const char c); int ssd_push_str(ssd1306_t *display, const char *str); #endif