Tuesday, November 16, 2021

[Technical] SSD1327 OLED Driver on Particle Photon

When trying to use a Particle Photon board to drive a Zio 1.5" monochrome OLED screen using U8G2 as the driver (per Zio's instructions), I hit a few problems.

Hardware

My microcontroller board is a Particle Photon. I had heard a lot about the Particle devices in a maker community I frequent, so I'm trying one out.

https://docs.particle.io/photon/

My screen is a  "Zio Qwiic OLED Display (1.5inch, 128x128)" monochrome OLED screen:

https://www.smart-prototyping.com/Zio-Qwiic-OLED-Display-1_5inch-128x128

(SparkFun resells it, and I acquired it as a SparkFun item through DigiKey. Yay pandemic supply chain logistics!)

Software

Given that the Particle development environment is Arduino-ish, the Zio docs:

https://www.smart-prototyping.com/blog/Zio-Qwiic-1.5in-OLED-Display-Qwiic-Start-Guide

state that I should be using U8G2 as the driver for the SSD1327 IC on it:

https://github.com/olikraus/u8g2

specifically:

U8G2_SSD1327_EA_W128128_1_HW_I2C

Breaking this down:

All-caps class: the C++ wrapper for the C-based U8G2 driver

U8G2: the library itself

SSD1327: the OLED driver IC

EA: I don't know.

W128128: the size of the screen; not sure what the W means

1: one-page-flip operation (u8g2 offers full and partial framebuffer operation)

HW_I2C: use the global Arduino hardware I2C driver, Wire

Web IDE Won't Install U8G2 from the Library

The Particle "Web IDE" is amazing. You get a portable, easy-to-access development environment right in your browser. The trouble with U8G2, as customer support was exceedingly helpful nailing down, is that the Particle cache of U8G2 is a multimegabyte ZIP file that Web IDE just can't handle. You can upload it yourself if you want, but the convenient module installer won't do it.

Particle Workbench won't install on ARM64 VS Code

Due to the nature of my work, most of the machines I do hobby electronics on are ARM64 Windows devices. Unfortunately, Particle Workbench uses the system architecture to select files to run and doesn't (yet?) know how to rely on x64 emulation to do what it needs to. Particle has updated its docs to reflect this fact.

I ended up working around this by setting up a small Azure VM running Windows Server to run the Windows+VS Code+Particle Workbench stack. Since flashing can be done through the Particle cloud, this works well.

(I also eventually buckled down and installed it on my desktop so I could try out the serial logging and debugging functionality. Serial monitoring is great; debugging requires a Particle Debugger board that I don't have.)

Hard Hangs

Any time I attempt to use the U8G2 variant listed in the Zio docs to do anything nontrivial (like write pixels to the device), the Photon would hard-hang (solid status LED, not an SOS).

This did not succumb to various attempts to ascertain or work around the problem:

  • Expanding the constructor into the same operations, then doing them one by one in my own code
  • Moving the constructor into my 'init' loop
  • Getting a Particle Debugger board (they're out of stock pretty much everywhere) 
  • Using Particle's ApplicationWatchdog (can't help with hard hangs)
  • Using U8x8 (the demo app crashes at around 70)

This is actually really, really annoying to debug because you have to do a two-button dance to reboot the Photon into a reflashable state, so I burned a number of hours on various permutations, combinations, tweaks, and attempts.

This is known to the U8G2 maintainer, but they don't have the hardware or time to drill into it:

https://github.com/olikraus/u8g2/issues/468

https://github.com/olikraus/u8g2/issues/895

I don't blame them! This is a massive ecosystem, and you don't need just a Particle board--you also need a Particle Debugger board and confidence the platform isn't brain-damaged.

It showed up on the SparkFun forum too:

https://community.particle.io/t/particle-boron-new-haven-oled-display-issue/48318/21

I quickly came up with a workaround so I could do other system integration work while this problem marinated:

Hackaround: use a different driver with a smaller feature set (I want moar features!)

Eventually I got some time to really dig into the problem. I didn't hit bottom (Particle debugger boards are out of stock pretty much everywhere), but I did try writing my own U8G2 HAL.

U8G2 is a C library. For ease of use with Arduino and other C++ environments, it offers a C++ wrapper. The recommended driver was one of these wrappers. In order to start messing with how U8G2 was talking to the hardware, I read the docs and discovered that using the C version not only allows for finer control of these interactions, but is the best way to port U8G2 to new platforms.

https://github.com/olikraus/u8g2/wiki/u8g2setupc

https://github.com/olikraus/u8g2/wiki/Porting-to-new-MCU-platform

Switching the GPIO+timing HAL function to 'return 0' seemed to help a lot, but as I narrowed down what I changed so I could transfer it from my testbed project to my main project, I found that it was just a matter of using the C setup sequence instead of the C++/Arduino one, still with the Arduino HAL:

u8g2_Setup_ssd1327_i2c_ea_w128128_f(&u8g2, U8G2_R0, u8x8_byte_arduino_hw_i2c, u8x8_gpio_and_delay_arduino);
u8g2_InitDisplay(&u8g2);
u8g2_SetPowerSave(&u8g2, 0);

This produced reliable, repeatable writes to the screen with no hangs! There was one more hurdle, though...

Workaround: switch to C

Missing Lines

The C driver worked alright, but the first and last 16 lines of my display disappeared. This is apparently not uncommon with the board I have; it shows up in the SparkFun forums:

https://forum.sparkfun.com/viewtopic.php?f=63&t=52726&p=218802&hilit=zio+qwiic+oled+display#p214390

What's happening is not a hardware bug or bad (or mis-spec'd, which I was worried about) hardware, it's a driver bug. Like I said at the beginning, I'm not sure what the EA means in the class name means--but switching to the _midas_ or _ws_ driver fixes it for me. At least in my case, the documentation is wrong.

u8g2_Setup_ssd1327_i2c_ws_128x128_f()

 

Happy Hacking!

No comments:

Post a Comment