1 /* microbit.c - BBC micro:bit specific hooks */
2 
3 /*
4  * Copyright (c) 2017 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 
10 #include <zephyr/bluetooth/mesh.h>
11 #include <zephyr/display/mb_display.h>
12 #include <zephyr/drivers/gpio.h>
13 #include "board.h"
14 
15 static uint32_t oob_number;
16 static const struct gpio_dt_spec button =
17 	GPIO_DT_SPEC_GET(DT_NODELABEL(buttona), gpios);
18 static const struct mb_image onoff[] = {
19 	MB_IMAGE({ 0, 0, 0, 0, 0 },
20 		 { 0, 0, 0, 0, 0 },
21 		 { 0, 0, 0, 0, 0 },
22 		 { 0, 0, 0, 0, 0 },
23 		 { 0, 0, 0, 0, 0 }),
24 	MB_IMAGE({ 1, 1, 1, 1, 1 },
25 		 { 1, 1, 1, 1, 1 },
26 		 { 1, 1, 1, 1, 1 },
27 		 { 1, 1, 1, 1, 1 },
28 		 { 1, 1, 1, 1, 1 }),
29 };
30 static struct k_work *button_work;
31 
button_pressed(const struct device * dev,struct gpio_callback * cb,uint32_t pins)32 static void button_pressed(const struct device *dev, struct gpio_callback *cb,
33 			   uint32_t pins)
34 {
35 	struct mb_display *disp = mb_display_get();
36 
37 	/*
38 	 * CONFIG_MICROBIT_DISPLAY_STR_MAX needs adjustment if you
39 	 * change this.
40 	 */
41 	mb_display_print(disp, MB_DISPLAY_MODE_DEFAULT, 500, "%04u",
42 			 oob_number);
43 
44 	if (button_work) {
45 		k_work_submit(button_work);
46 	}
47 }
48 
configure_button(void)49 static void configure_button(void)
50 {
51 	static struct gpio_callback button_cb;
52 
53 	gpio_pin_configure_dt(&button, GPIO_INPUT);
54 	gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);
55 
56 	gpio_init_callback(&button_cb, button_pressed, BIT(button.pin));
57 
58 	gpio_add_callback(button.port, &button_cb);
59 }
60 
board_output_number(bt_mesh_output_action_t action,uint32_t number)61 void board_output_number(bt_mesh_output_action_t action, uint32_t number)
62 {
63 	struct mb_display *disp = mb_display_get();
64 	const struct mb_image arrow = MB_IMAGE({ 0, 0, 1, 0, 0 },
65 					       { 0, 1, 0, 0, 0 },
66 					       { 1, 1, 1, 1, 1 },
67 					       { 0, 1, 0, 0, 0 },
68 					       { 0, 0, 1, 0, 0 });
69 
70 	oob_number = number;
71 
72 	gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);
73 
74 	mb_display_image(disp, MB_DISPLAY_MODE_DEFAULT, SYS_FOREVER_MS, &arrow,
75 			 1);
76 }
77 
board_prov_complete(void)78 void board_prov_complete(void)
79 {
80 	struct mb_display *disp = mb_display_get();
81 	const struct mb_image smile = MB_IMAGE({ 0, 1, 0, 1, 0 },
82 					       { 0, 1, 0, 1, 0 },
83 					       { 0, 0, 0, 0, 0 },
84 					       { 1, 0, 0, 0, 1 },
85 					       { 0, 1, 1, 1, 0 });
86 
87 	gpio_pin_interrupt_configure_dt(&button, GPIO_INT_DISABLE);
88 
89 	mb_display_image(disp, MB_DISPLAY_MODE_DEFAULT, 10 * MSEC_PER_SEC,
90 			 &smile, 1);
91 }
92 
board_init(struct k_work * button_work_arg)93 int board_init(struct k_work *button_work_arg)
94 {
95 	struct mb_display *disp = mb_display_get();
96 
97 	mb_display_image(disp, MB_DISPLAY_MODE_DEFAULT | MB_DISPLAY_FLAG_LOOP,
98 			 1 * MSEC_PER_SEC, onoff, ARRAY_SIZE(onoff));
99 
100 	button_work = button_work_arg;
101 
102 	configure_button();
103 
104 	return 0;
105 }
106 
board_led_set(bool val)107 void board_led_set(bool val)
108 {
109 	struct mb_display *disp = mb_display_get();
110 
111 	mb_display_image(disp, MB_DISPLAY_MODE_DEFAULT, SYS_FOREVER_MS,
112 			 &onoff[val], 1);
113 }
114