summaryrefslogtreecommitdiff
path: root/src/ssd1306.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ssd1306.h')
-rw-r--r--src/ssd1306.h138
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