diff options
| author | Maxwell Beck <max@rastertail.net> | 2026-10-26 20:32:56 -0500 |
|---|---|---|
| committer | Maxwell Beck <max@rastertail.net> | 2026-10-26 20:32:56 -0500 |
| commit | 2a590986e1ee2aca934181e0ced958c520e97332 (patch) | |
| tree | b731744bc2c26b44646d65a302c489253ba7412e /src/ssd1306.h | |
| parent | aa9936120a933f14d52c213a29c6b2b87ec90201 (diff) | |
ssd1306 driver sketch
Diffstat (limited to 'src/ssd1306.h')
| -rw-r--r-- | src/ssd1306.h | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/ssd1306.h b/src/ssd1306.h new file mode 100644 index 0000000..7f6755e --- /dev/null +++ b/src/ssd1306.h @@ -0,0 +1,138 @@ +#ifndef PICO1541_SSD1306_H +#define PICO1541_SSD1306_H + +#include <stdint.h> +#include <hardware/i2c.h> + +/* ------------------------------------------------------------------ */ +/* 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); + +#endif |
