@@ -25,59 +25,43 @@ LOG_MODULE_REGISTER(button_handler, CONFIG_MODULE_BUTTON_HANDLER_LOG_LEVEL);
25
25
ZBUS_CHAN_DEFINE (button_chan , struct button_msg , NULL , NULL , ZBUS_OBSERVERS_EMPTY ,
26
26
ZBUS_MSG_INIT (0 ));
27
27
28
- /* How many buttons does the module support. Increase at memory cost */
29
- #define BUTTONS_MAX 5
30
- #define BASE_10 10
28
+ /* Button configuration structure. */
29
+ struct btn_cfg_data {
30
+ const char * name ;
31
+ const struct gpio_dt_spec gpio ;
32
+ void * user_cfg ;
33
+ };
34
+
35
+ struct btn_unit_cfg {
36
+ uint32_t num_buttons ;
37
+ struct btn_cfg_data * buttons ;
38
+ };
39
+
40
+ #define BASE_10 10
31
41
32
42
/* Only allow one button msg at a time, as a mean of debounce */
33
43
K_MSGQ_DEFINE (button_queue , sizeof (struct button_msg ), 1 , 4 );
34
44
35
45
static bool debounce_is_ongoing ;
36
- static struct gpio_callback btn_callback [BUTTONS_MAX ];
37
-
38
- /* clang-format off */
39
- const static struct btn_config btn_cfg [] = {
40
- {
41
- .btn_name = STRINGIFY (BUTTON_VOLUME_DOWN ),
42
- .btn_pin = BUTTON_VOLUME_DOWN ,
43
- .btn_cfg_mask = DT_GPIO_FLAGS (DT_ALIAS (sw0 ), gpios ),
44
- },
45
- {
46
- .btn_name = STRINGIFY (BUTTON_VOLUME_UP ),
47
- .btn_pin = BUTTON_VOLUME_UP ,
48
- .btn_cfg_mask = DT_GPIO_FLAGS (DT_ALIAS (sw1 ), gpios ),
49
- },
50
- {
51
- .btn_name = STRINGIFY (BUTTON_PLAY_PAUSE ),
52
- .btn_pin = BUTTON_PLAY_PAUSE ,
53
- .btn_cfg_mask = DT_GPIO_FLAGS (DT_ALIAS (sw2 ), gpios ),
54
- },
55
- #if defined(CONFIG_BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP )
56
- {
57
- .btn_name = STRINGIFY (BUTTON_4 ),
58
- .btn_pin = BUTTON_4 ,
59
- .btn_cfg_mask = DT_GPIO_FLAGS (DT_ALIAS (sw3 ), gpios ),
60
- },
61
- {
62
- .btn_name = STRINGIFY (BUTTON_5 ),
63
- .btn_pin = BUTTON_5 ,
64
- .btn_cfg_mask = DT_GPIO_FLAGS (DT_ALIAS (sw4 ), gpios ),
65
- }
46
+
47
+ #if DT_NODE_EXISTS (DT_PATH (buttons ))
48
+ #define BUTTON DT_PATH(buttons)
66
49
#else
67
- {
68
- .btn_name = STRINGIFY (BUTTON_4 ),
69
- .btn_pin = BUTTON_4 ,
70
- },
71
- {
72
- .btn_name = STRINGIFY (BUTTON_5 ),
73
- .btn_pin = BUTTON_5 ,
74
- .btn_cfg_mask = DT_GPIO_FLAGS (DT_ALIAS (sw3 ), gpios ),
75
- }
76
- #endif /* CONFIG_BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP */
77
- };
78
- /* clang-format on */
50
+ #pragma error("No buttons node found")
51
+ #endif
52
+
53
+ #define BUTTON_GPIO (button_node_id ) \
54
+ { \
55
+ .name = STRINGIFY(BUTTON_##button_node_id), \
56
+ .gpio = GPIO_DT_SPEC_GET(button_node_id, gpios), \
57
+ },
79
58
80
- static const struct device * gpio_53_dev ;
59
+ static struct btn_cfg_data btn_config_data [] = {DT_FOREACH_CHILD (BUTTON , BUTTON_GPIO )};
60
+
61
+ static const struct btn_unit_cfg btn_config = {.num_buttons = ARRAY_SIZE (btn_config_data ),
62
+ .buttons = btn_config_data };
63
+
64
+ static struct gpio_callback btn_callback [ARRAY_SIZE (btn_config_data )];
81
65
82
66
/**@brief Simple debouncer for buttons
83
67
*
@@ -95,8 +79,8 @@ K_TIMER_DEFINE(button_debounce_timer, on_button_debounce_timeout, NULL);
95
79
*/
96
80
static int pin_to_btn_idx (uint8_t btn_pin , uint32_t * pin_idx )
97
81
{
98
- for (uint8_t i = 0 ; i < ARRAY_SIZE ( btn_cfg ) ; i ++ ) {
99
- if (btn_pin == btn_cfg [i ].btn_pin ) {
82
+ for (uint8_t i = 0 ; i < btn_config . num_buttons ; i ++ ) {
83
+ if (btn_pin == btn_config . buttons [i ].gpio . pin ) {
100
84
* pin_idx = i ;
101
85
return 0 ;
102
86
}
@@ -174,7 +158,7 @@ static void button_isr(const struct device *port, struct gpio_callback *cb, uint
174
158
ERR_CHK (ret );
175
159
176
160
LOG_DBG ("Pushed button idx: %d pin: %d name: %s" , btn_idx , btn_pin ,
177
- btn_cfg [btn_idx ].btn_name );
161
+ btn_config . buttons [btn_idx ].name );
178
162
179
163
msg .button_pin = btn_pin ;
180
164
msg .button_action = BUTTON_PRESS ;
@@ -191,16 +175,22 @@ static void button_isr(const struct device *port, struct gpio_callback *cb, uint
191
175
int button_pressed (gpio_pin_t button_pin , bool * button_pressed )
192
176
{
193
177
int ret ;
178
+ uint32_t btn_idx ;
194
179
195
- if (! device_is_ready ( gpio_53_dev ) ) {
196
- return - ENODEV ;
180
+ if (button_pin == BUTTON_NOT_ASSIGNED || button_pressed == NULL ) {
181
+ return - EINVAL ;
197
182
}
198
183
199
- if (button_pressed == NULL ) {
184
+ ret = pin_to_btn_idx (button_pin , & btn_idx );
185
+ if (ret ) {
186
+ return - EINVAL ;
187
+ }
188
+
189
+ if (!device_is_ready (btn_config .buttons [btn_idx ].gpio .port )) {
200
190
return - EINVAL ;
201
191
}
202
192
203
- ret = gpio_pin_get (gpio_53_dev , button_pin );
193
+ ret = gpio_pin_get (btn_config . buttons [ btn_idx ]. gpio . port , button_pin );
204
194
switch (ret ) {
205
195
case 0 :
206
196
* button_pressed = false;
@@ -219,37 +209,34 @@ int button_handler_init(void)
219
209
{
220
210
int ret ;
221
211
222
- if (ARRAY_SIZE ( btn_cfg ) == 0 ) {
212
+ if (btn_config . num_buttons == 0 ) {
223
213
LOG_WRN ("No buttons assigned" );
224
214
return - EINVAL ;
225
215
}
226
216
227
- gpio_53_dev = DEVICE_DT_GET (DT_NODELABEL (gpio0 ));
228
-
229
- if (!device_is_ready (gpio_53_dev )) {
230
- LOG_ERR ("Device driver not ready." );
231
- return - ENODEV ;
232
- }
233
-
234
- for (uint8_t i = 0 ; i < ARRAY_SIZE (btn_cfg ); i ++ ) {
235
- if (btn_cfg [i ].btn_pin == BUTTON_NOT_ASSIGNED ) {
236
- continue ;
237
- }
238
-
239
- ret = gpio_pin_configure (gpio_53_dev , btn_cfg [i ].btn_pin ,
240
- GPIO_INPUT | btn_cfg [i ].btn_cfg_mask );
241
- if (ret ) {
242
- return ret ;
217
+ for (size_t i = 0 ; i < btn_config .num_buttons ; i ++ ) {
218
+ struct btn_cfg_data * button = & btn_config .buttons [i ];
219
+
220
+ if (device_is_ready (button -> gpio .port )) {
221
+ ret = gpio_pin_configure (button -> gpio .port , button -> gpio .pin ,
222
+ GPIO_INPUT | button -> gpio .dt_flags );
223
+ if (ret ) {
224
+ LOG_ERR ("Cannot configure GPIO (ret %d)" , ret );
225
+ return ret ;
226
+ }
227
+ } else {
228
+ LOG_ERR ("GPIO device not ready" );
229
+ return - ENODEV ;
243
230
}
244
231
245
- gpio_init_callback (& btn_callback [i ], button_isr , BIT (btn_cfg [ i ]. btn_pin ));
232
+ gpio_init_callback (& btn_callback [i ], button_isr , BIT (button -> gpio . pin ));
246
233
247
- ret = gpio_add_callback (gpio_53_dev , & btn_callback [i ]);
234
+ ret = gpio_add_callback (button -> gpio . port , & btn_callback [i ]);
248
235
if (ret ) {
249
236
return ret ;
250
237
}
251
238
252
- ret = gpio_pin_interrupt_configure (gpio_53_dev , btn_cfg [ i ]. btn_pin ,
239
+ ret = gpio_pin_interrupt_configure (button -> gpio . port , button -> gpio . pin ,
253
240
GPIO_INT_EDGE_TO_INACTIVE );
254
241
if (ret ) {
255
242
return ret ;
@@ -265,8 +252,9 @@ static int cmd_print_all_btns(const struct shell *shell, size_t argc, char **arg
265
252
ARG_UNUSED (argc );
266
253
ARG_UNUSED (argv );
267
254
268
- for (uint8_t i = 0 ; i < ARRAY_SIZE (btn_cfg ); i ++ ) {
269
- shell_print (shell , "Id %d: pin: %d %s" , i , btn_cfg [i ].btn_pin , btn_cfg [i ].btn_name );
255
+ for (uint8_t i = 0 ; i < btn_config .num_buttons ; i ++ ) {
256
+ shell_print (shell , "Id %d: pin: %d %s" , i , btn_config .buttons [i ].gpio .pin ,
257
+ btn_config .buttons [i ].name );
270
258
}
271
259
272
260
return 0 ;
@@ -291,21 +279,21 @@ static int cmd_push_btn(const struct shell *shell, size_t argc, char **argv)
291
279
292
280
btn_idx = strtoul (argv [1 ], NULL , BASE_10 );
293
281
294
- if (btn_idx >= ARRAY_SIZE (btn_cfg )) {
282
+ if (btn_idx >= ARRAY_SIZE (btn_config_data )) {
295
283
shell_error (shell , "Selected button ID out of range" );
296
284
return - EINVAL ;
297
285
}
298
286
299
- msg .button_pin = btn_cfg [btn_idx ].btn_pin ;
287
+ msg .button_pin = btn_config . buttons [btn_idx ].gpio . pin ;
300
288
msg .button_action = BUTTON_PRESS ;
301
289
302
290
ret = zbus_chan_pub (& button_chan , & msg , K_NO_WAIT );
303
291
if (ret ) {
304
292
LOG_ERR ("Failed to publish button msg, ret: %d" , ret );
305
293
}
306
294
307
- shell_print (shell , "Pushed button idx: %d pin: %d : %s" , btn_idx , btn_cfg [ btn_idx ]. btn_pin ,
308
- btn_cfg [btn_idx ].btn_name );
295
+ shell_print (shell , "Pushed button idx: %d pin: %d : %s" , btn_idx ,
296
+ btn_config . buttons [btn_idx ].gpio . pin , btn_config . buttons [ btn_idx ]. name );
309
297
310
298
return 0 ;
311
299
}
0 commit comments