Skip to content

Conversation

@Rekkice
Copy link

@Rekkice Rekkice commented Jan 15, 2026

This PR adds supporf for ssd1315 displays. ssd1315 is mostly compatible with ssd1306 drivers, but it has some small differences, such as requiring a special initialization sequence and needing an explicit column address reset when updating.

I also increased the timeout window from 10 to 100, to fix this error i was getting:
E (1225) SSD1306: I2C write failed for display update: 0x107 (a timeout)

The initialization sequence is based on the one used in u8g2.

Tested on an ESP32.

@petermm
Copy link
Contributor

petermm commented Jan 16, 2026

Thank you for the PR.

Lets improve PR title to something like Add sds1315 support

Lets improve PR description to something like:

sds1315 is similar to sds1306, but requires special initialization sequence

see https://github.com/olikraus/u8g2/blob/764ee93150d23779ea9d8a7e8cae73efb60749d4/csrc/u8x8_d_ssd1315_128x64_noname.c#L42 
and/or other link eg. add links/references

Finally it helps if you mentions it's tested on hardware and what specific hardware..

And also squash commits, unless it makes sense to have separate ones.

Buenos tardes y gracias!

Copy link
Collaborator

@bettio bettio left a comment

Choose a reason for hiding this comment

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

I just left 2 minor comments, also I agree with @petermm
Everything else looks good, thanks for the contribution. I'm looking forward merging this PR.

@Rekkice Rekkice changed the title Push mqqzuovmryqw Add support for ssd1315 displays Jan 17, 2026
@Rekkice
Copy link
Author

Rekkice commented Jan 17, 2026

Thanks for the feedback! i accidentally opened the PR earlier than intended, i'm sorry about the lack of details.

I tested the changes with an ESP32 and using the following Elixir program:

defmodule SerialTest do
  @sda_pin 21
  @scl_pin 22

  def start do
    i2c_opts = [
      sda: @sda_pin,
      scl: @scl_pin,
      clock_speed_hz: 100_000,
      peripheral: "i2c0"
    ]

    i2c_host = :i2c.open(i2c_opts)

    display_opts = [
      width: 128,
      height: 64,
      compatible: "solomon-systech,ssd1315",
      i2c_host: i2c_host,
      invert: false
    ]

    display = :erlang.open_port({:spawn, "display"}, display_opts)

    {:ok, _pid} =
      HelloScene.start_link([],
        display_server: {:port, display}
      )

    Process.sleep(:infinity)
  end
end

defmodule HelloScene do
  def start_link(args, opts) do
    :avm_scene.start_link(__MODULE__, args, opts)
  end

  def init(_args) do
    :erlang.send_after(100, self(), :update_display)
    {:ok, %{width: 320, height: 240}}
  end

  def handle_info(:update_display, %{width: width, height: height} = state) do
    items = [
      {:text, 10, 20, :default16px, 0x000000, 0xFFFFFF, "Hello World!"},
      {:rect, 0, 0, width, height, 0xFFFFFF}
    ]

    {:noreply, state, [{:push, items}]}
  end
end
image

I only have a ssd1315 screen to test with, so i'd really appreciate it if someone could check if any of the other screens are affected by the do_update change

#define CHAR_WIDTH 8

#define I2C_ADDRESS 0x3C
#define I2C_CHUNK_SIZE 64
Copy link
Contributor

Choose a reason for hiding this comment

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

I2C_CHUNK_SIZE is not used anywhere, so let's remove line.

Copy link
Contributor

Choose a reason for hiding this comment

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

solved

Copy link
Contributor

@petermm petermm left a comment

Choose a reason for hiding this comment

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

Tested ssd1306 on simulator, as working.. so LGTM besides that stray I2C_CHUNK_SIZE

i2c_master_write_byte(cmd, 0xAD, true); // Internal IREF Setting
i2c_master_write_byte(cmd, 0x10, true); // Internal Iref

i2c_master_write_byte(cmd, 0xAF, true); // Display ON
Copy link
Contributor

@petermm petermm Jan 17, 2026

Choose a reason for hiding this comment

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

this 0xAF is redundant as it's being sent later CMD_DISPLAY_ON for all displays..

Copy link
Contributor

Choose a reason for hiding this comment

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

solved

This PR adds supporf for ssd1315 displays. ssd1315 is mostly compatible with ssd1306 drivers, but it has some small differences, such as requiring a special initialization sequence and needing an explicit column address reset when updating.

I also increased the timeout window from 10 to 100, to fix this error i was getting:
`E (1225) SSD1306: I2C write failed for display update: 0x107` [(a timeout)](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/error-codes.html)

The initialization sequence is based on the one used in [u8g2](https://github.com/olikraus/u8g2/blob/dbd338af5d57b219e48ea1ffdb97c4153668676c/csrc/u8x8_d_ssd1315_128x64_noname.c).

Tested on an ESP32.
@bettio bettio merged commit d15bdb5 into atomvm:main Jan 19, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants