1
1
/*
2
2
* Copyright (c) 2024 Lukasz Hawrylko
3
+ * Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
3
4
*
4
5
* SPDX-License-Identifier: Apache-2.0
5
6
*/
@@ -26,6 +27,7 @@ LOG_MODULE_REGISTER(ssd1322, CONFIG_DISPLAY_LOG_LEVEL);
26
27
#define SSD1322_SET_DISPLAY_OFFSET 0xA2
27
28
#define SSD1322_BLANKING_ON 0xA4
28
29
#define SSD1322_BLANKING_OFF 0xA6
30
+ #define SSD1322_BLANKING_OFF_INVERSE 0xA7
29
31
#define SSD1322_EXIT_PARTIAL 0xA9
30
32
#define SSD1322_DISPLAY_OFF 0xAE
31
33
#define SSD1322_DISPLAY_ON 0xAF
@@ -38,7 +40,15 @@ LOG_MODULE_REGISTER(ssd1322, CONFIG_DISPLAY_LOG_LEVEL);
38
40
#define SSD1322_SET_VCOMH 0xBE
39
41
#define SSD1322_SET_CONTRAST 0xC1
40
42
#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
42
52
43
53
#define BITS_PER_SEGMENT 4
44
54
#define SEGMENTS_PER_BYTE (8 / BITS_PER_SEGMENT)
@@ -58,7 +68,14 @@ struct ssd1322_config {
58
68
bool remap_nibble ;
59
69
bool remap_com_odd_even_split ;
60
70
bool remap_com_dual ;
71
+ bool greyscale_enhancement ;
72
+ bool color_inversion ;
61
73
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 ;
62
79
uint8_t * conversion_buf ;
63
80
size_t conversion_buf_size ;
64
81
};
@@ -78,7 +95,11 @@ static int ssd1322_blanking_on(const struct device *dev)
78
95
79
96
static int ssd1322_blanking_off (const struct device * dev )
80
97
{
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 );
82
103
}
83
104
84
105
/*
@@ -235,31 +256,34 @@ static int ssd1322_init_device(const struct device *dev)
235
256
}
236
257
k_usleep (100 );
237
258
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
+
238
266
ret = ssd1322_write_command (dev , SSD1322_DISPLAY_OFF , NULL , 0 );
239
267
if (ret < 0 ) {
240
268
return ret ;
241
269
}
242
270
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 );
245
272
if (ret < 0 ) {
246
273
return ret ;
247
274
}
248
275
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 );
251
277
if (ret < 0 ) {
252
278
return ret ;
253
279
}
254
280
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 );
257
282
if (ret < 0 ) {
258
283
return ret ;
259
284
}
260
285
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 );
263
287
if (ret < 0 ) {
264
288
return ret ;
265
289
}
@@ -288,26 +312,23 @@ static int ssd1322_init_device(const struct device *dev)
288
312
return ret ;
289
313
}
290
314
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 );
293
316
if (ret < 0 ) {
294
317
return ret ;
295
318
}
296
319
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 );
299
321
if (ret < 0 ) {
300
322
return ret ;
301
323
}
302
324
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 );
305
327
if (ret < 0 ) {
306
328
return ret ;
307
329
}
308
330
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 );
311
332
if (ret < 0 ) {
312
333
return ret ;
313
334
}
@@ -317,6 +338,14 @@ static int ssd1322_init_device(const struct device *dev)
317
338
return ret ;
318
339
}
319
340
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
+
320
349
ret = ssd1322_blanking_on (dev );
321
350
if (ret < 0 ) {
322
351
return ret ;
@@ -371,13 +400,20 @@ static DEVICE_API(display, ssd1322_driver_api) = {
371
400
.row_offset = DT_PROP(node_id, row_offset), \
372
401
.start_line = DT_PROP(node_id, start_line), \
373
402
.mux_ratio = DT_PROP(node_id, mux_ratio), \
403
+ .greyscale_enhancement = DT_PROP(node_id, greyscale_enhancement), \
374
404
.remap_row_first = DT_PROP(node_id, remap_row_first), \
375
405
.remap_columns = DT_PROP(node_id, remap_columns), \
376
406
.remap_rows = DT_PROP(node_id, remap_rows), \
377
407
.remap_nibble = DT_PROP(node_id, remap_nibble), \
378
408
.remap_com_odd_even_split = DT_PROP(node_id, remap_com_odd_even_split), \
379
409
.remap_com_dual = DT_PROP(node_id, remap_com_dual), \
380
410
.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), \
381
417
.mipi_dev = DEVICE_DT_GET(DT_PARENT(node_id)), \
382
418
.dbi_config = {.mode = MIPI_DBI_MODE_SPI_4WIRE, \
383
419
.config = MIPI_DBI_SPI_CONFIG_DT( \
0 commit comments