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 {
5253struct 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
213216static int st7789v_set_pixel_format (const struct device * dev ,
@@ -227,11 +230,65 @@ static int st7789v_set_pixel_format(const struct device *dev,
227230static 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
237294static 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