WebguiappTemplate/components/Display/sh1106/sh1106.c

181 lines
5.5 KiB
C

#include <stdio.h>
#include <string.h>
#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);
}