Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions display_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ Context *display_create_port(GlobalContext *global, term opts)
ctx = ili948x_display_create_port(global, opts);
} else if (!strcmp(compat_string, "solomon-systech,ssd1306")) {
ctx = ssd1306_display_create_port(global, opts);
} else if (!strcmp(compat_string, "solomon-systech,ssd1315")) {
ctx = ssd1306_display_create_port(global, opts);
} else if (!strcmp(compat_string, "sino-wealth,sh1106")) {
ctx = ssd1306_display_create_port(global, opts);
} else if (!strcmp(compat_string, "sitronix,st7789")
Expand Down
59 changes: 45 additions & 14 deletions ssd1306_display_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,17 @@
#define CMD_SET_COM_SCAN_MODE 0xC8
#define CMD_SET_CHARGE_PUMP 0x8D

typedef enum {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, move { at new line:

typedef enum
{

See also https://github.com/atomvm/AtomVM/blob/main/C_CODING_STYLE.md#style-rules (AVMCCS-F001 rule).

DISPLAY_SSD1306,
DISPLAY_SSD1315,
DISPLAY_SH1106,
} display_type_t;

// TODO: let's change name, since also non SPI display are supported now
struct SPI
{
term i2c_host;
bool is_sh1106;
display_type_t type;
Context *ctx;
};

Expand Down Expand Up @@ -116,7 +122,7 @@ static void do_update(Context *ctx, term display_list)

i2c_master_write_byte(cmd, CTRL_BYTE_CMD_SINGLE, true);
i2c_master_write_byte(cmd, 0xB0 | ypos / 8, true);
if (spi->is_sh1106) {
if (spi->type == DISPLAY_SH1106) {
// set the column, otherwise the starting column will be somewhere in the middle
i2c_master_write_byte(cmd, CTRL_BYTE_CMD_SINGLE, true);
i2c_master_write_byte(cmd, 0x00, true);
Expand All @@ -126,7 +132,7 @@ static void do_update(Context *ctx, term display_list)
i2c_master_write_byte(cmd, CTRL_BYTE_DATA_STREAM, true);


if (spi->is_sh1106) {
if (spi->type == DISPLAY_SH1106) {
// add 2 empty pages on sh1106 since it can have up to 132 pixels
// and 128 pixel screen starts at (2, 0)
i2c_master_write_byte(cmd, 0, true);
Expand All @@ -137,12 +143,6 @@ static void do_update(Context *ctx, term display_list)
i2c_master_write_byte(cmd, out_buf[j], true);
}

// no need to send the last 2 page, the position will be set on next line again
// if (spi->is_sh1106) {
// i2c_master_write_byte(cmd, 0, true);
// i2c_master_write_byte(cmd, 0, true);
// }

i2c_master_stop(cmd);
i2c_master_cmd_begin(i2c_num, cmd, 10 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
Expand Down Expand Up @@ -180,13 +180,26 @@ static void display_init(Context *ctx, term opts)
term compat_value_term = interop_kv_get_value_default(opts, ATOM_STR("\xA", "compatible"), term_nil(), ctx->global);
int str_ok;
char *compat_string = interop_term_to_string(compat_value_term, &str_ok);
if (str_ok && compat_string) {
spi->is_sh1106 = !strcmp(compat_string, "sino-wealth,sh1106");
free(compat_string);

if (!(str_ok && compat_string)) {
ESP_LOGE(TAG, "Compatible display not found.");
return;
}

if(!strcmp(compat_string, "solomon-systech,ssd1306")) {
spi->type = DISPLAY_SSD1306;
} else if(!strcmp(compat_string, "solomon-systech,ssd1315")) {
spi->type = DISPLAY_SSD1315;
} else if(!strcmp(compat_string, "sino-wealth,sh1106")) {
spi->type = DISPLAY_SH1106;
} else {
ESP_LOGE(TAG, "Unsupported display: %s", compat_string);
free(compat_string);
return;
}

free(compat_string);

int reset_gpio;
if (!display_common_gpio_from_opts(opts, ATOM_STR("\x5", "reset"), &reset_gpio, glb)) {
ESP_LOGI(TAG, "Reset GPIO not configured.");
Expand All @@ -209,8 +222,26 @@ static void display_init(Context *ctx, term opts)
i2c_master_write_byte(cmd, (I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, CTRL_BYTE_CMD_STREAM, true);

i2c_master_write_byte(cmd, CMD_SET_CHARGE_PUMP, true);
i2c_master_write_byte(cmd, 0x14, true);
if(spi->type == DISPLAY_SSD1306) {
i2c_master_write_byte(cmd, CMD_SET_CHARGE_PUMP, true);
i2c_master_write_byte(cmd, 0x14, true);
} else if(spi->type == DISPLAY_SSD1315) {
i2c_master_write_byte(cmd, CMD_SET_CHARGE_PUMP, true);
i2c_master_write_byte(cmd, 0x10, true);

i2c_master_write_byte(cmd, 0xD5, true); // Display clock
i2c_master_write_byte(cmd, 0x80, true);

i2c_master_write_byte(cmd, 0xA8, true); // Multiplex
i2c_master_write_byte(cmd, 0x3F, true);

i2c_master_write_byte(cmd, 0xD9, true); // Pre-charge
i2c_master_write_byte(cmd, 0x22, true);

i2c_master_write_byte(cmd, 0xDB, true); // VCOMH
i2c_master_write_byte(cmd, 0x20, true);
}
// SH1106 Do not need CMD_SET_CHARGE_PUMP setting

i2c_master_write_byte(cmd, CMD_SET_SEGMENT_REMAP, true);
i2c_master_write_byte(cmd, CMD_SET_COM_SCAN_MODE, true);
Expand Down