summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md44
-rwxr-xr-xcmake-nRF5x/CMake_nRF5x.cmake3
-rw-r--r--doc/ble.md27
-rw-r--r--doc/ble/ans_sequence.pngbin0 -> 36606 bytes
-rw-r--r--doc/ble/ans_sequence.puml29
-rw-r--r--doc/ble/connection_sequence.pngbin0 -> 17958 bytes
-rw-r--r--doc/ble/connection_sequence.puml14
-rw-r--r--src/BLE/BleManager.c288
-rw-r--r--src/BLE/BleManager.h6
-rw-r--r--src/CMakeLists.txt55
-rw-r--r--src/Components/Battery/BatteryController.cpp4
-rw-r--r--src/Components/Ble/BleController.cpp4
-rw-r--r--src/Components/Ble/BleController.h7
-rw-r--r--src/Components/Ble/NotificationManager.cpp29
-rw-r--r--src/Components/Ble/NotificationManager.h29
-rw-r--r--src/Components/Brightness/BrightnessController.cpp70
-rw-r--r--src/Components/Brightness/BrightnessController.h28
-rw-r--r--src/DisplayApp/DisplayApp.cpp111
-rw-r--r--src/DisplayApp/DisplayApp.h34
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_005.c56
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_005.pngbin0 -> 1540 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_010.c58
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_010.pngbin0 -> 1859 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_020.c58
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_020.pngbin0 -> 1558 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_030.c58
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_030.pngbin0 -> 1553 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_040.c56
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_040.pngbin0 -> 1542 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_050.c56
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_050.pngbin0 -> 1539 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_060.c56
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_060.pngbin0 -> 1543 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_070.c56
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_070.pngbin0 -> 1545 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_080.c56
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_080.pngbin0 -> 1549 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_090.c56
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_090.pngbin0 -> 1554 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_100.c58
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_100.pngbin0 -> 1574 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_error.c58
-rw-r--r--src/DisplayApp/Icons/battery/os_battery_error.pngbin0 -> 2128 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_005.c56
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_005.pngbin0 -> 1952 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_010.c58
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_010.pngbin0 -> 1983 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_020.c58
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_020.pngbin0 -> 1982 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_030.c58
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_030.pngbin0 -> 1997 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_040.c56
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_040.pngbin0 -> 1993 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_050.c56
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_050.pngbin0 -> 2036 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_060.c56
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_060.pngbin0 -> 2035 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_070.c56
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_070.pngbin0 -> 2035 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_080.c58
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_080.pngbin0 -> 2087 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_090.c58
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_090.pngbin0 -> 2100 bytes
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_100.c56
-rw-r--r--src/DisplayApp/Icons/battery/os_batterycharging_100.pngbin0 -> 1919 bytes
-rw-r--r--src/DisplayApp/Icons/bluetooth/ck_os_bt_connected.pngbin0 -> 2237 bytes
-rw-r--r--src/DisplayApp/Icons/bluetooth/ck_os_bt_disconnected.pngbin0 -> 2441 bytes
-rw-r--r--src/DisplayApp/Icons/bluetooth/os_bt_connected.c56
-rw-r--r--src/DisplayApp/Icons/bluetooth/os_bt_connected.pngbin0 -> 2237 bytes
-rw-r--r--src/DisplayApp/Icons/bluetooth/os_bt_disconnected.c58
-rw-r--r--src/DisplayApp/Icons/bluetooth/os_bt_disconnected.pngbin0 -> 2441 bytes
-rw-r--r--src/DisplayApp/Screens/BatteryIcon.cpp62
-rw-r--r--src/DisplayApp/Screens/BatteryIcon.h15
-rw-r--r--src/DisplayApp/Screens/BleIcon.cpp12
-rw-r--r--src/DisplayApp/Screens/BleIcon.h14
-rw-r--r--src/DisplayApp/Screens/Brightness.cpp92
-rw-r--r--src/DisplayApp/Screens/Brightness.h33
-rw-r--r--src/DisplayApp/Screens/Clock.cpp43
-rw-r--r--src/DisplayApp/Screens/Clock.h3
-rw-r--r--src/DisplayApp/Screens/Label.cpp28
-rw-r--r--src/DisplayApp/Screens/Label.h24
-rw-r--r--src/DisplayApp/Screens/Modal.cpp52
-rw-r--r--src/DisplayApp/Screens/Modal.h3
-rw-r--r--src/DisplayApp/Screens/Screen.h4
-rw-r--r--src/DisplayApp/Screens/ScreenList.cpp115
-rw-r--r--src/DisplayApp/Screens/ScreenList.h38
-rw-r--r--src/DisplayApp/Screens/Tile.cpp19
-rw-r--r--src/DisplayApp/Screens/Tile.h3
-rw-r--r--src/DisplayApp/TouchEvents.h8
-rw-r--r--src/SystemTask/SystemTask.cpp31
-rw-r--r--src/SystemTask/SystemTask.h17
-rw-r--r--src/drivers/Watchdog.cpp20
-rw-r--r--src/drivers/Watchdog.h14
-rw-r--r--src/libs/lv_conf.h2
-rw-r--r--src/main.cpp14
-rw-r--r--src/sdk_config.h10
96 files changed, 2697 insertions, 183 deletions
diff --git a/README.md b/README.md
index 2940dfd9..790e3de1 100644
--- a/README.md
+++ b/README.md
@@ -29,10 +29,16 @@ I've tested this project on the actual PineTime hardware.
* SPI (DMA & IRQ based) LCD driver;
* BLE advertising, connection and bonding;
* BLE CTS client (retrieves the time from the connected device if it implements a CTS server);
- * Push button to go to disable screen (and go to low power mode) / enable screen (and wake-up);
+ * Push button to go to disable screen (and go to low power mode) / enable screen (and wake-up) and UI navigation
* Touch panel support;
- * Basic user interface via display, touchpanel and push button.
- * Digital watch face and 4 demo applications (spinning meter, analog gauche, push button and message box);
+ * Rich user interface (using [LittleVGL](https://littlevgl.com/)) via display, touchpanel and push button.
+ * Digital watch face and 4 demo applications (spinning meter, analog gauche, push button and message box);
+ * Watchdog (automatic reset in case of firmware crash) and reset support (push and hold the button for 7 - 10s);
+ * BLE Notification support (still Work-In-Progress, [companion app](https://github.com/JF002/gobbledegook) needed).
+
+## Documentation
+
+ * [BLE implementation and API](./doc/ble.md)
## Stub using NRF52-DK
![Pinetime stub](./images/pinetimestub1.jpg "PinetimeStub")
@@ -206,6 +212,7 @@ $ JLinkRTTClient
At runtime, BLE advertising is started. You can then use a smartphone or computer to connect and bond to your Pinetime.
As soon as a device is bonded, Pinetime will look for a **CTS** server (**C**urrent **T**ime **S**ervice) on the connected device.
+### Using Android and NRFConnect
Here is how to do it with an Android smartphone running NRFConnect:
* Build and program the firmware on the Pinetime
@@ -217,4 +224,33 @@ Here is how to do it with an Android smartphone running NRFConnect:
* Go back to the main screen and scan for BLE devices. A device called "PineTime" should appear
* Tap the button "Connect" next to the PineTime device. It should connect to the PineTime and switch to a new tab.
* On this tab, on the top right, there is a 3 dots button. Tap on it and select Bond. The bonding process begins, and if it is sucessful, the PineTime should update its time and display it on the screen.
- \ No newline at end of file
+
+### Using Linux and bluetoothctl
+* Ensure that your bluetooth controller is enabled and working fine. I've tested this on a x86 Debian computer and on a RaspberryPi 3.
+* Run bluetoothctl as root : `sudo bluetoothctl`
+* Enter the following commands:
+ * `scan on` and wait for you Pinetime to be detected. Note the BLE MAC address
+ * `scan off'
+ * `trust <MAC ADDRESS>`
+ * `pair <MAC ADDRESS>`
+ * Wait for some time, and the connection should be established.
+
+**NOTE : ** The commands above establish a BLE connection between your PC, but the time synchronization and notifications won't work because there is not CTS or ANS server running. I'm currently working on an application that'll provide both of these servers.
+
+### Troubleshooting
+If the connection cannot be established, or the time synchronization does not work, try the following steps.
+
+On Android:
+* Disable and re-enable your bluetooth device
+* In NRFConnect, in the device tab corresponding to your pinetime, tap on the menu on the top left of the screen and select "Delete bond information".
+* Then re-try to bond/connect.
+
+On Linux:
+* Reset the bluetooth device : `sudo hciconfig hci0 reset`
+* Restart the Bluetooth service : `sudo systemctl restart bluetooth.service`
+* In bluetootctl:
+ * `remove <MAC ADDRESS>`
+ * `trust <MAC ADDRESS>`
+ * `pair <MAC ADDRESS>`
+
+Note that the current firmware only advertise for the first 3 minutes. If you cannot connect after more than 3 minutes, try resetting the device (push the button and hold it for 7-10 seconds). \ No newline at end of file
diff --git a/cmake-nRF5x/CMake_nRF5x.cmake b/cmake-nRF5x/CMake_nRF5x.cmake
index 8a43cf12..3e8e96aa 100755
--- a/cmake-nRF5x/CMake_nRF5x.cmake
+++ b/cmake-nRF5x/CMake_nRF5x.cmake
@@ -260,7 +260,8 @@ macro(nRF5x_setup)
list(APPEND SDK_SOURCE_FILES
"${NRF5_SDK_PATH}/components/ble/ble_db_discovery/ble_db_discovery.c"
"${NRF5_SDK_PATH}/components/ble/ble_services/ble_cts_c/ble_cts_c.c"
- "${NRF5_SDK_PATH}/external/thedotfactory_fonts/orkney24pts.c"
+ "${NRF5_SDK_PATH}/components/ble/ble_services/ble_ans_c/ble_ans_c.c"
+# "${NRF5_SDK_PATH}/external/thedotfactory_fonts/orkney24pts.c"
)
#BLE S132
diff --git a/doc/ble.md b/doc/ble.md
new file mode 100644
index 00000000..0302b471
--- /dev/null
+++ b/doc/ble.md
@@ -0,0 +1,27 @@
+# Bluetooth Low-Energy :
+## Introduction
+This page describes the BLE implementation and API built in this firmware.
+
+**Note** : I'm a beginner in BLE related technologies and the information of this document reflect my current knowledge and understanding of the BLE stack. These informations might be erroneous or incomplete. Feel free to submit a PR if you think you can improve these.
+
+## BLE Connection
+When starting the firmware start a BLE advertising : it send small messages that can be received by any *central* device in range. This allows the device to announce its presence to other devices.
+
+A companion application (running on a PC, RasberryPi, smartphone) which received this avertising packet can request a connection to the device. This connection procedure allows the 2 devices to negociate communication parameters, security keys,...
+
+When the connection is established, the pinetime will try to discover services running on the companion application. For now **CTS** (**C**urrent **T**ime **S**ervice) and **ANS** (**A**lert **N**otification **S**ervice) are supported.
+
+If **CTS** is detected, it'll request the current time to the companion application. If **ANS** is detected, it will listen to new notifications coming from the companion application.
+
+![BLE connection sequence diagram](ble/connection_sequence.png "BLE connection sequence diagram")
+
+## BLE services
+[List of standard BLE services](https://www.bluetooth.com/specifications/gatt/services/)
+
+### CTS
+[Current Time Service](https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Services/org.bluetooth.service.alert_notification.xml)
+
+### ANS
+[Alert Notification Service](https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Services/org.bluetooth.service.current_time.xml)
+
+![ANS sequence diagram](./ble/ans_sequence.png "ANS sequence diagram") \ No newline at end of file
diff --git a/doc/ble/ans_sequence.png b/doc/ble/ans_sequence.png
new file mode 100644
index 00000000..99cf8493
--- /dev/null
+++ b/doc/ble/ans_sequence.png
Binary files differ
diff --git a/doc/ble/ans_sequence.puml b/doc/ble/ans_sequence.puml
new file mode 100644
index 00000000..c3819059
--- /dev/null
+++ b/doc/ble/ans_sequence.puml
@@ -0,0 +1,29 @@
+@startuml
+group Get configuration from server
+Pinetime -> CompanionApp : Read request (Supported 'new' notification categories - 0x2A47)
+CompanionApp --> Pinetime: Response (0xff = all categories)
+
+Pinetime -> CompanionApp : Read request (Supported 'unread' notification categories - 0x2A48)
+CompanionApp --> Pinetime: Response (0xff = all categories)
+end
+
+group Configure the server
+Pinetime -> CompanionApp : Configure 'new' notifications categories : Accept all (Write [0, 0xFF] to Control Point - 0x2A44)
+activate CompanionApp
+deactivate CompanionApp
+Pinetime -> CompanionApp : Configure 'unread' notifications categories : Accept all (Write [1, 0xFF] to Control Point - 0x2A44)
+activate CompanionApp
+deactivate CompanionApp
+end
+
+group Server sends a notification
+CompanionApp -> Pinetime : Notify new_alert (0x2A46)
+activate Pinetime
+note over Pinetime
+ Pinetime FW handles the
+ notification (display on UI)
+end note
+deactivate Pinetime
+end
+
+@enduml \ No newline at end of file
diff --git a/doc/ble/connection_sequence.png b/doc/ble/connection_sequence.png
new file mode 100644
index 00000000..7e8babcb
--- /dev/null
+++ b/doc/ble/connection_sequence.png
Binary files differ
diff --git a/doc/ble/connection_sequence.puml b/doc/ble/connection_sequence.puml
new file mode 100644
index 00000000..55531829
--- /dev/null
+++ b/doc/ble/connection_sequence.puml
@@ -0,0 +1,14 @@
+@startuml
+Pinetime --> CompanionApp: Start advertising
+
+group BLE Connection
+CompanionApp -> Pinetime: Connection request
+CompanionApp <-> Pinetime: Connection parameters negociation, security procedure,...
+end
+
+group Service Discovery
+CompanionApp <-> Pinetime: Discover service 0x1805 (CTS)
+CompanionApp <-> Pinetime: Discover service 0x1811 (ANS)
+end
+
+@enduml \ No newline at end of file
diff --git a/src/BLE/BleManager.c b/src/BLE/BleManager.c
index cf56dd48..8caf120a 100644
--- a/src/BLE/BleManager.c
+++ b/src/BLE/BleManager.c
@@ -12,7 +12,9 @@
#include <ble/ble_services/ble_hrs/ble_hrs.h>
#include <ble/ble_services/ble_bas/ble_bas.h>
#include <ble/ble_services/ble_dis/ble_dis.h>
+#include <ble/ble_services/ble_ans_c/ble_ans_c.h>
#include <ble/common/ble_conn_params.h>
+#include <libraries/fds/fds.h>
#include "nrf_sdh_soc.h"
#include "BleManager.h"
@@ -41,14 +43,31 @@ void ble_manager_cts_print_time(ble_cts_c_evt_t *p_evt);
void ble_manager_conn_params_event_handler(ble_conn_params_evt_t *p_evt);
void ble_manager_conn_params_error_handler(uint32_t nrf_error);
+typedef enum
+{
+ ALERT_NOTIFICATION_DISABLED, /**< Alert Notifications has been disabled. */
+ ALERT_NOTIFICATION_ENABLED, /**< Alert Notifications has been enabled. */
+ ALERT_NOTIFICATION_ON, /**< Alert State is on. */
+} ble_ans_c_alert_state_t;
+
+void on_ans_c_evt(ble_ans_c_evt_t * p_evt);
+void alert_notification_error_handler(uint32_t nrf_error);
+void handle_alert_notification(ble_ans_c_evt_t * p_evt);
+void supported_alert_notification_read(void);
+void alert_notification_setup(void);
+void control_point_setup(ble_ans_c_evt_t * p_evt);
+
uint16_t ble_manager_connection_handle = BLE_CONN_HANDLE_INVALID; // Handle of the current connection.
NRF_BLE_QWR_DEF(ble_manager_queue_write); // Context for the Queued Write module.
BLE_CTS_C_DEF(ble_manager_cts_client); // Current Time service instance.
NRF_BLE_GATT_DEF(ble_manager_gatt); // GATT module instance.
BLE_ADVERTISING_DEF(ble_manager_advertising); // Advertising module instance.
BLE_DB_DISCOVERY_DEF(ble_manager_db_discovery);
+BLE_ANS_C_DEF(m_ans_c);
-
+static uint8_t m_alert_message_buffer[MESSAGE_BUFFER_SIZE]; /**< Message buffer for optional notify messages. */
+static ble_ans_c_alert_state_t m_new_alert_state = ALERT_NOTIFICATION_DISABLED; /**< State that holds the current state of New Alert Notifications, i.e. Enabled, Alert On, Disabled. */
+static ble_ans_c_alert_state_t m_unread_alert_state = ALERT_NOTIFICATION_DISABLED; /**< State that holds the current state of Unread Alert Notifications, i.e. Enabled, Alert On, Disabled. */
static ble_uuid_t ble_manager_advertising_uuids[] = /* Universally unique service identifiers.*/
{
@@ -87,6 +106,21 @@ static char const *month_of_year[] =
"December"
};
+static char const * lit_catid[BLE_ANS_NB_OF_CATEGORY_ID] =
+ {
+ "Simple alert",
+ "Email",
+ "News",
+ "Incoming call",
+ "Missed call",
+ "SMS/MMS",
+ "Voice mail",
+ "Schedule",
+ "High prioritized alert",
+ "Instant message"
+ };
+
+
void ble_manager_init() {
ble_manager_init_stack();
ble_manager_init_gap_params();
@@ -132,13 +166,18 @@ void ble_manager_set_ble_disconnection_callback(void (*OnBleDisconnection)()) {
OnBleDisconnectionCallback = OnBleDisconnection;
}
+void (*OnNewNotificationCallback)(const char* message, uint8_t size);
+void ble_manager_set_new_notification_callback(void (*OnNewNotification)(const char*, uint8_t size)) {
+ OnNewNotificationCallback = OnNewNotification;
+}
+
void ble_manager_event_handler(ble_evt_t const *p_ble_evt, void *p_context) {
uint32_t err_code;
switch (p_ble_evt->header.evt_id) {
case BLE_GAP_EVT_CONNECTED:
- NRF_LOG_INFO("Connected");
+ NRF_LOG_INFO("[BLE] Connected to peer");
ble_manager_connection_handle = p_ble_evt->evt.gap_evt.conn_handle;
err_code = nrf_ble_qwr_conn_handle_assign(&ble_manager_queue_write, ble_manager_connection_handle);
OnBleConnectionCallback();
@@ -146,7 +185,7 @@ void ble_manager_event_handler(ble_evt_t const *p_ble_evt, void *p_context) {
break;
case BLE_GAP_EVT_DISCONNECTED:
- NRF_LOG_INFO("Disconnected");
+ NRF_LOG_INFO("[Ble] Disconnected from peer]");
ble_manager_connection_handle = BLE_CONN_HANDLE_INVALID;
if (p_ble_evt->evt.gap_evt.conn_handle == ble_manager_cts_client.conn_handle) {
ble_manager_cts_client.conn_handle = BLE_CONN_HANDLE_INVALID;
@@ -155,7 +194,7 @@ void ble_manager_event_handler(ble_evt_t const *p_ble_evt, void *p_context) {
break;
case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
- NRF_LOG_DEBUG("PHY update request.");
+ NRF_LOG_INFO("[BLE] PHY update request.");
ble_gap_phys_t const phys =
{
@@ -169,7 +208,7 @@ void ble_manager_event_handler(ble_evt_t const *p_ble_evt, void *p_context) {
case BLE_GATTC_EVT_TIMEOUT:
// Disconnect on GATT Client timeout event.
- NRF_LOG_DEBUG("GATT Client Timeout.");
+ NRF_LOG_INFO("[BLE] GATT Client Timeout.");
err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
APP_ERROR_CHECK(err_code);
@@ -177,7 +216,7 @@ void ble_manager_event_handler(ble_evt_t const *p_ble_evt, void *p_context) {
case BLE_GATTS_EVT_TIMEOUT:
// Disconnect on GATT Server timeout event.
- NRF_LOG_DEBUG("GATT Server Timeout.");
+ NRF_LOG_INFO("[BLE] GATT Server Timeout.");
err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
APP_ERROR_CHECK(err_code);
@@ -226,6 +265,7 @@ void ble_manager_init_db_discovery() {
void ble_manager_discover_handler(ble_db_discovery_evt_t *p_evt) {
ble_cts_c_on_db_disc_evt(&ble_manager_cts_client, p_evt);
+ ble_ans_c_on_db_disc_evt(&m_ans_c, p_evt);
}
void ble_manager_init_advertising() {
@@ -259,10 +299,11 @@ void ble_manager_advertising_event_handler(ble_adv_evt_t ble_adv_evt) {
switch (ble_adv_evt) {
case BLE_ADV_EVT_FAST:
- NRF_LOG_INFO("Fast advertising.");
+ NRF_LOG_INFO("[Advertising] Fast advertising started.");
break;
case BLE_ADV_EVT_IDLE:
+ NRF_LOG_INFO("[Advertising] Idling...");
break;
default:
@@ -270,11 +311,42 @@ void ble_manager_advertising_event_handler(ble_adv_evt_t ble_adv_evt) {
}
}
+bool record_delete_next(void)
+{
+ fds_find_token_t tok = {0};
+ fds_record_desc_t desc = {0};
+
+ if (fds_record_iterate(&desc, &tok) == FDS_SUCCESS)
+ {
+ ret_code_t rc = fds_record_delete(&desc);
+ if (rc != FDS_SUCCESS)
+ {
+ return false;
+ }
+
+ return true;
+ }
+ else
+ {
+ /* No records left to delete. */
+ return false;
+ }
+}
+
void ble_manager_init_peer_manager() {
ble_gap_sec_params_t sec_param;
ret_code_t err_code;
err_code = pm_init();
+ if(err_code != NRF_SUCCESS) {
+ // Many errors can occur here, but the most probable is the "Storage full" error from sdk/components/libraries/fds/fds.c : FDS_ERR_NO_PAGES.
+ // TODO : it erases the whole memory, it's not nice to do that...
+ NRF_LOG_WARNING("Error while initializing BLE peer management, Erasing all record from memory");
+ do {
+
+ } while(record_delete_next());
+ err_code = pm_init();
+ }
APP_ERROR_CHECK(err_code);
memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));
@@ -308,18 +380,33 @@ void ble_manager_peer_manager_event_handler(pm_evt_t const *p_evt) {
switch (p_evt->evt_id) {
case PM_EVT_CONN_SEC_SUCCEEDED: {
-// m_peer_id = p_evt->peer_id;
-
- // Discover peer's services.
+ NRF_LOG_INFO("[Peer management] A link has been secured, starting service discovery.");
err_code = ble_db_discovery_start(&ble_manager_db_discovery, p_evt->conn_handle);
APP_ERROR_CHECK(err_code);
}
break;
case PM_EVT_PEERS_DELETE_SUCCEEDED:
+ NRF_LOG_INFO("[Peer management] All peers data has been successfuly deleted.");
ble_manager_start_advertising(&delete_bonds);
break;
+ case PM_EVT_STORAGE_FULL: {
+ NRF_LOG_INFO("[Peer management] Storage full, trying to run garbage collection on flash storage.");
+ // Run garbage collection on the flash.
+ err_code = fds_gc();
+ if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES)
+ {
+ NRF_LOG_INFO("[Peer management] Garbage collection issue.");
+ // Retry.
+ }
+ else
+ {
+ APP_ERROR_CHECK(err_code);
+ NRF_LOG_INFO("[Peer management] Garbage collection done.");
+ }
+ }break;
+
default:
break;
}
@@ -337,12 +424,154 @@ void ble_manager_start_advertising(void *p_erase_bonds) {
}
}
+void handle_alert_notification(ble_ans_c_evt_t * p_evt)
+{
+ ret_code_t err_code;
+
+ if (p_evt->uuid.uuid == BLE_UUID_UNREAD_ALERT_CHAR)
+ {
+ if (m_unread_alert_state == ALERT_NOTIFICATION_ENABLED)
+ {
+// err_code = bsp_indication_set(BSP_INDICATE_ALERT_1);
+ APP_ERROR_CHECK(err_code);
+ m_unread_alert_state = ALERT_NOTIFICATION_ON;
+ NRF_LOG_INFO("Unread Alert state: On.");
+ NRF_LOG_INFO(" Category: %s",
+ (uint32_t)lit_catid[p_evt->data.alert.alert_category]);
+ NRF_LOG_INFO(" Number of unread alerts: %d",
+ p_evt->data.alert.alert_category_count);
+ }
+ }
+ else if (p_evt->uuid.uuid == BLE_UUID_NEW_ALERT_CHAR)
+ {
+ m_new_alert_state = ALERT_NOTIFICATION_ON;
+ NRF_LOG_INFO("New Alert state: On.");
+ NRF_LOG_INFO(" Category: %s",
+ (uint32_t)lit_catid[p_evt->data.alert.alert_category]);
+ NRF_LOG_INFO(" Number of new alerts: %d",
+ p_evt->data.alert.alert_category_count);
+ NRF_LOG_INFO(" Text String Information: (%d) %s",
+ p_evt->data.alert.alert_msg_length, (uint32_t)p_evt->data.alert.p_alert_msg_buf);
+
+ OnNewNotificationCallback(p_evt->data.alert.p_alert_msg_buf, p_evt->data.alert.alert_msg_length);
+ }
+ else
+ {
+ // Only Unread and New Alerts exists, thus do nothing.
+ }
+}
+
+void supported_alert_notification_read(void)
+{
+ NRF_LOG_INFO("Read supported Alert Notification characteristics on the connected peer.");
+ ret_code_t err_code;
+
+ err_code = ble_ans_c_new_alert_read(&m_ans_c);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = ble_ans_c_unread_alert_read(&m_ans_c);
+ APP_ERROR_CHECK(err_code);
+}
+
+void alert_notification_setup(void)
+{
+ ret_code_t err_code;
+
+ err_code = ble_ans_c_enable_notif_new_alert(&m_ans_c);
+ APP_ERROR_CHECK(err_code);
+
+ m_new_alert_state = ALERT_NOTIFICATION_ENABLED;
+ NRF_LOG_INFO("New Alert State: Enabled.");
+
+ err_code = ble_ans_c_enable_notif_unread_alert(&m_ans_c);
+ APP_ERROR_CHECK(err_code);
+
+ m_unread_alert_state = ALERT_NOTIFICATION_ENABLED;
+ NRF_LOG_INFO("Unread Alert State: Enabled.");
+
+ NRF_LOG_INFO("Notifications enabled.");
+}
+
+void control_point_setup(ble_ans_c_evt_t * p_evt)
+{
+ uint32_t err_code;
+ ble_ans_control_point_t setting;
+
+ if (p_evt->uuid.uuid == BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR)
+ {
+ setting.command = ANS_ENABLE_UNREAD_CATEGORY_STATUS_NOTIFICATION;
+ setting.category = (ble_ans_category_id_t)p_evt->data.alert.alert_category;
+ NRF_LOG_INFO("Unread status notification enabled for received categories.");
+ }
+ else if (p_evt->uuid.uuid == BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR)
+ {
+ setting.command = ANS_ENABLE_NEW_INCOMING_ALERT_NOTIFICATION;
+ setting.category = (ble_ans_category_id_t)p_evt->data.alert.alert_category;
+ NRF_LOG_INFO("New incoming notification enabled for received categories.");
+ }
+ else
+ {
+ return;
+ }
+
+ err_code = ble_ans_c_control_point_write(&m_ans_c, &setting);
+ APP_ERROR_CHECK(err_code);
+}
+
+void on_ans_c_evt(ble_ans_c_evt_t * p_evt)
+{
+ ret_code_t err_code;
+
+ switch (p_evt->evt_type) {
+ case BLE_ANS_C_EVT_DISCOVERY_FAILED:
+ // TODO When another service is found, this event is sent to all the other service handled.
+ // In this case, this is not an error, it just tells that the service that have just been found is not this one...
+ NRF_LOG_INFO("[ANS] Discovery failed");
+ break;
+ case BLE_ANS_C_EVT_NOTIFICATION:
+ handle_alert_notification(p_evt);
+ NRF_LOG_INFO("[ANS] Alert Notification received from server, UUID: %X.", p_evt->uuid.uuid);
+ break; // BLE_ANS_C_EVT_NOTIFICATION
+
+ case BLE_ANS_C_EVT_DISCOVERY_COMPLETE:
+ NRF_LOG_INFO("[ANS] Alert Notification Service discovered on the server.");
+ err_code = ble_ans_c_handles_assign(&m_ans_c,
+ p_evt->conn_handle,
+ &p_evt->data.service);
+ APP_ERROR_CHECK(err_code);
+ supported_alert_notification_read();
+ alert_notification_setup();
+ break; // BLE_ANS_C_EVT_DISCOVERY_COMPLETE
+
+ case BLE_ANS_C_EVT_READ_RESP:
+ NRF_LOG_INFO("[ANS] Alert Setup received from server, UUID: %X.", p_evt->uuid.uuid);
+ control_point_setup(p_evt);
+ break; // BLE_ANS_C_EVT_READ_RESP
+
+ case BLE_ANS_C_EVT_DISCONN_COMPLETE:
+ NRF_LOG_INFO("[ANS] ANS : disconnecting from server");
+ m_new_alert_state = ALERT_NOTIFICATION_DISABLED;
+ m_unread_alert_state = ALERT_NOTIFICATION_DISABLED;
+ break; // BLE_ANS_C_EVT_DISCONN_COMPLETE
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+void alert_notification_error_handler(uint32_t nrf_error)
+{
+ APP_ERROR_HANDLER(nrf_error);
+}
+
void ble_manager_init_services() {
ret_code_t err_code;
ble_hrs_init_t hrs_init;
ble_bas_init_t bas_init;
ble_dis_init_t dis_init;
ble_cts_c_init_t cts_init;
+ ble_ans_c_init_t ans_init_obj;
nrf_ble_qwr_init_t qwr_init = {0};
uint8_t body_sensor_location;
@@ -396,6 +625,19 @@ void ble_manager_init_services() {
cts_init.error_handler = ble_manager_cts_error_handler;
err_code = ble_cts_c_init(&ble_manager_cts_client, &cts_init);
APP_ERROR_CHECK(err_code);
+
+ // Alert Notification service
+ memset(&ans_init_obj, 0, sizeof(ans_init_obj));
+ memset(m_alert_message_buffer, 0, MESSAGE_BUFFER_SIZE);
+
+ ans_init_obj.evt_handler = on_ans_c_evt;
+ ans_init_obj.message_buffer_size = MESSAGE_BUFFER_SIZE;
+ ans_init_obj.p_message_buffer = m_alert_message_buffer;
+ ans_init_obj.error_handler = alert_notification_error_handler;
+
+ err_code = ble_ans_c_init(&m_ans_c, &ans_init_obj);
+
+ APP_ERROR_CHECK(err_code);
}
void ble_manager_queue_write_error_handler(uint32_t nrf_error) {
@@ -405,11 +647,9 @@ void ble_manager_queue_write_error_handler(uint32_t nrf_error) {
void ble_manager_cts_event_handler(ble_cts_c_t *p_cts, ble_cts_c_evt_t *p_evt) {
ret_code_t err_code;
- NRF_LOG_INFO("CTS %d", p_evt->evt_type);
-
switch (p_evt->evt_type) {
case BLE_CTS_C_EVT_DISCOVERY_COMPLETE:
- NRF_LOG_INFO("Current Time Service discovered on server.");
+ NRF_LOG_INFO("[CTS] Current Time Service discovered on server, requesting current time...");
err_code = ble_cts_c_handles_assign(&ble_manager_cts_client,
p_evt->conn_handle,
&p_evt->params.char_handles);
@@ -419,27 +659,22 @@ void ble_manager_cts_event_handler(ble_cts_c_t *p_cts, ble_cts_c_evt_t *p_evt) {
break;
case BLE_CTS_C_EVT_DISCOVERY_FAILED:
- NRF_LOG_INFO("Current Time Service not found on server. ");
- // CTS not found in this case we just disconnect. There is no reason to stay
- // in the connection for this simple app since it all wants is to interact with CT
- if (p_evt->conn_handle != BLE_CONN_HANDLE_INVALID) {
- err_code = sd_ble_gap_disconnect(p_evt->conn_handle,
- BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
- APP_ERROR_CHECK(err_code);
- }
+ // TODO When another service is found, this event is sent to all the other service handled.
+ // In this case, this is not an error, it just tells that the service that have just been found is not this one...
+ NRF_LOG_INFO("[CTS] Current Time Service not found on server.");
break;
case BLE_CTS_C_EVT_DISCONN_COMPLETE:
- NRF_LOG_INFO("Disconnect Complete.");
+ NRF_LOG_INFO("[CTS] Disconnect Complete.");
break;
case BLE_CTS_C_EVT_CURRENT_TIME:
- NRF_LOG_INFO("Current Time received.");
+ NRF_LOG_INFO("[CTS] Current Time received.");
ble_manager_cts_print_time(p_evt);
break;
case BLE_CTS_C_EVT_INVALID_TIME:
- NRF_LOG_INFO("Invalid Time received.");
+ NRF_LOG_INFO("[CTS] Invalid Time received.");
break;
default:
@@ -522,7 +757,10 @@ void ble_manager_init_connection_params() {
void ble_manager_conn_params_event_handler(ble_conn_params_evt_t *p_evt) {
ret_code_t err_code;
- if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) {
+ if(p_evt->evt_type == BLE_CONN_PARAMS_EVT_SUCCEEDED) {
+ NRF_LOG_INFO("BLE connection parameters negotiation successful!");
+ } else if(p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) {
+ NRF_LOG_ERROR("BLE connection parameters negotiation error, disconnecting.");
err_code = sd_ble_gap_disconnect(ble_manager_connection_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
APP_ERROR_CHECK(err_code);
}
diff --git a/src/BLE/BleManager.h b/src/BLE/BleManager.h
index 4424d665..da5f8e3f 100644
--- a/src/BLE/BleManager.h
+++ b/src/BLE/BleManager.h
@@ -10,7 +10,7 @@ extern "C" {
#define BLE_MANAGER_DEVICE_NAME "PineTime" /* Name of device. Will be included in the advertising data.*/
#define BLE_MANAGER_MANUFACTURER_NAME "Codingfield"
-#define BLE_MANAGER_MIN_CONN_INTERVAL MSEC_TO_UNITS(400, UNIT_1_25_MS) /* Minimum acceptable connection interval (0.4 seconds).*/
+#define BLE_MANAGER_MIN_CONN_INTERVAL MSEC_TO_UNITS(100, UNIT_1_25_MS) /* Minimum acceptable connection interval (0.4 seconds).*/
#define BLE_MANAGER_MAX_CONN_INTERVAL MSEC_TO_UNITS(650, UNIT_1_25_MS) /*Maximum acceptable connection interval (0.65 second).*/
#define BLE_MANAGER_SLAVE_LATENCY 0 /* Slave latency.*/
#define BLE_MANAGER_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /* Connection supervisory time-out (4 seconds).*/
@@ -31,6 +31,8 @@ extern "C" {
#define NEXT_CONN_PARAMS_UPDATE_DELAY 30000 /* Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /* Number of attempts before giving up the connection parameter negotiation. */
+#define MESSAGE_BUFFER_SIZE 18 /**< Size of buffer holding optional messages in notifications. */
+#define BLE_ANS_NB_OF_CATEGORY_ID 10 /**< Number of categories. */
void ble_manager_init();
void ble_manager_start_advertising(void *p_erase_bonds);
@@ -41,6 +43,8 @@ void ble_manager_set_new_time_callback(void (*OnNewTime)(current_time_char_t* cu
void ble_manager_set_ble_disconnection_callback(void (*OnBleDisconnection)());
void ble_manager_set_ble_connection_callback(void (*OnBleConnection)());
+void ble_manager_set_new_notification_callback(void (*OnNewNotification)(const char* message, uint8_t size));
+
#ifdef __cplusplus
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c93feb38..e92e3998 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -161,6 +161,42 @@ set(LVGL_SRC
libs/lvgl/src/lv_objx/lv_mbox.c
libs/lvgl/src/lv_objx/lv_mbox.h
+ libs/lvgl/src/lv_objx/lv_bar.c
+ libs/lvgl/src/lv_objx/lv_bar.h
+ libs/lvgl/src/lv_objx/lv_slider.h
+ libs/lvgl/src/lv_objx/lv_slider.c
+
+ )
+
+list(APPEND IMAGE_FILES
+ DisplayApp/Icons/battery/os_battery_error.c
+
+ DisplayApp/Icons/battery/os_battery_100.c
+ DisplayApp/Icons/battery/os_battery_090.c
+ DisplayApp/Icons/battery/os_battery_080.c
+ DisplayApp/Icons/battery/os_battery_070.c
+ DisplayApp/Icons/battery/os_battery_060.c
+ DisplayApp/Icons/battery/os_battery_050.c
+ DisplayApp/Icons/battery/os_battery_040.c
+ DisplayApp/Icons/battery/os_battery_030.c
+ DisplayApp/Icons/battery/os_battery_020.c
+ DisplayApp/Icons/battery/os_battery_010.c
+ DisplayApp/Icons/battery/os_battery_005.c
+
+ DisplayApp/Icons/battery/os_batterycharging_100.c
+ DisplayApp/Icons/battery/os_batterycharging_090.c
+ DisplayApp/Icons/battery/os_batterycharging_080.c
+ DisplayApp/Icons/battery/os_batterycharging_070.c
+ DisplayApp/Icons/battery/os_batterycharging_060.c
+ DisplayApp/Icons/battery/os_batterycharging_050.c
+ DisplayApp/Icons/battery/os_batterycharging_040.c
+ DisplayApp/Icons/battery/os_batterycharging_030.c
+ DisplayApp/Icons/battery/os_batterycharging_020.c
+ DisplayApp/Icons/battery/os_batterycharging_010.c
+ DisplayApp/Icons/battery/os_batterycharging_005.c
+
+ DisplayApp/Icons/bluetooth/os_bt_connected.c
+ DisplayApp/Icons/bluetooth/os_bt_disconnected.c
)
list(APPEND SOURCE_FILES
@@ -174,6 +210,11 @@ list(APPEND SOURCE_FILES
DisplayApp/Screens/Meter.cpp
DisplayApp/Screens/Gauge.cpp
DisplayApp/Screens/Modal.cpp
+ DisplayApp/Screens/BatteryIcon.cpp
+ DisplayApp/Screens/BleIcon.cpp
+ DisplayApp/Screens/Brightness.cpp
+ DisplayApp/Screens/ScreenList.cpp
+ DisplayApp/Screens/Label.cpp
main.cpp
drivers/St7789.cpp
drivers/SpiMaster.cpp
@@ -182,12 +223,15 @@ list(APPEND SOURCE_FILES
BLE/BleManager.c
Components/Battery/BatteryController.cpp
Components/Ble/BleController.cpp
+ Components/Ble/NotificationManager.cpp
Components/DateTime/DateTimeController.cpp
+ Components/Brightness/BrightnessController.cpp
drivers/Cst816s.cpp
FreeRTOS/port.c
FreeRTOS/port_cmsis_systick.c
FreeRTOS/port_cmsis.c
${LVGL_SRC}
+ ${IMAGE_FILES}
DisplayApp/LittleVgl.cpp
DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c
@@ -201,6 +245,7 @@ set(INCLUDE_FILES
Logging/NrfLogger.h
BlinkApp/BlinkApp.h
DisplayApp/DisplayApp.h
+ DisplayApp/TouchEvents.h
DisplayApp/Screens/Screen.h
DisplayApp/Screens/Clock.h
DisplayApp/Screens/Message.h
@@ -208,7 +253,11 @@ set(INCLUDE_FILES
DisplayApp/Screens/Meter.h
DisplayApp/Screens/Gauge.h
DisplayApp/Screens/Modal.h
-# DisplayApp/Screens/Tab.h
+ DisplayApp/Screens/BatteryIcon.h
+ DisplayApp/Screens/BleIcon.cpp
+ DisplayApp/Screens/Brightness.h
+ DisplayApp/Screens/ScreenList.h
+ DisplayApp/Screens/Label.h
drivers/St7789.h
drivers/SpiMaster.h
drivers/Watchdog.h
@@ -216,7 +265,9 @@ set(INCLUDE_FILES
BLE/BleManager.h
Components/Battery/BatteryController.h
Components/Ble/BleController.h
+ Components/Ble/NotificationManager.h
Components/DateTime/DateTimeController.h
+ Components/Brightness/BrightnessController.h
drivers/Cst816s.h
FreeRTOS/portmacro.h
FreeRTOS/portmacro_cmsis.h
@@ -243,4 +294,4 @@ link_directories(
../
)
-nRF5x_addExecutable(pinetime-app "${SOURCE_FILES}")
+nRF5x_addExecutable(pinetime-app "${SOURCE_FILES}" ${INCLUDE_FILES})
diff --git a/src/Components/Battery/BatteryController.cpp b/src/Components/Battery/BatteryController.cpp
index 7719bcbb..198ce5aa 100644
--- a/src/Components/Battery/BatteryController.cpp
+++ b/src/Components/Battery/BatteryController.cpp
@@ -36,8 +36,8 @@ void Battery::Update() {
voltage = (value * 2.0f) / (1024/3.0f);
percentRemaining = ((voltage - 3.55)*100)*3.9;
- NRF_LOG_INFO("BATTERY " NRF_LOG_FLOAT_MARKER " %% - " NRF_LOG_FLOAT_MARKER " v", NRF_LOG_FLOAT(percentRemaining), NRF_LOG_FLOAT(voltage));
- NRF_LOG_INFO("POWER Charging : %d - Power : %d", isCharging, isPowerPresent);
+// NRF_LOG_INFO("BATTERY " NRF_LOG_FLOAT_MARKER " %% - " NRF_LOG_FLOAT_MARKER " v", NRF_LOG_FLOAT(percentRemaining), NRF_LOG_FLOAT(voltage));
+// NRF_LOG_INFO("POWER Charging : %d - Power : %d", isCharging, isPowerPresent);
}
void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * event) {
diff --git a/src/Components/Ble/BleController.cpp b/src/Components/Ble/BleController.cpp
index c2458087..5fa51688 100644
--- a/src/Components/Ble/BleController.cpp
+++ b/src/Components/Ble/BleController.cpp
@@ -1,3 +1,5 @@
+#include <cstring>
+#include <cstdlib>
#include "BleController.h"
using namespace Pinetime::Controllers;
@@ -9,3 +11,5 @@ void Ble::Connect() {
void Ble::Disconnect() {
isConnected = false;
}
+
+
diff --git a/src/Components/Ble/BleController.h b/src/Components/Ble/BleController.h
index be491ee9..31d66986 100644
--- a/src/Components/Ble/BleController.h
+++ b/src/Components/Ble/BleController.h
@@ -1,15 +1,20 @@
#pragma once
+#include <FreeRTOS.h>>
+#include <queue.h>
+
namespace Pinetime {
namespace Controllers {
class Ble {
public:
+
+ Ble() = default;
bool IsConnected() const {return isConnected;}
void Connect();
void Disconnect();
-
private:
bool isConnected = false;
+
};
}
} \ No newline at end of file
diff --git a/src/Components/Ble/NotificationManager.cpp b/src/Components/Ble/NotificationManager.cpp
new file mode 100644
index 00000000..2e02cb15
--- /dev/null
+++ b/src/Components/Ble/NotificationManager.cpp
@@ -0,0 +1,29 @@
+#include <cstring>
+#include "NotificationManager.h"
+
+using namespace Pinetime::Controllers;
+
+void NotificationManager::Push(Pinetime::Controllers::NotificationManager::Categories category,
+ const char *message, uint8_t messageSize) {
+ // TODO handle edge cases on read/write index
+ auto& notif = notifications[writeIndex];
+ std::memcpy(notif.message.data(), message, messageSize);
+ notif.message[messageSize] = '\0';
+ notif.category = category;
+
+ writeIndex = (writeIndex + 1 < TotalNbNotifications) ? writeIndex + 1 : 0;
+ if(!empty && writeIndex == readIndex)
+ readIndex = writeIndex + 1;
+}
+
+NotificationManager::Notification Pinetime::Controllers::NotificationManager::Pop() {
+// TODO handle edge cases on read/write index
+ NotificationManager::Notification notification = notifications[readIndex];
+
+ if(readIndex != writeIndex) {
+ readIndex = (readIndex + 1 < TotalNbNotifications) ? readIndex + 1 : 0;
+ }
+
+ // TODO Check move optimization on return
+ return notification;
+}
diff --git a/src/Components/Ble/NotificationManager.h b/src/Components/Ble/NotificationManager.h
new file mode 100644
index 00000000..8edd6828
--- /dev/null
+++ b/src/Components/Ble/NotificationManager.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <array>
+
+namespace Pinetime {
+ namespace Controllers {
+ class NotificationManager {
+ public:
+ enum class Categories {Unknown, SimpleAlert, Email, News, IncomingCall, MissedCall, Sms, VoiceMail, Schedule, HighProriotyAlert, InstantMessage };
+ static constexpr uint8_t MessageSize = 18;
+
+ struct Notification {
+ std::array<char, MessageSize> message;
+ Categories category = Categories::Unknown;
+ };
+
+ void Push(Categories category, const char* message, uint8_t messageSize);
+ Notification Pop();
+
+
+ private:
+ static constexpr uint8_t TotalNbNotifications = 5;
+ std::array<Notification, TotalNbNotifications> notifications;
+ uint8_t readIndex = 0;
+ uint8_t writeIndex = 0;
+ bool empty = true;
+ };
+ }
+} \ No newline at end of file
diff --git a/src/Components/Brightness/BrightnessController.cpp b/src/Components/Brightness/BrightnessController.cpp
new file mode 100644
index 00000000..c8825d68
--- /dev/null
+++ b/src/Components/Brightness/BrightnessController.cpp
@@ -0,0 +1,70 @@
+#include <hal/nrf_gpio.h>
+#include "BrightnessController.h"
+
+using namespace Pinetime::Controllers;
+
+
+void BrightnessController::Init() {
+ nrf_gpio_cfg_output(pinLcdBacklight1);
+ nrf_gpio_cfg_output(pinLcdBacklight2);
+ nrf_gpio_cfg_output(pinLcdBacklight3);
+ Set(level);
+}
+
+void BrightnessController::Set(BrightnessController::Levels level) {
+ this->level = level;
+ switch(level) {
+ default:
+ case Levels::High:
+ nrf_gpio_pin_clear(pinLcdBacklight1);
+ nrf_gpio_pin_clear(pinLcdBacklight2);
+ nrf_gpio_pin_clear(pinLcdBacklight3);
+ break;
+ case Levels::Medium:
+ nrf_gpio_pin_clear(pinLcdBacklight1);
+ nrf_gpio_pin_clear(pinLcdBacklight2);
+ nrf_gpio_pin_set(pinLcdBacklight3);
+ break;
+ case Levels::Low:
+ nrf_gpio_pin_clear(pinLcdBacklight1);
+ nrf_gpio_pin_set(pinLcdBacklight2);
+ nrf_gpio_pin_set(pinLcdBacklight3);
+ break;
+ case Levels::Off:
+ nrf_gpio_pin_set(pinLcdBacklight1);
+ nrf_gpio_pin_set(pinLcdBacklight2);
+ nrf_gpio_pin_set(pinLcdBacklight3);
+ break;
+ }
+}
+
+void BrightnessController::Lower() {
+ switch(level) {
+ case Levels::High: Set(Levels::Medium); break;
+ case Levels::Medium: Set(Levels::Low); break;
+ case Levels::Low: Set(Levels::Off); break;
+ default: break;
+ }
+}
+
+void BrightnessController::Higher() {
+ switch(level) {
+ case Levels::Off: Set(Levels::Low); break;
+ case Levels::Low: Set(Levels::Medium); break;
+ case Levels::Medium: Set(Levels::High); break;
+ default: break;
+ }
+}
+
+BrightnessController::Levels BrightnessController::Level() const {
+ return level;
+}
+
+void BrightnessController::Backup() {
+ backupLevel = level;
+}
+
+void BrightnessController::Restore() {
+ Set(backupLevel);
+}
+
diff --git a/src/Components/Brightness/BrightnessController.h b/src/Components/Brightness/BrightnessController.h
new file mode 100644
index 00000000..b8354ec0
--- /dev/null
+++ b/src/Components/Brightness/BrightnessController.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <cstdint>
+
+namespace Pinetime {
+ namespace Controllers {
+ class BrightnessController {
+ public:
+ enum class Levels {Off, Low, Medium, High};
+ void Init();
+
+ void Set(Levels level);
+ Levels Level() const;
+ void Lower();
+ void Higher();
+
+ void Backup();
+ void Restore();
+
+ private:
+ static constexpr uint8_t pinLcdBacklight1 = 14;
+ static constexpr uint8_t pinLcdBacklight2 = 22;
+ static constexpr uint8_t pinLcdBacklight3 = 23;
+ Levels level = Levels::High;
+ Levels backupLevel = Levels::High;
+ };
+ }
+}
diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp
index 7464175e..1b4515e0 100644
--- a/src/DisplayApp/DisplayApp.cpp
+++ b/src/DisplayApp/DisplayApp.cpp
@@ -13,27 +13,31 @@
#include <DisplayApp/Screens/Message.h>
#include <DisplayApp/Screens/Meter.h>
#include <DisplayApp/Screens/Gauge.h>
+#include <DisplayApp/Screens/Brightness.h>
+#include <DisplayApp/Screens/ScreenList.h>
+#include <Components/Ble/NotificationManager.h>
#include "../SystemTask/SystemTask.h"
using namespace Pinetime::Applications;
-DisplayApp::DisplayApp(Pinetime::Drivers::St7789& lcd,
- Pinetime::Components::LittleVgl& lvgl,
- Pinetime::Drivers::Cst816S& touchPanel,
- Controllers::Battery &batteryController,
- Controllers::Ble &bleController,
- Controllers::DateTime &dateTimeController,
- Pinetime::System::SystemTask& systemTask) :
+DisplayApp::DisplayApp(Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Drivers::Cst816S &touchPanel,
+ Controllers::Battery &batteryController, Controllers::Ble &bleController,
+ Controllers::DateTime &dateTimeController, Drivers::WatchdogView &watchdog,
+ System::SystemTask &systemTask,
+ Pinetime::Controllers::NotificationManager& notificationManager) :
lcd{lcd},
lvgl{lvgl},
- touchPanel{touchPanel},
batteryController{batteryController},
bleController{bleController},
dateTimeController{dateTimeController},
+ watchdog{watchdog},
+ touchPanel{touchPanel},
currentScreen{new Screens::Clock(this, dateTimeController, batteryController, bleController) },
- systemTask{systemTask} {
+ systemTask{systemTask},
+ notificationManager{notificationManager} {
msgQueue = xQueueCreate(queueSize, itemSize);
onClockApp = true;
+ modal.reset(new Screens::Modal(this));
}
void DisplayApp::Start() {
@@ -57,12 +61,7 @@ void DisplayApp::Process(void *instance) {
}
void DisplayApp::InitHw() {
- nrf_gpio_cfg_output(pinLcdBacklight1);
- nrf_gpio_cfg_output(pinLcdBacklight2);
- nrf_gpio_cfg_output(pinLcdBacklight3);
- nrf_gpio_pin_clear(pinLcdBacklight1);
- nrf_gpio_pin_clear(pinLcdBacklight2);
- nrf_gpio_pin_clear(pinLcdBacklight3);
+ brightnessController.Init();
}
uint32_t acc = 0;
@@ -85,11 +84,11 @@ void DisplayApp::Refresh() {
if (xQueueReceive(msgQueue, &msg, queueTimeout)) {
switch (msg) {
case Messages::GoToSleep:
- nrf_gpio_pin_set(pinLcdBacklight3);
- vTaskDelay(100);
- nrf_gpio_pin_set(pinLcdBacklight2);
- vTaskDelay(100);
- nrf_gpio_pin_set(pinLcdBacklight1);
+ brightnessController.Backup();
+ while(brightnessController.Level() != Controllers::BrightnessController::Levels::Off) {
+ brightnessController.Lower();
+ vTaskDelay(100);
+ }
lcd.DisplayOff();
lcd.Sleep();
touchPanel.Sleep();
@@ -100,12 +99,11 @@ void DisplayApp::Refresh() {
touchPanel.Wakeup();
lcd.DisplayOn();
- nrf_gpio_pin_clear(pinLcdBacklight3);
- nrf_gpio_pin_clear(pinLcdBacklight2);
- nrf_gpio_pin_clear(pinLcdBacklight1);
+ brightnessController.Restore();
state = States::Running;
break;
case Messages::UpdateDateTime:
+// modal->Show();
break;
case Messages::UpdateBleConnection:
// clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected : Screens::Clock::BleConnectionStates::NotConnected);
@@ -113,20 +111,27 @@ void DisplayApp::Refresh() {
case Messages::UpdateBatteryLevel:
// clockScreen.SetBatteryPercentRemaining(batteryController.PercentRemaining());
break;
+ case Messages::NewNotification: {
+ auto notification = notificationManager.Pop();
+ modal->Show(notification.message.data());
+ }
+ break;
case Messages::TouchEvent: {
if (state != States::Running) break;
auto gesture = OnTouchEvent();
- switch (gesture) {
- case DisplayApp::TouchEvents::SwipeUp:
- currentScreen->OnButtonPushed();
- lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Up);
- break;
- case DisplayApp::TouchEvents::SwipeDown:
- currentScreen->OnButtonPushed();
- lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Down);
- break;
- default:
- break;
+ if(!currentScreen->OnTouchEvent(gesture)) {
+ switch (gesture) {
+ case TouchEvents::SwipeUp:
+ currentScreen->OnButtonPushed();
+ lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Up);
+ break;
+ case TouchEvents::SwipeDown:
+ currentScreen->OnButtonPushed();
+ lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Down);
+ break;
+ default:
+ break;
+ }
}
}
break;
@@ -171,9 +176,11 @@ void DisplayApp::RunningState() {
currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController));
onClockApp = true;
break;
- case Apps::Test: currentScreen.reset(new Screens::Message(this)); break;
+// case Apps::Test: currentScreen.reset(new Screens::Message(this)); break;
+ case Apps::SysInfo: currentScreen.reset(new Screens::ScreenList(this, dateTimeController, batteryController, brightnessController, watchdog)); break;
case Apps::Meter: currentScreen.reset(new Screens::Meter(this)); break;
case Apps::Gauge: currentScreen.reset(new Screens::Gauge(this)); break;
+ case Apps::Brightness : currentScreen.reset(new Screens::Brightness(this, brightnessController)); break;
}
nextApp = Apps::None;
}
@@ -194,34 +201,46 @@ void DisplayApp::PushMessage(DisplayApp::Messages msg) {
}
}
-DisplayApp::TouchEvents DisplayApp::OnTouchEvent() {
+TouchEvents DisplayApp::OnTouchEvent() {
auto info = touchPanel.GetTouchInfo();
if(info.isTouch) {
switch(info.gesture) {
case Pinetime::Drivers::Cst816S::Gestures::SingleTap:
- // TODO set x,y to LittleVgl
lvgl.SetNewTapEvent(info.x, info.y);
- return DisplayApp::TouchEvents::Tap;
+ return TouchEvents::Tap;
case Pinetime::Drivers::Cst816S::Gestures::LongPress:
- return DisplayApp::TouchEvents::LongTap;
+ return TouchEvents::LongTap;
case Pinetime::Drivers::Cst816S::Gestures::DoubleTap:
- return DisplayApp::TouchEvents::DoubleTap;
+ return TouchEvents::DoubleTap;
case Pinetime::Drivers::Cst816S::Gestures::SlideRight:
- return DisplayApp::TouchEvents::SwipeRight;
+ return TouchEvents::SwipeRight;
case Pinetime::Drivers::Cst816S::Gestures::SlideLeft:
- return DisplayApp::TouchEvents::SwipeLeft;
+ return TouchEvents::SwipeLeft;
case Pinetime::Drivers::Cst816S::Gestures::SlideDown:
- return DisplayApp::TouchEvents::SwipeDown;
+ return TouchEvents::SwipeDown;
case Pinetime::Drivers::Cst816S::Gestures::SlideUp:
- return DisplayApp::TouchEvents::SwipeUp;
+ return TouchEvents::SwipeUp;
case Pinetime::Drivers::Cst816S::Gestures::None:
default:
- return DisplayApp::TouchEvents::None;
+ return TouchEvents::None;
}
}
- return DisplayApp::TouchEvents::None;
+ return TouchEvents::None;
}
void DisplayApp::StartApp(DisplayApp::Apps app) {
nextApp = app;
}
+
+void DisplayApp::SetFullRefresh(DisplayApp::FullRefreshDirections direction) {
+ switch(direction){
+ case DisplayApp::FullRefreshDirections::Down:
+ lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Down);
+ break;
+ case DisplayApp::FullRefreshDirections::Up:
+ lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Up);
+ break;
+ default: break;
+ }
+
+}
diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h
index eaad1baa..09f0d1cd 100644
--- a/src/DisplayApp/DisplayApp.h
+++ b/src/DisplayApp/DisplayApp.h
@@ -7,6 +7,7 @@
#include <bits/unique_ptr.h>
#include <queue.h>
#include <Components/Battery/BatteryController.h>
+#include <Components/Brightness/BrightnessController.h>
#include <Components/Ble/BleController.h>
#include <Components/DateTime/DateTimeController.h>
#include "Fonts/lcdfont14.h"
@@ -14,6 +15,10 @@
#include "LittleVgl.h"
#include <date/date.h>
#include <DisplayApp/Screens/Clock.h>
+#include <drivers/Watchdog.h>
+#include <DisplayApp/Screens/Modal.h>
+#include <Components/Ble/NotificationManager.h>
+#include "TouchEvents.h"
namespace Pinetime {
@@ -24,22 +29,24 @@ namespace Pinetime {
class DisplayApp {
public:
enum class States {Idle, Running};
- enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent, SwitchScreen,ButtonPushed} ;
- enum class TouchEvents { None, Tap, SwipeLeft, SwipeRight, SwipeUp, SwipeDown, LongTap, DoubleTap
+ enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent, SwitchScreen,ButtonPushed,
+ NewNotification
};
- DisplayApp(Pinetime::Drivers::St7789& lcd,
- Pinetime::Components::LittleVgl& lvgl,
- Pinetime::Drivers::Cst816S&,
- Controllers::Battery &batteryController,
- Controllers::Ble &bleController,
- Controllers::DateTime& dateTimeController,
- Pinetime::System::SystemTask& systemTask);
+ enum class FullRefreshDirections { None, Up, Down };
+
+
+ DisplayApp(Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Drivers::Cst816S &,
+ Controllers::Battery &batteryController, Controllers::Ble &bleController,
+ Controllers::DateTime &dateTimeController, Drivers::WatchdogView &watchdog,
+ System::SystemTask &systemTask,
+ Pinetime::Controllers::NotificationManager& notificationManager);
void Start();
void PushMessage(Messages msg);
- enum class Apps {None, Launcher, Clock, Test, Meter, Gauge};
+ enum class Apps {None, Launcher, Clock, SysInfo, Meter, Gauge, Brightness};
void StartApp(Apps app);
+ void SetFullRefresh(FullRefreshDirections direction);
private:
TaskHandle_t taskHandle;
static void Process(void* instance);
@@ -59,20 +66,21 @@ namespace Pinetime {
Pinetime::Controllers::Battery &batteryController;
Pinetime::Controllers::Ble &bleController;
Pinetime::Controllers::DateTime& dateTimeController;
+ Pinetime::Drivers::WatchdogView& watchdog;
Pinetime::Drivers::Cst816S& touchPanel;
TouchEvents OnTouchEvent();
std::unique_ptr<Screens::Screen> currentScreen;
- static constexpr uint8_t pinLcdBacklight1 = 14;
- static constexpr uint8_t pinLcdBacklight2 = 22;
- static constexpr uint8_t pinLcdBacklight3 = 23;
bool isClock = true;
Pinetime::System::SystemTask& systemTask;
Apps nextApp = Apps::None;
bool onClockApp = false; // TODO find a better way to know that we should handle gestures and button differently for the Clock app.
+ Controllers::BrightnessController brightnessController;
+ std::unique_ptr<Screens::Modal> modal;
+ Pinetime::Controllers::NotificationManager& notificationManager;
};
}
}
diff --git a/src/DisplayApp/Icons/battery/os_battery_005.c b/src/DisplayApp/Icons/battery/os_battery_005.c
new file mode 100644
index 00000000..64832b5c
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_005.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERY_005
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERY_005
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERY_005 uint8_t ck_os_battery_005_map[] = {
+ 0x04, 0x02, 0xcc, 0xff, /*Color of index 0*/
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 1*/
+
+ 0xfc, 0x00, 0x3f,
+ 0xf8, 0x00, 0x1f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0x00, 0xff, 0x00,
+ 0x00, 0xff, 0x00,
+ 0x00, 0xff, 0x00,
+ 0x00, 0xff, 0x00,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+};
+
+const lv_img_dsc_t ck_os_battery_005 = {
+ .header.always_zero = 0,
+ .header.w = 24,
+ .header.h = 32,
+ .data_size = 104,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_battery_005_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_battery_005.png b/src/DisplayApp/Icons/battery/os_battery_005.png
new file mode 100644
index 00000000..963767be
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_005.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_battery_010.c b/src/DisplayApp/Icons/battery/os_battery_010.c
new file mode 100644
index 00000000..f36b684b
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_010.c
@@ -0,0 +1,58 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERY_010
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERY_010
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERY_010 uint8_t ck_os_battery_010_map[] = {
+ 0x04, 0x02, 0xcc, 0xff, /*Color of index 0*/
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 1*/
+ 0x04, 0x7a, 0xf4, 0xff, /*Color of index 2*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 3*/
+
+ 0x55, 0x5f, 0xff, 0xff, 0xf5, 0x55, 0x55,
+ 0x55, 0x7f, 0xff, 0xff, 0xfd, 0x55, 0x55,
+ 0x55, 0xff, 0xff, 0xff, 0xff, 0x55, 0x55,
+ 0x55, 0xff, 0xff, 0xff, 0xff, 0x55, 0x55,
+ 0xff, 0xff, 0x55, 0x55, 0xff, 0xff, 0x55,
+ 0xff, 0xff, 0x55, 0x55, 0xff, 0xff, 0x55,
+ 0xff, 0xff, 0x55, 0x55, 0xff, 0xff, 0x55,
+ 0xff, 0xff, 0x55, 0x55, 0xff, 0xff, 0x55,
+ 0xff, 0x55, 0x55, 0x55, 0x55, 0xff, 0x55,
+ 0xff, 0x55, 0x55, 0x55, 0x55, 0xff, 0x55,
+ 0xff, 0x55, 0x55, 0x55, 0x55, 0xff, 0x55,
+ 0xff, 0x55, 0x55, 0x55, 0x55, 0xff, 0x55,
+ 0xff, 0x55, 0x55, 0x55, 0x55, 0xff, 0x55,
+ 0xff, 0x55, 0x55, 0x55, 0x55, 0xff, 0x55,
+ 0xff, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0xff, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0xff, 0x55, 0x55, 0x6a, 0xaa, 0xaa, 0xa9,
+ 0xff, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xff, 0x55, 0x55, 0xaa, 0xa5, 0x5a, 0xaa,
+ 0xff, 0x55, 0x55, 0xaa, 0xa5, 0x5a, 0xaa,
+ 0xff, 0x55, 0x55, 0xaa, 0xa5, 0x5a, 0xaa,
+ 0xff, 0x55, 0x55, 0xaa, 0xa5, 0x5a, 0xaa,
+ 0xff, 0x55, 0x55, 0xaa, 0xa5, 0x5a, 0xaa,
+ 0xff, 0x55, 0x55, 0xaa, 0xa5, 0x5a, 0xaa,
+ 0xff, 0x50, 0x05, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xff, 0x50, 0x05, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xff, 0x55, 0x55, 0xaa, 0xa5, 0x5a, 0xaa,
+ 0xff, 0x55, 0x55, 0xaa, 0xa5, 0x5a, 0xaa,
+ 0xff, 0xff, 0xf5, 0xaa, 0xa5, 0x5a, 0xaa,
+ 0xff, 0xff, 0xf5, 0xaa, 0xa5, 0x5a, 0xaa,
+ 0xff, 0xff, 0xf5, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xff, 0xff, 0xf5, 0x6a, 0xaa, 0xaa, 0xa9,
+};
+
+const lv_img_dsc_t ck_os_battery_010 = {
+ .header.always_zero = 0,
+ .header.w = 28,
+ .header.h = 32,
+ .data_size = 240,
+ .header.cf = LV_IMG_CF_INDEXED_2BIT,
+ .data = ck_os_battery_010_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_battery_010.png b/src/DisplayApp/Icons/battery/os_battery_010.png
new file mode 100644
index 00000000..68a9f406
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_010.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_battery_020.c b/src/DisplayApp/Icons/battery/os_battery_020.c
new file mode 100644
index 00000000..3f648fb9
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_020.c
@@ -0,0 +1,58 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERY_020
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERY_020
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERY_020 uint8_t ck_os_battery_020_map[] = {
+ 0x04, 0x02, 0xcc, 0xff, /*Color of index 0*/
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 1*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 2*/
+ 0xff, 0xff, 0xff, 0xff, /*Color of index 3*/
+
+ 0x55, 0x5a, 0xaa, 0xaa, 0xa5, 0x55,
+ 0x55, 0x6a, 0xaa, 0xaa, 0xa9, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x50, 0x00, 0x00, 0x05, 0xaa,
+ 0xaa, 0x50, 0x00, 0x00, 0x05, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+};
+
+const lv_img_dsc_t ck_os_battery_020 = {
+ .header.always_zero = 0,
+ .header.w = 24,
+ .header.h = 32,
+ .data_size = 208,
+ .header.cf = LV_IMG_CF_INDEXED_2BIT,
+ .data = ck_os_battery_020_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_battery_020.png b/src/DisplayApp/Icons/battery/os_battery_020.png
new file mode 100644
index 00000000..32eca651
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_020.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_battery_030.c b/src/DisplayApp/Icons/battery/os_battery_030.c
new file mode 100644
index 00000000..4d5719b7
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_030.c
@@ -0,0 +1,58 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERY_030
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERY_030
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERY_030 uint8_t ck_os_battery_030_map[] = {
+ 0x04, 0x7a, 0xf4, 0xff, /*Color of index 0*/
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 1*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 2*/
+ 0xff, 0xff, 0xff, 0xff, /*Color of index 3*/
+
+ 0x55, 0x5a, 0xaa, 0xaa, 0xa5, 0x55,
+ 0x55, 0x6a, 0xaa, 0xaa, 0xa9, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x50, 0x00, 0x00, 0x05, 0xaa,
+ 0xaa, 0x50, 0x00, 0x00, 0x05, 0xaa,
+ 0xaa, 0x50, 0x00, 0x00, 0x05, 0xaa,
+ 0xaa, 0x50, 0x00, 0x00, 0x05, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+};
+
+const lv_img_dsc_t ck_os_battery_030 = {
+ .header.always_zero = 0,
+ .header.w = 24,
+ .header.h = 32,
+ .data_size = 208,
+ .header.cf = LV_IMG_CF_INDEXED_2BIT,
+ .data = ck_os_battery_030_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_battery_030.png b/src/DisplayApp/Icons/battery/os_battery_030.png
new file mode 100644
index 00000000..aeb5eb1f
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_030.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_battery_040.c b/src/DisplayApp/Icons/battery/os_battery_040.c
new file mode 100644
index 00000000..0606fc35
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_040.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERY_040
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERY_040
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERY_040 uint8_t ck_os_battery_040_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+
+ 0x03, 0xff, 0xc0,
+ 0x07, 0xff, 0xe0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+};
+
+const lv_img_dsc_t ck_os_battery_040 = {
+ .header.always_zero = 0,
+ .header.w = 24,
+ .header.h = 32,
+ .data_size = 104,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_battery_040_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_battery_040.png b/src/DisplayApp/Icons/battery/os_battery_040.png
new file mode 100644
index 00000000..d84fda40
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_040.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_battery_050.c b/src/DisplayApp/Icons/battery/os_battery_050.c
new file mode 100644
index 00000000..8732dc7a
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_050.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERY_050
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERY_050
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERY_050 uint8_t ck_os_battery_050_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+
+ 0x03, 0xff, 0xc0,
+ 0x07, 0xff, 0xe0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+};
+
+const lv_img_dsc_t ck_os_battery_050 = {
+ .header.always_zero = 0,
+ .header.w = 24,
+ .header.h = 32,
+ .data_size = 104,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_battery_050_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_battery_050.png b/src/DisplayApp/Icons/battery/os_battery_050.png
new file mode 100644
index 00000000..224d38d6
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_050.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_battery_060.c b/src/DisplayApp/Icons/battery/os_battery_060.c
new file mode 100644
index 00000000..a65936bf
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_060.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERY_060
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERY_060
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERY_060 uint8_t ck_os_battery_060_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+
+ 0x03, 0xff, 0xc0,
+ 0x07, 0xff, 0xe0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+};
+
+const lv_img_dsc_t ck_os_battery_060 = {
+ .header.always_zero = 0,
+ .header.w = 24,
+ .header.h = 32,
+ .data_size = 104,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_battery_060_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_battery_060.png b/src/DisplayApp/Icons/battery/os_battery_060.png
new file mode 100644
index 00000000..e5e00eda
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_060.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_battery_070.c b/src/DisplayApp/Icons/battery/os_battery_070.c
new file mode 100644
index 00000000..949c0b8b
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_070.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERY_070
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERY_070
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERY_070 uint8_t ck_os_battery_070_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+
+ 0x03, 0xff, 0xc0,
+ 0x07, 0xff, 0xe0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+};
+
+const lv_img_dsc_t ck_os_battery_070 = {
+ .header.always_zero = 0,
+ .header.w = 24,
+ .header.h = 32,
+ .data_size = 104,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_battery_070_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_battery_070.png b/src/DisplayApp/Icons/battery/os_battery_070.png
new file mode 100644
index 00000000..dee969b8
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_070.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_battery_080.c b/src/DisplayApp/Icons/battery/os_battery_080.c
new file mode 100644
index 00000000..f447370e
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_080.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERY_080
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERY_080
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERY_080 uint8_t ck_os_battery_080_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+
+ 0x03, 0xff, 0xc0,
+ 0x07, 0xff, 0xe0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+};
+
+const lv_img_dsc_t ck_os_battery_080 = {
+ .header.always_zero = 0,
+ .header.w = 24,
+ .header.h = 32,
+ .data_size = 104,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_battery_080_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_battery_080.png b/src/DisplayApp/Icons/battery/os_battery_080.png
new file mode 100644
index 00000000..3b13fbb2
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_080.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_battery_090.c b/src/DisplayApp/Icons/battery/os_battery_090.c
new file mode 100644
index 00000000..6fa41b20
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_090.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERY_090
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERY_090
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERY_090 uint8_t ck_os_battery_090_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+
+ 0x03, 0xff, 0xc0,
+ 0x07, 0xff, 0xe0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+};
+
+const lv_img_dsc_t ck_os_battery_090 = {
+ .header.always_zero = 0,
+ .header.w = 24,
+ .header.h = 32,
+ .data_size = 104,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_battery_090_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_battery_090.png b/src/DisplayApp/Icons/battery/os_battery_090.png
new file mode 100644
index 00000000..d79f396b
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_090.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_battery_100.c b/src/DisplayApp/Icons/battery/os_battery_100.c
new file mode 100644
index 00000000..92cf9a41
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_100.c
@@ -0,0 +1,58 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERY_100
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERY_100
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERY_100 uint8_t ck_os_battery_100_map[] = {
+ 0x7c, 0xd2, 0x34, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 2*/
+ 0xff, 0xff, 0xff, 0xff, /*Color of index 3*/
+
+ 0xaa, 0xa5, 0x55, 0x55, 0x5a, 0xaa,
+ 0xaa, 0x95, 0x55, 0x55, 0x56, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55,
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+};
+
+const lv_img_dsc_t ck_os_battery_100 = {
+ .header.always_zero = 0,
+ .header.w = 24,
+ .header.h = 32,
+ .data_size = 208,
+ .header.cf = LV_IMG_CF_INDEXED_2BIT,
+ .data = ck_os_battery_100_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_battery_100.png b/src/DisplayApp/Icons/battery/os_battery_100.png
new file mode 100644
index 00000000..dd0d306f
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_100.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_battery_error.c b/src/DisplayApp/Icons/battery/os_battery_error.c
new file mode 100644
index 00000000..af6aba5d
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_error.c
@@ -0,0 +1,58 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERY_ERROR
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERY_ERROR
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERY_ERROR uint8_t ck_os_battery_error_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xc4, 0xc2, 0xc4, 0xff, /*Color of index 1*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 2*/
+ 0xff, 0xff, 0xff, 0xff, /*Color of index 3*/
+
+ 0x00, 0x05, 0x55, 0x55, 0x50, 0x00,
+ 0x00, 0x15, 0x55, 0x55, 0x54, 0x00,
+ 0x00, 0x55, 0x55, 0x55, 0x55, 0x00,
+ 0x00, 0x55, 0x55, 0x55, 0x55, 0x00,
+ 0x55, 0x55, 0x00, 0x00, 0x55, 0x55,
+ 0x55, 0x55, 0x00, 0x00, 0x55, 0x55,
+ 0x55, 0x55, 0x00, 0x00, 0x55, 0x55,
+ 0x55, 0x54, 0x00, 0x00, 0x15, 0x55,
+ 0x55, 0x00, 0x0a, 0xa0, 0x00, 0x55,
+ 0x55, 0x00, 0xaa, 0xaa, 0x00, 0x55,
+ 0x55, 0x02, 0xaa, 0xaa, 0x80, 0x55,
+ 0x55, 0x02, 0xaa, 0xaa, 0x80, 0x55,
+ 0x55, 0x0a, 0xa8, 0x2a, 0xa0, 0x55,
+ 0x55, 0x0a, 0xa0, 0x0a, 0xa0, 0x55,
+ 0x55, 0x00, 0x00, 0x0a, 0xa0, 0x55,
+ 0x55, 0x00, 0x00, 0x2a, 0xa0, 0x55,
+ 0x55, 0x00, 0x02, 0xaa, 0x80, 0x55,
+ 0x55, 0x00, 0x0a, 0xaa, 0x80, 0x55,
+ 0x55, 0x00, 0x0a, 0xaa, 0x00, 0x55,
+ 0x55, 0x00, 0x0a, 0xa0, 0x00, 0x55,
+ 0x55, 0x00, 0x0a, 0xa0, 0x00, 0x55,
+ 0x55, 0x00, 0x0a, 0xa0, 0x00, 0x55,
+ 0x55, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x55, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x55, 0x00, 0x02, 0x80, 0x00, 0x55,
+ 0x55, 0x00, 0x0a, 0xa0, 0x00, 0x55,
+ 0x55, 0x00, 0x0a, 0xa0, 0x00, 0x55,
+ 0x55, 0x00, 0x02, 0x80, 0x00, 0x55,
+ 0x55, 0x55, 0x40, 0x01, 0x55, 0x55,
+ 0x55, 0x55, 0x50, 0x05, 0x55, 0x55,
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+};
+
+const lv_img_dsc_t ck_os_battery_error = {
+ .header.always_zero = 0,
+ .header.w = 24,
+ .header.h = 32,
+ .data_size = 208,
+ .header.cf = LV_IMG_CF_INDEXED_2BIT,
+ .data = ck_os_battery_error_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_battery_error.png b/src/DisplayApp/Icons/battery/os_battery_error.png
new file mode 100644
index 00000000..4c7632fe
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_battery_error.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_005.c b/src/DisplayApp/Icons/battery/os_batterycharging_005.c
new file mode 100644
index 00000000..1b0c71df
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_005.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_005
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_005
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_005 uint8_t ck_os_batterycharging_005_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+
+ 0x03, 0xff, 0xc0, 0x00,
+ 0x07, 0xff, 0xe0, 0x00,
+ 0x0f, 0xff, 0xf0, 0x00,
+ 0x0f, 0xff, 0xf0, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x00, 0x00,
+ 0xf0, 0x00, 0x00, 0x00,
+ 0xf0, 0x00, 0x07, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x1f, 0x00,
+ 0xf0, 0x00, 0x3e, 0x00,
+ 0xf0, 0x00, 0x7e, 0x00,
+ 0xf0, 0x00, 0xfc, 0x00,
+ 0xf0, 0x01, 0xff, 0xf0,
+ 0xf0, 0x03, 0xff, 0xf0,
+ 0xf0, 0x03, 0xff, 0xf0,
+ 0xf0, 0x03, 0xff, 0xe0,
+ 0xf0, 0x00, 0x0f, 0xc0,
+ 0xf0, 0x00, 0x1f, 0x80,
+ 0xff, 0xff, 0x3f, 0x00,
+ 0xff, 0xff, 0x3e, 0x00,
+ 0xff, 0xff, 0x3c, 0x00,
+ 0xff, 0xff, 0x38, 0x00,
+};
+
+const lv_img_dsc_t ck_os_batterycharging_005 = {
+ .header.always_zero = 0,
+ .header.w = 28,
+ .header.h = 32,
+ .data_size = 136,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_batterycharging_005_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_005.png b/src/DisplayApp/Icons/battery/os_batterycharging_005.png
new file mode 100644
index 00000000..f9545bc1
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_005.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_010.c b/src/DisplayApp/Icons/battery/os_batterycharging_010.c
new file mode 100644
index 00000000..304c0184
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_010.c
@@ -0,0 +1,58 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_010
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_010
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_010 uint8_t ck_os_batterycharging_010_map[] = {
+ 0x04, 0x02, 0xcc, 0xff, /*Color of index 0*/
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 1*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 2*/
+ 0xff, 0xff, 0xff, 0xff, /*Color of index 3*/
+
+ 0x55, 0x5a, 0xaa, 0xaa, 0xa5, 0x55, 0x55,
+ 0x55, 0x6a, 0xaa, 0xaa, 0xa9, 0x55, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0x6a, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x56, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x5a, 0xa9, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x6a, 0xa9, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0xaa, 0xa5, 0x55,
+ 0xaa, 0x55, 0x55, 0x56, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0x55, 0x55, 0x5a, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0x50, 0x00, 0x5a, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0x50, 0x00, 0x5a, 0xaa, 0xaa, 0xa9,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xa5,
+ 0xaa, 0x55, 0x55, 0x55, 0x56, 0xaa, 0x95,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x5a, 0xaa, 0x55,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x5a, 0xa9, 0x55,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x5a, 0xa5, 0x55,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x5a, 0x95, 0x55,
+};
+
+const lv_img_dsc_t ck_os_batterycharging_010 = {
+ .header.always_zero = 0,
+ .header.w = 28,
+ .header.h = 32,
+ .data_size = 240,
+ .header.cf = LV_IMG_CF_INDEXED_2BIT,
+ .data = ck_os_batterycharging_010_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_010.png b/src/DisplayApp/Icons/battery/os_batterycharging_010.png
new file mode 100644
index 00000000..04d5f820
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_010.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_020.c b/src/DisplayApp/Icons/battery/os_batterycharging_020.c
new file mode 100644
index 00000000..1721be15
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_020.c
@@ -0,0 +1,58 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_020
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_020
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_020 uint8_t ck_os_batterycharging_020_map[] = {
+ 0x04, 0x02, 0xcc, 0xff, /*Color of index 0*/
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 1*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 2*/
+ 0xff, 0xff, 0xff, 0xff, /*Color of index 3*/
+
+ 0x55, 0x5a, 0xaa, 0xaa, 0xa5, 0x55, 0x55,
+ 0x55, 0x6a, 0xaa, 0xaa, 0xa9, 0x55, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0x6a, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x56, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x5a, 0xa9, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x6a, 0xa9, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0xaa, 0xa5, 0x55,
+ 0xaa, 0x55, 0x55, 0x56, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0x55, 0x55, 0x5a, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0x50, 0x00, 0x5a, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0x50, 0x00, 0x5a, 0xaa, 0xaa, 0xa9,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xa5,
+ 0xaa, 0x55, 0x55, 0x55, 0x56, 0xaa, 0x95,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x5a, 0xaa, 0x55,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x5a, 0xa9, 0x55,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x5a, 0xa5, 0x55,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x5a, 0x95, 0x55,
+};
+
+const lv_img_dsc_t ck_os_batterycharging_020 = {
+ .header.always_zero = 0,
+ .header.w = 28,
+ .header.h = 32,
+ .data_size = 240,
+ .header.cf = LV_IMG_CF_INDEXED_2BIT,
+ .data = ck_os_batterycharging_020_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_020.png b/src/DisplayApp/Icons/battery/os_batterycharging_020.png
new file mode 100644
index 00000000..6416e1e6
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_020.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_030.c b/src/DisplayApp/Icons/battery/os_batterycharging_030.c
new file mode 100644
index 00000000..83101fd9
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_030.c
@@ -0,0 +1,58 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_030
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_030
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_030 uint8_t ck_os_batterycharging_030_map[] = {
+ 0x04, 0x7a, 0xf4, 0xff, /*Color of index 0*/
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 1*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 2*/
+ 0xff, 0xff, 0xff, 0xff, /*Color of index 3*/
+
+ 0x55, 0x5a, 0xaa, 0xaa, 0xa5, 0x55, 0x55,
+ 0x55, 0x6a, 0xaa, 0xaa, 0xa9, 0x55, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0x6a, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x56, 0xaa, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x5a, 0xa9, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0x6a, 0xa9, 0x55,
+ 0xaa, 0x55, 0x55, 0x55, 0xaa, 0xa5, 0x55,
+ 0xaa, 0x50, 0x00, 0x56, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0x50, 0x00, 0x5a, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0x50, 0x00, 0x5a, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0x50, 0x00, 0x5a, 0xaa, 0xaa, 0xa9,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xa5,
+ 0xaa, 0x55, 0x55, 0x55, 0x56, 0xaa, 0x95,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x5a, 0xaa, 0x55,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x5a, 0xa9, 0x55,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x5a, 0xa5, 0x55,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x5a, 0x95, 0x55,
+};
+
+const lv_img_dsc_t ck_os_batterycharging_030 = {
+ .header.always_zero = 0,
+ .header.w = 28,
+ .header.h = 32,
+ .data_size = 240,
+ .header.cf = LV_IMG_CF_INDEXED_2BIT,
+ .data = ck_os_batterycharging_030_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_030.png b/src/DisplayApp/Icons/battery/os_batterycharging_030.png
new file mode 100644
index 00000000..96b44d2e
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_030.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_040.c b/src/DisplayApp/Icons/battery/os_batterycharging_040.c
new file mode 100644
index 00000000..02af00e5
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_040.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_040
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_040
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_040 uint8_t ck_os_batterycharging_040_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+
+ 0x03, 0xff, 0xc0, 0x00,
+ 0x07, 0xff, 0xe0, 0x00,
+ 0x0f, 0xff, 0xf0, 0x00,
+ 0x0f, 0xff, 0xf0, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x00, 0x00,
+ 0xf0, 0x00, 0x00, 0x00,
+ 0xf0, 0x00, 0x07, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x1f, 0x00,
+ 0xf0, 0x00, 0x3e, 0x00,
+ 0xf3, 0xf8, 0x7e, 0x00,
+ 0xf3, 0xf0, 0xfc, 0x00,
+ 0xf3, 0xf1, 0xff, 0xf0,
+ 0xf3, 0xf3, 0xff, 0xf0,
+ 0xf3, 0xf3, 0xff, 0xf0,
+ 0xf3, 0xf3, 0xff, 0xe0,
+ 0xf0, 0x00, 0x0f, 0xc0,
+ 0xf0, 0x00, 0x1f, 0x80,
+ 0xff, 0xff, 0x3f, 0x00,
+ 0xff, 0xff, 0x3e, 0x00,
+ 0xff, 0xff, 0x3c, 0x00,
+ 0xff, 0xff, 0x38, 0x00,
+};
+
+const lv_img_dsc_t ck_os_batterycharging_040 = {
+ .header.always_zero = 0,
+ .header.w = 28,
+ .header.h = 32,
+ .data_size = 136,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_batterycharging_040_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_040.png b/src/DisplayApp/Icons/battery/os_batterycharging_040.png
new file mode 100644
index 00000000..5a42caf2
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_040.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_050.c b/src/DisplayApp/Icons/battery/os_batterycharging_050.c
new file mode 100644
index 00000000..d2eea829
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_050.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_050
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_050
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_050 uint8_t ck_os_batterycharging_050_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+
+ 0x03, 0xff, 0xc0, 0x00,
+ 0x07, 0xff, 0xe0, 0x00,
+ 0x0f, 0xff, 0xf0, 0x00,
+ 0x0f, 0xff, 0xf0, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x00, 0x00,
+ 0xf0, 0x00, 0x00, 0x00,
+ 0xf0, 0x00, 0x07, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf3, 0xfe, 0x1f, 0x00,
+ 0xf3, 0xfc, 0x3e, 0x00,
+ 0xf3, 0xf8, 0x7e, 0x00,
+ 0xf3, 0xf0, 0xfc, 0x00,
+ 0xf3, 0xf1, 0xff, 0xf0,
+ 0xf3, 0xf3, 0xff, 0xf0,
+ 0xf3, 0xf3, 0xff, 0xf0,
+ 0xf3, 0xf3, 0xff, 0xe0,
+ 0xf0, 0x00, 0x0f, 0xc0,
+ 0xf0, 0x00, 0x1f, 0x80,
+ 0xff, 0xff, 0x3f, 0x00,
+ 0xff, 0xff, 0x3e, 0x00,
+ 0xff, 0xff, 0x3c, 0x00,
+ 0xff, 0xff, 0x38, 0x00,
+};
+
+const lv_img_dsc_t ck_os_batterycharging_050 = {
+ .header.always_zero = 0,
+ .header.w = 28,
+ .header.h = 32,
+ .data_size = 136,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_batterycharging_050_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_050.png b/src/DisplayApp/Icons/battery/os_batterycharging_050.png
new file mode 100644
index 00000000..ca0e04dd
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_050.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_060.c b/src/DisplayApp/Icons/battery/os_batterycharging_060.c
new file mode 100644
index 00000000..05f8b975
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_060.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_060
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_060
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_060 uint8_t ck_os_batterycharging_060_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+
+ 0x03, 0xff, 0xc0, 0x00,
+ 0x07, 0xff, 0xe0, 0x00,
+ 0x0f, 0xff, 0xf0, 0x00,
+ 0x0f, 0xff, 0xf0, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x00, 0x00,
+ 0xf0, 0x00, 0x00, 0x00,
+ 0xf3, 0xff, 0x87, 0x00,
+ 0xf3, 0xff, 0x0f, 0x00,
+ 0xf3, 0xfe, 0x1f, 0x00,
+ 0xf3, 0xfc, 0x3e, 0x00,
+ 0xf3, 0xf8, 0x7e, 0x00,
+ 0xf3, 0xf0, 0xfc, 0x00,
+ 0xf3, 0xf1, 0xff, 0xf0,
+ 0xf3, 0xf3, 0xff, 0xf0,
+ 0xf3, 0xf3, 0xff, 0xf0,
+ 0xf3, 0xf3, 0xff, 0xe0,
+ 0xf0, 0x00, 0x0f, 0xc0,
+ 0xf0, 0x00, 0x1f, 0x80,
+ 0xff, 0xff, 0x3f, 0x00,
+ 0xff, 0xff, 0x3e, 0x00,
+ 0xff, 0xff, 0x3c, 0x00,
+ 0xff, 0xff, 0x38, 0x00,
+};
+
+const lv_img_dsc_t ck_os_batterycharging_060 = {
+ .header.always_zero = 0,
+ .header.w = 28,
+ .header.h = 32,
+ .data_size = 136,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_batterycharging_060_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_060.png b/src/DisplayApp/Icons/battery/os_batterycharging_060.png
new file mode 100644
index 00000000..2930068a
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_060.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_070.c b/src/DisplayApp/Icons/battery/os_batterycharging_070.c
new file mode 100644
index 00000000..ac3e319c
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_070.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_070
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_070
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_070 uint8_t ck_os_batterycharging_070_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+
+ 0x03, 0xff, 0xc0, 0x00,
+ 0x07, 0xff, 0xe0, 0x00,
+ 0x0f, 0xff, 0xf0, 0x00,
+ 0x0f, 0xff, 0xf0, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0xff, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf0, 0x00, 0x0f, 0x00,
+ 0xf3, 0xff, 0xc0, 0x00,
+ 0xf3, 0xff, 0xc0, 0x00,
+ 0xf3, 0xff, 0x87, 0x00,
+ 0xf3, 0xff, 0x0f, 0x00,
+ 0xf3, 0xfe, 0x1f, 0x00,
+ 0xf3, 0xfc, 0x3e, 0x00,
+ 0xf3, 0xf8, 0x7e, 0x00,
+ 0xf3, 0xf0, 0xfc, 0x00,
+ 0xf3, 0xf1, 0xff, 0xf0,
+ 0xf3, 0xf3, 0xff, 0xf0,
+ 0xf3, 0xf3, 0xff, 0xf0,
+ 0xf3, 0xf3, 0xff, 0xe0,
+ 0xf0, 0x00, 0x0f, 0xc0,
+ 0xf0, 0x00, 0x1f, 0x80,
+ 0xff, 0xff, 0x3f, 0x00,
+ 0xff, 0xff, 0x3e, 0x00,
+ 0xff, 0xff, 0x3c, 0x00,
+ 0xff, 0xff, 0x38, 0x00,
+};
+
+const lv_img_dsc_t ck_os_batterycharging_070 = {
+ .header.always_zero = 0,
+ .header.w = 28,
+ .header.h = 32,
+ .data_size = 136,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_batterycharging_070_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_070.png b/src/DisplayApp/Icons/battery/os_batterycharging_070.png
new file mode 100644
index 00000000..7d5f55d7
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_070.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_080.c b/src/DisplayApp/Icons/battery/os_batterycharging_080.c
new file mode 100644
index 00000000..cc1c1d23
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_080.c
@@ -0,0 +1,58 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_080
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_080
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_080 uint8_t ck_os_batterycharging_080_map[] = {
+ 0x7c, 0xd2, 0x34, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 2*/
+ 0xff, 0xff, 0xff, 0xff, /*Color of index 3*/
+
+ 0xaa, 0xa5, 0x55, 0x55, 0x5a, 0xaa, 0xaa,
+ 0xaa, 0x95, 0x55, 0x55, 0x56, 0xaa, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0xaa,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0xaa,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0xaa,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0xaa, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0xaa, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0x2a, 0x95, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0xaa, 0x55, 0xaa,
+ 0x55, 0xa0, 0x00, 0x02, 0xa9, 0x55, 0xaa,
+ 0x55, 0xa0, 0x00, 0x0a, 0xa5, 0x56, 0xaa,
+ 0x55, 0xa0, 0x00, 0x2a, 0x95, 0x56, 0xaa,
+ 0x55, 0xa0, 0x00, 0xaa, 0x55, 0x5a, 0xaa,
+ 0x55, 0xa0, 0x00, 0xa9, 0x55, 0x55, 0x55,
+ 0x55, 0xa0, 0x00, 0xa5, 0x55, 0x55, 0x55,
+ 0x55, 0xa0, 0x00, 0xa5, 0x55, 0x55, 0x55,
+ 0x55, 0xa0, 0x00, 0xa5, 0x55, 0x55, 0x56,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x5a,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xa9, 0x55, 0x6a,
+ 0x55, 0x55, 0x55, 0x55, 0xa5, 0x55, 0xaa,
+ 0x55, 0x55, 0x55, 0x55, 0xa5, 0x56, 0xaa,
+ 0x55, 0x55, 0x55, 0x55, 0xa5, 0x5a, 0xaa,
+ 0x55, 0x55, 0x55, 0x55, 0xa5, 0x6a, 0xaa,
+};
+
+const lv_img_dsc_t ck_os_batterycharging_080 = {
+ .header.always_zero = 0,
+ .header.w = 28,
+ .header.h = 32,
+ .data_size = 240,
+ .header.cf = LV_IMG_CF_INDEXED_2BIT,
+ .data = ck_os_batterycharging_080_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_080.png b/src/DisplayApp/Icons/battery/os_batterycharging_080.png
new file mode 100644
index 00000000..cce5052f
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_080.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_090.c b/src/DisplayApp/Icons/battery/os_batterycharging_090.c
new file mode 100644
index 00000000..85e1c260
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_090.c
@@ -0,0 +1,58 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_090
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_090
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_090 uint8_t ck_os_batterycharging_090_map[] = {
+ 0x7c, 0xd2, 0x34, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 2*/
+ 0xff, 0xff, 0xff, 0xff, /*Color of index 3*/
+
+ 0xaa, 0xa5, 0x55, 0x55, 0x5a, 0xaa, 0xaa,
+ 0xaa, 0x95, 0x55, 0x55, 0x56, 0xaa, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa,
+ 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0xaa,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0x55, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0xaa, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0x0a, 0xaa, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0x2a, 0x95, 0xaa,
+ 0x55, 0xa0, 0x00, 0x00, 0xaa, 0x55, 0xaa,
+ 0x55, 0xa0, 0x00, 0x02, 0xa9, 0x55, 0xaa,
+ 0x55, 0xa0, 0x00, 0x0a, 0xa5, 0x56, 0xaa,
+ 0x55, 0xa0, 0x00, 0x2a, 0x95, 0x56, 0xaa,
+ 0x55, 0xa0, 0x00, 0xaa, 0x55, 0x5a, 0xaa,
+ 0x55, 0xa0, 0x00, 0xa9, 0x55, 0x55, 0x55,
+ 0x55, 0xa0, 0x00, 0xa5, 0x55, 0x55, 0x55,
+ 0x55, 0xa0, 0x00, 0xa5, 0x55, 0x55, 0x55,
+ 0x55, 0xa0, 0x00, 0xa5, 0x55, 0x55, 0x56,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x5a,
+ 0x55, 0xaa, 0xaa, 0xaa, 0xa9, 0x55, 0x6a,
+ 0x55, 0x55, 0x55, 0x55, 0xa5, 0x55, 0xaa,
+ 0x55, 0x55, 0x55, 0x55, 0xa5, 0x56, 0xaa,
+ 0x55, 0x55, 0x55, 0x55, 0xa5, 0x5a, 0xaa,
+ 0x55, 0x55, 0x55, 0x55, 0xa5, 0x6a, 0xaa,
+};
+
+const lv_img_dsc_t ck_os_batterycharging_090 = {
+ .header.always_zero = 0,
+ .header.w = 28,
+ .header.h = 32,
+ .data_size = 240,
+ .header.cf = LV_IMG_CF_INDEXED_2BIT,
+ .data = ck_os_batterycharging_090_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_090.png b/src/DisplayApp/Icons/battery/os_batterycharging_090.png
new file mode 100644
index 00000000..fc7b443d
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_090.png
Binary files differ
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_100.c b/src/DisplayApp/Icons/battery/os_batterycharging_100.c
new file mode 100644
index 00000000..8dec0cb5
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_100.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_100
+#define LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_100
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BATTERYCHARGING_100 uint8_t ck_os_batterycharging_100_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+
+ 0x03, 0xff, 0xc0,
+ 0x07, 0xff, 0xe0,
+ 0x0f, 0xff, 0xf0,
+ 0x0f, 0xff, 0xf0,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xff, 0x00, 0xff,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x07, 0x0f,
+ 0xf0, 0x0f, 0x0f,
+ 0xf0, 0x1f, 0x0f,
+ 0xf0, 0x3e, 0x0f,
+ 0xf0, 0x7e, 0x0f,
+ 0xf0, 0xfc, 0x0f,
+ 0xf1, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0xcf,
+ 0xf3, 0xff, 0x8f,
+ 0xf0, 0x3f, 0x0f,
+ 0xf0, 0x7e, 0x0f,
+ 0xf0, 0x7c, 0x0f,
+ 0xf0, 0xf8, 0x0f,
+ 0xf0, 0xf0, 0x0f,
+ 0xf0, 0xe0, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xf0, 0x00, 0x0f,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff,
+};
+
+const lv_img_dsc_t ck_os_batterycharging_100 = {
+ .header.always_zero = 0,
+ .header.w = 24,
+ .header.h = 32,
+ .data_size = 104,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_batterycharging_100_map,
+};
diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_100.png b/src/DisplayApp/Icons/battery/os_batterycharging_100.png
new file mode 100644
index 00000000..7c8ce0c4
--- /dev/null
+++ b/src/DisplayApp/Icons/battery/os_batterycharging_100.png
Binary files differ
diff --git a/src/DisplayApp/Icons/bluetooth/ck_os_bt_connected.png b/src/DisplayApp/Icons/bluetooth/ck_os_bt_connected.png
new file mode 100644
index 00000000..53716115
--- /dev/null
+++ b/src/DisplayApp/Icons/bluetooth/ck_os_bt_connected.png
Binary files differ
diff --git a/src/DisplayApp/Icons/bluetooth/ck_os_bt_disconnected.png b/src/DisplayApp/Icons/bluetooth/ck_os_bt_disconnected.png
new file mode 100644
index 00000000..3275895d
--- /dev/null
+++ b/src/DisplayApp/Icons/bluetooth/ck_os_bt_disconnected.png
Binary files differ
diff --git a/src/DisplayApp/Icons/bluetooth/os_bt_connected.c b/src/DisplayApp/Icons/bluetooth/os_bt_connected.c
new file mode 100644
index 00000000..d30dc9d0
--- /dev/null
+++ b/src/DisplayApp/Icons/bluetooth/os_bt_connected.c
@@ -0,0 +1,56 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BT_CONNECTED
+#define LV_ATTRIBUTE_IMG_CK_OS_BT_CONNECTED
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BT_CONNECTED uint8_t ck_os_bt_connected_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 1*/
+
+ 0x00, 0x0e, 0x00, 0x00,
+ 0x00, 0x0f, 0x00, 0x00,
+ 0x00, 0x0f, 0x80, 0x00,
+ 0x00, 0x0f, 0xc0, 0x00,
+ 0x00, 0x0f, 0xe0, 0x00,
+ 0x00, 0x0f, 0xf0, 0x00,
+ 0x03, 0x8f, 0xf8, 0x00,
+ 0x03, 0xcf, 0x7c, 0x00,
+ 0x03, 0xef, 0x3e, 0x00,
+ 0x01, 0xff, 0x1f, 0x00,
+ 0x00, 0xff, 0x1f, 0x00,
+ 0x00, 0x7f, 0x3e, 0x00,
+ 0x00, 0x3f, 0x7c, 0x00,
+ 0x00, 0x1f, 0xf8, 0x00,
+ 0x00, 0x0f, 0xf0, 0x00,
+ 0x00, 0x0f, 0xe0, 0x00,
+ 0x00, 0x0f, 0xe0, 0x00,
+ 0x00, 0x0f, 0xf0, 0x00,
+ 0x00, 0x1f, 0xf8, 0x00,
+ 0x00, 0x3f, 0x7c, 0x00,
+ 0x00, 0x7f, 0x3e, 0x00,
+ 0x00, 0xff, 0x1f, 0x00,
+ 0x01, 0xff, 0x1f, 0x00,
+ 0x03, 0xef, 0x3e, 0x00,
+ 0x03, 0xcf, 0x7c, 0x00,
+ 0x03, 0x8f, 0xf8, 0x00,
+ 0x00, 0x0f, 0xf0, 0x00,
+ 0x00, 0x0f, 0xe0, 0x00,
+ 0x00, 0x0f, 0xc0, 0x00,
+ 0x00, 0x0f, 0x80, 0x00,
+ 0x00, 0x0f, 0x00, 0x00,
+ 0x00, 0x0e, 0x00, 0x00,
+};
+
+const lv_img_dsc_t ck_os_bt_connected = {
+ .header.always_zero = 0,
+ .header.w = 32,
+ .header.h = 32,
+ .data_size = 136,
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .data = ck_os_bt_connected_map,
+};
diff --git a/src/DisplayApp/Icons/bluetooth/os_bt_connected.png b/src/DisplayApp/Icons/bluetooth/os_bt_connected.png
new file mode 100644
index 00000000..53716115
--- /dev/null
+++ b/src/DisplayApp/Icons/bluetooth/os_bt_connected.png
Binary files differ
diff --git a/src/DisplayApp/Icons/bluetooth/os_bt_disconnected.c b/src/DisplayApp/Icons/bluetooth/os_bt_disconnected.c
new file mode 100644
index 00000000..930179b6
--- /dev/null
+++ b/src/DisplayApp/Icons/bluetooth/os_bt_disconnected.c
@@ -0,0 +1,58 @@
+#include "lvgl/lvgl.h"
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_CK_OS_BT_DISCONNECTED
+#define LV_ATTRIBUTE_IMG_CK_OS_BT_DISCONNECTED
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_CK_OS_BT_DISCONNECTED uint8_t ck_os_bt_disconnected_map[] = {
+ 0x6c, 0xfe, 0x6c, 0xff, /*Color of index 0*/
+ 0xc4, 0xc2, 0xc4, 0xff, /*Color of index 1*/
+ 0xe4, 0xe6, 0xe4, 0xff, /*Color of index 2*/
+ 0xff, 0xff, 0xff, 0xff, /*Color of index 3*/
+
+ 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00,
+ 0x2a, 0x80, 0x00, 0x55, 0x40, 0x00, 0x00, 0x00,
+ 0x2a, 0xa0, 0x00, 0x55, 0x50, 0x00, 0x00, 0x00,
+ 0x0a, 0xa8, 0x00, 0x55, 0x54, 0x00, 0x00, 0x00,
+ 0x02, 0xaa, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00,
+ 0x00, 0xaa, 0x80, 0x55, 0x55, 0x40, 0x00, 0x00,
+ 0x00, 0x2a, 0xa0, 0x55, 0x15, 0x50, 0x00, 0x00,
+ 0x00, 0x0a, 0xa8, 0x15, 0x05, 0x54, 0x00, 0x00,
+ 0x00, 0x02, 0xaa, 0x05, 0x01, 0x55, 0x00, 0x00,
+ 0x00, 0x00, 0xaa, 0x81, 0x01, 0x55, 0x00, 0x00,
+ 0x00, 0x00, 0x2a, 0xa0, 0x05, 0x54, 0x00, 0x00,
+ 0x00, 0x00, 0x0a, 0xa8, 0x15, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0xaa, 0x05, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xaa, 0x81, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2a, 0xa0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0xa8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xaa, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x50, 0xaa, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x05, 0x54, 0x2a, 0xa0, 0x00, 0x00,
+ 0x00, 0x00, 0x15, 0x55, 0x0a, 0xa8, 0x00, 0x00,
+ 0x00, 0x00, 0x55, 0x55, 0x02, 0xaa, 0x00, 0x00,
+ 0x00, 0x01, 0x55, 0x55, 0x00, 0xaa, 0x80, 0x00,
+ 0x00, 0x05, 0x54, 0x55, 0x04, 0x2a, 0xa0, 0x00,
+ 0x00, 0x05, 0x50, 0x55, 0x15, 0x0a, 0xa8, 0x00,
+ 0x00, 0x05, 0x40, 0x55, 0x55, 0x42, 0xaa, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0xaa, 0x80,
+ 0x00, 0x00, 0x00, 0x55, 0x54, 0x00, 0x2a, 0xa0,
+ 0x00, 0x00, 0x00, 0x55, 0x50, 0x00, 0x0a, 0xa8,
+ 0x00, 0x00, 0x00, 0x55, 0x40, 0x00, 0x02, 0xa8,
+ 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xa0,
+ 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00,
+};
+
+const lv_img_dsc_t ck_os_bt_disconnected = {
+ .header.always_zero = 0,
+ .header.w = 32,
+ .header.h = 32,
+ .data_size = 272,
+ .header.cf = LV_IMG_CF_INDEXED_2BIT,
+ .data = ck_os_bt_disconnected_map,
+};
diff --git a/src/DisplayApp/Icons/bluetooth/os_bt_disconnected.png b/src/DisplayApp/Icons/bluetooth/os_bt_disconnected.png
new file mode 100644
index 00000000..3275895d
--- /dev/null
+++ b/src/DisplayApp/Icons/bluetooth/os_bt_disconnected.png
Binary files differ
diff --git a/src/DisplayApp/Screens/BatteryIcon.cpp b/src/DisplayApp/Screens/BatteryIcon.cpp
new file mode 100644
index 00000000..e20167d8
--- /dev/null
+++ b/src/DisplayApp/Screens/BatteryIcon.cpp
@@ -0,0 +1,62 @@
+#include "BatteryIcon.h"
+
+using namespace Pinetime::Applications::Screens;
+
+
+extern lv_img_dsc_t ck_os_battery_error;
+extern lv_img_dsc_t ck_os_batterycharging_100;
+extern lv_img_dsc_t ck_os_batterycharging_090;
+extern lv_img_dsc_t ck_os_batterycharging_080;
+extern lv_img_dsc_t ck_os_batterycharging_070;
+extern lv_img_dsc_t ck_os_batterycharging_060;
+extern lv_img_dsc_t ck_os_batterycharging_050;
+extern lv_img_dsc_t ck_os_batterycharging_040;
+extern lv_img_dsc_t ck_os_batterycharging_030;
+extern lv_img_dsc_t ck_os_batterycharging_020;
+extern lv_img_dsc_t ck_os_batterycharging_010;
+extern lv_img_dsc_t ck_os_batterycharging_005;
+
+extern lv_img_dsc_t ck_os_battery_100;
+extern lv_img_dsc_t ck_os_battery_090;
+extern lv_img_dsc_t ck_os_battery_080;
+extern lv_img_dsc_t ck_os_battery_070;
+extern lv_img_dsc_t ck_os_battery_060;
+extern lv_img_dsc_t ck_os_battery_050;
+extern lv_img_dsc_t ck_os_battery_040;
+extern lv_img_dsc_t ck_os_battery_030;
+extern lv_img_dsc_t ck_os_battery_020;
+extern lv_img_dsc_t ck_os_battery_010;
+extern lv_img_dsc_t ck_os_battery_005;
+
+
+lv_img_dsc_t *BatteryIcon::GetIcon(bool isCharging, float batteryPercent) {
+ if(isCharging) {
+ if(batteryPercent > 90.0f) return &ck_os_batterycharging_100;
+ else if(batteryPercent > 80.0f) return &ck_os_batterycharging_090;
+ else if(batteryPercent > 70.0f) return &ck_os_batterycharging_080;
+ else if(batteryPercent > 60.0f) return &ck_os_batterycharging_070;
+ else if(batteryPercent > 50.0f) return &ck_os_batterycharging_060;
+ else if(batteryPercent > 40.0f) return &ck_os_batterycharging_050;
+ else if(batteryPercent > 30.0f) return &ck_os_batterycharging_040;
+ else if(batteryPercent > 20.0f) return &ck_os_batterycharging_030;
+ else if(batteryPercent > 10.0f) return &ck_os_batterycharging_020;
+ else if(batteryPercent > 5.0f) return &ck_os_batterycharging_010;
+ else return &ck_os_batterycharging_005;
+ } else {
+ if(batteryPercent > 90.0f) return &ck_os_battery_100;
+ else if(batteryPercent > 80.0f) return &ck_os_battery_090;
+ else if(batteryPercent > 70.0f) return &ck_os_battery_080;
+ else if(batteryPercent > 60.0f) return &ck_os_battery_070;
+ else if(batteryPercent > 50.0f) return &ck_os_battery_060;
+ else if(batteryPercent > 40.0f) return &ck_os_battery_050;
+ else if(batteryPercent > 30.0f) return &ck_os_battery_040;
+ else if(batteryPercent > 20.0f) return &ck_os_battery_030;
+ else if(batteryPercent > 10.0f) return &ck_os_battery_020;
+ else if(batteryPercent > 5.0f) return &ck_os_battery_010;
+ else return &ck_os_battery_005;
+ }
+}
+
+lv_img_dsc_t *BatteryIcon::GetUnknownIcon() {
+ return &ck_os_battery_error;
+}
diff --git a/src/DisplayApp/Screens/BatteryIcon.h b/src/DisplayApp/Screens/BatteryIcon.h
new file mode 100644
index 00000000..4e2a3a03
--- /dev/null
+++ b/src/DisplayApp/Screens/BatteryIcon.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <libs/lvgl/src/lv_draw/lv_img_decoder.h>
+
+namespace Pinetime {
+ namespace Applications {
+ namespace Screens {
+ class BatteryIcon {
+ public:
+ static lv_img_dsc_t* GetUnknownIcon();
+ static lv_img_dsc_t* GetIcon(bool isCharging, float batteryPercent);
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/src/DisplayApp/Screens/BleIcon.cpp b/src/DisplayApp/Screens/BleIcon.cpp
new file mode 100644
index 00000000..28a7727c
--- /dev/null
+++ b/src/DisplayApp/Screens/BleIcon.cpp
@@ -0,0 +1,12 @@
+#include "BleIcon.h"
+
+using namespace Pinetime::Applications::Screens;
+
+
+extern lv_img_dsc_t ck_os_bt_connected;
+extern lv_img_dsc_t ck_os_bt_disconnected;
+
+lv_img_dsc_t *BleIcon::GetIcon(bool isConnected) {
+ if(isConnected) return &ck_os_bt_connected;
+ else return &ck_os_bt_disconnected;
+} \ No newline at end of file
diff --git a/src/DisplayApp/Screens/BleIcon.h b/src/DisplayApp/Screens/BleIcon.h
new file mode 100644
index 00000000..ee090f96
--- /dev/null
+++ b/src/DisplayApp/Screens/BleIcon.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <libs/lvgl/src/lv_draw/lv_img_decoder.h>
+
+namespace Pinetime {
+ namespace Applications {
+ namespace Screens {
+ class BleIcon {
+ public:
+ static lv_img_dsc_t* GetIcon(bool isConnected);
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/src/DisplayApp/Screens/Brightness.cpp b/src/DisplayApp/Screens/Brightness.cpp
new file mode 100644
index 00000000..9e3416c0
--- /dev/null
+++ b/src/DisplayApp/Screens/Brightness.cpp
@@ -0,0 +1,92 @@
+#include <libs/lvgl/lvgl.h>
+#include "Brightness.h"
+
+using namespace Pinetime::Applications::Screens;
+
+void slider_event_cb(lv_obj_t * slider, lv_event_t event) {
+ if(event == LV_EVENT_VALUE_CHANGED) {
+ auto* brightnessSlider = static_cast<Brightness*>(slider->user_data);
+ brightnessSlider->OnValueChanged();
+ }
+}
+
+Brightness::Brightness(Pinetime::Applications::DisplayApp *app, Controllers::BrightnessController& brightness) : Screen(app), brightness{brightness} {
+ slider = lv_slider_create(lv_scr_act(), NULL);
+ lv_obj_set_user_data(slider, this);
+ lv_obj_set_width(slider, LV_DPI * 2);
+ lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0);
+ lv_obj_set_event_cb(slider, slider_event_cb);
+ lv_slider_set_range(slider, 0, 2);
+ lv_slider_set_value(slider, LevelToInt(brightness.Level()), LV_ANIM_OFF);
+
+ slider_label = lv_label_create(lv_scr_act(), NULL);
+ lv_label_set_text(slider_label, LevelToString(brightness.Level()));
+ lv_obj_set_auto_realign(slider_label, true);
+ lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
+}
+
+Brightness::~Brightness() {
+ lv_obj_clean(lv_scr_act());
+}
+
+bool Brightness::Refresh() {
+ return running;
+}
+
+bool Brightness::OnButtonPushed() {
+ running = false;
+ return true;
+}
+
+const char *Brightness::LevelToString(Pinetime::Controllers::BrightnessController::Levels level) {
+ switch(level) {
+ case Pinetime::Controllers::BrightnessController::Levels::Off: return "Off";
+ case Pinetime::Controllers::BrightnessController::Levels::Low: return "Low";
+ case Pinetime::Controllers::BrightnessController::Levels::Medium: return "Medium";
+ case Pinetime::Controllers::BrightnessController::Levels::High: return "High";
+ default : return "???";
+ }
+}
+
+void Brightness::OnValueChanged() {
+ SetValue(lv_slider_get_value(slider));
+}
+
+void Brightness::SetValue(uint8_t value) {
+ switch(value) {
+ case 0: brightness.Set(Controllers::BrightnessController::Levels::Low); break;
+ case 1: brightness.Set(Controllers::BrightnessController::Levels::Medium); break;
+ case 2: brightness.Set(Controllers::BrightnessController::Levels::High); break;
+ }
+ lv_label_set_text(slider_label, LevelToString(brightness.Level()));
+}
+
+uint8_t Brightness::LevelToInt(Pinetime::Controllers::BrightnessController::Levels level) {
+ switch(level) {
+ case Pinetime::Controllers::BrightnessController::Levels::Off: return 0;
+ case Pinetime::Controllers::BrightnessController::Levels::Low: return 0;
+ case Pinetime::Controllers::BrightnessController::Levels::Medium: return 1;
+ case Pinetime::Controllers::BrightnessController::Levels::High: return 2;
+ default : return 0;
+ }
+}
+
+bool Brightness::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
+ switch(event) {
+ case TouchEvents::SwipeLeft:
+ brightness.Lower();
+ SetValue();
+ return true;
+ case TouchEvents::SwipeRight:
+ brightness.Higher();
+ SetValue();
+ return true;
+ default:
+ return false;
+ }
+}
+
+void Brightness::SetValue() {
+ lv_slider_set_value(slider, LevelToInt(brightness.Level()), LV_ANIM_OFF);
+ lv_label_set_text(slider_label, LevelToString(brightness.Level()));
+}
diff --git a/src/DisplayApp/Screens/Brightness.h b/src/DisplayApp/Screens/Brightness.h
new file mode 100644
index 00000000..37cbcd7e
--- /dev/null
+++ b/src/DisplayApp/Screens/Brightness.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <libs/lvgl/src/lv_core/lv_obj.h>
+#include <Components/Brightness/BrightnessController.h>
+#include "Screen.h"
+
+namespace Pinetime {
+ namespace Applications {
+ namespace Screens {
+ class Brightness : public Screen {
+ public:
+ Brightness(DisplayApp* app, Controllers::BrightnessController& brightness);
+ ~Brightness() override;
+ bool Refresh() override;
+ bool OnButtonPushed() override;
+ bool OnTouchEvent(TouchEvents event) override;
+
+ void OnValueChanged();
+ private:
+ bool running = true;
+ Controllers::BrightnessController& brightness;
+
+ lv_obj_t * slider_label;
+ lv_obj_t * slider;
+
+ const char* LevelToString(Controllers::BrightnessController::Levels level);
+ uint8_t LevelToInt(Controllers::BrightnessController::Levels level);
+ void SetValue(uint8_t value);
+ void SetValue();
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/src/DisplayApp/Screens/Clock.cpp b/src/DisplayApp/Screens/Clock.cpp
index abc4d627..07db83ee 100644
--- a/src/DisplayApp/Screens/Clock.cpp
+++ b/src/DisplayApp/Screens/Clock.cpp
@@ -5,11 +5,14 @@
#include <libs/lvgl/lvgl.h>
#include "Clock.h"
#include "../DisplayApp.h"
+#include "BatteryIcon.h"
+#include "BleIcon.h"
using namespace Pinetime::Applications::Screens;
extern lv_font_t jetbrains_mono_extrabold_compressed;
extern lv_font_t jetbrains_mono_bold_20;
+
static void event_handler(lv_obj_t * obj, lv_event_t event) {
Clock* screen = static_cast<Clock *>(obj->user_data);
screen->OnObjectEvent(obj, event);
@@ -26,30 +29,30 @@ Clock::Clock(DisplayApp* app,
displayedChar[3] = 0;
displayedChar[4] = 0;
- label_battery = lv_label_create(lv_scr_act(), NULL);
- lv_obj_align(label_battery, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -80, 0);
+ batteryIcon = lv_img_create(lv_scr_act(), NULL);
+ lv_img_set_src(batteryIcon, BatteryIcon::GetUnknownIcon());
+ lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0);
+
+ bleIcon = lv_img_create(lv_scr_act(), NULL);
+ lv_img_set_src(bleIcon, BleIcon::GetIcon(false));
+ lv_obj_align(bleIcon, batteryIcon, LV_ALIGN_OUT_LEFT_MID, 0, 0);
+
+ label_date = lv_label_create(lv_scr_act(), NULL);
- labelStyle = const_cast<lv_style_t *>(lv_label_get_style(label_battery, LV_LABEL_STYLE_MAIN));
+ lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60);
+
+ labelStyle = const_cast<lv_style_t *>(lv_label_get_style(label_date, LV_LABEL_STYLE_MAIN));
labelStyle->text.font = &jetbrains_mono_bold_20;
lv_style_copy(&labelBigStyle, labelStyle);
labelBigStyle.text.font = &jetbrains_mono_extrabold_compressed;
- lv_label_set_style(label_battery, LV_LABEL_STYLE_MAIN, labelStyle);
-
- label_ble = lv_label_create(lv_scr_act(), NULL);
- lv_label_set_style(label_ble, LV_LABEL_STYLE_MAIN, labelStyle);
- lv_obj_align(label_ble, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 10, 0);
+ lv_label_set_style(label_date, LV_LABEL_STYLE_MAIN, labelStyle);
label_time = lv_label_create(lv_scr_act(), NULL);
lv_label_set_style(label_time, LV_LABEL_STYLE_MAIN, &labelBigStyle);
lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 0);
-
- label_date = lv_label_create(lv_scr_act(), NULL);
- lv_label_set_style(label_date, LV_LABEL_STYLE_MAIN, labelStyle);
- lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60);
-
backgroundLabel = lv_label_create(lv_scr_act(), NULL);
backgroundLabel->user_data = this;
lv_label_set_style(backgroundLabel, LV_LABEL_STYLE_MAIN, labelStyle);
@@ -68,22 +71,16 @@ Clock::~Clock() {
bool Clock::Refresh() {
batteryPercentRemaining = batteryController.PercentRemaining();
if (batteryPercentRemaining.IsUpdated()) {
- char batteryChar[11];
- auto newBatteryValue = batteryPercentRemaining.Get();
- newBatteryValue = (newBatteryValue > 100) ? 100 : newBatteryValue;
- newBatteryValue = (newBatteryValue < 0) ? 0 : newBatteryValue;
-
- sprintf(batteryChar, "BAT: %d%%", newBatteryValue);
- lv_label_set_text(label_battery, batteryChar);
+ auto batteryPercent = batteryPercentRemaining.Get();
+ lv_img_set_src(batteryIcon, BatteryIcon::GetIcon(batteryController.IsCharging() || batteryController.IsPowerPresent(), batteryPercent));
}
bleState = bleController.IsConnected();
if (bleState.IsUpdated()) {
if(bleState.Get() == true) {
- lv_obj_set_hidden(label_ble, false);
- lv_label_set_text(label_ble, "BLE");
+ lv_img_set_src(bleIcon, BleIcon::GetIcon(true));
} else {
- lv_obj_set_hidden(label_ble, true);
+ lv_img_set_src(bleIcon, BleIcon::GetIcon(false));
}
}
diff --git a/src/DisplayApp/Screens/Clock.h b/src/DisplayApp/Screens/Clock.h
index d14595b0..7c4a09df 100644
--- a/src/DisplayApp/Screens/Clock.h
+++ b/src/DisplayApp/Screens/Clock.h
@@ -76,6 +76,9 @@ namespace Pinetime {
lv_obj_t* label_version;
lv_obj_t* backgroundLabel;
+ lv_obj_t * batteryIcon;
+ lv_obj_t * bleIcon;
+
Controllers::DateTime& dateTimeController;
Controllers::Battery& batteryController;
Controllers::Ble& bleController;
diff --git a/src/DisplayApp/Screens/Label.cpp b/src/DisplayApp/Screens/Label.cpp
new file mode 100644
index 00000000..ba35279d
--- /dev/null
+++ b/src/DisplayApp/Screens/Label.cpp
@@ -0,0 +1,28 @@
+#include <libs/lvgl/lvgl.h>
+#include "Label.h"
+
+using namespace Pinetime::Applications::Screens;
+
+
+Label::Label(const char* text) : text{text} {
+
+}
+
+Label::~Label() {
+
+}
+
+void Label::Refresh() {
+
+}
+
+void Label::Show() {
+ label = lv_label_create(lv_scr_act(), NULL);
+ lv_label_set_align(label, LV_LABEL_ALIGN_LEFT);
+ lv_obj_set_size(label, 240, 240);
+ lv_label_set_text(label, text);
+}
+
+void Label::Hide() {
+ lv_obj_clean(lv_scr_act());
+}
diff --git a/src/DisplayApp/Screens/Label.h b/src/DisplayApp/Screens/Label.h
new file mode 100644
index 00000000..b73540f4
--- /dev/null
+++ b/src/DisplayApp/Screens/Label.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <vector>
+#include "Screen.h"
+
+namespace Pinetime {
+ namespace Applications {
+ namespace Screens {
+ class Label {
+ public:
+ Label() = default;
+ explicit Label(const char* text);
+ ~Label();
+ void Refresh();
+
+ void Hide();
+ void Show();
+ private:
+ lv_obj_t * label = nullptr;
+ const char* text = nullptr;
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/src/DisplayApp/Screens/Modal.cpp b/src/DisplayApp/Screens/Modal.cpp
index fc353c49..63ae70c0 100644
--- a/src/DisplayApp/Screens/Modal.cpp
+++ b/src/DisplayApp/Screens/Modal.cpp
@@ -25,7 +25,31 @@ bool Modal::OnButtonPushed() {
return true;
}
-void Modal::Show() {
+void Modal::Hide() {
+ /* Delete the parent modal background */
+ lv_obj_del_async(lv_obj_get_parent(mbox));
+ mbox = NULL; /* happens before object is actually deleted! */
+ isVisible = false;
+}
+
+void Modal::mbox_event_cb(lv_obj_t *obj, lv_event_t evt) {
+ auto* m = static_cast<Modal *>(obj->user_data);
+ m->OnEvent(obj, evt);
+}
+
+void Modal::OnEvent(lv_obj_t *event_obj, lv_event_t evt) {
+ if(evt == LV_EVENT_DELETE && event_obj == mbox) {
+ Hide();
+ } else if(evt == LV_EVENT_VALUE_CHANGED) {
+ /* A button was clicked */
+ lv_mbox_start_auto_close(mbox, 0);
+// Hide();
+ }
+}
+
+void Modal::Show(const char* msg) {
+ if(isVisible) return;
+ isVisible = true;
lv_style_copy(&modal_style, &lv_style_plain_color);
modal_style.body.main_color = modal_style.body.grad_color = LV_COLOR_BLACK;
modal_style.body.opa = LV_OPA_50;
@@ -41,10 +65,7 @@ void Modal::Show() {
/* Create the message box as a child of the modal background */
mbox = lv_mbox_create(obj, NULL);
lv_mbox_add_btns(mbox, btns2);
- char versionStr[20];
- sprintf(versionStr, "VERSION: %d.%d.%d", Version::Major(), Version::Minor(), Version::Patch());
- lv_mbox_set_text(mbox, versionStr);
-// lv_mbox_set_text(mbox, "Hello world!");
+ lv_mbox_set_text(mbox, msg);
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_event_cb(mbox, Modal::mbox_event_cb);
@@ -58,24 +79,3 @@ void Modal::Show() {
lv_anim_set_exec_cb(&a, obj, (lv_anim_exec_xcb_t)lv_obj_set_opa_scale);
lv_anim_create(&a);
}
-
-void Modal::Hide() {
- /* Delete the parent modal background */
- lv_obj_del_async(lv_obj_get_parent(mbox));
- mbox = NULL; /* happens before object is actually deleted! */
-}
-
-void Modal::mbox_event_cb(lv_obj_t *obj, lv_event_t evt) {
- auto* m = static_cast<Modal *>(obj->user_data);
- m->OnEvent(obj, evt);
-}
-
-void Modal::OnEvent(lv_obj_t *event_obj, lv_event_t evt) {
- if(evt == LV_EVENT_DELETE && event_obj == mbox) {
- Hide();
- } else if(evt == LV_EVENT_VALUE_CHANGED) {
- /* A button was clicked */
- lv_mbox_start_auto_close(mbox, 0);
-// Hide();
- }
-}
diff --git a/src/DisplayApp/Screens/Modal.h b/src/DisplayApp/Screens/Modal.h
index de287293..b5425906 100644
--- a/src/DisplayApp/Screens/Modal.h
+++ b/src/DisplayApp/Screens/Modal.h
@@ -22,7 +22,7 @@ namespace Pinetime {
Modal(DisplayApp* app);
~Modal() override;
- void Show();
+ void Show(const char* msg);
void Hide();
bool Refresh() override;
@@ -37,6 +37,7 @@ namespace Pinetime {
lv_obj_t *mbox;
lv_obj_t *info;
bool running = true;
+ bool isVisible = false;
};
}
diff --git a/src/DisplayApp/Screens/Screen.h b/src/DisplayApp/Screens/Screen.h
index 6cbd41ad..d8902317 100644
--- a/src/DisplayApp/Screens/Screen.h
+++ b/src/DisplayApp/Screens/Screen.h
@@ -1,4 +1,5 @@
#pragma once
+#include "../TouchEvents.h"
namespace Pinetime {
namespace Applications {
@@ -15,6 +16,9 @@ namespace Pinetime {
// Return false if the button hasn't been handled by the app, true if it has been handled
virtual bool OnButtonPushed() { return false; }
+ // Return false if the event hasn't been handled by the app, true if it has been handled
+ virtual bool OnTouchEvent(TouchEvents event) { return false; }
+
protected:
DisplayApp* app;
};
diff --git a/src/DisplayApp/Screens/ScreenList.cpp b/src/DisplayApp/Screens/ScreenList.cpp
new file mode 100644
index 00000000..93a91212
--- /dev/null
+++ b/src/DisplayApp/Screens/ScreenList.cpp
@@ -0,0 +1,115 @@
+#include <libs/lvgl/lvgl.h>
+#include <DisplayApp/DisplayApp.h>
+#include "ScreenList.h"
+
+using namespace Pinetime::Applications::Screens;
+
+// TODO this class must be improved to receive the list of "sub screens" via pointer or
+// move operation.
+// It should accept many type of "sub screen" (it only supports Label for now).
+// The number of sub screen it supports must be dynamic.
+ScreenList::ScreenList(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::DateTime &dateTimeController,
+ Pinetime::Controllers::Battery& batteryController, Pinetime::Controllers::BrightnessController& brightnessController, Pinetime::Drivers::WatchdogView& watchdog) :
+ Screen(app),
+ dateTimeController{dateTimeController}, batteryController{batteryController}, brightnessController{brightnessController}, watchdog{watchdog} {
+ screens.reserve(3);
+
+ // TODO all of this is far too heavy (string processing). This should be improved.
+ // TODO the info (battery, time,...) should be updated in the Refresh method.
+
+
+ auto batteryPercent = static_cast<int16_t>(batteryController.PercentRemaining());
+ if(batteryPercent > 100) batteryPercent = 100;
+ else if(batteryPercent < 0) batteryPercent = 0;
+
+ uint8_t brightness = 0;
+ switch(brightnessController.Level()) {
+ case Controllers::BrightnessController::Levels::Low: brightness = 1; break;
+ case Controllers::BrightnessController::Levels::Medium: brightness = 2; break;
+ case Controllers::BrightnessController::Levels::High: brightness = 3; break;
+ }
+ auto resetReason = [&watchdog]() {
+ switch (watchdog.ResetReason()) {
+ case Drivers::Watchdog::ResetReasons::Watchdog: return "wtdg";
+ case Drivers::Watchdog::ResetReasons::HardReset: return "hardr";
+ case Drivers::Watchdog::ResetReasons::NFC: return "nfc";
+ case Drivers::Watchdog::ResetReasons::SoftReset: return "softr";
+ case Drivers::Watchdog::ResetReasons::CpuLockup: return "cpulock";
+ case Drivers::Watchdog::ResetReasons::SystemOff: return "off";
+ case Drivers::Watchdog::ResetReasons::LpComp: return "lpcomp";
+ case Drivers::Watchdog::ResetReasons::DebugInterface: return "dbg";
+ case Drivers::Watchdog::ResetReasons::ResetPin: return "rst";
+ default: return "?";
+ }
+ }();
+
+
+ sprintf(t1, "Pinetime\n"
+ "Version:%d.%d.%d\n"
+ "Build: xx/xx/xxxx\n"
+ "Time: %02d:%02d:%02d\n"
+ "date: %02d/%02d/%04d\n"
+ "Uptime: xd xxhxx:xx\n"
+ "Battery: %d%%\n"
+ "Backlight: %d/3\n"
+ "Last reset: %s\n"
+ "BLE MAC: \n AA:BB:CC:DD:EE:FF", Version::Major(), Version::Minor(), Version::Patch(),
+ dateTimeController.Hours(), dateTimeController.Minutes(), dateTimeController.Seconds(),
+ dateTimeController.Day(), dateTimeController.Month(), dateTimeController.Year(),
+ batteryPercent, brightness, resetReason);
+
+ screens.emplace_back(t1);
+
+ strncpy(t2, "Hello from\nthe developper!", 27);
+ screens.emplace_back(t2);
+
+ strncpy(t3, "Place holder\nin case we need\nmore room!", 40);
+ screens.emplace_back(t3);
+
+ auto &screen = screens[screenIndex];
+ screen.Show();
+}
+
+ScreenList::~ScreenList() {
+ lv_obj_clean(lv_scr_act());
+}
+
+bool ScreenList::Refresh() {
+ auto &screen = screens[screenIndex];
+ screen.Refresh();
+
+ return running;
+}
+
+bool ScreenList::OnButtonPushed() {
+ running = false;
+ return true;
+}
+
+bool ScreenList::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
+ switch (event) {
+ case TouchEvents::SwipeDown:
+ if (screenIndex > 0) {
+ app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down);
+ auto &oldScreen = screens[screenIndex];
+ oldScreen.Hide();
+ screenIndex--;
+ auto &newScreen = screens[screenIndex];
+ newScreen.Show();
+ }
+ return true;
+ case TouchEvents::SwipeUp:
+ app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up);
+ if (screenIndex < screens.size() - 1) {
+ auto &oldScreen = screens[screenIndex];
+ oldScreen.Hide();
+ screenIndex++;
+ auto &newScreen = screens[screenIndex];
+ newScreen.Show();
+ }
+ return true;
+ default:
+ return false;
+ }
+ return false;
+}
diff --git a/src/DisplayApp/Screens/ScreenList.h b/src/DisplayApp/Screens/ScreenList.h
new file mode 100644
index 00000000..ad093d35
--- /dev/null
+++ b/src/DisplayApp/Screens/ScreenList.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include <vector>
+#include "Screen.h"
+#include "Label.h"
+
+namespace Pinetime {
+ namespace Applications {
+ namespace Screens {
+ class ScreenList : public Screen {
+ public:
+ explicit ScreenList(DisplayApp* app,
+ Pinetime::Controllers::DateTime& dateTimeController,
+ Pinetime::Controllers::Battery& batteryController,
+ Pinetime::Controllers::BrightnessController& brightnessController,
+ Pinetime::Drivers::WatchdogView& watchdog);
+ ~ScreenList() override;
+ bool Refresh() override;
+ bool OnButtonPushed() override;
+ bool OnTouchEvent(TouchEvents event) override;
+ private:
+ bool running = true;
+ uint8_t screenIndex = 0;
+
+ // TODO choose another container without dynamic alloc
+ std::vector<Screens::Label> screens;
+ Pinetime::Controllers::DateTime& dateTimeController;
+ Pinetime::Controllers::Battery& batteryController;
+ Pinetime::Controllers::BrightnessController& brightnessController;
+ Pinetime::Drivers::WatchdogView& watchdog;
+
+ char t1[200];
+ char t2[30];
+ char t3[42];
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp
index 004c8d31..6c225c9d 100644
--- a/src/DisplayApp/Screens/Tile.cpp
+++ b/src/DisplayApp/Screens/Tile.cpp
@@ -16,7 +16,7 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) {
screen->OnObjectEvent(obj, event, eventData);
}
-static const char * btnm_map1[] = {"Meter", "Gauge", "Clock", "\n", "Soft\nversion", "App2", "App3", ""};
+static const char * btnm_map1[] = {"Meter", "Gauge", "Clock", "\n", "Soft\nversion", "App2", "Brightness", ""};
Tile::Tile(DisplayApp* app) : Screen(app) {
modal.reset(new Modal(app));
@@ -123,11 +123,15 @@ void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event, uint32_t buttonId) {
tile->StartClockApp();
break;
case 3:
- modal->Show();
+ char versionStr[20];
+ sprintf(versionStr, "VERSION: %d.%d.%d", Version::Major(), Version::Minor(), Version::Patch());
+ modal->Show(versionStr);
break;
case 4:
+ tile->StartSysInfoApp();
+ break;
case 5:
- tile->StartTestApp();
+ tile->StartBrightnessApp();
break;
}
@@ -146,8 +150,13 @@ void Tile::StartClockApp() {
running = false;
}
-void Tile::StartTestApp() {
- app->StartApp(DisplayApp::Apps::Test);
+void Tile::StartSysInfoApp() {
+ app->StartApp(DisplayApp::Apps::SysInfo);
+ running = false;
+}
+
+void Tile::StartBrightnessApp() {
+ app->StartApp(DisplayApp::Apps::Brightness);
running = false;
}
diff --git a/src/DisplayApp/Screens/Tile.h b/src/DisplayApp/Screens/Tile.h
index eb253435..fa2d6db0 100644
--- a/src/DisplayApp/Screens/Tile.h
+++ b/src/DisplayApp/Screens/Tile.h
@@ -52,12 +52,13 @@ namespace Pinetime {
uint32_t clickCount = 0 ;
uint32_t previousClickCount = 0;
void StartClockApp();
- void StartTestApp();
+ void StartSysInfoApp();
void StartMeterApp();
void StartGaugeApp();
bool running = true;
std::unique_ptr<Modal> modal;
+ void StartBrightnessApp();
};
}
}
diff --git a/src/DisplayApp/TouchEvents.h b/src/DisplayApp/TouchEvents.h
new file mode 100644
index 00000000..cf2f88dd
--- /dev/null
+++ b/src/DisplayApp/TouchEvents.h
@@ -0,0 +1,8 @@
+#pragma once
+
+namespace Pinetime {
+ namespace Applications {
+
+ enum class TouchEvents { None, Tap, SwipeLeft, SwipeRight, SwipeUp, SwipeDown, LongTap, DoubleTap};
+ }
+} \ No newline at end of file
diff --git a/src/SystemTask/SystemTask.cpp b/src/SystemTask/SystemTask.cpp
index e90672d9..e65abb61 100644
--- a/src/SystemTask/SystemTask.cpp
+++ b/src/SystemTask/SystemTask.cpp
@@ -5,15 +5,19 @@
#include <hal/nrf_rtc.h>
#include <BLE/BleManager.h>
#include <softdevice/common/nrf_sdh_freertos.h>
+#include <Components/Ble/NotificationManager.h>
#include "SystemTask.h"
#include "../main.h"
using namespace Pinetime::System;
-SystemTask::SystemTask(Pinetime::Drivers::SpiMaster &spi, Pinetime::Drivers::St7789 &lcd,
- Pinetime::Drivers::Cst816S &touchPanel, Pinetime::Components::LittleVgl &lvgl,
- Pinetime::Controllers::Battery &batteryController, Pinetime::Controllers::Ble &bleController,
- Pinetime::Controllers::DateTime& dateTimeController) :
- spi{spi}, lcd{lcd}, touchPanel{touchPanel}, lvgl{lvgl}, batteryController{batteryController}, bleController{bleController}, dateTimeController{dateTimeController} {
+SystemTask::SystemTask(Drivers::SpiMaster &spi, Drivers::St7789 &lcd, Drivers::Cst816S &touchPanel,
+ Components::LittleVgl &lvgl,
+ Controllers::Battery &batteryController, Controllers::Ble &bleController,
+ Controllers::DateTime &dateTimeController,
+ Pinetime::Controllers::NotificationManager& notificationManager) :
+ spi{spi}, lcd{lcd}, touchPanel{touchPanel}, lvgl{lvgl}, batteryController{batteryController},
+ bleController{bleController}, dateTimeController{dateTimeController},
+ watchdog{}, watchdogView{watchdog}, notificationManager{notificationManager} {
systemTaksMsgQueue = xQueueCreate(10, 1);
}
@@ -33,16 +37,17 @@ void SystemTask::Work() {
watchdog.Start();
NRF_LOG_INFO("Last reset reason : %s", Pinetime::Drivers::Watchdog::ResetReasonToString(watchdog.ResetReason()));
APP_GPIOTE_INIT(2);
- bool erase_bonds=false;
-// ble_manager_init_peer_manager();
-// nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds);
+ bool erase_bonds=true;
+ ble_manager_init_peer_manager();
+ nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds);
spi.Init();
lcd.Init();
touchPanel.Init();
batteryController.Init();
- displayApp.reset(new Pinetime::Applications::DisplayApp(lcd, lvgl, touchPanel, batteryController, bleController, dateTimeController, *this));
+ displayApp.reset(new Pinetime::Applications::DisplayApp(lcd, lvgl, touchPanel, batteryController, bleController,
+ dateTimeController, watchdogView, *this, notificationManager));
displayApp->Start();
batteryController.Update();
@@ -82,11 +87,18 @@ void SystemTask::Work() {
NRF_LOG_INFO("[SystemTask] Going to sleep");
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep);
isSleeping = true; break;
+ case Messages::OnNewTime:
+ displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateDateTime);
+ break;
+ case Messages::OnNewNotification:
+ displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::NewNotification);
+ break;
default: break;
}
}
uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG);
dateTimeController.UpdateTime(systick_counter);
+ batteryController.Update();
if(!nrf_gpio_pin_read(pinButton))
watchdog.Kick();
@@ -103,7 +115,6 @@ void SystemTask::OnButtonPushed() {
NRF_LOG_INFO("[SystemTask] Button pushed, waking up");
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToRunning);
isSleeping = false;
- batteryController.Update();
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBatteryLevel);
}
}
diff --git a/src/SystemTask/SystemTask.h b/src/SystemTask/SystemTask.h
index f5ba2d75..a1ba277a 100644
--- a/src/SystemTask/SystemTask.h
+++ b/src/SystemTask/SystemTask.h
@@ -13,15 +13,14 @@ namespace Pinetime {
namespace System {
class SystemTask {
public:
- enum class Messages {GoToSleep, GoToRunning};
+ enum class Messages {GoToSleep, GoToRunning, OnNewTime, OnNewNotification
+ };
- SystemTask(Pinetime::Drivers::SpiMaster& spi,
- Pinetime::Drivers::St7789& lcd,
- Pinetime::Drivers::Cst816S& touchPanel,
- Pinetime::Components::LittleVgl& lvgl,
- Pinetime::Controllers::Battery& batteryController,
- Pinetime::Controllers::Ble& bleController,
- Pinetime::Controllers::DateTime& dateTimeController);
+ SystemTask(Drivers::SpiMaster &spi, Drivers::St7789 &lcd, Drivers::Cst816S &touchPanel,
+ Components::LittleVgl &lvgl,
+ Controllers::Battery &batteryController, Controllers::Ble &bleController,
+ Controllers::DateTime &dateTimeController,
+ Pinetime::Controllers::NotificationManager& manager);
void Start();
@@ -43,6 +42,8 @@ namespace Pinetime {
QueueHandle_t systemTaksMsgQueue;
bool isSleeping = false;
Pinetime::Drivers::Watchdog watchdog;
+ Pinetime::Drivers::WatchdogView watchdogView;
+ Pinetime::Controllers::NotificationManager& notificationManager;
static constexpr uint8_t pinSpiSck = 2;
diff --git a/src/drivers/Watchdog.cpp b/src/drivers/Watchdog.cpp
index b0dc12e5..55b6de73 100644
--- a/src/drivers/Watchdog.cpp
+++ b/src/drivers/Watchdog.cpp
@@ -19,6 +19,8 @@ void Watchdog::Setup(uint8_t timeoutSeconds) {
/* Enable reload requests */
NRF_WDT->RREN = (WDT_RREN_RR0_Enabled << WDT_RREN_RR0_Pos);
+
+ resetReason = ActualResetReason();
}
void Watchdog::Start() {
@@ -29,18 +31,18 @@ void Watchdog::Kick() {
NRF_WDT->RR[0] = WDT_RR_RR_Reload;
}
-Watchdog::ResetReasons Watchdog::ResetReason() {
+Watchdog::ResetReasons Watchdog::ActualResetReason() const {
uint32_t resetReason;
sd_power_reset_reason_get(&resetReason);
sd_power_reset_reason_clr(0xFFFFFFFF);
- if(resetReason & 0x01) return ResetReasons::ResetPin;
- if((resetReason >> 1) & 0x01) return ResetReasons::Watchdog;
- if((resetReason >> 2) & 0x01) return ResetReasons::SoftReset;
- if((resetReason >> 3) & 0x01) return ResetReasons::CpuLockup;
- if((resetReason >> 16) & 0x01) return ResetReasons::SystemOff;
- if((resetReason >> 17) & 0x01) return ResetReasons::LpComp;
- if((resetReason >> 18) & 0x01) return ResetReasons::DebugInterface;
- if((resetReason >> 19) & 0x01) return ResetReasons::NFC;
+ if(resetReason & 0x01u) return ResetReasons::ResetPin;
+ if((resetReason >> 1u) & 0x01u) return ResetReasons::Watchdog;
+ if((resetReason >> 2u) & 0x01u) return ResetReasons::SoftReset;
+ if((resetReason >> 3u) & 0x01u) return ResetReasons::CpuLockup;
+ if((resetReason >> 16u) & 0x01u) return ResetReasons::SystemOff;
+ if((resetReason >> 17u) & 0x01u) return ResetReasons::LpComp;
+ if((resetReason >> 18u) & 0x01u) return ResetReasons::DebugInterface;
+ if((resetReason >> 19u) & 0x01u) return ResetReasons::NFC;
return ResetReasons::HardReset;
}
diff --git a/src/drivers/Watchdog.h b/src/drivers/Watchdog.h
index da192d9e..73f99ea1 100644
--- a/src/drivers/Watchdog.h
+++ b/src/drivers/Watchdog.h
@@ -8,10 +8,20 @@ namespace Pinetime {
void Setup(uint8_t timeoutSeconds);
void Start();
void Kick();
-
- ResetReasons ResetReason();
+ ResetReasons ResetReason() const { return resetReason; }
static const char* ResetReasonToString(ResetReasons reason);
+ private:
+ ResetReasons resetReason;
+ ResetReasons ActualResetReason() const;
+ };
+
+ class WatchdogView {
+ public:
+ WatchdogView(const Watchdog& watchdog) : watchdog{watchdog} { }
+ Watchdog::ResetReasons ResetReason() const { return watchdog.ResetReason();}
+ private:
+ const Watchdog& watchdog;
};
}
}
diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h
index 2f9c00e7..309d65be 100644
--- a/src/libs/lv_conf.h
+++ b/src/libs/lv_conf.h
@@ -37,7 +37,7 @@
#define LV_COLOR_SCREEN_TRANSP 0
/*Images pixels with this color will not be drawn (with chroma keying)*/
-#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
+#define LV_COLOR_TRANSP LV_COLOR_MAKE(0x6c, 0xFc, 0x6a)/*LV_COLOR_LIME*/ /*LV_COLOR_LIME: pure green*/
/* Enable chroma keying for indexed images. */
#define LV_INDEXED_CHROMA 1
diff --git a/src/main.cpp b/src/main.cpp
index 25a8a6c9..106d19eb 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -16,6 +16,7 @@
#include <drivers/SpiMaster.h>
#include <DisplayApp/LittleVgl.h>
#include <SystemTask/SystemTask.h>
+#include <Components/Ble/NotificationManager.h>
#if NRF_LOG_ENABLED
#include "Logging/NrfLogger.h"
@@ -55,6 +56,8 @@ void ble_manager_set_ble_disconnection_callback(void (*disconnection)());
static constexpr uint8_t pinTouchIrq = 28;
std::unique_ptr<Pinetime::System::SystemTask> systemTask;
+Pinetime::Controllers::NotificationManager notificationManager;
+
void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
if(pin == pinTouchIrq) {
systemTask->OnTouchEvent();
@@ -85,6 +88,11 @@ void OnBleDisconnection() {
bleController.Disconnect();
}
+void OnNewNotification(const char* message, uint8_t size) {
+ notificationManager.Push(Pinetime::Controllers::NotificationManager::Categories::SimpleAlert, message, size);
+ systemTask->PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification);
+}
+
void OnNewTime(current_time_char_t* currentTime) {
auto dayOfWeek = currentTime->exact_time_256.day_date_time.day_of_week;
auto year = currentTime->exact_time_256.day_date_time.date_time.year;
@@ -96,6 +104,8 @@ void OnNewTime(current_time_char_t* currentTime) {
dateTimeController.SetTime(year, month, day,
dayOfWeek, hour, minute, second, nrf_rtc_counter_get(portNRF_RTC_REG));
+
+ systemTask->PushMessage(Pinetime::System::SystemTask::Messages::OnNewTime);
}
void SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler(void) {
@@ -121,13 +131,15 @@ int main(void) {
debounceTimer = xTimerCreate ("debounceTimer", 200, pdFALSE, (void *) 0, DebounceTimerCallback);
- systemTask.reset(new Pinetime::System::SystemTask(spi, lcd, touchPanel, lvgl, batteryController, bleController, dateTimeController));
+ systemTask.reset(new Pinetime::System::SystemTask(spi, lcd, touchPanel, lvgl, batteryController, bleController,
+ dateTimeController, notificationManager));
systemTask->Start();
ble_manager_init();
ble_manager_set_new_time_callback(OnNewTime);
ble_manager_set_ble_connection_callback(OnBleConnection);
ble_manager_set_ble_disconnection_callback(OnBleDisconnection);
+ ble_manager_set_new_notification_callback(OnNewNotification);
vTaskStartScheduler();
diff --git a/src/sdk_config.h b/src/sdk_config.h
index 0d9b2744..a63eb6fb 100644
--- a/src/sdk_config.h
+++ b/src/sdk_config.h
@@ -1322,7 +1322,15 @@
#ifndef BLE_ANS_C_ENABLED
-#define BLE_ANS_C_ENABLED 0
+#define BLE_ANS_C_ENABLED 1
+#endif
+
+#ifndef BLE_ANS_C_LOG_ENABLED
+#define BLE_ANS_C_LOG_ENABLED 1
+#endif
+
+#ifndef BLE_ANS_C_LOG_LEVEL
+#define BLE_ANS_C_LOG_LEVEL 3
#endif
// <q> BLE_BAS_C_ENABLED - ble_bas_c - Battery Service Client