1 /** @file
2  *  @brief BBC micro:bit display APIs.
3  */
4 
5 /*
6  * Copyright (c) 2017 Intel Corporation
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 #ifndef ZEPHYR_INCLUDE_DISPLAY_MB_DISPLAY_H_
12 #define ZEPHYR_INCLUDE_DISPLAY_MB_DISPLAY_H_
13 
14 /**
15  * @brief BBC micro:bit display APIs
16  * @defgroup mb_display BBC micro:bit display APIs
17  * @ingroup third_party
18  * @{
19  */
20 
21 #include <stdio.h>
22 #include <zephyr/types.h>
23 #include <stdbool.h>
24 #include <zephyr/sys/util.h>
25 #include <zephyr/toolchain.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /**
32  * @brief Representation of a BBC micro:bit display image.
33  *
34  * This struct should normally not be used directly, rather created
35  * using the MB_IMAGE() macro.
36  */
37 struct mb_image {
38 	union {
39 		struct {
40 			uint8_t c1:1,
41 				c2:1,
42 				c3:1,
43 				c4:1,
44 				c5:1;
45 		} r[5];
46 		uint8_t row[5];
47 	};
48 };
49 
50 /**
51  * @brief Display mode.
52  *
53  * First 16 bits are reserved for modes, last 16 for flags.
54  */
55 enum mb_display_mode {
56 	/** Default mode ("single" for images, "scroll" for text). */
57 	MB_DISPLAY_MODE_DEFAULT,
58 
59 	/** Display images sequentially, one at a time. */
60 	MB_DISPLAY_MODE_SINGLE,
61 
62 	/** Display images by scrolling. */
63 	MB_DISPLAY_MODE_SCROLL,
64 
65 	/* Display flags, i.e. modifiers to the chosen mode */
66 
67 	/** Loop back to the beginning when reaching the last image. */
68 	MB_DISPLAY_FLAG_LOOP        = BIT(16),
69 };
70 
71 /**
72  *
73  * @brief Generate an image object from a given array rows/columns.
74  *
75  * This helper takes an array of 5 rows, each consisting of 5 0/1 values which
76  * correspond to the columns of that row. The value 0 means the pixel is
77  * disabled whereas a 1 means the pixel is enabled.
78  *
79  * The pixels go from left to right and top to bottom, i.e. top-left corner
80  * is the first row's first value, top-right is the first rows last value,
81  * and bottom-right corner is the last value of the last (5th) row. As an
82  * example, the following would create a smiley face image:
83  *
84  * <pre>
85  * static const struct mb_image smiley = MB_IMAGE({ 0, 1, 0, 1, 0 },
86  *						  { 0, 1, 0, 1, 0 },
87  *						  { 0, 0, 0, 0, 0 },
88  *						  { 1, 0, 0, 0, 1 },
89  *						  { 0, 1, 1, 1, 0 });
90  * </pre>
91  *
92  * @param _rows Each of the 5 rows represented as a 5-value column array.
93  *
94  * @return Image bitmap that can be passed e.g. to mb_display_image().
95  */
96 #define MB_IMAGE(_rows...) { .r = { _rows } }
97 
98 /**
99  * @brief Opaque struct representing the BBC micro:bit display.
100  *
101  * For more information see the following links:
102  *
103  * https://www.microbit.co.uk/device/screen
104  *
105  * https://lancaster-university.github.io/microbit-docs/ubit/display/
106  */
107 struct mb_display;
108 
109 /**
110  * @brief Get a pointer to the BBC micro:bit display object.
111  *
112  * @return Pointer to display object.
113  */
114 struct mb_display *mb_display_get(void);
115 
116 /**
117  * @brief Display one or more images on the BBC micro:bit LED display.
118  *
119  * This function takes an array of one or more images and renders them
120  * sequentially on the micro:bit display. The call is asynchronous, i.e.
121  * the processing of the display happens in the background. If there is
122  * another image being displayed it will be canceled and the new one takes
123  * over.
124  *
125  * @param disp      Display object.
126  * @param mode      One of the MB_DISPLAY_MODE_* options.
127  * @param duration  Duration how long to show each image (in milliseconds), or
128  *                  @ref SYS_FOREVER_MS.
129  * @param img       Array of image bitmaps (struct mb_image objects).
130  * @param img_count Number of images in 'img' array.
131  */
132 void mb_display_image(struct mb_display *disp, uint32_t mode, int32_t duration,
133 		      const struct mb_image *img, uint8_t img_count);
134 
135 /**
136  * @brief Print a string of characters on the BBC micro:bit LED display.
137  *
138  * This function takes a printf-style format string and outputs it in a
139  * scrolling fashion to the display.
140  *
141  * The call is asynchronous, i.e. the processing of the display happens in
142  * the background. If there is another image or string being displayed it
143  * will be canceled and the new one takes over.
144  *
145  * @param disp     Display object.
146  * @param mode     One of the MB_DISPLAY_MODE_* options.
147  * @param duration Duration how long to show each character (in milliseconds),
148  *                 or @ref SYS_FOREVER_MS.
149  * @param fmt      printf-style format string
150  * @param ...      Optional list of format arguments.
151  */
152 __printf_like(4, 5) void mb_display_print(struct mb_display *disp,
153 					  uint32_t mode, int32_t duration,
154 					  const char *fmt, ...);
155 
156 /**
157  * @brief Stop the ongoing display of an image.
158  *
159  * @param disp    Display object.
160  */
161 void mb_display_stop(struct mb_display *disp);
162 
163 #ifdef __cplusplus
164 }
165 #endif
166 
167 /**
168  * @}
169  */
170 
171 #endif /* ZEPHYR_INCLUDE_DISPLAY_MB_DISPLAY_H_ */
172