Skip to content

Commit 8ba134c

Browse files
kuligakartben
authored andcommitted
drivers: auxdisplay: hd44780: implement busy-flag polling mechanism
HD44780 controller can indicate via busy flag whether it's finished processing current command. This allows for faster completion of HD44780 commands as seen from MCU perspective, as the MCU doesn't have to wait for fixed long period of time. Implement this functionality. Signed-off-by: Jan Kuliga <[email protected]>
1 parent 1b784f9 commit 8ba134c

File tree

1 file changed

+79
-15
lines changed

1 file changed

+79
-15
lines changed

drivers/auxdisplay/auxdisplay_hd44780.c

Lines changed: 79 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,76 @@ static void hd44780_pulse_enable_line(const struct device *dev)
8989
k_sleep(K_NSEC(config->enable_line_fall_delay));
9090
}
9191

92-
static void auxdisplay_hd44780_command(const struct device *dev, bool rs, uint8_t cmd,
93-
uint8_t mode)
92+
static inline void hd44780_set_rs_rw_lines(const struct device *dev, bool rs, bool rw)
93+
{
94+
const struct auxdisplay_hd44780_config *const config = dev->config;
95+
96+
gpio_pin_set_dt(&config->rs_gpio, rs);
97+
if (config->rw_gpio.port) {
98+
gpio_pin_set_dt(&config->rw_gpio, rw);
99+
}
100+
101+
k_sleep(K_NSEC(config->rs_line_delay));
102+
}
103+
104+
static int hd44780_db_gpios_configure(const struct device *dev, uint8_t lsb_line,
105+
gpio_flags_t flags)
94106
{
107+
const struct auxdisplay_hd44780_config *config = dev->config;
108+
int rc;
109+
110+
for (int line = 7; line >= lsb_line; --line) {
111+
rc = gpio_pin_configure_dt(&config->db_gpios[line], flags);
112+
if (rc < 0) {
113+
return rc;
114+
}
115+
}
116+
117+
return 0;
118+
}
119+
120+
static void auxdisplay_hd44780_command(const struct device *dev, bool rs,
121+
uint8_t cmd, uint8_t mode)
122+
{
123+
int rc;
95124
const struct auxdisplay_hd44780_config *config = dev->config;
96125
int8_t i = 7;
97126
const int8_t lsb_line = (mode == AUXDISPLAY_HD44780_MODE_8_BIT) ? 0 : 4;
98127
int8_t ncommands = (mode == AUXDISPLAY_HD44780_MODE_4_BIT) ? 2 : 1;
128+
const bool check_busy_flag = (!config->rw_gpio.port ||
129+
(mode == AUXDISPLAY_HD44780_MODE_4_BIT_ONCE)) ?
130+
false : true;
99131

100-
gpio_pin_set_dt(&config->rs_gpio, rs);
101-
k_sleep(K_NSEC(config->rs_line_delay));
132+
if (check_busy_flag) {
133+
bool busy;
134+
135+
rc = hd44780_db_gpios_configure(dev, lsb_line, GPIO_INPUT | GPIO_PULL_DOWN);
136+
if (rc < 0) {
137+
LOG_ERR("Configuration of db-gpios as inputs failed: %d", rc);
138+
return;
139+
}
140+
141+
hd44780_set_rs_rw_lines(dev, 0, 1);
142+
do {
143+
hd44780_pulse_enable_line(dev);
102144

145+
/* We don't care about the other pins. */
146+
busy = gpio_pin_get_dt(&config->db_gpios[7]);
147+
148+
if (config->capabilities.mode == AUXDISPLAY_HD44780_MODE_4_BIT) {
149+
/* In this mode we have to initiate two separate readbacks. */
150+
hd44780_pulse_enable_line(dev);
151+
}
152+
} while (busy);
153+
154+
rc = hd44780_db_gpios_configure(dev, lsb_line, GPIO_OUTPUT);
155+
if (rc < 0) {
156+
LOG_ERR("Configuration of db-gpios as outputs failed: %d", rc);
157+
return;
158+
}
159+
}
160+
161+
hd44780_set_rs_rw_lines(dev, rs, 0);
103162
while (ncommands--) {
104163
for (int8_t line = 7; line >= lsb_line; --line) {
105164
gpio_pin_set_dt(&config->db_gpios[line], ((cmd & BIT(i)) ? 1 : 0));
@@ -108,6 +167,13 @@ static void auxdisplay_hd44780_command(const struct device *dev, bool rs, uint8_
108167

109168
hd44780_pulse_enable_line(dev);
110169
}
170+
171+
if (!check_busy_flag) {
172+
/* Sleep for a max execution time for a given instruction. */
173+
uint16_t cmd_delay_us = (cmd == AUXDISPLAY_HD44780_CMD_CLEAR) ? 1520 : 37;
174+
175+
k_sleep(K_USEC(cmd_delay_us));
176+
}
111177
}
112178

113179
static void hd44780_ic_initialize(const struct device *dev)
@@ -172,17 +238,6 @@ static int auxdisplay_hd44780_init(const struct device *dev)
172238
return rc;
173239
}
174240

175-
if (config->rw_gpio.port) {
176-
rc = gpio_pin_configure_dt(&config->rw_gpio, GPIO_OUTPUT);
177-
178-
if (rc < 0) {
179-
LOG_ERR("Configuration of RW GPIO failed: %d", rc);
180-
return rc;
181-
}
182-
183-
gpio_pin_set_dt(&config->rw_gpio, 0);
184-
}
185-
186241
rc = gpio_pin_configure_dt(&config->e_gpio, GPIO_OUTPUT);
187242

188243
if (rc < 0) {
@@ -215,6 +270,15 @@ static int auxdisplay_hd44780_init(const struct device *dev)
215270
++i;
216271
}
217272

273+
if (config->rw_gpio.port) {
274+
rc = gpio_pin_configure_dt(&config->rw_gpio, GPIO_OUTPUT);
275+
276+
if (rc < 0) {
277+
LOG_ERR("Configuration of RW GPIO failed: %d", rc);
278+
return rc;
279+
}
280+
}
281+
218282
if (config->backlight_gpio.port) {
219283
rc = gpio_pin_configure_dt(&config->backlight_gpio, GPIO_OUTPUT);
220284

0 commit comments

Comments
 (0)