Merge branch 'develop' of JF/PineTime into master

This commit is contained in:
JF 2020-04-05 19:59:22 +02:00 committed by Gitea
commit 86d5732b96
96 changed files with 2705 additions and 191 deletions

View File

@ -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.
* 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
@ -218,3 +225,32 @@ Here is how to do it with an Android smartphone running NRFConnect:
* 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.
### 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).

View File

@ -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

27
doc/ble.md Normal file
View File

@ -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")

BIN
doc/ble/ans_sequence.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

29
doc/ble/ans_sequence.puml Normal file
View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -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

View File

@ -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);
}

View File

@ -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
}

View File

@ -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})

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;
};
}
}

View File

@ -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;
}

View File

@ -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;
};
}
}

View File

@ -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);
}

View File

@ -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;
};
}
}

View File

@ -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;
}
}

View File

@ -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;
};
}
}

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -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,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -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;
}

View File

@ -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);
};
}
}
}

View File

@ -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;
}

View File

@ -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);
};
}
}
}

View File

@ -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()));
}

View File

@ -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();
};
}
}
}

View File

@ -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);
labelStyle = const_cast<lv_style_t *>(lv_label_get_style(label_battery, LV_LABEL_STYLE_MAIN));
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);
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));
}
}

View File

@ -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;

View File

@ -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());
}

View File

@ -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;
};
}
}
}

View File

@ -25,44 +25,11 @@ bool Modal::OnButtonPushed() {
return true;
}
void Modal::Show() {
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;
obj = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_style(obj, &modal_style);
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, LV_HOR_RES, LV_VER_RES);
lv_obj_set_opa_scale_enable(obj, true); /* Enable opacity scaling for the animation */
static const char * btns2[] = {"Ok", ""};
/* 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_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_event_cb(mbox, Modal::mbox_event_cb);
mbox->user_data = this;
/* Fade the message box in with an animation */
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_time(&a, 500, 0);
lv_anim_set_values(&a, LV_OPA_TRANSP, LV_OPA_COVER);
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! */
isVisible = false;
}
void Modal::mbox_event_cb(lv_obj_t *obj, lv_event_t evt) {
@ -79,3 +46,36 @@ void Modal::OnEvent(lv_obj_t *event_obj, lv_event_t evt) {
// 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;
obj = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_style(obj, &modal_style);
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, LV_HOR_RES, LV_VER_RES);
lv_obj_set_opa_scale_enable(obj, true); /* Enable opacity scaling for the animation */
static const char * btns2[] = {"Ok", ""};
/* Create the message box as a child of the modal background */
mbox = lv_mbox_create(obj, NULL);
lv_mbox_add_btns(mbox, btns2);
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);
mbox->user_data = this;
/* Fade the message box in with an animation */
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_time(&a, 500, 0);
lv_anim_set_values(&a, LV_OPA_TRANSP, LV_OPA_COVER);
lv_anim_set_exec_cb(&a, obj, (lv_anim_exec_xcb_t)lv_obj_set_opa_scale);
lv_anim_create(&a);
}

View File

@ -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;
};
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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];
};
}
}
}

View File

@ -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;
}

View File

@ -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();
};
}
}

View File

@ -0,0 +1,8 @@
#pragma once
namespace Pinetime {
namespace Applications {
enum class TouchEvents { None, Tap, SwipeLeft, SwipeRight, SwipeUp, SwipeDown, LongTap, DoubleTap};
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
};
}
}

View File

@ -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

View File

@ -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();

View File

@ -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