1 | #include <string.h>
|
2 |
|
3 | #include "freertos/FreeRTOS.h"
|
4 | #include "freertos/task.h"
|
5 |
|
6 | #include "driver/gpio.h"
|
7 | #include "driver/i2c.h"
|
8 |
|
9 | #include "esp_err.h"
|
10 | #include "esp_log.h"
|
11 |
|
12 | #include "ssd1366.h"
|
13 | #include "font8x8_basic.h"
|
14 |
|
15 | #define SDA_PIN GPIO_NUM_21
|
16 | #define SCL_PIN GPIO_NUM_22
|
17 |
|
18 | #define tag "ssd1306"
|
19 |
|
20 | void i2c_master_init() {
|
21 |
|
22 | i2c_config_t i2c_config = {
|
23 |
|
24 | .mode = I2C_MODE_MASTER,
|
25 | .sda_io_num = SDA_PIN,
|
26 | .scl_io_num = SCL_PIN,
|
27 | .sda_pullup_en = GPIO_PULLUP_ENABLE,
|
28 | .scl_pullup_en = GPIO_PULLUP_ENABLE,
|
29 | .master.clk_speed = 1000000
|
30 | };
|
31 |
|
32 | i2c_param_config(I2C_NUM_0, &i2c_config);
|
33 | i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);
|
34 | }
|
35 |
|
36 | void ssd1306_init() {
|
37 | esp_err_t espRc;
|
38 | i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
39 | i2c_master_start(cmd);
|
40 | i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
41 | i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);
|
42 | i2c_master_write_byte(cmd, OLED_CMD_SET_CHARGE_PUMP, true);
|
43 | i2c_master_write_byte(cmd, 0x14, true); // 0x14(enable)
|
44 | i2c_master_write_byte(cmd, OLED_CMD_SET_SEGMENT_REMAP, true); // reverse left-right mapping
|
45 | i2c_master_write_byte(cmd, OLED_CMD_SET_COM_SCAN_MODE, true); // reverse up-bottom mapping
|
46 | i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_ON, true);
|
47 | i2c_master_stop(cmd);
|
48 | espRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
|
49 | if (espRc == ESP_OK) {
|
50 | ESP_LOGI(tag, "ssd1306_init successfully");
|
51 | } else {
|
52 | ESP_LOGE(tag, "ssd1306_init failed. code: 0x%.2X", espRc);
|
53 | }
|
54 | i2c_cmd_link_delete(cmd);
|
55 | }
|
56 |
|
57 | void ssd1306_display_clear(void) {
|
58 | i2c_cmd_handle_t cmd;
|
59 | uint8_t zero[128] = {0};
|
60 | for (uint8_t i = 0; i < 8; i++) {
|
61 | cmd = i2c_cmd_link_create();
|
62 | i2c_master_start(cmd);
|
63 | i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
64 | i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_SINGLE, true);
|
65 | i2c_master_write_byte(cmd, 0xB0 | i, true); // Set GDDRAM page start address
|
66 | i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true);
|
67 | i2c_master_write(cmd, zero, 128, true);
|
68 | i2c_master_stop(cmd);
|
69 | i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
|
70 | i2c_cmd_link_delete(cmd);
|
71 | }
|
72 | }
|
73 |
|
74 | void ssd1306_display_text(void *arg_text) {
|
75 | char *text = (char*)arg_text;
|
76 | uint8_t text_len = strlen(text);
|
77 | i2c_cmd_handle_t cmd;
|
78 | uint8_t cur_page = 0;
|
79 | cmd = i2c_cmd_link_create();
|
80 | i2c_master_start(cmd);
|
81 | i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
82 | i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);
|
83 | i2c_master_write_byte(cmd, 0x00, true); // reset column
|
84 | i2c_master_write_byte(cmd, 0x10, true);
|
85 | i2c_master_write_byte(cmd, 0xB0 | cur_page, true); // reset page
|
86 | i2c_master_stop(cmd);
|
87 | i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
|
88 | i2c_cmd_link_delete(cmd);
|
89 | for (uint8_t i = 0; i < text_len; i++) {
|
90 | if (text[i] == '\n') {
|
91 | cmd = i2c_cmd_link_create();
|
92 | i2c_master_start(cmd);
|
93 | i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
94 | i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);
|
95 | i2c_master_write_byte(cmd, 0x00, true); // reset column
|
96 | i2c_master_write_byte(cmd, 0x10, true);
|
97 | i2c_master_write_byte(cmd, 0xB0 | ++cur_page, true); // increment page
|
98 | i2c_master_stop(cmd);
|
99 | i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
|
100 | i2c_cmd_link_delete(cmd);
|
101 | } else {
|
102 | cmd = i2c_cmd_link_create();
|
103 | i2c_master_start(cmd);
|
104 | i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
105 | i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true);
|
106 | i2c_master_write(cmd, font8x8_basic_tr[(uint8_t)text[i]], 8, true);
|
107 | i2c_master_stop(cmd);
|
108 | i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
|
109 | i2c_cmd_link_delete(cmd);
|
110 | }
|
111 | }
|
112 | }
|
113 |
|
114 | void app_main(void) {
|
115 | i2c_master_init();
|
116 | ssd1306_init();
|
117 | ssd1306_display_clear();
|
118 | ssd1306_display_text("ABCDEFGHIJKLMNOP");
|
119 | }
|