Skip to content

Commit f7fa955

Browse files
authored
Merge branch 'master' into sha2017
2 parents bd94683 + fd5e1f5 commit f7fa955

8 files changed

Lines changed: 320 additions & 0 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
if(CONFIG_DRIVER_SSD1306_ENABLE)
2+
set(srcs
3+
"driver_ssd1306.c"
4+
)
5+
set(includes
6+
"include"
7+
)
8+
else()
9+
set(srcs "")
10+
set(includes
11+
""
12+
)
13+
endif()
14+
15+
idf_component_register(SRCS "${srcs}"
16+
INCLUDE_DIRS ${includes}
17+
REQUIRES driver_framebuffer)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
menu "Driver: SSD1306 OLED display"
2+
config DRIVER_SSD1306_ENABLE
3+
depends on BUS_I2C0_ENABLE || BUS_I2C1_ENABLE
4+
bool "Enable the SSD1306 display driver"
5+
default n
6+
7+
config I2C_ADDR_SSD1306
8+
depends on DRIVER_SSD1306_ENABLE
9+
int "SSD1306 I2C address"
10+
default 60
11+
12+
config DRIVER_SSD1306_I2C_BUS
13+
depends on DRIVER_SSD1306_ENABLE
14+
int"SSD1306 I2C bus"
15+
default 0
16+
range 0 1
17+
18+
config PIN_NUM_SSD1306_RESET
19+
depends on DRIVER_SSD1306_ENABLE
20+
int "GPIO pin used for SSD1306 reset"
21+
endmenu
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
#include <sdkconfig.h>
2+
#include <stdbool.h>
3+
#include <stdint.h>
4+
#include <stdio.h>
5+
#include <string.h>
6+
7+
#include <freertos/FreeRTOS.h>
8+
#include <freertos/semphr.h>
9+
#include <freertos/task.h>
10+
#include <esp_log.h>
11+
#include <driver/gpio.h>
12+
13+
#include <buses.h>
14+
#include "include/driver_ssd1306.h"
15+
16+
#ifdef CONFIG_DRIVER_SSD1306_ENABLE
17+
18+
static const char *TAG = "ssd1306";
19+
20+
static inline esp_err_t i2c_command(uint8_t value)
21+
{
22+
esp_err_t res = driver_i2c_write_reg(CONFIG_DRIVER_SSD1306_I2C_BUS, CONFIG_I2C_ADDR_SSD1306, 0x00, value);
23+
if (res != ESP_OK) {
24+
ESP_LOGE(TAG, "i2c write command(0x%02x): error %d", value, res);
25+
return res;
26+
}
27+
return res;
28+
}
29+
30+
static inline esp_err_t i2c_data(const uint8_t* buffer, uint16_t len)
31+
{
32+
esp_err_t res = driver_i2c_write_buffer_reg(CONFIG_DRIVER_SSD1306_I2C_BUS, CONFIG_I2C_ADDR_SSD1306, 0x40, buffer, len);
33+
if (res != ESP_OK) {
34+
ESP_LOGE(TAG, "i2c write data: error %d", res);
35+
return res;
36+
}
37+
return res;
38+
}
39+
40+
esp_err_t driver_ssd1306_reset(void)
41+
{
42+
#if CONFIG_PIN_NUM_SSD1306_RESET >= 0
43+
gpio_set_level(CONFIG_PIN_NUM_SSD1306_RESET, false);
44+
vTaskDelay(10 / portTICK_PERIOD_MS);
45+
gpio_set_level(CONFIG_PIN_NUM_SSD1306_RESET, true);
46+
vTaskDelay(5 / portTICK_PERIOD_MS);
47+
#endif
48+
return ESP_OK;
49+
}
50+
51+
esp_err_t driver_ssd1306_init(void)
52+
{
53+
#if CONFIG_PIN_NUM_SSD1306_RESET >= 0
54+
gpio_set_direction(CONFIG_PIN_NUM_SSD1306_RESET, GPIO_MODE_OUTPUT);
55+
driver_ssd1306_reset();
56+
#endif
57+
58+
esp_err_t res;
59+
60+
#ifdef CONFIG_SSD1306_12832
61+
res=i2c_command(0xae); // SSD1306_DISPLAYOFF
62+
if (res != ESP_OK) return res;
63+
res=i2c_command(0xd5); // SSD1306_SETDISPLAYCLOCKDIV
64+
if (res != ESP_OK) return res;
65+
res=i2c_command(0xf0); // Sets frequency to highest value and divider to 1 for less flicker
66+
if (res != ESP_OK) return res;
67+
res=i2c_command(0xa8); // SSD1306_SETMULTIPLEX
68+
if (res != ESP_OK) return res;
69+
res=i2c_command(0x1f); // 1/32
70+
if (res != ESP_OK) return res;
71+
res=i2c_command(0xd3); // SSD1306_SETDISPLAYOFFSET
72+
if (res != ESP_OK) return res;
73+
res=i2c_command(0x00); // 0 no offset
74+
if (res != ESP_OK) return res;
75+
res=i2c_command(0x40); // SSD1306_SETSTARTLINE line #0
76+
if (res != ESP_OK) return res;
77+
res=i2c_command(0x8d); // SSD1306_CHARGEPUMP
78+
if (res != ESP_OK) return res;
79+
res=i2c_command(0x14); // Charge pump on
80+
if (res != ESP_OK) return res;
81+
res=i2c_command(0x20); // SSD1306_MEMORYMODE
82+
if (res != ESP_OK) return res;
83+
res=i2c_command(0x00); // 0x0 act like ks0108
84+
if (res != ESP_OK) return res;
85+
res=i2c_command(0xa1); // SSD1306_SEGREMAP | 1
86+
if (res != ESP_OK) return res;
87+
res=i2c_command(0xc8); // SSD1306_COMSCANDEC
88+
if (res != ESP_OK) return res;
89+
res=i2c_command(0xda); // SSD1306_SETCOMPINS
90+
if (res != ESP_OK) return res;
91+
res=i2c_command(0x02);
92+
if (res != ESP_OK) return res;
93+
res=i2c_command(0x81); // SSD1306_SETCONTRAST
94+
if (res != ESP_OK) return res;
95+
res=i2c_command(0x2f);
96+
if (res != ESP_OK) return res;
97+
res=i2c_command(0xd9); // SSD1306_SETPRECHARGE
98+
if (res != ESP_OK) return res;
99+
res=i2c_command(0xf1);
100+
if (res != ESP_OK) return res;
101+
res=i2c_command(0xdb); // SSD1306_SETVCOMDETECT
102+
if (res != ESP_OK) return res;
103+
res=i2c_command(0x40);
104+
if (res != ESP_OK) return res;
105+
res=i2c_command(0x2e); // SSD1306_DEACTIVATE_SCROLL
106+
if (res != ESP_OK) return res;
107+
res=i2c_command(0xa4); // SSD1306_DISPLAYALLON_RESUME
108+
if (res != ESP_OK) return res;
109+
res=i2c_command(0xa6); // SSD1306_NORMALDISPLAY
110+
if (res != ESP_OK) return res;
111+
#else
112+
res=i2c_command(0xae); // SSD1306_DISPLAYOFF
113+
if (res != ESP_OK) return res;
114+
res=i2c_command(0xd5); // SSD1306_SETDISPLAYCLOCKDIV
115+
if (res != ESP_OK) return res;
116+
res=i2c_command(0x80); // Suggested value 0x80
117+
if (res != ESP_OK) return res;
118+
res=i2c_command(0xa8); // SSD1306_SETMULTIPLEX
119+
if (res != ESP_OK) return res;
120+
res=i2c_command(0x3f); // 1/64
121+
if (res != ESP_OK) return res;
122+
res=i2c_command(0xd3); // SSD1306_SETDISPLAYOFFSET
123+
if (res != ESP_OK) return res;
124+
res=i2c_command(0x00); // 0 no offset
125+
if (res != ESP_OK) return res;
126+
res=i2c_command(0x40); // SSD1306_SETSTARTLINE line #0
127+
if (res != ESP_OK) return res;
128+
res=i2c_command(0x20); // SSD1306_MEMORYMODE
129+
if (res != ESP_OK) return res;
130+
res=i2c_command(0x01); // 0x0 act like ks0108 / 0x01 vertical addressing mode
131+
if (res != ESP_OK) return res;
132+
res=i2c_command(0xa1); // SSD1306_SEGREMAP | 1
133+
if (res != ESP_OK) return res;
134+
res=i2c_command(0xc8); // SSD1306_COMSCANDEC
135+
if (res != ESP_OK) return res;
136+
res=i2c_command(0xda); // SSD1306_SETCOMPINS
137+
if (res != ESP_OK) return res;
138+
res=i2c_command(0x12);
139+
if (res != ESP_OK) return res;
140+
res=i2c_command(0x81); // SSD1306_SETCONTRAST
141+
if (res != ESP_OK) return res;
142+
res=i2c_command(0xcf);
143+
if (res != ESP_OK) return res;
144+
res=i2c_command(0xd9); // SSD1306_SETPRECHARGE
145+
if (res != ESP_OK) return res;
146+
res=i2c_command(0xf1);
147+
if (res != ESP_OK) return res;
148+
res=i2c_command(0xdb); // SSD1306_SETVCOMDETECT
149+
if (res != ESP_OK) return res;
150+
res=i2c_command(0x30);
151+
if (res != ESP_OK) return res;
152+
res=i2c_command(0x8d); // SSD1306_CHARGEPUMP
153+
if (res != ESP_OK) return res;
154+
res=i2c_command(0x14); // Charge pump on
155+
if (res != ESP_OK) return res;
156+
res=i2c_command(0x2e); // SSD1306_DEACTIVATE_SCROLL
157+
if (res != ESP_OK) return res;
158+
res=i2c_command(0xa4); // SSD1306_DISPLAYALLON_RESUME
159+
if (res != ESP_OK) return res;
160+
res=i2c_command(0xa6); // SSD1306_NORMALDISPLAY
161+
if (res != ESP_OK) return res;
162+
#endif
163+
res=i2c_command(0xaf); // SSD1306_DISPLAYON
164+
if (res != ESP_OK) return res;
165+
166+
uint8_t buffer[1024] = {0};
167+
res = driver_ssd1306_write(buffer); //Clear screen
168+
if (res != ESP_OK) return res;
169+
return ESP_OK;
170+
}
171+
172+
esp_err_t driver_ssd1306_write_part(const uint8_t *buffer, int16_t x0, int16_t y0, int16_t x1, int16_t y1)
173+
{
174+
uint16_t addr0 = x0*(SSD1306_HEIGHT/8);
175+
uint16_t addr1 = x1*(SSD1306_HEIGHT/8) + (SSD1306_HEIGHT/8);
176+
uint16_t length = addr1-addr0;
177+
178+
esp_err_t res;
179+
res = i2c_command(0x21); //Column address
180+
if (res != ESP_OK) return res;
181+
res = i2c_command(x0); //Column start
182+
if (res != ESP_OK) return res;
183+
res = i2c_command(x1);//SSD1306_WIDTH-1); //Column end
184+
if (res != ESP_OK) return res;
185+
res = i2c_command(0x22); //Page address
186+
if (res != ESP_OK) return res;
187+
res = i2c_command(0); //Page start
188+
if (res != ESP_OK) return res;
189+
res = i2c_command(7); //Page end
190+
if (res != ESP_OK) return res;
191+
res = i2c_data(buffer+addr0, length);
192+
if ( res != ESP_OK) return res;
193+
return res;
194+
}
195+
196+
esp_err_t driver_ssd1306_write(const uint8_t *buffer)
197+
{
198+
esp_err_t res;
199+
res = i2c_command(0x21); //Column address
200+
if (res != ESP_OK) return res;
201+
res = i2c_command( 0); //Column start
202+
if (res != ESP_OK) return res;
203+
res = i2c_command( SSD1306_WIDTH-1); //Column end
204+
if (res != ESP_OK) return res;
205+
206+
res = i2c_command(0x22); //Page address
207+
if (res != ESP_OK) return res;
208+
res = i2c_command(0); //Page start
209+
if (res != ESP_OK) return res;
210+
res = i2c_command(7); //Page end
211+
if (res != ESP_OK) return res;
212+
213+
res = i2c_data(buffer, SSD1306_BUFFER_SIZE);
214+
if ( res != ESP_OK) return res;
215+
216+
ESP_LOGD(TAG, "i2c write data ok");
217+
return res;
218+
}
219+
#else
220+
esp_err_t driver_ssd1306_init(void) { return ESP_OK; } //Dummy function.
221+
#endif // CONFIG_DRIVER_SSD1306_ENABLE
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef DRIVER_SSD1306_H
2+
#define DRIVER_SSD1306_H
3+
4+
#include <stdbool.h>
5+
#include <stdint.h>
6+
#include <esp_err.h>
7+
8+
#define SSD1306_WIDTH 128
9+
10+
#ifdef CONFIG_SSD1306_12832
11+
#define SSD1306_HEIGHT 32
12+
#else
13+
#define SSD1306_HEIGHT 64
14+
#endif
15+
16+
#define SSD1306_BUFFER_SIZE (SSD1306_WIDTH * SSD1306_HEIGHT) / 8
17+
18+
__BEGIN_DECLS
19+
20+
extern esp_err_t driver_ssd1306_init(void);
21+
extern esp_err_t driver_ssd1306_write_part(const uint8_t *buffer, int16_t x0, int16_t y0, int16_t x1, int16_t y1);
22+
extern esp_err_t driver_ssd1306_write(const uint8_t *buffer);
23+
24+
__END_DECLS
25+
26+
#endif // DRIVER_SSD1306_H
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef __FRAMEBUFFER_DISPLAY_H__
2+
#define __FRAMEBUFFER_DISPLAU_H__
3+
4+
#include "driver_ssd1306.h"
5+
6+
//This header file containes the defines used by the framebuffer driver.
7+
8+
#define FB_SIZE SSD1306_BUFFER_SIZE
9+
#define FB_WIDTH SSD1306_WIDTH
10+
#define FB_HEIGHT SSD1306_HEIGHT
11+
#define FB_TYPE_1BPP
12+
#define FB_1BPP_VERT2
13+
#define FB_FLUSH(buffer,eink_flags,x0,y0,x1,y1) driver_ssd1306_write_part(buffer,x0,y0,x1,y1)
14+
#define COLOR_FILL_DEFAULT 0x000000
15+
#define COLOR_TEXT_DEFAULT 0xFFFFFF
16+
17+
#endif
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#Include all files that contain MP bindings
2+
3+
#Define the name of your module here
4+
set(mod_name "ssd1306")
5+
set(driver_name "ssd1306")
6+
set(mod_register "ssd1306 DISPLAY")
7+
8+
if(CONFIG_DRIVER_SSD1306_ENABLE)
9+
message(STATUS "ssd1306 enabled")
10+
set(EXTMODS_INIT "${EXTMODS_INIT}" "\"${driver_name}\"@\"${mod_register}\"^" CACHE INTERNAL "")
11+
else()
12+
message(STATUS "ssd1306 disabled")
13+
endif()

components/driver_framebuffer/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ set(IDF_COMPONENTS
6565
buses
6666
driver_display_ili9341
6767
driver_display_depg0290b1
68+
driver_display_ssd1306
6869
driver_io_disobey_samd
6970
spi_flash
7071
)

components/driver_mch22/modmch22.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
#include "py/runtime.h"
88
#include <driver/uart.h>
99

10+
#ifdef CONFIG_DRIVER_ILI9341_ENABLE
1011
#include "driver_ili9341.h"
12+
#endif
1113

1214
#include <esp_system.h>
1315
#include "soc/rtc.h"
@@ -273,7 +275,9 @@ static mp_obj_t driver_ice40_send_turbo(mp_obj_t transmit_data) {
273275
static MP_DEFINE_CONST_FUN_OBJ_1(ice40_send_turbo_obj, driver_ice40_send_turbo);
274276

275277
static mp_obj_t driver_mch22_set_lcd_mode(mp_obj_t mode) {
278+
#ifdef CONFIG_DRIVER_ILI9341_ENABLE
276279
driver_ili9341_set_mode(mp_obj_get_int(mode));
280+
#endif
277281
return mp_const_none;
278282
}
279283

0 commit comments

Comments
 (0)