diff options
-rw-r--r-- | CMakeLists.txt | 3 | ||||
-rw-r--r-- | apps/main_clock.c | 27 | ||||
-rw-r--r-- | apps/main_clock.h | 1 | ||||
-rw-r--r-- | buttons.c | 49 | ||||
-rw-r--r-- | buttons.h | 19 | ||||
-rw-r--r-- | pico-watch.c | 8 |
6 files changed, 102 insertions, 5 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b849c3..e9e2c8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,10 @@ add_executable(pico-watch pico-watch.c init.c init.h + buttons.c + buttons.h apps/main_clock.c + apps/main_clock.h ) pico_set_program_name(pico-watch "pico-watch") diff --git a/apps/main_clock.c b/apps/main_clock.c index ec95585..496c696 100644 --- a/apps/main_clock.c +++ b/apps/main_clock.c @@ -5,6 +5,7 @@ #include "../oled/ss_oled.h" #include "main_clock.h" +#include "../buttons.h" // Time as string // Adapted from pico-sdk/scr/common/pico_util/datetime.c @@ -51,15 +52,33 @@ void show_datetime(SSOLED *oled) { } int main_clock_render(SSOLED *oled, char *data, uint data_size) { + oledWriteString(oled, 0,15,0, (char *)"Test clock", FONT_8x8, 0, 1); show_datetime(oled); -// data[1] += 1; // testing -// oledWriteString(oled, 0,0,2, &data[0], FONT_6x8, 0, 1); + oledWriteString(oled, 0,0,0, &data[0], FONT_6x8, 0, 1); + return 0; +} + +// Example of how button inputs could be interpreted. +// Drawing on screen should be done in the render function. +int main_clock_btnpressed(SSOLED *oled, char *data, uint data_size, uint gpio) { + switch (gpio) { + case BUTTON_HOME: // Apps will generally not receive the Home button press + data[0] = 'H'; break; + case BUTTON_SELECT: + data[0] = 'S'; break; + case BUTTON_MODE: + data[0] = 'M'; break; + case BUTTON_DOWN: + data[0] = 'D'; break; + case BUTTON_UP: + data[0] = 'U'; break; + default: + data[0] = '?'; + } return 0; } int main_clock_init(SSOLED *oled, char *data, uint data_size) { -// data[0] = 'a'; // testing, to showcase the use of data -// data[1] = 'b'; return 1; // return 1 when function not implemented } diff --git a/apps/main_clock.h b/apps/main_clock.h index d47e837..a7acdfe 100644 --- a/apps/main_clock.h +++ b/apps/main_clock.h @@ -10,6 +10,7 @@ void show_datetime(SSOLED *oled); int main_clock_init(SSOLED *oled, char *data, uint data_size); int main_clock_render(SSOLED *oled, char *data, uint data_size); +int main_clock_btnpressed(SSOLED *oled, char *data, uint data_size, uint gpio); int main_clock_bgrefresh(SSOLED *oled, char *data, uint data_size); int main_clock_destroy(SSOLED *oled, char *data, uint data_size); diff --git a/buttons.c b/buttons.c new file mode 100644 index 0000000..2e9996b --- /dev/null +++ b/buttons.c @@ -0,0 +1,49 @@ +#include <stdio.h> +#include "pico/stdlib.h" + +#include "buttons.h" +extern int app_btnpressed(int app_id, uint gpio); +extern int current_app; + +// Debounce control +// See https://www.raspberrypi.org/forums/viewtopic.php?f=145&t=301522#p1812063 +// time is currently shared between all buttons. +unsigned long button_time; +const int button_delayTime = 50; // 50ms worked fine for me .... change it to your needs/specs. + +//const uint BUTTON_PINS[] = {BUTTON_HOME, BUTTON_SELECT, BUTTON_MODE, BUTTON_UP, BUTTON_DOWN}; + +void gpio_interrupt_cb(uint gpio, uint32_t events) { + if ((to_ms_since_boot(get_absolute_time())-button_time)>button_delayTime) { + app_btnpressed(current_app, gpio); + button_time = to_ms_since_boot(get_absolute_time()); + } +} + +void init_buttons() { + gpio_init(BUTTON_HOME); + gpio_pull_up(BUTTON_HOME); + gpio_set_irq_enabled_with_callback(BUTTON_HOME, GPIO_IRQ_EDGE_FALL , true, &gpio_interrupt_cb); + gpio_init(BUTTON_SELECT); + gpio_pull_up(BUTTON_SELECT); + gpio_set_irq_enabled_with_callback(BUTTON_SELECT, GPIO_IRQ_EDGE_FALL , true, &gpio_interrupt_cb); + gpio_init(BUTTON_MODE); + gpio_pull_up(BUTTON_MODE); + gpio_set_irq_enabled_with_callback(BUTTON_MODE, GPIO_IRQ_EDGE_FALL , true, &gpio_interrupt_cb); + gpio_init(BUTTON_DOWN); + gpio_pull_up(BUTTON_DOWN); + gpio_set_irq_enabled_with_callback(BUTTON_DOWN, GPIO_IRQ_EDGE_FALL , true, &gpio_interrupt_cb); + gpio_init(BUTTON_UP); + gpio_pull_up(BUTTON_UP); + gpio_set_irq_enabled_with_callback(BUTTON_UP, GPIO_IRQ_EDGE_FALL , true, &gpio_interrupt_cb); + + /* For some reason for loop does not work… TODO + for (int i=0; i == NUMBER_OF_BUTTONS; i++) { + uint button = BUTTON_PINS[i]; + gpio_init(button); + gpio_pull_up(button); + gpio_set_irq_enabled_with_callback(button, GPIO_IRQ_EDGE_FALL , true, &gpio_interrupt_cb); + } + */ + button_time = to_ms_since_boot(get_absolute_time()); +} diff --git a/buttons.h b/buttons.h new file mode 100644 index 0000000..756c849 --- /dev/null +++ b/buttons.h @@ -0,0 +1,19 @@ +#ifndef __BUTTONS_H__ +#define __BUTTONS_H__ +#include <stdio.h> + +// Init buttons used in conjuction with interrupts +// All buttons are connected to ground. +#define NUMBER_OF_BUTTONS 5 +#define BUTTON_HOME 22 +#define BUTTON_SELECT 18 +#define BUTTON_MODE 19 +#define BUTTON_DOWN 20 +#define BUTTON_UP 21 +unsigned long button_time; +const int button_delayTime; + +void init_buttons(); +void gpio_interrupt_cb(uint gpio, uint32_t events); + +#endif
\ No newline at end of file diff --git a/pico-watch.c b/pico-watch.c index a7c3886..eb5f7cc 100644 --- a/pico-watch.c +++ b/pico-watch.c @@ -6,6 +6,7 @@ #include "oled/ss_oled.h" #include "init.h" +#include "buttons.h" #include "apps/main_clock.h" int current_app = 0; @@ -14,6 +15,7 @@ int current_app = 0; #define APP_DATA_BUFFER_LEN 256 int (*APPS_FUNC_INIT[NUMBER_OF_APPS])(SSOLED *oled, char *data, uint data_size) = {main_clock_init}; int (*APPS_FUNC_RENDER[NUMBER_OF_APPS])(SSOLED *oled, char *data, uint data_size) = {main_clock_render}; +int (*APPS_FUNC_BTNPRESS[NUMBER_OF_APPS])(SSOLED *oled, char *data, uint data_size, uint gpio) = {main_clock_btnpressed}; int (*APPS_FUNC_BGREFRESH[NUMBER_OF_APPS])(SSOLED *oled, char *data, uint data_size) = {main_clock_bgrefresh}; int (*APPS_FUNC_DESTROY[NUMBER_OF_APPS])(SSOLED *oled, char *data, uint data_size) = {main_clock_destroy}; char APPS_DATA[NUMBER_OF_APPS][APP_DATA_BUFFER_LEN]; @@ -29,6 +31,10 @@ int app_render(int app_id) { return (*APPS_FUNC_RENDER[app_id])(&oled, &APPS_DATA[app_id][0], sizeof(APPS_DATA[app_id])); } +int app_btnpressed(int app_id, uint gpio) { + return (*APPS_FUNC_BTNPRESS[app_id])(&oled, &APPS_DATA[app_id][0], sizeof(APPS_DATA[app_id]), gpio); +} + int app_destroy(int app_id) { if (APPS_IS_INIT[app_id]) return (*APPS_FUNC_INIT[app_id])(&oled, &APPS_DATA[app_id][0], sizeof(APPS_DATA[app_id])); @@ -36,10 +42,10 @@ int app_destroy(int app_id) { int main() { init_all(); + init_buttons(); app_init(current_app); - oledWriteString(&oled, 0,15,0, (char *)"Test clock", FONT_8x8, 0, 1); while (1) { app_render(current_app); sleep_ms(500); |