Adafruit-GFX-Library
Adafruit-GFX-Library copied to clipboard
Add oled_commandAndArglist() method
Hi Limor, & Adafruit pals.
I recently bought a sample of a 256x64 OLED panel based on the SSD1322 controller from a supplier. I wanted to use the panel in its grayscale mode, so I adapted Limor's SSD1327 driver on a fresh fork.
A difference between the SSD1327 controller and the SSD1322 controller is how the SSD1322 receives commands vs. data. The SSD1327 D/C# pin is always logically false ("command") when commands and arguments are sent. The SSD1322, on the other hand, requires arguments to be sent as ("data") with the D/C# pin high.
Description of changes
The oled_commandList() method does not control the D/C# pin for the SSD1327 controller, so a new method oled_commandAndArglist() has been added. The method asserts D/C# low for each command byte, and high for each argument byte.
It works like this:
static const uint8_t init_256x64[] {
2, 0xfd, 0x12, /* unlock */
1, 0xae, /* display off */
2, 0xb3, 0x91, /* set display clock divide ratio/oscillator frequency (set clock as 80 frames/sec) */
2, 0xca, 0x3f, /* multiplex ratio 1/64 Duty (0x0F~0x3F) */
2, 0xa2, 0x00, /* display offset, shift mapping ram counter */
2, 0xa1, 0x00, /* display start line */
3, 0xa0, 0x06, 0x11, /* Set Re-Map / Dual COM Line Mode */
2, 0xab, 0x01, /* Enable Internal VDD Regulator */
3, 0xb4, 0xa0, 0x05|0xfd, /* Display Enhancement A */
2, 0xc1, 0x9f, /* contrast */
2, 0xc7, 0x0f, /* Set Scale Factor of Segment Output Current Control */
1, 0xb9, /* linear grayscale */
2, 0xb1, 0xe2, /* Phase 1 (Reset) & Phase 2 (Pre-Charge) Period Adjustment */
3, 0xd1, 0x82|0x20, 0x20, /* Display Enhancement B */
2, 0xbb, 0x1f, /* precharge voltage */
2, 0xb6, 0x08, /* precharge period */
2, 0xbe, 0x07, /* vcomh */
1, 0xa6, /* normal display */
1, 0xa9 /* exit partial display */
};
if (!oled_commandAndArgsList(init_256x64, sizeof(init_256x64))) {
return false;
}
See also, full implementation for SSD1322.
Limitations
This introduces two means of specifying list of display commands to the Adafruit_GrayOLED class. I don't love the duplication or how each method implicitly handles the D/C# pin. A better approach might be to modify oled_commandList() to use a similarly specified list of command and args as my oled_commandAndArglist() method and add a bool argument argAsData to define whether or not D/C# is asserted when sending command arguments. For example:
static const uint8_t init_256x64[] {
2, 0xfd, 0x12, /* unlock */
/* ... * /
3, 0xb4, 0xa0, 0x05|0xfd, /* Display Enhancement A */
2, 0xc1, 0x9f, /* contrast */
/* ... * /
1, 0xa9 /* exit partial display */
};
if (!oled_commandList(init_256x64, sizeof(init_256x64), /* argAsData */ true)) {
return false;
}
I didn't want to introduce this change to your interface as a few downstream drivers depend on it. If you prefer it, I'd be happy to give PRs against the existing Adafruit drivers that rely on Adafruit_GrayOLED::oled_commandList(). If you want to go that route, just let me know in the comments here and we can coordinate.
ok to clarify you just need to have the D/C pin inverted right? can you have an optional argument to the existing library function for the DC polarity then?