Skip to content

Commit b6a253d

Browse files
committed
drivers: display: ili9342c display driver
This driver implement basic functions of ili9342c controller which comes mostly with IPS displays. Signed-off-by: Mohamed ElShahawi <[email protected]>
1 parent 942e4a3 commit b6a253d

File tree

8 files changed

+415
-10
lines changed

8 files changed

+415
-10
lines changed

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@
252252
/drivers/counter/*esp32* @glaubermaroto
253253
/drivers/crypto/*nrf_ecb* @maciekfabia @anangl
254254
/drivers/display/*rm68200* @mmahadevan108
255+
/drivers/display/display_ili9342c.* @extremegtx
255256
/drivers/dac/ @martinjaeger
256257
/drivers/dai/ @juimonen @marcinszkudlinski @abonislawski
257258
/drivers/dai/intel/ @juimonen @marcinszkudlinski @abonislawski

drivers/display/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ zephyr_library_sources_ifdef(CONFIG_UC81XX uc81xx.c)
1010
zephyr_library_sources_ifdef(CONFIG_ILI9XXX display_ili9xxx.c)
1111
zephyr_library_sources_ifdef(CONFIG_ILI9340 display_ili9340.c)
1212
zephyr_library_sources_ifdef(CONFIG_ILI9341 display_ili9341.c)
13+
zephyr_library_sources_ifdef(CONFIG_ILI9342C display_ili9342c.c)
1314
zephyr_library_sources_ifdef(CONFIG_ILI9488 display_ili9488.c)
1415
zephyr_library_sources_ifdef(CONFIG_LS0XX ls0xx.c)
1516
zephyr_library_sources_ifdef(CONFIG_MAX7219 display_max7219.c)

drivers/display/Kconfig.ili9xxx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ config ILI9341
2828
help
2929
Enable driver for ILI9341 display driver.
3030

31+
config ILI9342C
32+
bool "ILI9342C display driver"
33+
default y
34+
depends on DT_HAS_ILITEK_ILI9342C_ENABLED
35+
select SPI
36+
select ILI9XXX
37+
help
38+
Enable driver for ILI9342C display driver.
39+
3140
config ILI9488
3241
bool "ILI9488 display driver"
3342
default y

drivers/display/display_ili9342c.c

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright (c) 2020 Teslabs Engineering S.L.
3+
* Copyright (c) 2021 Krivorot Oleg <[email protected]>
4+
* Copyright (c) 2022 Konstantinos Papadopoulos <[email protected]>
5+
* Copyright (c) 2022 Mohamed ElShahawi <[email protected]>
6+
*
7+
* SPDX-License-Identifier: Apache-2.0
8+
*/
9+
10+
#include "display_ili9342c.h"
11+
#include "display_ili9xxx.h"
12+
13+
#include <zephyr/logging/log.h>
14+
LOG_MODULE_REGISTER(display_ili9342c, CONFIG_DISPLAY_LOG_LEVEL);
15+
16+
int ili9342c_regs_init(const struct device *dev)
17+
{
18+
const struct ili9xxx_config *config = dev->config;
19+
const struct ili9342c_regs *regs = config->regs;
20+
int r;
21+
22+
/* some commands require that SETEXTC be set first before it becomes enabled. */
23+
LOG_HEXDUMP_DBG(regs->setextc, ILI9342C_SETEXTC_LEN, "SETEXTC");
24+
r = ili9xxx_transmit(dev, ILI9342C_SETEXTC, regs->setextc,
25+
ILI9342C_SETEXTC_LEN);
26+
if (r < 0) {
27+
return r;
28+
}
29+
30+
LOG_HEXDUMP_DBG(regs->gamset, ILI9342C_GAMSET_LEN, "GAMSET");
31+
r = ili9xxx_transmit(dev, ILI9342C_GAMSET, regs->gamset,
32+
ILI9342C_GAMSET_LEN);
33+
if (r < 0) {
34+
return r;
35+
}
36+
37+
LOG_HEXDUMP_DBG(regs->ifmode, ILI9342C_IFMODE_LEN, "IFMODE");
38+
r = ili9xxx_transmit(dev, ILI9342C_IFMODE, regs->ifmode,
39+
ILI9342C_IFMODE_LEN);
40+
if (r < 0) {
41+
return r;
42+
}
43+
44+
LOG_HEXDUMP_DBG(regs->frmctr1, ILI9342C_FRMCTR1_LEN, "FRMCTR1");
45+
r = ili9xxx_transmit(dev, ILI9342C_FRMCTR1, regs->frmctr1,
46+
ILI9342C_FRMCTR1_LEN);
47+
if (r < 0) {
48+
return r;
49+
}
50+
51+
LOG_HEXDUMP_DBG(regs->invtr, ILI9342C_INVTR_LEN, "INVTR");
52+
r = ili9xxx_transmit(dev, ILI9342C_INVTR, regs->invtr,
53+
ILI9342C_INVTR_LEN);
54+
if (r < 0) {
55+
return r;
56+
}
57+
58+
LOG_HEXDUMP_DBG(regs->disctrl, ILI9342C_DISCTRL_LEN, "DISCTRL");
59+
r = ili9xxx_transmit(dev, ILI9342C_DISCTRL, regs->disctrl,
60+
ILI9342C_DISCTRL_LEN);
61+
if (r < 0) {
62+
return r;
63+
}
64+
65+
LOG_HEXDUMP_DBG(regs->etmod, ILI9342C_ETMOD_LEN, "ETMOD");
66+
r = ili9xxx_transmit(dev, ILI9342C_ETMOD, regs->etmod,
67+
ILI9342C_ETMOD_LEN);
68+
if (r < 0) {
69+
return r;
70+
}
71+
72+
LOG_HEXDUMP_DBG(regs->pwctrl1, ILI9342C_PWCTRL1_LEN, "PWCTRL1");
73+
r = ili9xxx_transmit(dev, ILI9342C_PWCTRL1, regs->pwctrl1,
74+
ILI9342C_PWCTRL1_LEN);
75+
if (r < 0) {
76+
return r;
77+
}
78+
79+
LOG_HEXDUMP_DBG(regs->pwctrl2, ILI9342C_PWCTRL2_LEN, "PWCTRL2");
80+
r = ili9xxx_transmit(dev, ILI9342C_PWCTRL2, regs->pwctrl2,
81+
ILI9342C_PWCTRL2_LEN);
82+
if (r < 0) {
83+
return r;
84+
}
85+
86+
LOG_HEXDUMP_DBG(regs->pwctrl3, ILI9342C_PWCTRL3_LEN, "PWCTRL3");
87+
r = ili9xxx_transmit(dev, ILI9342C_PWCTRL3, regs->pwctrl3,
88+
ILI9342C_PWCTRL3_LEN);
89+
if (r < 0) {
90+
return r;
91+
}
92+
93+
LOG_HEXDUMP_DBG(regs->vmctrl1, ILI9342C_VMCTRL1_LEN, "VMCTRL1");
94+
r = ili9xxx_transmit(dev, ILI9342C_VMCTRL1, regs->vmctrl1,
95+
ILI9342C_VMCTRL1_LEN);
96+
if (r < 0) {
97+
return r;
98+
}
99+
100+
LOG_HEXDUMP_DBG(regs->pgamctrl, ILI9342C_PGAMCTRL_LEN, "PGAMCTRL");
101+
r = ili9xxx_transmit(dev, ILI9342C_PGAMCTRL, regs->pgamctrl,
102+
ILI9342C_PGAMCTRL_LEN);
103+
if (r < 0) {
104+
return r;
105+
}
106+
107+
LOG_HEXDUMP_DBG(regs->ngamctrl, ILI9342C_NGAMCTRL_LEN, "NGAMCTRL");
108+
r = ili9xxx_transmit(dev, ILI9342C_NGAMCTRL, regs->ngamctrl,
109+
ILI9342C_NGAMCTRL_LEN);
110+
if (r < 0) {
111+
return r;
112+
}
113+
114+
LOG_HEXDUMP_DBG(regs->ifctl, ILI9342C_IFCTL_LEN, "IFCTL");
115+
r = ili9xxx_transmit(dev, ILI9342C_IFCTL, regs->ifctl,
116+
ILI9342C_IFCTL_LEN);
117+
if (r < 0) {
118+
return r;
119+
}
120+
121+
return 0;
122+
}

drivers/display/display_ili9342c.h

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright (c) 2020 Teslabs Engineering S.L.
3+
* Copyright (c) 2021 Krivorot Oleg <[email protected]>
4+
* Copyright (c) 2022 Konstantinos Papadopoulos <[email protected]>
5+
*
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
#ifndef ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ILI9342C_H_
9+
#define ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ILI9342C_H_
10+
11+
#include <zephyr/device.h>
12+
13+
/* Commands/registers. */
14+
#define ILI9342C_GAMSET 0x26
15+
#define ILI9342C_IFMODE 0xB0
16+
#define ILI9342C_FRMCTR1 0xB1
17+
#define ILI9342C_INVTR 0xB4
18+
#define ILI9342C_DISCTRL 0xB6
19+
#define ILI9342C_ETMOD 0xB7
20+
#define ILI9342C_PWCTRL1 0xC0
21+
#define ILI9342C_PWCTRL2 0xC1
22+
#define ILI9342C_PWCTRL3 0xC2
23+
#define ILI9342C_VMCTRL1 0xC5
24+
#define ILI9342C_SETEXTC 0xC8
25+
#define ILI9342C_PGAMCTRL 0xE0
26+
#define ILI9342C_NGAMCTRL 0xE1
27+
#define ILI9342C_IFCTL 0xF6
28+
29+
/* Commands/registers length. */
30+
#define ILI9342C_GAMSET_LEN 1U
31+
#define ILI9342C_IFMODE_LEN 1U
32+
#define ILI9342C_FRMCTR1_LEN 2U
33+
#define ILI9342C_INVTR_LEN 1U
34+
#define ILI9342C_DISCTRL_LEN 4U
35+
#define ILI9342C_ETMOD_LEN 1U
36+
#define ILI9342C_PWCTRL1_LEN 2U
37+
#define ILI9342C_PWCTRL2_LEN 1U
38+
#define ILI9342C_PWCTRL3_LEN 1U
39+
#define ILI9342C_VMCTRL1_LEN 1U
40+
#define ILI9342C_SETEXTC_LEN 3U
41+
#define ILI9342C_PGAMCTRL_LEN 15U
42+
#define ILI9342C_NGAMCTRL_LEN 15U
43+
#define ILI9342C_IFCTL_LEN 3U
44+
45+
/** X resolution (pixels). */
46+
#define ILI9342c_X_RES 320U
47+
/** Y resolution (pixels). */
48+
#define ILI9342c_Y_RES 240U
49+
50+
/** ILI9342C registers to be initialized. */
51+
struct ili9342c_regs {
52+
uint8_t gamset[ILI9342C_GAMSET_LEN];
53+
uint8_t ifmode[ILI9342C_IFMODE_LEN];
54+
uint8_t frmctr1[ILI9342C_FRMCTR1_LEN];
55+
uint8_t invtr[ILI9342C_INVTR_LEN];
56+
uint8_t disctrl[ILI9342C_DISCTRL_LEN];
57+
uint8_t etmod[ILI9342C_ETMOD_LEN];
58+
uint8_t pwctrl1[ILI9342C_PWCTRL1_LEN];
59+
uint8_t pwctrl2[ILI9342C_PWCTRL2_LEN];
60+
uint8_t pwctrl3[ILI9342C_PWCTRL3_LEN];
61+
uint8_t vmctrl1[ILI9342C_VMCTRL1_LEN];
62+
uint8_t setextc[ILI9342C_SETEXTC_LEN];
63+
uint8_t pgamctrl[ILI9342C_PGAMCTRL_LEN];
64+
uint8_t ngamctrl[ILI9342C_NGAMCTRL_LEN];
65+
uint8_t ifctl[ILI9342C_IFCTL_LEN];
66+
};
67+
68+
/* Initializer macro for ILI9342C registers. */
69+
#define ILI9342c_REGS_INIT(n) \
70+
static const struct ili9342c_regs ili9xxx_regs_##n = { \
71+
.gamset = DT_PROP(DT_INST(n, ilitek_ili9342c), gamset), \
72+
.ifmode = DT_PROP(DT_INST(n, ilitek_ili9342c), ifmode), \
73+
.frmctr1 = DT_PROP(DT_INST(n, ilitek_ili9342c), frmctr1), \
74+
.invtr = DT_PROP(DT_INST(n, ilitek_ili9342c), invtr), \
75+
.disctrl = DT_PROP(DT_INST(n, ilitek_ili9342c), disctrl), \
76+
.etmod = DT_PROP(DT_INST(n, ilitek_ili9342c), etmod), \
77+
.pwctrl1 = DT_PROP(DT_INST(n, ilitek_ili9342c), pwctrl1), \
78+
.pwctrl2 = DT_PROP(DT_INST(n, ilitek_ili9342c), pwctrl2), \
79+
.pwctrl3 = DT_PROP(DT_INST(n, ilitek_ili9342c), pwctrl3), \
80+
.vmctrl1 = DT_PROP(DT_INST(n, ilitek_ili9342c), vmctrl1), \
81+
.setextc = {0xFF, 0x93, 0x42}, \
82+
.pgamctrl = DT_PROP(DT_INST(n, ilitek_ili9342c), pgamctrl), \
83+
.ngamctrl = DT_PROP(DT_INST(n, ilitek_ili9342c), ngamctrl), \
84+
.ifctl = DT_PROP(DT_INST(n, ilitek_ili9342c), ifctl), \
85+
};
86+
87+
/**
88+
* @brief Initialize ILI9342C registers with DT values.
89+
*
90+
* @param dev ILI9342C device instance
91+
* @return 0 on success, errno otherwise.
92+
*/
93+
int ili9342c_regs_init(const struct device *dev);
94+
95+
#endif /* ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ILI9342C_H_ */

drivers/display/display_ili9xxx.c

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -244,20 +244,32 @@ ili9xxx_set_pixel_format(const struct device *dev,
244244
static int ili9xxx_set_orientation(const struct device *dev,
245245
const enum display_orientation orientation)
246246
{
247+
const struct ili9xxx_config *config = dev->config;
247248
struct ili9xxx_data *data = dev->data;
248249

249250
int r;
250251
uint8_t tx_data = ILI9XXX_MADCTL_BGR;
251-
252-
if (orientation == DISPLAY_ORIENTATION_NORMAL) {
253-
tx_data |= ILI9XXX_MADCTL_MX;
254-
} else if (orientation == DISPLAY_ORIENTATION_ROTATED_90) {
255-
tx_data |= ILI9XXX_MADCTL_MV;
256-
} else if (orientation == DISPLAY_ORIENTATION_ROTATED_180) {
257-
tx_data |= ILI9XXX_MADCTL_MY;
258-
} else if (orientation == DISPLAY_ORIENTATION_ROTATED_270) {
259-
tx_data |= ILI9XXX_MADCTL_MV | ILI9XXX_MADCTL_MX |
260-
ILI9XXX_MADCTL_MY;
252+
if (config->quirks->cmd_set == CMD_SET_1) {
253+
if (orientation == DISPLAY_ORIENTATION_NORMAL) {
254+
tx_data |= ILI9XXX_MADCTL_MX;
255+
} else if (orientation == DISPLAY_ORIENTATION_ROTATED_90) {
256+
tx_data |= ILI9XXX_MADCTL_MV;
257+
} else if (orientation == DISPLAY_ORIENTATION_ROTATED_180) {
258+
tx_data |= ILI9XXX_MADCTL_MY;
259+
} else if (orientation == DISPLAY_ORIENTATION_ROTATED_270) {
260+
tx_data |= ILI9XXX_MADCTL_MV | ILI9XXX_MADCTL_MX |
261+
ILI9XXX_MADCTL_MY;
262+
}
263+
} else if (config->quirks->cmd_set == CMD_SET_2) {
264+
if (orientation == DISPLAY_ORIENTATION_NORMAL) {
265+
/* Do nothing */
266+
} else if (orientation == DISPLAY_ORIENTATION_ROTATED_90) {
267+
tx_data |= ILI9XXX_MADCTL_MV | ILI9XXX_MADCTL_MY;
268+
} else if (orientation == DISPLAY_ORIENTATION_ROTATED_180) {
269+
tx_data |= ILI9XXX_MADCTL_MY | ILI9XXX_MADCTL_MX;
270+
} else if (orientation == DISPLAY_ORIENTATION_ROTATED_270) {
271+
tx_data |= ILI9XXX_MADCTL_MV | ILI9XXX_MADCTL_MX;
272+
}
261273
}
262274

263275
r = ili9xxx_transmit(dev, ILI9XXX_MADCTL, &tx_data, 1U);
@@ -420,12 +432,37 @@ static const struct display_driver_api ili9xxx_api = {
420432
.set_orientation = ili9xxx_set_orientation,
421433
};
422434

435+
#ifdef CONFIG_ILI9340
436+
static const struct ili9xxx_quirks ili9340_quirks = {
437+
.cmd_set = CMD_SET_1,
438+
};
439+
#endif
440+
441+
#ifdef CONFIG_ILI9341
442+
static const struct ili9xxx_quirks ili9341_quirks = {
443+
.cmd_set = CMD_SET_1,
444+
};
445+
#endif
446+
447+
#ifdef CONFIG_ILI9342C
448+
static const struct ili9xxx_quirks ili9342c_quirks = {
449+
.cmd_set = CMD_SET_2,
450+
};
451+
#endif
452+
453+
#ifdef CONFIG_ILI9488
454+
static const struct ili9xxx_quirks ili9488_quirks = {
455+
.cmd_set = CMD_SET_1,
456+
};
457+
#endif
458+
423459
#define INST_DT_ILI9XXX(n, t) DT_INST(n, ilitek_ili##t)
424460

425461
#define ILI9XXX_INIT(n, t) \
426462
ILI##t##_REGS_INIT(n); \
427463
\
428464
static const struct ili9xxx_config ili9xxx_config_##n = { \
465+
.quirks = &ili##t##_quirks, \
429466
.spi = SPI_DT_SPEC_GET(INST_DT_ILI9XXX(n, t), \
430467
SPI_OP_MODE_MASTER | SPI_WORD_SET(8), \
431468
0), \
@@ -462,6 +499,11 @@ DT_INST_FOREACH_ILI9XXX_STATUS_OKAY(9340);
462499
DT_INST_FOREACH_ILI9XXX_STATUS_OKAY(9341);
463500
#endif
464501

502+
#ifdef CONFIG_ILI9342C
503+
#include "display_ili9342c.h"
504+
DT_INST_FOREACH_ILI9XXX_STATUS_OKAY(9342c);
505+
#endif
506+
465507
#ifdef CONFIG_ILI9488
466508
#include "display_ili9488.h"
467509
DT_INST_FOREACH_ILI9XXX_STATUS_OKAY(9488);

drivers/display/display_ili9xxx.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,18 @@
5454
/** Reset wait time (ms), ref 15.4 of ILI9XXX manual. */
5555
#define ILI9XXX_RESET_WAIT_TIME 5
5656

57+
enum madctl_cmd_set {
58+
CMD_SET_1, /* Default for most of ILI9xxx display controllers */
59+
CMD_SET_2, /* Used by ILI9342c */
60+
};
61+
62+
struct ili9xxx_quirks {
63+
enum madctl_cmd_set cmd_set;
64+
};
65+
5766
struct ili9xxx_config {
67+
const struct ili9xxx_quirks *quirks;
68+
5869
struct spi_dt_spec spi;
5970
struct gpio_dt_spec cmd_data;
6071
struct gpio_dt_spec reset;

0 commit comments

Comments
 (0)