Skip to content

Commit 8608f09

Browse files
VynDragonhenrikbrixandersen
authored andcommitted
drivers: display: Various fixes and additions to ssd1322
Fixes possible init issue with unlock Add many missing configuration settings Signed-off-by: Camille BAUD <[email protected]>
1 parent 1a23d45 commit 8608f09

File tree

2 files changed

+99
-24
lines changed

2 files changed

+99
-24
lines changed

drivers/display/ssd1322.c

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2024 Lukasz Hawrylko
3+
* Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
34
*
45
* SPDX-License-Identifier: Apache-2.0
56
*/
@@ -26,6 +27,7 @@ LOG_MODULE_REGISTER(ssd1322, CONFIG_DISPLAY_LOG_LEVEL);
2627
#define SSD1322_SET_DISPLAY_OFFSET 0xA2
2728
#define SSD1322_BLANKING_ON 0xA4
2829
#define SSD1322_BLANKING_OFF 0xA6
30+
#define SSD1322_BLANKING_OFF_INVERSE 0xA7
2931
#define SSD1322_EXIT_PARTIAL 0xA9
3032
#define SSD1322_DISPLAY_OFF 0xAE
3133
#define SSD1322_DISPLAY_ON 0xAF
@@ -38,7 +40,15 @@ LOG_MODULE_REGISTER(ssd1322, CONFIG_DISPLAY_LOG_LEVEL);
3840
#define SSD1322_SET_VCOMH 0xBE
3941
#define SSD1322_SET_CONTRAST 0xC1
4042
#define SSD1322_SET_MUX_RATIO 0xCA
41-
#define SSD1322_COMMAND_LOCK 0xFD
43+
44+
#define SSD1322_SET_ENHANCE 0xD1
45+
#define SSD1322_SET_ENHANCE_ENABLE 0x82
46+
#define SSD1322_SET_ENHANCE_DISABLE 0xA2
47+
#define SSD1322_SET_ENHANCE_END 0x20
48+
49+
#define SSD1322_COMMAND_LOCK 0xFD
50+
#define SSD1322_COMMAND_LOCK_UNLOCK 0x12
51+
#define SSD1322_COMMAND_LOCK_LOCK 0x16
4252

4353
#define BITS_PER_SEGMENT 4
4454
#define SEGMENTS_PER_BYTE (8 / BITS_PER_SEGMENT)
@@ -58,7 +68,14 @@ struct ssd1322_config {
5868
bool remap_nibble;
5969
bool remap_com_odd_even_split;
6070
bool remap_com_dual;
71+
bool greyscale_enhancement;
72+
bool color_inversion;
6173
uint8_t segments_per_pixel;
74+
uint8_t oscillator_freq;
75+
uint8_t precharge_voltage;
76+
uint8_t vcomh_voltage;
77+
uint8_t phase_length;
78+
uint8_t precharge_period;
6279
uint8_t *conversion_buf;
6380
size_t conversion_buf_size;
6481
};
@@ -78,7 +95,11 @@ static int ssd1322_blanking_on(const struct device *dev)
7895

7996
static int ssd1322_blanking_off(const struct device *dev)
8097
{
81-
return ssd1322_write_command(dev, SSD1322_BLANKING_OFF, NULL, 0);
98+
const struct ssd1322_config *config = dev->config;
99+
100+
return ssd1322_write_command(
101+
dev, config->color_inversion ? SSD1322_BLANKING_OFF_INVERSE : SSD1322_BLANKING_OFF,
102+
NULL, 0);
82103
}
83104

84105
/*
@@ -235,31 +256,34 @@ static int ssd1322_init_device(const struct device *dev)
235256
}
236257
k_usleep(100);
237258

259+
/* Unlock display */
260+
data[0] = SSD1322_COMMAND_LOCK_UNLOCK;
261+
ret = ssd1322_write_command(dev, SSD1322_COMMAND_LOCK, data, 1);
262+
if (ret < 0) {
263+
return ret;
264+
}
265+
238266
ret = ssd1322_write_command(dev, SSD1322_DISPLAY_OFF, NULL, 0);
239267
if (ret < 0) {
240268
return ret;
241269
}
242270

243-
data[0] = 0x91;
244-
ret = ssd1322_write_command(dev, SSD1322_SET_CLOCK_DIV, data, 1);
271+
ret = ssd1322_write_command(dev, SSD1322_SET_CLOCK_DIV, &config->oscillator_freq, 1);
245272
if (ret < 0) {
246273
return ret;
247274
}
248275

249-
data[0] = config->mux_ratio - 1;
250-
ret = ssd1322_write_command(dev, SSD1322_SET_MUX_RATIO, data, 1);
276+
ret = ssd1322_write_command(dev, SSD1322_SET_MUX_RATIO, &config->mux_ratio, 1);
251277
if (ret < 0) {
252278
return ret;
253279
}
254280

255-
data[0] = config->start_line;
256-
ret = ssd1322_write_command(dev, SSD1322_SET_START_LINE, data, 1);
281+
ret = ssd1322_write_command(dev, SSD1322_SET_START_LINE, &config->start_line, 1);
257282
if (ret < 0) {
258283
return ret;
259284
}
260285

261-
data[0] = config->row_offset;
262-
ret = ssd1322_write_command(dev, SSD1322_SET_DISPLAY_OFFSET, data, 1);
286+
ret = ssd1322_write_command(dev, SSD1322_SET_DISPLAY_OFFSET, &config->row_offset, 1);
263287
if (ret < 0) {
264288
return ret;
265289
}
@@ -288,26 +312,23 @@ static int ssd1322_init_device(const struct device *dev)
288312
return ret;
289313
}
290314

291-
data[0] = 0xE2;
292-
ret = ssd1322_write_command(dev, SSD1322_SET_PHASE_LENGTH, data, 1);
315+
ret = ssd1322_write_command(dev, SSD1322_SET_PHASE_LENGTH, &config->phase_length, 1);
293316
if (ret < 0) {
294317
return ret;
295318
}
296319

297-
data[0] = 0x1F;
298-
ret = ssd1322_write_command(dev, SSD1322_SET_PRECHARGE, data, 1);
320+
ret = ssd1322_write_command(dev, SSD1322_SET_PRECHARGE, &config->precharge_voltage, 1);
299321
if (ret < 0) {
300322
return ret;
301323
}
302324

303-
data[0] = 0x08;
304-
ret = ssd1322_write_command(dev, SSD1322_SET_SECOND_PRECHARGE, data, 1);
325+
ret = ssd1322_write_command(dev, SSD1322_SET_SECOND_PRECHARGE, &config->precharge_period,
326+
1);
305327
if (ret < 0) {
306328
return ret;
307329
}
308330

309-
data[0] = 0x07;
310-
ret = ssd1322_write_command(dev, SSD1322_SET_VCOMH, data, 1);
331+
ret = ssd1322_write_command(dev, SSD1322_SET_VCOMH, &config->vcomh_voltage, 1);
311332
if (ret < 0) {
312333
return ret;
313334
}
@@ -317,6 +338,14 @@ static int ssd1322_init_device(const struct device *dev)
317338
return ret;
318339
}
319340

341+
data[0] = config->greyscale_enhancement ? SSD1322_SET_ENHANCE_ENABLE
342+
: SSD1322_SET_ENHANCE_DISABLE;
343+
data[1] = SSD1322_SET_ENHANCE_END;
344+
ret = ssd1322_write_command(dev, SSD1322_SET_ENHANCE, data, 2);
345+
if (ret < 0) {
346+
return ret;
347+
}
348+
320349
ret = ssd1322_blanking_on(dev);
321350
if (ret < 0) {
322351
return ret;
@@ -371,13 +400,20 @@ static DEVICE_API(display, ssd1322_driver_api) = {
371400
.row_offset = DT_PROP(node_id, row_offset), \
372401
.start_line = DT_PROP(node_id, start_line), \
373402
.mux_ratio = DT_PROP(node_id, mux_ratio), \
403+
.greyscale_enhancement = DT_PROP(node_id, greyscale_enhancement), \
374404
.remap_row_first = DT_PROP(node_id, remap_row_first), \
375405
.remap_columns = DT_PROP(node_id, remap_columns), \
376406
.remap_rows = DT_PROP(node_id, remap_rows), \
377407
.remap_nibble = DT_PROP(node_id, remap_nibble), \
378408
.remap_com_odd_even_split = DT_PROP(node_id, remap_com_odd_even_split), \
379409
.remap_com_dual = DT_PROP(node_id, remap_com_dual), \
380410
.segments_per_pixel = DT_PROP(node_id, segments_per_pixel), \
411+
.oscillator_freq = DT_PROP(node_id, oscillator_freq), \
412+
.precharge_voltage = DT_PROP(node_id, precharge_voltage), \
413+
.vcomh_voltage = DT_PROP(node_id, vcomh_voltage), \
414+
.phase_length = DT_PROP(node_id, phase_length), \
415+
.precharge_period = DT_PROP(node_id, precharge_period), \
416+
.color_inversion = DT_PROP(node_id, inversion_on), \
381417
.mipi_dev = DEVICE_DT_GET(DT_PARENT(node_id)), \
382418
.dbi_config = {.mode = MIPI_DBI_MODE_SPI_4WIRE, \
383419
.config = MIPI_DBI_SPI_CONFIG_DT( \

dts/bindings/display/solomon,ssd1322.yaml

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,39 @@ properties:
1212
column-offset:
1313
type: int
1414
required: true
15-
description: First visible column number.
15+
description: First visible column number. Number used is unintuitive,
16+
try aligning driver display sample to figure it out.
17+
18+
oscillator-freq:
19+
type: int
20+
required: true
21+
description: Front clock divider (3:0) / oscillator frequency (7:4). It can be set to 0x0.
22+
If you get weird scanlines, increase oscillator frequency and play with phase length values,
23+
for example set this to 0x90. Note this increases power consumption. A good starting value
24+
for SSD1322 is 0x91.
25+
26+
precharge-voltage:
27+
type: int
28+
required: true
29+
description: Set precharge voltage, from 0 (0.2 x VCC) to 0x1F (0.6x VCC).
30+
Try highest value then go down.
31+
32+
vcomh-voltage:
33+
type: int
34+
required: true
35+
description: Set COM deselect voltage, from 0 (0.72 x VCC) to 0x7 (0.86 x VCC).
36+
Try highest value then go down.
37+
38+
mux-ratio:
39+
type: int
40+
required: true
41+
description: COM Pin Multiplex ratio from 15-127. Typically height - 1.
42+
43+
phase-length:
44+
type: int
45+
required: true
46+
description: Phase Length for segment charging (7:4) and discharging (3:0).
47+
On SSD1322, 0xE2 is a good start value.
1648

1749
row-offset:
1850
type: int
@@ -28,12 +60,11 @@ properties:
2860
Starting line address of display ram (0-127).
2961
The default corresponds to the reset value of the register.
3062
31-
mux-ratio:
63+
precharge-period:
3264
type: int
33-
default: 128
34-
description: |
35-
COM Pin Multiplex ratio from 16-128.
36-
The default corresponds to the reset value of the register.
65+
default: 8
66+
description: Second precharge period, from 0 (0 dclk) to 0xF (15 dclks).
67+
8 is the reset value.
3768

3869
remap-row-first:
3970
type: boolean
@@ -59,6 +90,14 @@ properties:
5990
type: boolean
6091
description: Dual COM mode.
6192

93+
greyscale-enhancement:
94+
type: boolean
95+
description: Enable greyscale enhancement on some displays, partially undocumented.
96+
97+
inversion-on:
98+
type: boolean
99+
description: Turn on display color inverting
100+
62101
segments-per-pixel:
63102
type: int
64103
default: 1

0 commit comments

Comments
 (0)