#include "ssd1366.h" #include "font8x8_basic.h" #include #include "driver/gpio.h" #define SSD1366_SDA_PIN GPIO_NUM_4 #define SSD1366_SCL_PIN GPIO_NUM_15 #define SSD1366_RST_PIN GPIO_NUM_16 #define SSD1366_VEXT_PIN GPIO_NUM_21 #define I2C_NUM I2C_NUM_0 //#define I2C_NUM I2C_NUM #define I2C_MASTER_FREQ_HZ 400000U /*!< I2C clock of SSD1306 can run at 400 kHz max. */ #define tag "SSD1306" void i2c_master_init() { i2c_config_t i2c_config; i2c_config.mode = I2C_MODE_MASTER; i2c_config.sda_io_num = SSD1366_SDA_PIN; i2c_config.scl_io_num = SSD1366_SCL_PIN; i2c_config.sda_pullup_en = GPIO_PULLUP_ENABLE; i2c_config.scl_pullup_en = GPIO_PULLUP_ENABLE; i2c_config.master.clk_speed = I2C_MASTER_FREQ_HZ; ESP_ERROR_CHECK(i2c_param_config(I2C_NUM, &i2c_config)); ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM, I2C_MODE_MASTER, 0, 0, 0)); } void ssd1306_init() { esp_err_t espRc; gpio_set_direction(SSD1366_RST_PIN, GPIO_MODE_OUTPUT); gpio_set_direction(SSD1366_VEXT_PIN, GPIO_MODE_OUTPUT); gpio_set_level(SSD1366_VEXT_PIN, 0); //enable power to oled gpio_set_level(SSD1366_RST_PIN, 0); vTaskDelay(50 / portTICK_PERIOD_MS); gpio_set_level(SSD1366_RST_PIN, 1); 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_DISPLAY_OFF, true); // AE i2c_master_write_byte(cmd, OLED_CMD_SET_MUX_RATIO, true); // A8 i2c_master_write_byte(cmd, 0x3F, true); i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_OFFSET, true); // D3 i2c_master_write_byte(cmd, 0x00, true); i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_START_LINE, true); // 40 i2c_master_write_byte(cmd, OLED_CMD_SET_SEGMENT_REMAP, true); // reverse left-right mapping i2c_master_write_byte(cmd, OLED_CMD_SET_COM_SCAN_MODE, true); // reverse up-bottom mapping i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_CLK_DIV, true); // D5 i2c_master_write_byte(cmd, 0x80, true); i2c_master_write_byte(cmd, OLED_CMD_SET_COM_PIN_MAP, true); // DA i2c_master_write_byte(cmd, 0x12, true); i2c_master_write_byte(cmd, OLED_CMD_SET_CONTRAST, true); // 81 i2c_master_write_byte(cmd, 0xFF, true); i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_RAM, true); // A4 i2c_master_write_byte(cmd, OLED_CMD_SET_VCOMH_DESELCT, true); // DB i2c_master_write_byte(cmd, 0x40, true); i2c_master_write_byte(cmd, OLED_CMD_SET_MEMORY_ADDR_MODE, true); // 20 //i2c_master_write_byte(cmd, OLED_CMD_SET_HORI_ADDR_MODE, true); // 00 i2c_master_write_byte(cmd, OLED_CMD_SET_PAGE_ADDR_MODE, true); // 02 // Set Lower Column Start Address for Page Addressing Mode i2c_master_write_byte(cmd, 0x00, true); // Set Higher Column Start Address for Page Addressing Mode i2c_master_write_byte(cmd, 0x10, true); i2c_master_write_byte(cmd, OLED_CMD_SET_CHARGE_PUMP, true); // 8D i2c_master_write_byte(cmd, 0x14, true); i2c_master_write_byte(cmd, OLED_CMD_DEACTIVE_SCROLL, true); // 2E i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_NORMAL, true); // A6 i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_ON, true); i2c_master_stop(cmd); espRc = i2c_master_cmd_begin(I2C_NUM, 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); } void i2c_contrast( int contrast) { i2c_cmd_handle_t cmd; int _contrast = contrast; if (contrast < 0x0) _contrast = 0; if (contrast > 0xFF) _contrast = 0xFF; 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); // 81 i2c_master_write_byte(cmd, _contrast, true); i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); } void ssd1306_display_clear(void) { i2c_cmd_handle_t cmd; uint8_t zero[128] = {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); // Set GDDRAM page start address i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true); i2c_master_write(cmd, zero, 128, true); i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); } } void ssd1306_display_text(char* text, uint16_t text_len) { i2c_cmd_handle_t cmd; uint8_t cur_page = 0; 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, 0x00, true); // reset column i2c_master_write_byte(cmd, 0x10, true); i2c_master_write_byte(cmd, 0xB0 | cur_page, true); // reset page i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); for (uint8_t i = 0; i < text_len; i++) { if (text[i] == '\n') { 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, 0x00, true); // reset column i2c_master_write_byte(cmd, 0x10, true); i2c_master_write_byte(cmd, 0xB0 | ++cur_page, true); // increment page i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); } else { 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, font8x8_basic_tr[(uint8_t)text[i]], 8, true); i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); } } } void task_ssd1306_display_text(void *pvParameters) { char *pcTaskName; pcTaskName = (char *) pvParameters; //char text[13] = "Hello world!"; //uint8_t text_len = strlen(text); ssd1306_display_text(pcTaskName, strlen(pcTaskName)); vTaskDelete(NULL); }