Skip to content

Commit d43b4fa

Browse files
committed
drivers: display: st7789v: implement display_set_orientation API
Add support for communicating to 135x240, 240x320, 240x240 displays at 0, 90, 180, and 270 degree orientation. Signed-off-by: Noah Luskey <[email protected]>
1 parent 5c6d096 commit d43b4fa

File tree

1 file changed

+64
-6
lines changed

1 file changed

+64
-6
lines changed

drivers/display/display_st7789v.c

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <zephyr/device.h>
1717
#include <zephyr/drivers/spi.h>
1818
#include <zephyr/drivers/gpio.h>
19+
#include <zephyr/drivers/display.h>
1920
#include <zephyr/pm/device.h>
2021
#include <zephyr/sys/byteorder.h>
2122
#include <zephyr/drivers/display.h>
@@ -52,6 +53,7 @@ struct st7789v_config {
5253
struct st7789v_data {
5354
uint16_t x_offset;
5455
uint16_t y_offset;
56+
enum display_orientation orientation;
5557
};
5658

5759
#ifdef CONFIG_ST7789V_RGB565
@@ -168,7 +170,7 @@ static int st7789v_write(const struct device *dev, const uint16_t x, const uint1
168170

169171
__ASSERT(desc->width <= desc->pitch, "Pitch is smaller then width");
170172
__ASSERT((desc->pitch * ST7789V_PIXEL_SIZE * desc->height) <= desc->buf_size,
171-
"Input buffer to small");
173+
"Input buffer too small");
172174

173175
LOG_DBG("Writing %dx%d (w,h) @ %dx%d (x,y)", desc->width, desc->height, x, y);
174176
st7789v_set_mem_area(dev, x, y, desc->width, desc->height);
@@ -195,6 +197,7 @@ static void st7789v_get_capabilities(const struct device *dev,
195197
struct display_capabilities *capabilities)
196198
{
197199
const struct st7789v_config *config = dev->config;
200+
const struct st7789v_data *data = dev->data;
198201

199202
memset(capabilities, 0, sizeof(struct display_capabilities));
200203
capabilities->x_resolution = config->width;
@@ -207,7 +210,7 @@ static void st7789v_get_capabilities(const struct device *dev,
207210
capabilities->supported_pixel_formats = PIXEL_FORMAT_RGB_888;
208211
capabilities->current_pixel_format = PIXEL_FORMAT_RGB_888;
209212
#endif
210-
capabilities->current_orientation = DISPLAY_ORIENTATION_NORMAL;
213+
capabilities->current_orientation = data->orientation;
211214
}
212215

213216
static int st7789v_set_pixel_format(const struct device *dev,
@@ -227,11 +230,65 @@ static int st7789v_set_pixel_format(const struct device *dev,
227230
static int st7789v_set_orientation(const struct device *dev,
228231
const enum display_orientation orientation)
229232
{
230-
if (orientation == DISPLAY_ORIENTATION_NORMAL) {
231-
return 0;
233+
const struct st7789v_config *config = dev->config;
234+
struct st7789v_data *data = dev->data;
235+
236+
/* only modifying the MY, MX, MV bits, keep existing MDAC config */
237+
uint8_t tx_data = config->mdac & (ST7789V_MADCTL_ML | ST7789V_MADCTL_BGR |
238+
ST7789V_MADCTL_MH_RIGHT_TO_LEFT);
239+
240+
uint16_t x_offset = 0;
241+
uint16_t y_offset = 0;
242+
243+
uint16_t row_offset = 0;
244+
uint16_t col_offset = 0;
245+
246+
if (config->width < 240) {
247+
/* 135x240 display */
248+
row_offset = data->y_offset;
249+
col_offset = data->x_offset;
250+
} else {
251+
/* 240x320 and 240x240 displays */
252+
row_offset = (320 - config->height);
253+
col_offset = (240 - config->width);
232254
}
233-
LOG_ERR("Changing display orientation not implemented");
234-
return -ENOTSUP;
255+
256+
switch (orientation) {
257+
case DISPLAY_ORIENTATION_NORMAL:
258+
tx_data |= ST7789V_MADCTL_MV_NORMAL_MODE;
259+
x_offset = data->x_offset;
260+
y_offset = data->y_offset;
261+
break;
262+
263+
case DISPLAY_ORIENTATION_ROTATED_90:
264+
tx_data |= (ST7789V_MADCTL_MY_BOTTOM_TO_TOP | ST7789V_MADCTL_MV_REVERSE_MODE);
265+
x_offset = row_offset;
266+
y_offset = col_offset;
267+
break;
268+
269+
case DISPLAY_ORIENTATION_ROTATED_180:
270+
tx_data |= (ST7789V_MADCTL_MY_BOTTOM_TO_TOP | ST7789V_MADCTL_MX_RIGHT_TO_LEFT);
271+
x_offset = col_offset;
272+
y_offset = row_offset;
273+
break;
274+
275+
case DISPLAY_ORIENTATION_ROTATED_270:
276+
tx_data |= (ST7789V_MADCTL_MX_RIGHT_TO_LEFT | ST7789V_MADCTL_MV_REVERSE_MODE);
277+
x_offset = data->y_offset;
278+
y_offset = data->x_offset;
279+
break;
280+
281+
default:
282+
LOG_ERR("Error changing display orientation");
283+
return -ENOTSUP;
284+
}
285+
286+
st7789v_set_lcd_margins(dev, x_offset, y_offset);
287+
st7789v_transmit(dev, ST7789V_CMD_MADCTL, &tx_data, 1U);
288+
data->orientation = orientation;
289+
LOG_INF("Changed orientation to: '%d'", data->orientation);
290+
291+
return 0;
235292
}
236293

237294
static void st7789v_lcd_init(const struct device *dev)
@@ -416,6 +473,7 @@ static const struct display_driver_api st7789v_api = {
416473
static struct st7789v_data st7789v_data_##inst = { \
417474
.x_offset = DT_INST_PROP(inst, x_offset), \
418475
.y_offset = DT_INST_PROP(inst, y_offset), \
476+
.orientation = DISPLAY_ORIENTATION_NORMAL, \
419477
}; \
420478
\
421479
PM_DEVICE_DT_INST_DEFINE(inst, st7789v_pm_action); \

0 commit comments

Comments
 (0)