#include #include #include "driver/gpio.h" #include "driver/i2c.h" #include "esp_err.h" #include "esp_log.h" #include "freertos/task.h" #include "sdkconfig.h" // generated by "make menuconfig" #include "sh1106.h" #include "font8x8_basic.h" //#define SDA_PIN GPIO_NUM_21 //#define SCL_PIN GPIO_NUM_22 #define tag "SH1106" /* bool i2c_master_init() { i2c_config_t i2c_config = { .mode = I2C_MODE_MASTER, .sda_io_num = SDA_PIN, .scl_io_num = SCL_PIN, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE, .master.clk_speed = 1000000 }; i2c_param_config(I2C_NUM_0, &i2c_config); i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0); return true; } */ void sh1106_set_display_start_line(i2c_cmd_handle_t cmd, uint_fast8_t start_line) { // REQUIRES: // 0 <= start_line <= 63 if (start_line <= 63) { i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_START_LINE | start_line, true); } } esp_err_t sh1106_init() { esp_err_t espRc; i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); i2c_master_write_byte(cmd, OLED_CMD_SET_CHARGE_PUMP_CTRL, true); i2c_master_write_byte(cmd, OLED_CMD_SET_CHARGE_PUMP_ON, true); i2c_master_write_byte(cmd, OLED_CMD_SET_SEGMENT_REMAP_INVERSE, true); // reverse left-right mapping i2c_master_write_byte(cmd, OLED_CMD_SET_COM_SCAN_MODE_REVERSE, true); // reverse up-bottom mapping i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_ON, true); i2c_master_write_byte(cmd, 0x00, true); // reset column low bits i2c_master_write_byte(cmd, 0x10, true); // reset column high bits i2c_master_write_byte(cmd, 0xB0, true); // reset page i2c_master_write_byte(cmd, 0x40, true); // set start line i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_OFFSET, true); i2c_master_write_byte(cmd, 0x00, true); i2c_master_stop(cmd); espRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); if (espRc == ESP_OK) { ESP_LOGI(tag, "OLED configured successfully"); } else { ESP_LOGE(tag, "OLED configuration failed. code: 0x%.2X", espRc); } i2c_cmd_link_delete(cmd); return espRc; } void task_sh1106_display_clear(void *ignore) { i2c_cmd_handle_t cmd; uint8_t S[132] = { 0 }; for (uint8_t i = 0; i < 8; i++) { cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_SINGLE, true); i2c_master_write_byte(cmd, 0xB0 | i, true); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true); i2c_master_write(cmd, S, 132, true); i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); } cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); i2c_master_write_byte(cmd, 0x00, true); // reset column i2c_master_write_byte(cmd, 0x10, true); i2c_master_write_byte(cmd, 0xB0, true); // reset page i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); } void task_sh1106_contrast(void *ignore) { i2c_cmd_handle_t cmd; uint8_t contrast = 0; uint8_t direction = 1; while (true) { cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); i2c_master_write_byte(cmd, OLED_CMD_SET_CONTRAST, true); i2c_master_write_byte(cmd, contrast, true); i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); vTaskDelay(1 / portTICK_PERIOD_MS); contrast += direction; if (contrast == 0xFF) { direction = -1; } if (contrast == 0x0) { direction = 1; } } vTaskDelete(NULL); } void task_sh1106_write_string(const void *arg_text, uint8_t strpos) { uint8_t S[132] = { 0 }; unsigned char *text = (unsigned char*) arg_text; uint8_t text_len = strlen((const char*)text); if (text_len > 22) return; for (uint8_t i = 0; i < text_len; i++) { memcpy(&S[i*6], font6x8[(uint8_t)*(text + i)], 6); } i2c_cmd_handle_t cmd; cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); i2c_master_write_byte(cmd, 0x01, true); // reset column i2c_master_write_byte(cmd, 0x10, true); i2c_master_write_byte(cmd, 0xB0 | strpos, true); // reset page i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true); i2c_master_write(cmd, S, 132, true); i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); }