Commit f7e8fced authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

Add SSD1306 OLED display driver

parent e585d524
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -108,6 +108,10 @@ ifneq ($(findstring sharp96,${drivers}), )
	CONFIG_driver_sharp96 = y
endif

ifneq ($(findstring ssd1306,${drivers}), )
	CONFIG_driver_ssd1306 = y
endif

ifneq ($(findstring tsl2591,${drivers}), )
	CONFIG_driver_tsl2591 = y
endif
@@ -251,6 +255,11 @@ ifdef CONFIG_driver_sharp96
	COMMON_FLAGS += -DSHARP96_CS_PIN=GPIO::${sharp96_cs_pin}
endif

ifdef CONFIG_driver_ssd1306
	CXX_TARGETS += src/driver/ssd1306.cc
	COMMON_FLAGS += -DDRIVER_SSD1306 -DSSD1306_WIDTH=${CONFIG_driver_ssd1306_width} -DSSD1306_HEIGHT=${CONFIG_driver_ssd1306_height}
endif

ifdef CONFIG_driver_resistive_load
	CXX_TARGETS += src/driver/resistive_load.cc
	resistor1_pin ?= p3_0
+78 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 Daniel Friesel
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */
#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 <stdint.h>
#include <stddef.h>

class SSD1306 {
	private:
		const uint8_t width = SSD1306_WIDTH;
		const uint8_t height = SSD1306_HEIGHT;
		SSD1306(const SSD1306 &copy);

		unsigned char const address = 0x3c;

		unsigned char txbuf[130];
		unsigned char rxbuf[2];

		const unsigned char init1[6] = {
			SSD1306_SET_DISP | 0x00,
			SSD1306_SET_MEM_ADDR, 0x00,
			SSD1306_SET_DISP_START_LINE | 0x00,
			SSD1306_SET_SEG_REMAP | 0x01,
			SSD1306_SET_MUX_RATIO
		};
		// height
		const unsigned char init2[4] = {
			SSD1306_SET_COM_OUT_DIR | 0x08,
			SSD1306_SET_DISP_OFFSET, 0x00,
			SSD1306_SET_COM_PIN_CFG
		};
		// height == 32? 0x02 : 0x12
		const unsigned char init3[13] = {
			SSD1306_SET_DISP_CLK_DIV, 0x80,
			SSD1306_SET_PRECHARGE, 0xf1,
			SSD1306_SET_VCOM_DESEL, 0x30,
			SSD1306_SET_CONTRAST, 0xff,
			SSD1306_SET_ENTIRE_ON,
			SSD1306_SET_NORM_INV,
			SSD1306_SET_CHARGE_PUMP, 0x14,
			SSD1306_SET_DISP | 0x01
		};

		void writeCommand(uint8_t command);
		void writeData(unsigned char* data);

	public:
		SSD1306() {}

		void init();
		void showImage(unsigned char* data, uint16_t length);
};

extern SSD1306 ssd1306;

#endif
+14 −0
Original line number Diff line number Diff line
@@ -80,6 +80,20 @@ config driver_sharp96
bool "sharp LS013B4DN 96x96px Transflective LC Display"
depends on ( arch_msp430fr5969lp || arch_msp430fr5994lp ) && meta_driver_spi

config driver_ssd1306
bool "SSD1306 I2C OLED display"
depends on meta_driver_i2c

config driver_ssd1306_width
int "Display width"
default 128
depends on driver_ssd1306

config driver_ssd1306_height
int "Display height"
default 64
depends on driver_ssd1306

config driver_softi2c
bool "Software I2C"
#depends on !driver_i2c

src/driver/ssd1306.cc

0 → 100644
+52 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 Daniel Friesel
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */
#include "driver/ssd1306.h"
#include "driver/i2c.h"
#include "driver/soft_i2c.h"

void SSD1306::writeCommand(uint8_t command)
{
	txbuf[0] = 0x80;
	txbuf[1] = command;
	i2c.xmit(address, 2, txbuf, 0, rxbuf);
}

void SSD1306::init()
{
	unsigned char i;
	for (i = 0; i < sizeof(init1); i++) {
		writeCommand(init1[i]);
	}
	writeCommand(height - 1);
	for (i = 0; i < sizeof(init2); i++) {
		writeCommand(init2[i]);
	}
	writeCommand(height == 32 ? 0x02 : 0x12);
	for (i = 0; i < sizeof(init3); i++) {
		writeCommand(init3[i]);
	}
}

void SSD1306::showImage(unsigned char* data, uint16_t length)
{
	uint8_t i;
	uint8_t j;
	txbuf[0] = 0x40;
	for (i = 0; i < length / 128; i++) {
		for (j = 0; j < 128; j++) {
			txbuf[j+1] = data[(uint16_t)i*128 + j];
		}
		i2c.xmit(address, 129, txbuf, 0, rxbuf);
	}
	if (length % 128) {
		for (j = 0; j < length % 128; j++) {
			txbuf[j+1] = data[(uint16_t)i*128 + j];
		}
		i2c.xmit(address, (length % 128) + 1, txbuf, 0, rxbuf);
	}
}

SSD1306 ssd1306;