aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorConfuSomu2021-02-27 13:29:37 -0500
committerConfuSomu2021-02-27 13:29:37 -0500
commit2a0571ba87183023b1073af1badb5fb91da763cf (patch)
treeb73cd5d8d810e398c614611ecd7b602d10d7b58d
parent06d5f492eca8e57bc8ce7479ec6149fbc6a15d08 (diff)
downloadpico-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.txt2
-rw-r--r--api.cpp28
-rw-r--r--api.hpp18
-rw-r--r--apps/home_menu.cpp23
-rw-r--r--apps/home_menu.hpp12
-rw-r--r--apps/main_clock.cpp23
-rw-r--r--apps/main_clock.hpp12
-rw-r--r--init.cpp10
-rw-r--r--init.hpp3
-rw-r--r--pico-watch.cpp25
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
diff --git a/api.cpp b/api.cpp
new file mode 100644
index 0000000..60c0bcd
--- /dev/null
+++ b/api.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);
+}
diff --git a/api.hpp b/api.hpp
new file mode 100644
index 0000000..0e4992f
--- /dev/null
+++ b/api.hpp
@@ -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
diff --git a/init.cpp b/init.cpp
index 11d38a6..eb33533 100644
--- a/init.cpp
+++ b/init.cpp
@@ -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();
}
diff --git a/init.hpp b/init.hpp
index f63187f..fc2a53f 100644
--- a/init.hpp
+++ b/init.hpp
@@ -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);