1 /*
2 * Copyright (c) 2017 Jan Van Winkel <jan.van_winkel@dxplore.eu>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Public API for display drivers and applications
10 */
11
12 #ifndef ZEPHYR_INCLUDE_DRIVERS_DISPLAY_H_
13 #define ZEPHYR_INCLUDE_DRIVERS_DISPLAY_H_
14
15 /**
16 * @brief Display Interface
17 * @defgroup display_interface Display Interface
18 * @since 1.14
19 * @version 0.8.0
20 * @ingroup io_interfaces
21 * @{
22 */
23
24 #include <zephyr/device.h>
25 #include <errno.h>
26 #include <stddef.h>
27 #include <zephyr/types.h>
28 #include <zephyr/dt-bindings/display/panel.h>
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 /**
35 * @brief Display pixel formats
36 *
37 * Display pixel format enumeration.
38 *
39 * In case a pixel format consists out of multiple bytes the byte order is
40 * big endian.
41 */
42 enum display_pixel_format {
43 PIXEL_FORMAT_RGB_888 = BIT(0), /**< 24-bit RGB */
44 PIXEL_FORMAT_MONO01 = BIT(1), /**< Monochrome (0=Black 1=White) */
45 PIXEL_FORMAT_MONO10 = BIT(2), /**< Monochrome (1=Black 0=White) */
46 PIXEL_FORMAT_ARGB_8888 = BIT(3), /**< 32-bit ARGB */
47 PIXEL_FORMAT_RGB_565 = BIT(4), /**< 16-bit RGB */
48 PIXEL_FORMAT_BGR_565 = BIT(5), /**< 16-bit BGR */
49 PIXEL_FORMAT_L_8 = BIT(6), /**< 8-bit Grayscale/Luminance, equivalent to */
50 /**< GRAY, GREY, GRAY8, Y8, R8, etc... */
51 };
52
53 /**
54 * @brief Bits required per pixel for display format
55 *
56 * This macro expands to the number of bits required for a given display
57 * format. It can be used to allocate a framebuffer based on a given
58 * display format type
59 */
60 #define DISPLAY_BITS_PER_PIXEL(fmt) \
61 ((((fmt & PIXEL_FORMAT_RGB_888) >> 0) * 24U) + \
62 (((fmt & PIXEL_FORMAT_MONO01) >> 1) * 1U) + \
63 (((fmt & PIXEL_FORMAT_MONO10) >> 2) * 1U) + \
64 (((fmt & PIXEL_FORMAT_ARGB_8888) >> 3) * 32U) + \
65 (((fmt & PIXEL_FORMAT_RGB_565) >> 4) * 16U) + \
66 (((fmt & PIXEL_FORMAT_BGR_565) >> 5) * 16U) + \
67 (((fmt & PIXEL_FORMAT_L_8) >> 6) * 8U))
68
69 /**
70 * @brief Display screen information
71 */
72 enum display_screen_info {
73 /**
74 * If selected, one octet represents 8 pixels ordered vertically,
75 * otherwise ordered horizontally.
76 */
77 SCREEN_INFO_MONO_VTILED = BIT(0),
78 /**
79 * If selected, the MSB represents the first pixel,
80 * otherwise MSB represents the last pixel.
81 */
82 SCREEN_INFO_MONO_MSB_FIRST = BIT(1),
83 /**
84 * Electrophoretic Display.
85 */
86 SCREEN_INFO_EPD = BIT(2),
87 /**
88 * Screen has two alternating ram buffers
89 */
90 SCREEN_INFO_DOUBLE_BUFFER = BIT(3),
91 /**
92 * Screen has x alignment constrained to width.
93 */
94 SCREEN_INFO_X_ALIGNMENT_WIDTH = BIT(4),
95 };
96
97 /**
98 * @brief Enumeration with possible display orientation
99 */
100 enum display_orientation {
101 DISPLAY_ORIENTATION_NORMAL, /**< No rotation */
102 DISPLAY_ORIENTATION_ROTATED_90, /**< Rotated 90 degrees clockwise */
103 DISPLAY_ORIENTATION_ROTATED_180, /**< Rotated 180 degrees clockwise */
104 DISPLAY_ORIENTATION_ROTATED_270, /**< Rotated 270 degrees clockwise */
105 };
106
107 /** @brief Structure holding display capabilities. */
108 struct display_capabilities {
109 /** Display resolution in the X direction */
110 uint16_t x_resolution;
111 /** Display resolution in the Y direction */
112 uint16_t y_resolution;
113 /** Bitwise or of pixel formats supported by the display */
114 uint32_t supported_pixel_formats;
115 /** Information about display panel */
116 uint32_t screen_info;
117 /** Currently active pixel format for the display */
118 enum display_pixel_format current_pixel_format;
119 /** Current display orientation */
120 enum display_orientation current_orientation;
121 };
122
123 /** @brief Structure to describe display data buffer layout */
124 struct display_buffer_descriptor {
125 /** Data buffer size in bytes */
126 uint32_t buf_size;
127 /** Data buffer row width in pixels */
128 uint16_t width;
129 /** Data buffer column height in pixels */
130 uint16_t height;
131 /** Number of pixels between consecutive rows in the data buffer */
132 uint16_t pitch;
133 /** Indicates that this is not the last write buffer of the frame */
134 bool frame_incomplete;
135 };
136
137 /**
138 * @typedef display_blanking_on_api
139 * @brief Callback API to turn on display blanking
140 * See display_blanking_on() for argument description
141 */
142 typedef int (*display_blanking_on_api)(const struct device *dev);
143
144 /**
145 * @typedef display_blanking_off_api
146 * @brief Callback API to turn off display blanking
147 * See display_blanking_off() for argument description
148 */
149 typedef int (*display_blanking_off_api)(const struct device *dev);
150
151 /**
152 * @typedef display_write_api
153 * @brief Callback API for writing data to the display
154 * See display_write() for argument description
155 */
156 typedef int (*display_write_api)(const struct device *dev, const uint16_t x,
157 const uint16_t y,
158 const struct display_buffer_descriptor *desc,
159 const void *buf);
160
161 /**
162 * @typedef display_read_api
163 * @brief Callback API for reading data from the display
164 * See display_read() for argument description
165 */
166 typedef int (*display_read_api)(const struct device *dev, const uint16_t x,
167 const uint16_t y,
168 const struct display_buffer_descriptor *desc,
169 void *buf);
170
171 /**
172 * @typedef display_clear
173 * @brief Callback API for clearing the screen of the display
174 * See display_clear() for argument description
175 */
176 typedef int (*display_clear_api)(const struct device *dev);
177
178 /**
179 * @typedef display_get_framebuffer_api
180 * @brief Callback API to get framebuffer pointer
181 * See display_get_framebuffer() for argument description
182 */
183 typedef void *(*display_get_framebuffer_api)(const struct device *dev);
184
185 /**
186 * @typedef display_set_brightness_api
187 * @brief Callback API to set display brightness
188 * See display_set_brightness() for argument description
189 */
190 typedef int (*display_set_brightness_api)(const struct device *dev,
191 const uint8_t brightness);
192
193 /**
194 * @typedef display_set_contrast_api
195 * @brief Callback API to set display contrast
196 * See display_set_contrast() for argument description
197 */
198 typedef int (*display_set_contrast_api)(const struct device *dev,
199 const uint8_t contrast);
200
201 /**
202 * @typedef display_get_capabilities_api
203 * @brief Callback API to get display capabilities
204 * See display_get_capabilities() for argument description
205 */
206 typedef void (*display_get_capabilities_api)(const struct device *dev,
207 struct display_capabilities *
208 capabilities);
209
210 /**
211 * @typedef display_set_pixel_format_api
212 * @brief Callback API to set pixel format used by the display
213 * See display_set_pixel_format() for argument description
214 */
215 typedef int (*display_set_pixel_format_api)(const struct device *dev,
216 const enum display_pixel_format
217 pixel_format);
218
219 /**
220 * @typedef display_set_orientation_api
221 * @brief Callback API to set orientation used by the display
222 * See display_set_orientation() for argument description
223 */
224 typedef int (*display_set_orientation_api)(const struct device *dev,
225 const enum display_orientation
226 orientation);
227
228 /**
229 * @brief Display driver API
230 * API which a display driver should expose
231 */
232 __subsystem struct display_driver_api {
233 display_blanking_on_api blanking_on;
234 display_blanking_off_api blanking_off;
235 display_write_api write;
236 display_read_api read;
237 display_clear_api clear;
238 display_get_framebuffer_api get_framebuffer;
239 display_set_brightness_api set_brightness;
240 display_set_contrast_api set_contrast;
241 display_get_capabilities_api get_capabilities;
242 display_set_pixel_format_api set_pixel_format;
243 display_set_orientation_api set_orientation;
244 };
245
246 /**
247 * @brief Write data to display
248 *
249 * @param dev Pointer to device structure
250 * @param x x Coordinate of the upper left corner where to write the buffer
251 * @param y y Coordinate of the upper left corner where to write the buffer
252 * @param desc Pointer to a structure describing the buffer layout
253 * @param buf Pointer to buffer array
254 *
255 * @retval 0 on success else negative errno code.
256 */
display_write(const struct device * dev,const uint16_t x,const uint16_t y,const struct display_buffer_descriptor * desc,const void * buf)257 static inline int display_write(const struct device *dev, const uint16_t x,
258 const uint16_t y,
259 const struct display_buffer_descriptor *desc,
260 const void *buf)
261 {
262 struct display_driver_api *api =
263 (struct display_driver_api *)dev->api;
264
265 return api->write(dev, x, y, desc, buf);
266 }
267
268 /**
269 * @brief Read data from display
270 *
271 * @param dev Pointer to device structure
272 * @param x x Coordinate of the upper left corner where to read from
273 * @param y y Coordinate of the upper left corner where to read from
274 * @param desc Pointer to a structure describing the buffer layout
275 * @param buf Pointer to buffer array
276 *
277 * @retval 0 on success else negative errno code.
278 * @retval -ENOSYS if not implemented.
279 */
display_read(const struct device * dev,const uint16_t x,const uint16_t y,const struct display_buffer_descriptor * desc,void * buf)280 static inline int display_read(const struct device *dev, const uint16_t x,
281 const uint16_t y,
282 const struct display_buffer_descriptor *desc,
283 void *buf)
284 {
285 struct display_driver_api *api =
286 (struct display_driver_api *)dev->api;
287
288 if (api->read == NULL) {
289 return -ENOSYS;
290 }
291
292 return api->read(dev, x, y, desc, buf);
293 }
294
295 /**
296 * @brief Clear the screen of the display device
297 *
298 * @param dev Pointer to device structure
299 *
300 * @retval 0 on success else negative errno code.
301 * @retval -ENOSYS if not implemented.
302 */
display_clear(const struct device * dev)303 static inline int display_clear(const struct device *dev)
304 {
305 struct display_driver_api *api =
306 (struct display_driver_api *)dev->api;
307
308 if (api->clear == NULL) {
309 return -ENOSYS;
310 }
311
312 return api->clear(dev);
313 }
314
315 /**
316 * @brief Get pointer to framebuffer for direct access
317 *
318 * @param dev Pointer to device structure
319 *
320 * @retval Pointer to frame buffer or NULL if direct framebuffer access
321 * is not supported
322 *
323 */
display_get_framebuffer(const struct device * dev)324 static inline void *display_get_framebuffer(const struct device *dev)
325 {
326 struct display_driver_api *api =
327 (struct display_driver_api *)dev->api;
328
329 if (api->get_framebuffer == NULL) {
330 return NULL;
331 }
332
333 return api->get_framebuffer(dev);
334 }
335
336 /**
337 * @brief Turn display blanking on
338 *
339 * This function blanks the complete display.
340 * The content of the frame buffer will be retained while blanking is enabled
341 * and the frame buffer will be accessible for read and write operations.
342 *
343 * In case backlight control is supported by the driver the backlight is
344 * turned off. The backlight configuration is retained and accessible for
345 * configuration.
346 *
347 * In case the driver supports display blanking the initial state of the driver
348 * would be the same as if this function was called.
349 *
350 * @param dev Pointer to device structure
351 *
352 * @retval 0 on success else negative errno code.
353 * @retval -ENOSYS if not implemented.
354 */
display_blanking_on(const struct device * dev)355 static inline int display_blanking_on(const struct device *dev)
356 {
357 struct display_driver_api *api =
358 (struct display_driver_api *)dev->api;
359
360 if (api->blanking_on == NULL) {
361 return -ENOSYS;
362 }
363
364 return api->blanking_on(dev);
365 }
366
367 /**
368 * @brief Turn display blanking off
369 *
370 * Restore the frame buffer content to the display.
371 * In case backlight control is supported by the driver the backlight
372 * configuration is restored.
373 *
374 * @param dev Pointer to device structure
375 *
376 * @retval 0 on success else negative errno code.
377 * @retval -ENOSYS if not implemented.
378 */
display_blanking_off(const struct device * dev)379 static inline int display_blanking_off(const struct device *dev)
380 {
381 struct display_driver_api *api =
382 (struct display_driver_api *)dev->api;
383
384 if (api->blanking_off == NULL) {
385 return -ENOSYS;
386 }
387
388 return api->blanking_off(dev);
389 }
390
391 /**
392 * @brief Set the brightness of the display
393 *
394 * Set the brightness of the display in steps of 1/256, where 255 is full
395 * brightness and 0 is minimal.
396 *
397 * @param dev Pointer to device structure
398 * @param brightness Brightness in steps of 1/256
399 *
400 * @retval 0 on success else negative errno code.
401 * @retval -ENOSYS if not implemented.
402 */
display_set_brightness(const struct device * dev,uint8_t brightness)403 static inline int display_set_brightness(const struct device *dev,
404 uint8_t brightness)
405 {
406 struct display_driver_api *api =
407 (struct display_driver_api *)dev->api;
408
409 if (api->set_brightness == NULL) {
410 return -ENOSYS;
411 }
412
413 return api->set_brightness(dev, brightness);
414 }
415
416 /**
417 * @brief Set the contrast of the display
418 *
419 * Set the contrast of the display in steps of 1/256, where 255 is maximum
420 * difference and 0 is minimal.
421 *
422 * @param dev Pointer to device structure
423 * @param contrast Contrast in steps of 1/256
424 *
425 * @retval 0 on success else negative errno code.
426 * @retval -ENOSYS if not implemented.
427 */
display_set_contrast(const struct device * dev,uint8_t contrast)428 static inline int display_set_contrast(const struct device *dev, uint8_t contrast)
429 {
430 struct display_driver_api *api =
431 (struct display_driver_api *)dev->api;
432
433 if (api->set_contrast == NULL) {
434 return -ENOSYS;
435 }
436
437 return api->set_contrast(dev, contrast);
438 }
439
440 /**
441 * @brief Get display capabilities
442 *
443 * @param dev Pointer to device structure
444 * @param capabilities Pointer to capabilities structure to populate
445 */
display_get_capabilities(const struct device * dev,struct display_capabilities * capabilities)446 static inline void display_get_capabilities(const struct device *dev,
447 struct display_capabilities *
448 capabilities)
449 {
450 struct display_driver_api *api =
451 (struct display_driver_api *)dev->api;
452
453 api->get_capabilities(dev, capabilities);
454 }
455
456 /**
457 * @brief Set pixel format used by the display
458 *
459 * @param dev Pointer to device structure
460 * @param pixel_format Pixel format to be used by display
461 *
462 * @retval 0 on success else negative errno code.
463 * @retval -ENOSYS if not implemented.
464 */
465 static inline int
display_set_pixel_format(const struct device * dev,const enum display_pixel_format pixel_format)466 display_set_pixel_format(const struct device *dev,
467 const enum display_pixel_format pixel_format)
468 {
469 struct display_driver_api *api =
470 (struct display_driver_api *)dev->api;
471
472 if (api->set_pixel_format == NULL) {
473 return -ENOSYS;
474 }
475
476 return api->set_pixel_format(dev, pixel_format);
477 }
478
479 /**
480 * @brief Set display orientation
481 *
482 * @param dev Pointer to device structure
483 * @param orientation Orientation to be used by display
484 *
485 * @retval 0 on success else negative errno code.
486 * @retval -ENOSYS if not implemented.
487 */
display_set_orientation(const struct device * dev,const enum display_orientation orientation)488 static inline int display_set_orientation(const struct device *dev,
489 const enum display_orientation
490 orientation)
491 {
492 struct display_driver_api *api =
493 (struct display_driver_api *)dev->api;
494
495 if (api->set_orientation == NULL) {
496 return -ENOSYS;
497 }
498
499 return api->set_orientation(dev, orientation);
500 }
501
502 #ifdef __cplusplus
503 }
504 #endif
505
506 /**
507 * @}
508 */
509
510 #endif /* ZEPHYR_INCLUDE_DRIVERS_DISPLAY_H_ */
511