Skip to content

Commit 7f4bb69

Browse files
committed
pbio/sys/hmi_lcd: Move splash screen.
This doesn't belong in the driver. We can draw it with shapes now. We can keep this on while the user program runs. The user can delete it if they want.
1 parent 219c19b commit 7f4bb69

File tree

2 files changed

+63
-94
lines changed

2 files changed

+63
-94
lines changed

lib/pbio/drv/display/display_ev3.c

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -187,71 +187,6 @@ static uint8_t encode_triplet(uint8_t p0, uint8_t p1, uint8_t p2) {
187187
return p0 << 6 | p1 << 3 | p2;
188188
}
189189

190-
/**
191-
* Splash boot logo for Pybricks. This is a 178x128 pixel monochrome image.
192-
* Starts at no color, and toggles to on at every index below.
193-
*
194-
* Revisit: Use standard format, e.g. decompress PNG files from file storage or memory card.
195-
*/
196-
static const uint16_t pbdrv_display_pybricks_logo[] = {
197-
3227, 3359, 3403, 3539, 3580, 3718, 3757, 3897, 3934, 4076, 4111, 4255, 4289, 4433, 4466, 4612,
198-
4644, 4790, 4822, 4968, 5000, 5146, 5178, 5324, 5356, 5502, 5534, 5548, 5666, 5680, 5712, 5725,
199-
5845, 5858, 5890, 5903, 6023, 6036, 6068, 6081, 6201, 6214, 6246, 6259, 6379, 6392, 6424, 6437,
200-
6467, 6474, 6520, 6527, 6557, 6570, 6602, 6615, 6643, 6654, 6696, 6707, 6735, 6748, 6780, 6793,
201-
6820, 6833, 6873, 6886, 6913, 6926, 6958, 6971, 6997, 7012, 7050, 7065, 7091, 7104, 7136, 7149,
202-
7174, 7191, 7227, 7244, 7269, 7282, 7314, 7327, 7352, 7369, 7405, 7422, 7447, 7460, 7492, 7505,
203-
7530, 7548, 7582, 7601, 7625, 7638, 7670, 7683, 7707, 7726, 7760, 7779, 7803, 7816, 7848, 7861,
204-
7885, 7904, 7938, 7957, 7981, 7994, 8026, 8039, 8063, 8082, 8116, 8135, 8159, 8172, 8204, 8217,
205-
8241, 8260, 8294, 8313, 8337, 8350, 8382, 8395, 8419, 8438, 8472, 8491, 8515, 8528, 8560, 8573,
206-
8598, 8615, 8651, 8668, 8693, 8706, 8738, 8751, 8776, 8793, 8829, 8846, 8871, 8884, 8916, 8929,
207-
8955, 8970, 9008, 9023, 9049, 9062, 9094, 9107, 9134, 9148, 9186, 9201, 9227, 9240, 9272, 9285,
208-
9313, 9325, 9366, 9378, 9405, 9418, 9450, 9463, 9492, 9501, 9545, 9554, 9583, 9596, 9628, 9641,
209-
9673, 9676, 9726, 9729, 9761, 9774, 9806, 9819, 9939, 9952, 9984, 9997, 10117, 10130, 10162,
210-
10175, 10295, 10308, 10340, 10353, 10473, 10486, 10518, 10531, 10651, 10664, 10696, 10709,
211-
10829, 10842, 10874, 10887, 11007, 11020, 11052, 11065, 11185, 11198, 11230, 11243, 11363,
212-
11376, 11408, 11421, 11541, 11554, 11586, 11599, 11719, 11732, 11764, 11777, 11802, 11806,
213-
11815, 11819, 11828, 11832, 11841, 11846, 11855, 11859, 11868, 11872, 11897, 11910, 11942,
214-
11955, 11980, 11984, 11993, 11997, 12006, 12010, 12019, 12024, 12033, 12037, 12046, 12050,
215-
12075, 12088, 12120, 12133, 12158, 12162, 12171, 12175, 12184, 12188, 12197, 12202, 12211,
216-
12215, 12224, 12228, 12253, 12266, 12298, 12311, 12336, 12340, 12349, 12353, 12362, 12366,
217-
12375, 12380, 12389, 12393, 12402, 12406, 12431, 12444, 12476, 12489, 12514, 12518, 12527,
218-
12531, 12540, 12544, 12553, 12558, 12567, 12571, 12580, 12584, 12609, 12622, 12654, 12667,
219-
12681, 12774, 12787, 12800, 12832, 12845, 12859, 12952, 12965, 12978, 13010, 13023, 13037,
220-
13130, 13143, 13156, 13188, 13201, 13215, 13308, 13321, 13334, 13366, 13379, 13393, 13486,
221-
13499, 13512, 13544, 13557, 13571, 13664, 13677, 13690, 13722, 13735, 13749, 13842, 13855,
222-
13868, 13900, 13913, 13927, 14020, 14033, 14046, 14078, 14091, 14105, 14198, 14211, 14224,
223-
14256, 14269, 14283, 14376, 14389, 14402, 14434, 14447, 14461, 14554, 14567, 14580, 14612,
224-
14625, 14639, 14732, 14745, 14758, 14790, 14803, 14817, 14910, 14923, 14936, 14968, 14982,
225-
14994, 15088, 15100, 15114, 15146, 15186, 15252, 15292, 15324, 15364, 15430, 15470, 15502,
226-
15542, 15608, 15648, 15680, 15720, 15786, 15826, 15858, 15898, 15964, 16004, 16036, 16075,
227-
16143, 16182, 16215, 16253, 16321, 16359, 16393, 16431, 16499, 16537, 16572, 16608, 16678,
228-
16714, 16751, 16785, 16857, 16891, 16930, 16962, 17036, 17068, 17109, 17139, 17215, 17245,
229-
17289, 17314, 17396, 17421, 22784
230-
};
231-
232-
/**
233-
* Load an image encoded in the format above into the user frame buffer.
234-
*
235-
* @param bitmap Pointer to the bitmap data.
236-
*/
237-
static void pbdrv_display_load_indexed_bitmap(const uint16_t *indexed_bitmap) {
238-
bool set = 0;
239-
uint32_t switch_index = 0;
240-
for (size_t r = 0; r < PBDRV_CONFIG_DISPLAY_NUM_ROWS; r++) {
241-
for (size_t c = 0; c < PBDRV_CONFIG_DISPLAY_NUM_COLS; c++) {
242-
if ((r * PBDRV_CONFIG_DISPLAY_NUM_COLS + c) == indexed_bitmap[switch_index]) {
243-
set = !set;
244-
switch_index++;
245-
}
246-
pbdrv_display_user_frame[r][c] = set ? 3 : 0;
247-
}
248-
// Fill unused columns out of screen.
249-
for (size_t c = PBDRV_CONFIG_DISPLAY_NUM_COLS; c < ST7586S_NUM_COL_TRIPLETS * 3; c++) {
250-
pbdrv_display_user_frame[r][c] = 0;
251-
}
252-
}
253-
}
254-
255190
/**
256191
* Encode the user frame buffer into the display buffer.
257192
*/
@@ -495,14 +430,6 @@ static pbio_error_t pbdrv_display_ev3_process_thread(pbio_os_state_t *state, voi
495430
// Staying in data mode from here.
496431
pbdrv_gpio_out_high(&pin_lcd_a0);
497432

498-
// Briefly show initial splash screen. REVISIT: Move boot animation to sys/hmi.
499-
pbdrv_display_load_indexed_bitmap(pbdrv_display_pybricks_logo);
500-
pbdrv_display_st7586s_encode_user_frame();
501-
pbdrv_display_st7586s_write_data_begin(st7586s_send_buf, sizeof(st7586s_send_buf));
502-
PBIO_OS_AWAIT_UNTIL(state, spi_status == SPI_STATUS_COMPLETE);
503-
pbdrv_gpio_out_high(&pin_lcd_cs);
504-
PBIO_OS_AWAIT_MS(state, &timer, 500);
505-
506433
// Clear display to start with.
507434
memset(&pbdrv_display_user_frame, 0, sizeof(pbdrv_display_user_frame));
508435
pbdrv_display_user_frame_update_requested = true;

lib/pbio/sys/hmi_lcd.c

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,31 +35,71 @@
3535
#define DEBUG_PRINT(...)
3636
#endif
3737

38+
// Scaling factors and functions to simplify drawing the logo.
39+
static float _scale;
40+
static uint32_t _offset_x;
41+
static uint32_t _offset_y;
42+
43+
static uint32_t sx(uint32_t x) {
44+
return x * _scale + _offset_x + 0.5f;
45+
}
46+
47+
static uint32_t sy(uint32_t y) {
48+
return y * _scale + _offset_y + 0.5f;
49+
}
50+
51+
static uint32_t sr(uint32_t r) {
52+
return r * _scale + 0.5f;
53+
}
54+
55+
/**
56+
* Draws the Pybricks logo on the screen.
57+
*
58+
* @param x [in] Horizontal offset from the left.
59+
* @param y [in] Vertical offset from the top.
60+
* @param scale [in] Scale (1.0 is 154 x 84).
61+
*/
62+
static void draw_pybricks_logo(uint32_t x, uint32_t y, float scale) {
63+
_offset_x = x;
64+
_offset_y = y;
65+
_scale = scale;
66+
67+
pbio_image_t *display = pbdrv_display_get_image();
68+
pbio_image_fill(display, 0);
69+
70+
uint8_t v = pbdrv_display_get_max_value();
71+
72+
// Rounded rectangles making up the left and right side of the head.
73+
pbio_image_fill_rounded_rect(display, sx(0), sy(0), sr(42), sr(84), sr(11), v);
74+
pbio_image_fill_rounded_rect(display, sx(112), sy(0), sr(42), sr(84), sr(11), v);
75+
76+
// Forehead, main fill, and jaw.
77+
pbio_image_fill_rect(display, sx(14), sy(0), sr(126), sr(14), v);
78+
pbio_image_fill_rect(display, sx(14), sy(14), sr(126), sr(56), 0);
79+
pbio_image_fill_rect(display, sx(28), sy(56), sr(98), sr(14), v);
80+
81+
// Eyes.
82+
pbio_image_fill_circle(display, sx(49), sy(29), sr(10), v);
83+
pbio_image_fill_circle(display, sx(106), sy(29), sr(10), v);
84+
85+
// Teeth.
86+
for (uint32_t i = 0; i < 6; i++) {
87+
pbio_image_fill_rect(display, sx(40 + 14 * i), sy(51), sr(4), sr(5), v);
88+
}
89+
90+
pbdrv_display_update();
91+
}
92+
3893
static void hmi_lcd_grid_show_pixel(uint8_t row, uint8_t col, bool on) {
3994
pbio_image_t *display = pbdrv_display_get_image();
4095
uint8_t value = on ? pbdrv_display_get_max_value(): 0;
4196
const uint32_t size = PBDRV_CONFIG_DISPLAY_NUM_ROWS / PBSYS_CONFIG_HMI_NUM_SLOTS;
4297
const uint32_t width = size * 4 / 5;
4398
const uint32_t offset = (PBDRV_CONFIG_DISPLAY_NUM_COLS - (PBSYS_CONFIG_HMI_NUM_SLOTS * size)) / 2;
4499
pbio_image_fill_rect(display, col * size + offset, row * size, width, width, value);
45-
pbdrv_display_update();
46-
}
47-
48-
static void hmi_lcd_show_program_slot(void) {
49-
pbio_image_t *display = pbdrv_display_get_image();
50-
pbio_image_fill(display, 0);
51-
52-
for (uint8_t r = 0; r < PBSYS_CONFIG_HMI_NUM_SLOTS; r++) {
53-
for (uint8_t c = 0; c < PBSYS_CONFIG_HMI_NUM_SLOTS; c++) {
54-
bool is_on = r < 3 && c > 0 && c < 4;
55-
is_on |= (r == 4 && c == pbsys_status_get_selected_slot());
56-
hmi_lcd_grid_show_pixel(r, c, is_on);
57-
}
58-
}
59100
}
60101

61102
void pbsys_hmi_init(void) {
62-
63103
}
64104

65105
void pbsys_hmi_deinit(void) {
@@ -72,12 +112,18 @@ static pbio_error_t run_ui(pbio_os_state_t *state, pbio_os_timer_t *timer) {
72112

73113
PBIO_OS_ASYNC_BEGIN(state);
74114

115+
// Centered above 5 code slot indicators.
116+
draw_pybricks_logo(27, 12, 0.8);
117+
75118
for (;;) {
76119

77120
DEBUG_PRINT("Start HMI loop\n");
78121

79-
// Visually indicate current state on supported hubs.
80-
hmi_lcd_show_program_slot();
122+
// Visually indicate current slot.
123+
for (uint8_t c = 0; c < PBSYS_CONFIG_HMI_NUM_SLOTS; c++) {
124+
hmi_lcd_grid_show_pixel(4, c, c == pbsys_status_get_selected_slot());
125+
}
126+
pbdrv_display_update();
81127

82128
// Buttons could be pressed at the end of the user program, so wait for
83129
// a release and then a new press, or until we have to exit early.
@@ -152,10 +198,6 @@ static pbio_error_t run_ui(pbio_os_state_t *state, pbio_os_timer_t *timer) {
152198
pbdrv_button_get_pressed();
153199
}));
154200

155-
// Clear UI from display to start user program.
156-
pbio_image_fill(pbdrv_display_get_image(), 0);
157-
pbdrv_display_update();
158-
159201
// Start light or display animations.
160202
pbio_color_light_start_breathe_animation(pbsys_status_light_main, PBSYS_CONFIG_STATUS_LIGHT_STATE_ANIMATIONS_HUE);
161203

0 commit comments

Comments
 (0)