From d5aaab8929878963cfc00e276980cafa3256a8d6 Mon Sep 17 00:00:00 2001 From: Englebert <=> Date: Sat, 5 Feb 2022 11:33:55 +0800 Subject: [PATCH] Initial --- .gitignore | 1 + include/README | 39 ++++++++++++ lib/README | 46 ++++++++++++++ platformio.ini | 17 +++++ src/Screen.cpp | 168 +++++++++++++++++++++++++++++++++++++++++++++++++ src/Screen.h | 56 +++++++++++++++++ src/main.cpp | 37 +++++++++++ src/main.h | 13 ++++ test/README | 11 ++++ 9 files changed, 388 insertions(+) create mode 100644 .gitignore create mode 100644 include/README create mode 100644 lib/README create mode 100644 platformio.ini create mode 100644 src/Screen.cpp create mode 100644 src/Screen.h create mode 100644 src/main.cpp create mode 100644 src/main.h create mode 100644 test/README diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..03f4a3c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.pio diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..382b037 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,17 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:m5stack-core2] +platform = espressif32 +board = m5stack-core2 +framework = arduino +board_build.mcu = esp32 +board_build.f_cpu = 240000000L +lib_deps = m5stack/M5Core2@^0.1.0 diff --git a/src/Screen.cpp b/src/Screen.cpp new file mode 100644 index 0000000..4acb37a --- /dev/null +++ b/src/Screen.cpp @@ -0,0 +1,168 @@ +// REF: +// https://github.com/m5stack/m5-docs/blob/master/docs/en/api/lcd.md + +#include "Screen.h" + +Screen::Screen(void) { +} + + +void Screen::begin(void) { + M5.begin(); //Init M5Core2. Initialize M5Core2 + /* + * Power chip connected to gpio21, gpio22, I2C device + * Set battery charging voltage and current + * If used battery, please call this function in your project + */ + // Initial value + updated = true; +} + + +void Screen::update(void) { + M5.update(); + + // Update screen based on selected menu + if((uint32_t)(millis() - last_screen_update) > REFRESH_TIME) { + if(current_screen == SCREEN_MENU) { + menu(); + } else if(current_screen == SCREEN_MENU_REBOOT) { + menu_reboot(); + } + last_screen_update = millis(); + } + + /*** + if(M5.BtnA.wasPressed()) { + M5.Lcd.println("Button A Pressed"); + } + if(M5.BtnB.wasPressed()) { + M5.Lcd.println("Button B Pressed"); + } + if(M5.BtnC.wasPressed()) { + M5.Lcd.println("Button C Pressed"); + } + ***/ +} + + +void Screen::intro(void) { + M5.Lcd.drawRect(100, 100, 50, 50, BLUE); + + + vTaskDelay(INTRO_TIME); + current_screen = SCREEN_MENU; + M5.Lcd.fillScreen(BLACK); +} + + +// Main Menu +void Screen::menu(void) { + static uint8_t current_menu = MENU_RC_CONTROLLER; + static String menu_items_name[] = { + "RC Controller", + "Bluetooth", + "Stick Calibration", + "Stick Positions", + "Trims", + "WiFi", + "RX Binding", + "RF Settings", + "RF Scanners", + "Save Settings", + "Reset", + "Reboot" + }; + // Serial.println((int)sizeof(menu_items_name)/sizeof(menu_items_name[0])); + + uint8_t menu_total = (int)sizeof(menu_items_name)/sizeof(menu_items_name[0]); + uint8_t menu_count = 0; + + if(updated) { + // List all menus + M5.Lcd.fillRect(0, 0, 320, 240, BLACK); + M5.Lcd.setTextColor(WHITE, BLACK); + M5.Lcd.setTextSize(2); + + for(uint8_t y = 0; y < menu_total * MENU_HEIGHT; y+=MENU_HEIGHT) { + if(current_menu == menu_count) { + M5.Lcd.setTextColor(BLACK, YELLOW); + } else { + M5.Lcd.setTextColor(WHITE, BLACK); + } + M5.Lcd.setCursor(10, y); + M5.Lcd.print(menu_items_name[menu_count++]); + } + + updated = false; + } + + // Key Input Handler + if(M5.BtnC.wasPressed()) { + current_menu++; + + if(current_menu == menu_total) current_menu--; + updated = true; + } + + if(M5.BtnA.wasPressed()) { + current_menu--; + + if(current_menu == 255) current_menu = 0; + updated = true; + } + + if(M5.BtnB.wasPressed()) { + if(current_menu == MENU_REBOOT) { + current_screen = SCREEN_MENU_REBOOT; + updated = true; + } + } +} + + +// Reboot Confirmation +void Screen::menu_reboot(void) { + static uint8_t current_menu_reboot_selection = SELECTION_YES; + static uint8_t menu_reboot_selection_total = 2; + + if(updated) { + // Draw box + M5.Lcd.drawRect(50, 50, 220, 140, WHITE); + M5.Lcd.fillRect(51, 51, 218, 138, BLACK); + M5.Lcd.drawRect(52, 52, 216, 136, WHITE); + + // Show Text + M5.Lcd.setTextColor(WHITE, BLACK); + M5.Lcd.setCursor(68, 110); + M5.Lcd.print("Reboot Now? "); + + M5.Lcd.setTextColor(GREEN); + if(current_menu_reboot_selection == SELECTION_YES) { + M5.Lcd.print("YES"); + } else { + M5.Lcd.print("NO"); + } + + updated = false; + } + + // Key Input Handler + if(M5.BtnC.wasPressed() || M5.BtnA.wasPressed()) { // Either up or down is the same because only two options + current_menu_reboot_selection++; + + if(current_menu_reboot_selection == menu_reboot_selection_total) current_menu_reboot_selection = 0; + updated = true; + } + + if(M5.BtnB.wasPressed()) { + if(current_menu_reboot_selection == SELECTION_YES) { + ESP.restart(); + } else if(current_menu_reboot_selection == SELECTION_NO) { + // Return back to main menu + current_screen = SCREEN_MENU; + } + updated = true; + } +} + diff --git a/src/Screen.h b/src/Screen.h new file mode 100644 index 0000000..5425289 --- /dev/null +++ b/src/Screen.h @@ -0,0 +1,56 @@ +#ifndef _SCREEN_H +#define _SCREEN_H + +#include +#include + +#define REFRESH_TIME 1 +#define INTRO_TIME 100 + +#define MENU_HEIGHT 20 + +enum screen_names { + SCREEN_INTRO, + SCREEN_MENU, + SCREEN_MENU_REBOOT +}; + +enum menu_items { + MENU_RC_CONTROLLER, + MENU_BLUETOOTH, + MENU_STICK_CALIBRATION, + MENU_STICK_POSITIONS, + MENU_TRIMS, + MENU_WIFI, + MENU_RX_BINDING, + MENU_RF_SETTINGS, + MENU_RF_SCANNERS, + MENU_SAVE_SETTINGS, + MENU_RESET, + MENU_REBOOT +}; + +enum selection_choice_yesno { + SELECTION_YES, + SELECTION_NO +}; + + +class Screen { + public: + Screen(void); + void begin(void); + void intro(void); + void menu(void); + void menu_reboot(void); + void update(void); + + private: + uint8_t current_screen = SCREEN_INTRO; + uint32_t last_screen_update = 0; + bool updated = false; +}; + + +extern Screen screen; +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..e621236 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,37 @@ +#include +#include "main.h" + +Screen screen; + +void setup() { + Serial.begin(115200); + + screen.begin(); + + + // Task Creation + xTaskCreatePinnedToCore( + taskScreen, + "TaskScreen", // Name of the process + 4096, // This stack size can be checked & adjusted by reading the Stack Highwater + NULL, + 4, // Priority + NULL, + CPU_1 + ); +} + + +void loop() { +} + + +void taskScreen(void *pvParameters) { + (void) pvParameters; + screen.intro(); + + for(;;) { + screen.update(); + vTaskDelay(10); + } +} diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..6fbd047 --- /dev/null +++ b/src/main.h @@ -0,0 +1,13 @@ +#ifndef MAIN_H +#define MAIN_H + +// CPU NAMES +#define CPU_1 1 +#define CPU_0 0 + +#include "Screen.h" + +// Task Handler +void taskScreen(void *pvParameters); + +#endif diff --git a/test/README b/test/README new file mode 100644 index 0000000..b94d089 --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html