diff options
author | ConfuSomu | 2021-02-27 13:29:37 -0500 |
---|---|---|
committer | ConfuSomu | 2021-02-27 13:29:37 -0500 |
commit | 2a0571ba87183023b1073af1badb5fb91da763cf (patch) | |
tree | b73cd5d8d810e398c614611ecd7b602d10d7b58d | |
parent | 06d5f492eca8e57bc8ce7479ec6149fbc6a15d08 (diff) | |
download | pico-watch-2a0571ba87183023b1073af1badb5fb91da763cf.tar pico-watch-2a0571ba87183023b1073af1badb5fb91da763cf.tar.gz pico-watch-2a0571ba87183023b1073af1badb5fb91da763cf.zip |
Use an Api class for abstraction
It is currently very basic as functions will be added to it when the time
comes. The idea is to have a method to, for example, show notifications
(and store them in a list with metadata) to the user or also to easily
show a message box overlaying the current display.
Private class members will permit encapsulations of variables related
to these features and limit the privilage that each app has on the
device.
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | api.cpp | 28 | ||||
-rw-r--r-- | api.hpp | 18 | ||||
-rw-r--r-- | apps/home_menu.cpp | 23 | ||||
-rw-r--r-- | apps/home_menu.hpp | 12 | ||||
-rw-r--r-- | apps/main_clock.cpp | 23 | ||||
-rw-r--r-- | apps/main_clock.hpp | 12 | ||||
-rw-r--r-- | init.cpp | 10 | ||||
-rw-r--r-- | init.hpp | 3 | ||||
-rw-r--r-- | pico-watch.cpp | 25 |
10 files changed, 100 insertions, 56 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 758ac2d..5ba1f5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,8 @@ add_executable(pico-watch init.hpp buttons.cpp buttons.hpp + api.cpp + api.hpp apps/home_menu.cpp apps/home_menu.hpp apps/main_clock.cpp @@ -0,0 +1,28 @@ +#include <stdio.h> +#include "pico/stdlib.h" +#include "oled/ss_oled.h" + +#include "api.hpp" +#include "init.hpp" + +void Api::init() { + if (!m_init_done) { + init_display(); + m_init_done = 1; + } +} + +void Api::init_display() { + oledInit(&m_oled, OLED_128x64, 0x3d, 0, 0, 1, SDA_PIN, SCL_PIN, RESET_PIN, 1000000L); + oledFill(&m_oled, 0,1); + oledSetContrast(&m_oled, OLED_DEFAULT_CONTRAST); + //oledSetTextWrap(&oled, true); +} + +int Api::dispWriteString(int iScrollX, int x, int y, char *szMsg, int iSize, int bInvert, int bRender) { + return oledWriteString(&m_oled, iScrollX, x, y, szMsg, iSize, bInvert, bRender); +} + +void Api::dispFill(unsigned char ucData, int bRender) { + oledFill(&m_oled, ucData, bRender); +} @@ -0,0 +1,18 @@ +#ifndef __API_H__ +#define __API_H__ + +#include "pico/util/datetime.h" +#include "oled/ss_oled.h" + +class Api { + private: + SSOLED m_oled; + u_char m_init_done = 0; + void init_display(); + public: + void init(); + int dispWriteString(int iScrollX, int x, int y, char *szMsg, int iSize, int bInvert, int bRender); + void dispFill(unsigned char ucData, int bRender); +}; + +#endif
\ No newline at end of file diff --git a/apps/home_menu.cpp b/apps/home_menu.cpp index 7f53447..19458e6 100644 --- a/apps/home_menu.cpp +++ b/apps/home_menu.cpp @@ -7,6 +7,7 @@ extern "C" { #include "../oled/ss_oled.h" #include "home_menu.hpp" +#include "../api.hpp" #include "../buttons.hpp" extern void app_switch(int old_appid, int new_appid); @@ -15,7 +16,7 @@ extern bool rtc_get_datetime(datetime_t *t); #define NUMBER_OF_APPS 2 namespace app_home_menu { - const char* APPS_NAME[NUMBER_OF_APPS][12] = {"Home", "Clock"}; + char *APPS_NAME[NUMBER_OF_APPS] = {"Home", "Clock"}; char *pressed_button; int *selected_app; @@ -28,7 +29,7 @@ namespace app_home_menu { t->sec); }; - void show_title(SSOLED *oled) { + void show_title(Api *app_api) { char datetime_buf[256]; char *datetime_str = &datetime_buf[0]; datetime_t t; @@ -36,20 +37,20 @@ namespace app_home_menu { // title with time title_str(datetime_str, sizeof(datetime_buf), &t); - oledWriteString(oled, 0,0,0, datetime_str, FONT_8x8, 0, 1); + app_api->dispWriteString(0,0,0, datetime_str, FONT_8x8, 0, 1); } // Rendering of app - int render(SSOLED *oled) { - show_title(oled); - oledWriteString(oled, 0,0,2, pressed_button, FONT_6x8, 0, 1); - oledWriteString(oled, 0,5,3, const_cast<char*>(APPS_NAME[0][*selected_app]), FONT_12x16, 0, 1); + int render(Api *app_api) { + show_title(app_api); + app_api->dispWriteString(0,0,2, pressed_button, FONT_6x8, 0, 1); + app_api->dispWriteString(0,5,3, APPS_NAME[*selected_app], FONT_12x16, 0, 1); return 0; } // Example of how button inputs could be interpreted. // Drawing on screen should be done in the render function. - int btnpressed(SSOLED *oled, uint gpio) { + int btnpressed(Api *app_api, uint gpio) { switch (gpio) { case BUTTON_HOME: *pressed_button = 'H'; break; @@ -79,19 +80,19 @@ namespace app_home_menu { } // Initlisation of the app. - int init(SSOLED *oled) { + int init(Api *app_api) { pressed_button = new char; *pressed_button = '*'; selected_app = new int; return 0; // return 1 when function not implemented } // Processor intensive operations and functions related to drawing to the screen should only be done when the app is in_foreground(=1). This function is only called when the app is init. - int bgrefresh(SSOLED *oled, char in_foreground) { + int bgrefresh(Api *app_api, char in_foreground) { return 1; } // Destruction of app, deinitlisation should be done here. This is only called if the app's APPS_DESTROY_ON_EXIT is set to 1. When it is not a "service" app. - int destroy(SSOLED *oled) { + int destroy(Api *app_api) { delete pressed_button; pressed_button = nullptr; delete selected_app; selected_app = nullptr; return 1; diff --git a/apps/home_menu.hpp b/apps/home_menu.hpp index ebcc451..033dc6b 100644 --- a/apps/home_menu.hpp +++ b/apps/home_menu.hpp @@ -4,12 +4,14 @@ #include "pico/util/datetime.h" #include "../oled/ss_oled.h" +#include "../api.hpp" + namespace app_home_menu { - int init(SSOLED *oled); - int render(SSOLED *oled); - int btnpressed(SSOLED *oled, uint gpio); - int bgrefresh(SSOLED *oled, char in_foreground); - int destroy(SSOLED *oled); + int init(Api *app_api); + int render(Api *app_api); + int btnpressed(Api *app_api, uint gpio); + int bgrefresh(Api *app_api, char in_foreground); + int destroy(Api *app_api); } #endif diff --git a/apps/main_clock.cpp b/apps/main_clock.cpp index f9be3e5..db8e39e 100644 --- a/apps/main_clock.cpp +++ b/apps/main_clock.cpp @@ -7,6 +7,7 @@ extern "C" { #include "../oled/ss_oled.h" #include "main_clock.hpp" +#include "../api.hpp" #include "../buttons.hpp" namespace app_main_clock { @@ -39,7 +40,7 @@ namespace app_main_clock { DATETIME_DOWS[t->dotw - 1]); }; - void show_datetime(SSOLED *oled) { + void show_datetime(Api *app_api) { char datetime_buf[256]; char *datetime_str = &datetime_buf[0]; datetime_t t; @@ -47,38 +48,38 @@ namespace app_main_clock { // time time_as_str(datetime_str, sizeof(datetime_buf), &t); - oledWriteString(oled, 0,10,3, datetime_str, FONT_12x16, 0, 1); + app_api->dispWriteString(0,10,3, datetime_str, FONT_12x16, 0, 1); // date date_as_str(datetime_str, sizeof(datetime_buf), &t); - oledWriteString(oled, 0,0,7, datetime_str, FONT_8x8, 0, 1); + app_api->dispWriteString(0,0,7, datetime_str, FONT_8x8, 0, 1); } // Rendering of the app - int render(SSOLED *oled) { - oledWriteString(oled, 0,15,0, (char *)"Test clock", FONT_8x8, 0, 1); - show_datetime(oled); - //oledWriteString(oled, 0,0,0, &data[0], FONT_6x8, 0, 1); + int render(Api *app_api) { + app_api->dispWriteString(0,15,0, (char *)"Test clock", FONT_8x8, 0, 1); + show_datetime(app_api); + //app_api->dispWriteString(0,0,0, &data[0], FONT_6x8, 0, 1); return 0; } // Interpretation of button inputs - int btnpressed(SSOLED *oled, uint gpio) { + int btnpressed(Api *app_api, uint gpio) { return 0; } // Initlisation of the app. - int init(SSOLED *oled) { + int init(Api *app_api) { return 1; // return 1 when function not implemented } // Processor intensive operations and functions related to drawing to the screen should only be done when the app is in_foreground(=1). This function is only called when the app is init. - int bgrefresh(SSOLED *oled, char in_foreground) { + int bgrefresh(Api *app_api, char in_foreground) { return 1; } // Destruction of app, deinitlisation should be done here. This is only called if the app's APPS_DESTROY_ON_EXIT is set to 1. When it is not a "service" app. - int destroy(SSOLED *oled) { + int destroy(Api *app_api) { return 1; } }
\ No newline at end of file diff --git a/apps/main_clock.hpp b/apps/main_clock.hpp index 887dfa1..5440c1f 100644 --- a/apps/main_clock.hpp +++ b/apps/main_clock.hpp @@ -4,12 +4,14 @@ #include "pico/util/datetime.h" #include "../oled/ss_oled.h" +#include "../api.hpp" + namespace app_main_clock { - int init(SSOLED *oled); - int render(SSOLED *oled); - int btnpressed(SSOLED *oled, uint gpio); - int bgrefresh(SSOLED *oled, char in_foreground); - int destroy(SSOLED *oled); + int init(Api *app_api); + int render(Api *app_api); + int btnpressed(Api *app_api, uint gpio); + int bgrefresh(Api *app_api, char in_foreground); + int destroy(Api *app_api); } #endif
\ No newline at end of file @@ -4,17 +4,8 @@ extern "C" { #include "hardware/rtc.h" } -#include "oled/ss_oled.h" #include "init.hpp" -SSOLED oled; - -void init_display() { - oledInit(&oled, OLED_128x64, 0x3d, 0, 0, 1, SDA_PIN, SCL_PIN, RESET_PIN, 1000000L); - oledFill(&oled, 0,1); - oledSetContrast(&oled, OLED_DEFAULT_CONTRAST); - //oledSetTextWrap(&oled, true); -} void init_rtc() { datetime_t init_date = { @@ -31,6 +22,5 @@ void init_rtc() { void init_all() { stdio_init_all(); - init_display(); init_rtc(); } @@ -7,7 +7,6 @@ #define SCL_PIN 7 #define RESET_PIN -1 #define OLED_DEFAULT_CONTRAST 40 -extern SSOLED oled; // Initial date & time // The idea is to have the compiler set the date at compile-time. @@ -23,8 +22,6 @@ extern SSOLED oled; // Init every componement void init_all(); -// Init OLED display -void init_display(); // Init onboard RTC void init_rtc(); diff --git a/pico-watch.cpp b/pico-watch.cpp index 243f1e1..e888ba1 100644 --- a/pico-watch.cpp +++ b/pico-watch.cpp @@ -6,49 +6,51 @@ #include "oled/ss_oled.h" #include "init.hpp" +#include "api.hpp" #include "buttons.hpp" #include "apps/main_clock.hpp" #include "apps/home_menu.hpp" int current_app = 0; +Api app_api; #define NUMBER_OF_APPS 2 #define APP_DATA_BUFFER_LEN 256 -int (*APPS_FUNC_INIT[NUMBER_OF_APPS])(SSOLED *oled) = {app_home_menu::init, app_main_clock::init}; -int (*APPS_FUNC_RENDER[NUMBER_OF_APPS])(SSOLED *oled) = {app_home_menu::render, app_main_clock::render}; -int (*APPS_FUNC_BTNPRESS[NUMBER_OF_APPS])(SSOLED *oled, uint gpio) = {app_home_menu::btnpressed, app_main_clock::btnpressed}; -int (*APPS_FUNC_BGREFRESH[NUMBER_OF_APPS])(SSOLED *oled, char in_foreground) = {app_home_menu::bgrefresh, app_main_clock::bgrefresh}; -int (*APPS_FUNC_DESTROY[NUMBER_OF_APPS])(SSOLED *oled) = {app_home_menu::destroy, app_main_clock::destroy}; +int (*APPS_FUNC_INIT[NUMBER_OF_APPS])(Api *app_api) = {app_home_menu::init, app_main_clock::init}; +int (*APPS_FUNC_RENDER[NUMBER_OF_APPS])(Api *app_api) = {app_home_menu::render, app_main_clock::render}; +int (*APPS_FUNC_BTNPRESS[NUMBER_OF_APPS])(Api *app_api, uint gpio) = {app_home_menu::btnpressed, app_main_clock::btnpressed}; +int (*APPS_FUNC_BGREFRESH[NUMBER_OF_APPS])(Api *app_api, char in_foreground) = {app_home_menu::bgrefresh, app_main_clock::bgrefresh}; +int (*APPS_FUNC_DESTROY[NUMBER_OF_APPS])(Api *app_api) = {app_home_menu::destroy, app_main_clock::destroy}; int APPS_DESTROY_ON_EXIT[NUMBER_OF_APPS] = {0, 1}; int APPS_IS_INIT[NUMBER_OF_APPS] = {0, 0}; // Only run in background if init int app_init(int app_id) { - oledFill(&oled, 0,1); // Clear OLED + app_api.dispFill(0,1); // Clear OLED if (!APPS_IS_INIT[app_id]) { APPS_IS_INIT[app_id] = 1; - return (*APPS_FUNC_INIT[app_id])(&oled); + return (*APPS_FUNC_INIT[app_id])(&app_api); } } int app_render(int app_id) { - return (*APPS_FUNC_RENDER[app_id])(&oled); + return (*APPS_FUNC_RENDER[app_id])(&app_api); } int app_btnpressed(int app_id, uint gpio) { - return (*APPS_FUNC_BTNPRESS[app_id])(&oled, gpio); + return (*APPS_FUNC_BTNPRESS[app_id])(&app_api, gpio); } int app_destroy(int app_id) { // TODO: reset APPS_DATA for the app if (APPS_IS_INIT[app_id]) { APPS_IS_INIT[app_id] = 0; - return (*APPS_FUNC_DESTROY[app_id])(&oled); + return (*APPS_FUNC_DESTROY[app_id])(&app_api); } } int app_bgrefresh(int app_id) { if (APPS_IS_INIT[app_id]) - return (*APPS_FUNC_BGREFRESH[app_id])(&oled, app_id==current_app); + return (*APPS_FUNC_BGREFRESH[app_id])(&app_api, app_id==current_app); } bool apps_bgrefresh(struct repeating_timer *t) { // TODO: Refresh done on core1 @@ -69,6 +71,7 @@ void app_switch(int old_appid, int new_appid) { int main() { init_all(); init_buttons(); + app_api.init(); struct repeating_timer timer; add_repeating_timer_ms(250, apps_bgrefresh, NULL, &timer); |