Compare commits

..

11 Commits

Author SHA1 Message Date
anschrammh
1ef9face5a Updated lvgl simulated screen files 2023-03-30 13:27:24 +02:00
anschrammh
ea79af772b Halfed the BLE prefered MTU size changing it to 256 instead of 512 2023-03-30 13:26:28 +02:00
anschrammh
6a9639700b Added new functions to the watch face API such as watch_face_set_step_count_indicator or watch_face_is_in_use 2023-03-30 13:24:48 +02:00
anschrammh
61f7e21cb3 Added more information in the about section of the settings screen : battery voltage, factory reset button and other things 2023-03-30 13:16:35 +02:00
anschrammh
47753131d6 Added BLE support to the app, fixed a graphical glitch happening when
waking up the watch by touching the screen where the second hand was
jumping from the old time to the new time
2023-03-30 13:14:35 +02:00
anschrammh
3156976f7a Removed the BLE device name from this header file 2023-03-30 13:11:19 +02:00
anschrammh
b5cc52df81 Commented a trace statement in the ble service in order to keep the serial traces clean 2023-03-30 13:09:55 +02:00
anschrammh
e8583254e6 Wrapped the SDIO MMC IO busy wait statement in a function such that it can be called by any API needing it 2023-03-30 13:08:57 +02:00
anschrammh
2b79a31165 Fixed an issue when sending commands to the LCD screen while a DMA
transfer is in progress causing graphical issues
Detail :
A DMA transfer may be in progress when trying to send single byte commands to the LCD screen. This could badly configure the display as soon as the data/command select pin was set to command while the DMA was still sending data bytes.
The fix : doing a busy wait in the lcd_set_data function to be sure the bus is free to use.
2023-03-30 13:05:53 +02:00
anschrammh
a58c453f58 Added a define to easily set the BLE advertised name of the W800SmartWatch 2023-03-30 12:56:32 +02:00
anschrammh
1de2baa1eb Added information about the OS used as well as the different stacks (BLE and TCP/IP) 2023-03-30 12:54:53 +02:00
16 changed files with 210 additions and 47 deletions

View File

@ -10,13 +10,20 @@ The W800 is a pretty interesting chip with impressive characteristics for its pr
### Core : ### Core :
* 32bit XT804 CPU * 32bit XT804 CPU
* 240 Mhz max clock * 240 Mhz max clock
### Memory : ### Memory :
* 2 MB on chip flash * 2 MB on chip flash
* 288 KB RAM, ~130 KB available to the user * 288 KB RAM, ~130 KB available to the user
### Wireless connectivity : ### Wireless connectivity :
* Bluetooth EDR(Classic) and BLE 4.2 * Bluetooth EDR(Classic) and BLE 4.2
* WiFi 2.4Ghz 802.11 b/g/n * WiFi 2.4Ghz 802.11 b/g/n
### SDK & OS
* FreeRTOS v10.4.1
* BLE stack : NimBLE
* TCP IP stack : lwip v2.1.3
## Getting started : ## Getting started :
### So, you'd like to try this project yourself ? ### So, you'd like to try this project yourself ?
### Here are the steps to follow, in order to build the firmware and flash the board : ### Here are the steps to follow, in order to build the firmware and flash the board :
@ -192,7 +199,7 @@ using a magnetic 4 pin plug.
* [ ] Fix the issue with the DW01A chip, should be as easy as to replace the 100nf C12 cap with a lower value, let's say 80nf. * [ ] Fix the issue with the DW01A chip, should be as easy as to replace the 100nf C12 cap with a lower value, let's say 80nf.
## To do - SOFTWARE ## To do - SOFTWARE
* [X] Finish to design the settings page. * [X] Finish to design the settings page.
* [ ] Implement watch settings persistency using the integrated flash memory * [X] Implement watch settings persistency using the integrated flash memory
* [ ] Implement a good algorithm to handle adaptiv MCU clock * [ ] Implement a good algorithm to handle adaptiv MCU clock
to save power to save power
* Drivers: * Drivers:

View File

@ -99,4 +99,6 @@
#define VIBRATION_MOTOR_ENABLE WM_IO_PB_00 #define VIBRATION_MOTOR_ENABLE WM_IO_PB_00
#define VIBRATION_MOTOR_PWM_CHANNEL (0) #define VIBRATION_MOTOR_PWM_CHANNEL (0)
#define BLE_DEVICE_NAME "MDBT42Q_W800SW"
#endif //APP_CONFIG_H #endif //APP_CONFIG_H

View File

@ -382,7 +382,6 @@ void lcd_set_backlight(LCDConfig_t * const LCDConfig, uint8_t brightness)
tls_gpio_cfg(LCDConfig->LCDPWMBacklightPin, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING); tls_gpio_cfg(LCDConfig->LCDPWMBacklightPin, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING);
tls_gpio_write(LCDConfig->LCDPWMBacklightPin, 0); tls_gpio_write(LCDConfig->LCDPWMBacklightPin, 0);
} }
} }
void lcd_hardware_reset(LCDConfig_t * const LCDConfig) void lcd_hardware_reset(LCDConfig_t * const LCDConfig)
@ -523,5 +522,8 @@ static void lcd_set_cs(LCDConfig_t * const LCDConfig, LCDSelect_e selected)
static void lcd_set_data_command(LCDConfig_t * const LCDConfig, LCDDataCommand_e dataCommand) static void lcd_set_data_command(LCDConfig_t * const LCDConfig, LCDDataCommand_e dataCommand)
{ {
// We wait for the mmc sdio driver to be ready before changing the LCD access mode
mmc_sdio_driver_blocking_wait_bus_free();
tls_gpio_write(LCDConfig->LCDDataCommandPin, dataCommand); tls_gpio_write(LCDConfig->LCDDataCommandPin, dataCommand);
} }

View File

@ -99,7 +99,7 @@ void mmc_sdio_driver_write_dma_async(uint32_t *data, uint32_t dataLengthInBytes)
void mmc_sdio_driver_write_one(uint8_t data) void mmc_sdio_driver_write_one(uint8_t data)
{ {
/* Wait for MMC device to be ready to send the data */ /* Wait for MMC device to be ready to send the data */
while (SDIO_HOST->MMC_IO & 0x01); mmc_sdio_driver_blocking_wait_bus_free();
SDIO_HOST->BUF_CTL = 0x4820; SDIO_HOST->BUF_CTL = 0x4820;
SDIO_HOST->DATA_BUF[0] = (uint32_t)data; SDIO_HOST->DATA_BUF[0] = (uint32_t)data;
@ -107,19 +107,25 @@ void mmc_sdio_driver_write_one(uint8_t data)
/* Start the transfer */ /* Start the transfer */
SDIO_HOST->MMC_IO = 0x01; SDIO_HOST->MMC_IO = 0x01;
/* Wait for MMC device to be done sending the data */ /* Wait for MMC device to be done sending the data */
while (SDIO_HOST->MMC_IO & 0x01); mmc_sdio_driver_blocking_wait_bus_free();
} }
void mmc_sdio_driver_write(const uint8_t *data, uint16_t dataLengthInBytes) void mmc_sdio_driver_write(const uint8_t *data, uint16_t dataLengthInBytes)
{ {
/* Wait for MMC device to be ready to send the data */ /* Wait for MMC device to be ready to send the data */
while (SDIO_HOST->MMC_IO & 0x01); mmc_sdio_driver_blocking_wait_bus_free();
SDIO_HOST->BUF_CTL = 0x4820; SDIO_HOST->BUF_CTL = 0x4820;
memcpy((void *)SDIO_HOST->DATA_BUF, (void *)data, dataLengthInBytes); memcpy((void *)SDIO_HOST->DATA_BUF, (void *)data, dataLengthInBytes);
SDIO_HOST->MMC_BYTECNTL = dataLengthInBytes; SDIO_HOST->MMC_BYTECNTL = dataLengthInBytes;
/* Start the transfer */ /* Start the transfer */
SDIO_HOST->MMC_IO = 0x01; SDIO_HOST->MMC_IO = 0x01;
/* Wait for MMC device to be done sending the data */ /* Wait for MMC device to be done sending the data */
mmc_sdio_driver_blocking_wait_bus_free();
}
void mmc_sdio_driver_blocking_wait_bus_free(void)
{
while (SDIO_HOST->MMC_IO & 0x01); while (SDIO_HOST->MMC_IO & 0x01);
} }

View File

@ -23,7 +23,7 @@ void mmc_sdio_driver_periph_init(DMATransferDoneCb_t DMATransferDoneCb, void *ar
* @param dataLengthInBytes the size in bytes of the data to transfer. * @param dataLengthInBytes the size in bytes of the data to transfer.
* Maximum length is 65535 bytes. * Maximum length is 65535 bytes.
*/ */
void mmc_sdio_driver_write_dma_async(uint32_t *data, u32 dataLengthInBytes); void mmc_sdio_driver_write_dma_async(uint32_t *data, uint32_t dataLengthInBytes);
/** /**
* @brief Sends one byte of data to the slave * @brief Sends one byte of data to the slave
@ -43,4 +43,10 @@ void mmc_sdio_driver_write_one(uint8_t data);
*/ */
void mmc_sdio_driver_write(const uint8_t *data, uint16_t dataLengthInBytes); void mmc_sdio_driver_write(const uint8_t *data, uint16_t dataLengthInBytes);
/**
* @brief Performs a busy wait until the data bus is free for us to use.
*
*/
void mmc_sdio_driver_blocking_wait_bus_free(void);
#endif //MMC_SDIO_H #endif //MMC_SDIO_H

View File

@ -695,7 +695,7 @@ static int ble_gap_event_cb(struct ble_gap_event *event, void *arg)
else else
{ {
TLS_BT_APPL_TRACE_VERBOSE("last data chunk sent, end of the transfer"NEW_LINE); TLS_BT_APPL_TRACE_VERBOSE("last data chunk sent, end of the transfer"NEW_LINE);
// All data has been sent, end of the transfer // All data have been sent, end of the transfer
reset_data_being_sent(&notification_data); reset_data_being_sent(&notification_data);
} }
} }
@ -741,8 +741,7 @@ static int battery_level_char_access_cb(uint16_t conn_handle, uint16_t attr_hand
static int gatt_nus_char_access_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) static int gatt_nus_char_access_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
{ {
TLS_BT_APPL_TRACE_EVENT("gatt_nus_char_access_cb op : %s"NEW_LINE, tls_bt_access_opt_2_str(ctxt->op)); //TLS_BT_APPL_TRACE_EVENT("gatt_nus_char_access_cb op : %s"NEW_LINE, tls_bt_access_opt_2_str(ctxt->op));
switch(ctxt->op) switch(ctxt->op)
{ {
case BLE_GATT_ACCESS_OP_WRITE_CHR: case BLE_GATT_ACCESS_OP_WRITE_CHR:

View File

@ -2,7 +2,6 @@
#define BLUETOOTH_SIG_VALUES_H #define BLUETOOTH_SIG_VALUES_H
#define BLE_DEVICE_APPEARANCE (0x00C2) //Smart Watch #define BLE_DEVICE_APPEARANCE (0x00C2) //Smart Watch
#define BLE_DEVICE_NAME "MDBT42Q_W800SW"
#define BLE_DEVICE_ADV_SERVICE (0x180F) //Battery Service #define BLE_DEVICE_ADV_SERVICE (0x180F) //Battery Service

View File

@ -24,10 +24,11 @@ static void date_time_cb(struct tm * const dateTime)
{ {
if(!dateTime)return; if(!dateTime)return;
tls_get_rtc(dateTime); tls_get_rtc(dateTime);
//APP_LOG_DEBUG("RTC time : %d:%d:%d", dateTime->tm_hour, dateTime->tm_min, dateTime->tm_sec);
} }
static uint8_t _battery_percentage = 100; static void _perform_deferred_display_wake_up_set_sleeping(void);
static void _perform_deferred_display_wake_up_set_timestamp(void);
static void _perform_deferred_display_wake_up(uint8_t deferred_time_in_ms);
WatchFace_t watchFace; WatchFace_t watchFace;
MenuScreen_t menuScreen; MenuScreen_t menuScreen;
@ -39,17 +40,22 @@ struct bma4_accel_config accel_conf;
struct bma456w_wrist_wear_wakeup_params setting; struct bma456w_wrist_wear_wakeup_params setting;
struct bma4_int_pin_config pin_config; struct bma4_int_pin_config pin_config;
struct static struct
{ {
uint16_t int_status; uint16_t int_status;
bool battery_controller_status; bool battery_controller_status;
} _interrupts_statuses = {.int_status = 0, .battery_controller_status = false}; } _interrupts_statuses = {.int_status = 0, .battery_controller_status = false};
static struct
{
uint16_t battery_voltage;
uint8_t battery_percentage;
} _battery_stats = {.battery_voltage = 0, .battery_percentage = 100};
/* This call back is automatically called by the watch face when it wants to refresh the battery */ /* This call back is automatically called by the watch face when it wants to refresh the battery */
static void battery_indicator_cb(uint8_t *levelInPercent, BatteryState_e *batteryState) static void battery_indicator_cb(uint8_t *levelInPercent, BatteryState_e *batteryState)
{ {
*levelInPercent = _battery_percentage; *levelInPercent = _battery_stats.battery_percentage;
*batteryState = watch_peripherals_get_battery_controller_status(); *batteryState = watch_peripherals_get_battery_controller_status();
} }
@ -217,7 +223,17 @@ static void setLanguageCb(uint8_t *language, SettingMode_e mode)
} }
} }
static void saveSettingsToFlash(void) static void getBLEDeviceNameCb(const char **dev_name)
{
*dev_name = BLE_DEVICE_NAME;
}
static void getBatteryVoltageCb(uint16_t *battery_voltage)
{
*battery_voltage = _battery_stats.battery_voltage;
}
static void saveSettingsToFlashCb(void)
{ {
/*if(!persistency_save_settings_to_flash()) /*if(!persistency_save_settings_to_flash())
{ {
@ -225,7 +241,7 @@ static void saveSettingsToFlash(void)
}*/ }*/
} }
static void performFactoryReset() static void performFactoryResetCb()
{ {
// Reload factory settings // Reload factory settings
persistency_factory_reset(); persistency_factory_reset();
@ -251,8 +267,10 @@ SettingsScreenAPIInterface_t settingsScreenAPIInterface =
.setBLEEnabledSettingsCb = &(setBLEEnabledCb), .setBLEEnabledSettingsCb = &(setBLEEnabledCb),
.setWiFiEnabledSettingsCb = &(setWiFiEnabledCb), .setWiFiEnabledSettingsCb = &(setWiFiEnabledCb),
.setLanguageSettingsCb = &(setLanguageCb), .setLanguageSettingsCb = &(setLanguageCb),
.saveSettingsCb = &(saveSettingsToFlash), .getBLEDeviceNameCb = &(getBLEDeviceNameCb),
.factoryResetCb = &(performFactoryReset), .getBatteryVoltageCb = &(getBatteryVoltageCb),
.saveSettingsCb = &(saveSettingsToFlashCb),
.factoryResetCb = &(performFactoryResetCb),
}; };
static uint16_t angle_with_offset(uint16_t angle, uint16_t offset) static uint16_t angle_with_offset(uint16_t angle, uint16_t offset)
@ -284,6 +302,17 @@ static void delay_us(uint32_t period, void *intf_ptr)
tls_os_time_delay(pdMS_TO_TICKS(period / 1000)); tls_os_time_delay(pdMS_TO_TICKS(period / 1000));
} }
static void ble_service_nus_data_rx_cb(const uint8_t *data, uint16_t length)
{
for (uint16_t i = 0; i < length; i++)
{
if (data[i] < 32)
printf("[%u]", data[i]);
else
printf("%c", data[i]);
}
}
static void ble_service_state_change_cb(ble_service_state_e ble_service_state) static void ble_service_state_change_cb(ble_service_state_e ble_service_state)
{ {
switch(ble_service_state) switch(ble_service_state)
@ -336,6 +365,8 @@ static void scan_result_cb(void)
tls_mem_free(buffer); tls_mem_free(buffer);
} }
extern LCDConfig_t LCDConfig;
void gfx_task(void *param) void gfx_task(void *param)
{ {
APP_LOG_TRACE("GFX task starting"); APP_LOG_TRACE("GFX task starting");
@ -355,8 +386,8 @@ void gfx_task(void *param)
watch_peripherals_register_battery_controller_status_change_cb(&(battery_controller_status_on_change_cb)); watch_peripherals_register_battery_controller_status_change_cb(&(battery_controller_status_on_change_cb));
/* Make the first battery voltage reading here */ /* Make the first battery voltage reading here */
uint16_t battery_voltage = watch_peripherals_get_battery_voltage(battery_unit_mv); _battery_stats.battery_voltage = watch_peripherals_get_battery_voltage(battery_unit_mv);
_battery_percentage = battery_voltage_to_percentage(battery_voltage); _battery_stats.battery_percentage = battery_voltage_to_percentage(_battery_stats.battery_voltage);
/* Check whether the RTC is running or not, if not, then the board was reset /* Check whether the RTC is running or not, if not, then the board was reset
So we start the RTC */ So we start the RTC */
@ -392,8 +423,6 @@ void gfx_task(void *param)
/* Let's init the I2C interface */ /* Let's init the I2C interface */
i2c_init(I2C_SDA, I2C_SCL, I2C_CLOCK_SPEED); i2c_init(I2C_SDA, I2C_SCL, I2C_CLOCK_SPEED);
uint8_t aliveCounter = 0;
/* Init the magnetometer */ /* Init the magnetometer */
if(!QMC5883L_init()) if(!QMC5883L_init())
APP_LOG_INFO("Failed to init QMC5883L"); APP_LOG_INFO("Failed to init QMC5883L");
@ -499,6 +528,7 @@ void gfx_task(void *param)
APP_LOG_INFO("BMA456 step cnter feature enable failed"); APP_LOG_INFO("BMA456 step cnter feature enable failed");
/* Configure and register BLE stack and services callbacks */ /* Configure and register BLE stack and services callbacks */
ble_service_register_nus_data_rx_cb(&(ble_service_nus_data_rx_cb));
ble_service_register_state_change_cb(&(ble_service_state_change_cb)); ble_service_register_state_change_cb(&(ble_service_state_change_cb));
/* Once we are done with the initializing steps we /* Once we are done with the initializing steps we
@ -508,9 +538,9 @@ void gfx_task(void *param)
/* Enable WiFi hotspot scanning for antenna performance test purposes */ /* Enable WiFi hotspot scanning for antenna performance test purposes */
//tls_wifi_scan_result_cb_register(&(scan_result_cb)); //tls_wifi_scan_result_cb_register(&(scan_result_cb));
extern LCDConfig_t LCDConfig;
float temperature = 0; float temperature = 0;
float pressure = 0; float pressure = 0;
uint32_t update_tick = 0;
for(;;) for(;;)
{ {
@ -543,28 +573,27 @@ void gfx_task(void *param)
APP_LOG_DEBUG("Wrist tilt"); APP_LOG_DEBUG("Wrist tilt");
} }
if(++aliveCounter % 200 == 0) if(lv_tick_elaps(update_tick) > 5000)
{ {
uint32_t steps = 0; uint32_t steps = 0;
if(bma456w_step_counter_output(&steps, &bma) != BMA4_OK) if(bma456w_step_counter_output(&steps, &bma) != BMA4_OK)
APP_LOG_DEBUG("Failed to read step counts"); APP_LOG_DEBUG("Failed to read step counts");
watch_face_set_step_count(&watchFace, steps); watch_face_set_step_count_indicator(&watchFace, steps);
pressure = BMP280_get_pressure(&temperature); pressure = BMP280_get_pressure(&temperature);
BMP280_trigger_measurement(); BMP280_trigger_measurement();
battery_voltage = watch_peripherals_get_battery_voltage(battery_unit_mv); _battery_stats.battery_voltage = watch_peripherals_get_battery_voltage(battery_unit_mv);
_battery_percentage = battery_voltage_to_percentage(battery_voltage); _battery_stats.battery_percentage = battery_voltage_to_percentage(_battery_stats.battery_voltage);
APP_LOG_DEBUG("GFX thread, temp : %0.2f °C, press : %0.2f hPa, battery(%s) : %u mV <-> %u %%", APP_LOG_DEBUG("GFX thread, temp : %0.2f °C, press : %0.2f hPa, battery(%s) : %u mV <-> %u %%",
temperature, temperature,
pressure/100, pressure/100,
battery_controller_status_2_str(watch_peripherals_get_battery_controller_status()), battery_controller_status_2_str(watch_peripherals_get_battery_controller_status()),
battery_voltage, _battery_stats.battery_voltage,
_battery_percentage); _battery_stats.battery_percentage);
//APP_LOG_DEBUG("Scanning WiFi : %d", tls_wifi_scan()); //APP_LOG_DEBUG("Scanning WiFi : %d", tls_wifi_scan());
update_tick = lv_tick_get();
aliveCounter = 0;
} }
/* Handle inactivity periods : */ /* Handle inactivity periods : */
@ -589,9 +618,14 @@ void gfx_task(void *param)
QMC5883L_set_power_mode(Continuous); QMC5883L_set_power_mode(Continuous);
//lcd_on(&LCDConfig, true); //lcd_on(&LCDConfig, true);
lcd_sleep(&LCDConfig, false); lcd_sleep(&LCDConfig, false);
watch_peripherals_set_brightness(persistency_get_settings()->display.display_brightness); //watch_peripherals_set_brightness(persistency_get_settings()->display.display_brightness);
//lcd_on(&LCDConfig, false);
_perform_deferred_display_wake_up_set_timestamp();
} }
/* Will wake the display up after some ms to avoid seeing the second hand jumping */
_perform_deferred_display_wake_up(30);
/* Throttle CPU freq down when inactive to save power or to increase responsiveness */ /* Throttle CPU freq down when inactive to save power or to increase responsiveness */
tls_sys_clk clk; tls_sys_clk clk;
tls_sys_clk_get(&clk); tls_sys_clk_get(&clk);
@ -617,9 +651,31 @@ void gfx_task(void *param)
{ {
_interrupts_statuses.battery_controller_status = false; _interrupts_statuses.battery_controller_status = false;
//Let's refresh the battery percentage as well: //Let's refresh the battery percentage as well:
battery_voltage = watch_peripherals_get_battery_voltage(battery_unit_mv); _battery_stats.battery_voltage = watch_peripherals_get_battery_voltage(battery_unit_mv);
_battery_percentage = battery_voltage_to_percentage(battery_voltage); _battery_stats.battery_percentage = battery_voltage_to_percentage(_battery_stats.battery_voltage);
watch_face_set_battery_indicator(&watchFace, _battery_percentage, watch_peripherals_get_battery_controller_status()); watch_face_set_battery_indicator(&watchFace, _battery_stats.battery_percentage, watch_peripherals_get_battery_controller_status());
} }
} }
}
/* This handling logic should be moved somewhere ! I just don't know where yet ... */
static uint32_t _ticks = 0;
static bool _was_sleeping = false;
static void _perform_deferred_display_wake_up_set_timestamp(void)
{
_ticks = lv_tick_get();
_was_sleeping = true;
}
static void _perform_deferred_display_wake_up(uint8_t deferred_time_in_ms)
{
if(_was_sleeping && lv_tick_elaps(_ticks) > deferred_time_in_ms)
{
_was_sleeping = false;
lcd_on(&LCDConfig, true);
watch_peripherals_set_brightness(persistency_get_settings()->display.display_brightness);
}
} }

View File

@ -22,6 +22,7 @@ static const char* language_options = "Francais\nDeutsch\nEnglish";
static void _simulate_side_screen_item_click(SettingsScreen_t * const settingsScreen, lv_obj_t *item); static void _simulate_side_screen_item_click(SettingsScreen_t * const settingsScreen, lv_obj_t *item);
static void _set_rtc_time_to_label(SettingsScreen_t * const settingsScreen); static void _set_rtc_time_to_label(SettingsScreen_t * const settingsScreen);
static void _set_battery_voltage_to_label(SettingsScreen_t * const settingsScreen);
static void _settings_screen_update_labels_language(SettingsScreen_t * const settingsScreen) static void _settings_screen_update_labels_language(SettingsScreen_t * const settingsScreen)
{ {
@ -232,6 +233,7 @@ static void about_refresh_timer_cb(lv_timer_t *timer)
{ {
SettingsScreen_t *settingsScreen = timer->user_data; SettingsScreen_t *settingsScreen = timer->user_data;
_set_rtc_time_to_label(settingsScreen); _set_rtc_time_to_label(settingsScreen);
_set_battery_voltage_to_label(settingsScreen);
} }
static lv_obj_t *add_menu_list_item(lv_obj_t *list, const char *text, lv_event_cb_t event_cb, void *user_data) static lv_obj_t *add_menu_list_item(lv_obj_t *list, const char *text, lv_event_cb_t event_cb, void *user_data)
@ -479,10 +481,22 @@ static void load_connectivity_side_screen(SettingsScreen_t *settingsScreen)
lv_label_set_text_static(label, "Bluetooth"); lv_label_set_text_static(label, "Bluetooth");
lv_obj_align_to(label, settingsScreen->ble_switch, LV_ALIGN_OUT_RIGHT_MID, 10, 0); lv_obj_align_to(label, settingsScreen->ble_switch, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
label = lv_label_create(settingsScreen->side_screen);
lv_label_set_text_static(label, "Device Name :");
lv_obj_align_to(label, settingsScreen->ble_switch, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5);
lv_obj_t *dev_name_label = lv_label_create(settingsScreen->side_screen);
const char * ble_dev_name = NULL;
if(settingsScreen->settingsScreenAPIInterface.getBLEDeviceNameCb) settingsScreen->settingsScreenAPIInterface.getBLEDeviceNameCb(&ble_dev_name);
lv_label_set_text_static(dev_name_label, ble_dev_name);
lv_obj_set_style_text_color(dev_name_label, lv_color_make(130, 130, 130), LV_PART_MAIN);
lv_obj_align_to(dev_name_label, label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5);
settingsScreen->wifi_switch = lv_switch_create(settingsScreen->side_screen); settingsScreen->wifi_switch = lv_switch_create(settingsScreen->side_screen);
lv_obj_align_to(settingsScreen->wifi_switch, settingsScreen->ble_switch, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 10); lv_obj_align_to(settingsScreen->wifi_switch, dev_name_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 10);
if(settingsScreen->settingsScreenAPIInterface.setWiFiEnabledSettingsCb)settingsScreen->settingsScreenAPIInterface.setWiFiEnabledSettingsCb(&toggled, SETTING_MODE_GET); if(settingsScreen->settingsScreenAPIInterface.setWiFiEnabledSettingsCb)settingsScreen->settingsScreenAPIInterface.setWiFiEnabledSettingsCb(&toggled, SETTING_MODE_GET);
if(toggled) lv_obj_add_state(settingsScreen->wifi_switch, LV_STATE_CHECKED); if(toggled) lv_obj_add_state(settingsScreen->wifi_switch, LV_STATE_CHECKED);
lv_obj_add_state(settingsScreen->wifi_switch, LV_STATE_DISABLED);
lv_obj_add_event_cb(settingsScreen->wifi_switch, &(activation_switch_cb), LV_EVENT_VALUE_CHANGED, settingsScreen); lv_obj_add_event_cb(settingsScreen->wifi_switch, &(activation_switch_cb), LV_EVENT_VALUE_CHANGED, settingsScreen);
label = lv_label_create(settingsScreen->side_screen); label = lv_label_create(settingsScreen->side_screen);
@ -541,9 +555,18 @@ static void load_about_side_screen(SettingsScreen_t *settingsScreen)
lv_obj_align_to(settingsScreen->currentTime.current_time_label, rtc_time, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5); lv_obj_align_to(settingsScreen->currentTime.current_time_label, rtc_time, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5);
_set_rtc_time_to_label(settingsScreen); _set_rtc_time_to_label(settingsScreen);
lv_obj_t *battery_label = lv_label_create(settingsScreen->side_screen);
lv_label_set_text_static(battery_label, "Battery Voltage :");
lv_obj_align_to(battery_label, settingsScreen->currentTime.current_time_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5);
settingsScreen->batteryVoltage.batteryVoltageLabel = lv_label_create(settingsScreen->side_screen);
_set_battery_voltage_to_label(settingsScreen);
lv_obj_set_style_text_color(settingsScreen->batteryVoltage.batteryVoltageLabel, lv_color_make(130, 130, 130), LV_PART_MAIN);
lv_obj_align_to(settingsScreen->batteryVoltage.batteryVoltageLabel, battery_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5);
label = lv_label_create(settingsScreen->side_screen); label = lv_label_create(settingsScreen->side_screen);
lv_label_set_text_static(label, "Factory Reset :"); lv_label_set_text_static(label, "Factory Reset :");
lv_obj_align_to(label, settingsScreen->currentTime.current_time_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5); lv_obj_align_to(label, settingsScreen->batteryVoltage.batteryVoltageLabel, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5);
lv_obj_t *factory_rst_btn = lv_btn_create(settingsScreen->side_screen); lv_obj_t *factory_rst_btn = lv_btn_create(settingsScreen->side_screen);
lv_obj_align_to(factory_rst_btn, label, LV_ALIGN_OUT_BOTTOM_MID, 0, 5); lv_obj_align_to(factory_rst_btn, label, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);
@ -720,3 +743,11 @@ static void _set_rtc_time_to_label(SettingsScreen_t * const settingsScreen)
year+2000); year+2000);
lv_label_set_text_static(settingsScreen->currentTime.current_time_label, settingsScreen->currentTime.current_time_text); lv_label_set_text_static(settingsScreen->currentTime.current_time_label, settingsScreen->currentTime.current_time_text);
} }
static void _set_battery_voltage_to_label(SettingsScreen_t * const settingsScreen)
{
uint16_t voltage = 0;
if(settingsScreen->settingsScreenAPIInterface.getBatteryVoltageCb) settingsScreen->settingsScreenAPIInterface.getBatteryVoltageCb(&voltage);
sprintf(settingsScreen->batteryVoltage.batteryVoltageText, "%u mV", voltage);
lv_label_set_text_static(settingsScreen->batteryVoltage.batteryVoltageLabel, settingsScreen->batteryVoltage.batteryVoltageText);
}

View File

@ -21,6 +21,8 @@ typedef struct SettingsScreenAPIInterface
void (*setBLEEnabledSettingsCb)(bool *enabled, SettingMode_e mode); void (*setBLEEnabledSettingsCb)(bool *enabled, SettingMode_e mode);
void (*setWiFiEnabledSettingsCb)(bool *enabled, SettingMode_e mode); void (*setWiFiEnabledSettingsCb)(bool *enabled, SettingMode_e mode);
void (*setLanguageSettingsCb)(uint8_t *language, SettingMode_e mode); void (*setLanguageSettingsCb)(uint8_t *language, SettingMode_e mode);
void (*getBLEDeviceNameCb)(const char **dev_name);
void (*getBatteryVoltageCb)(uint16_t *battery_voltage);
void (*saveSettingsCb)(void); void (*saveSettingsCb)(void);
void (*factoryResetCb)(void); void (*factoryResetCb)(void);
} SettingsScreenAPIInterface_t; } SettingsScreenAPIInterface_t;
@ -38,6 +40,7 @@ typedef struct SettingsScreen
lv_obj_t *side_screen; lv_obj_t *side_screen;
/* Menu widgets */
lv_obj_t *hour_roller; lv_obj_t *hour_roller;
lv_obj_t *minute_roller; lv_obj_t *minute_roller;
lv_obj_t *second_roller; lv_obj_t *second_roller;
@ -56,6 +59,12 @@ typedef struct SettingsScreen
char current_time_text[20]; char current_time_text[20];
} currentTime; } currentTime;
struct
{
lv_obj_t *batteryVoltageLabel;
char batteryVoltageText[8];
} batteryVoltage;
/* Main screen */ /* Main screen */
lv_obj_t *display; lv_obj_t *display;

View File

@ -469,7 +469,7 @@ void watch_face_set_bluetooth_indicator(WatchFace_t * const watchFace, Bluetooth
_set_bluetooth_indicator(watchFace); _set_bluetooth_indicator(watchFace);
} }
void watch_face_set_step_count(WatchFace_t * const watchFace, uint32_t step_count) void watch_face_set_step_count_indicator(WatchFace_t * const watchFace, uint32_t step_count)
{ {
if(!watchFace) if(!watchFace)
{ {
@ -524,3 +524,14 @@ void watch_face_force_sync(WatchFace_t *const watchFace)
update_watch_hands_angles(watchFace, 0); update_watch_hands_angles(watchFace, 0);
} }
bool watch_face_is_in_use(WatchFace_t * const watchFace)
{
if(!watchFace)
{
LV_LOG_ERROR("NULL pointer given !");
return false;
}
return watchFace->display != NULL;
}

View File

@ -125,7 +125,13 @@ void watch_face_set_battery_indicator(WatchFace_t * const watchFace, uint8_t lev
*/ */
void watch_face_set_bluetooth_indicator(WatchFace_t * const watchFace, BluetoothState_e bluetoothState); void watch_face_set_bluetooth_indicator(WatchFace_t * const watchFace, BluetoothState_e bluetoothState);
void watch_face_set_step_count(WatchFace_t * const watchFace, uint32_t step_count); /**
* @brief Shows the current step count passed as parameter on the watch face.
*
* @param watchFace a pointer to the watch face context structure.
* @param step_count the step count to show on the watch face.
*/
void watch_face_set_step_count_indicator(WatchFace_t * const watchFace, uint32_t step_count);
/** /**
* @brief Forces the watch face to sync up with the RTC by calling the provided date_time_cb * @brief Forces the watch face to sync up with the RTC by calling the provided date_time_cb
@ -134,6 +140,15 @@ void watch_face_set_step_count(WatchFace_t * const watchFace, uint32_t step_coun
*/ */
void watch_face_force_sync(WatchFace_t * const watchFace); void watch_face_force_sync(WatchFace_t * const watchFace);
/**
* @brief Returns true if the watch face screen is currently being used and displayed.
*
* @param watchFace a pointer to the watch face context structure.
* @return true if the watch face screen is being used
* @return false if the watch face screen is not being used/displayed currently
*/
bool watch_face_is_in_use(WatchFace_t * const watchFace);
/** /**
* @brief Frees all resources used by the WatchFace object * @brief Frees all resources used by the WatchFace object
* *

View File

@ -425,7 +425,7 @@
/*** @apache-mynewt-nimble/nimble/host */ /*** @apache-mynewt-nimble/nimble/host */
#ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU
#define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (512) #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) // 512
#endif #endif
#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO #ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO

View File

@ -183,7 +183,7 @@ static void apply_altitude_event_cb(lv_event_t *e)
{ {
AltimeterScreen_t *altimeterScreen = e->user_data; AltimeterScreen_t *altimeterScreen = e->user_data;
uint32_t spinbox_value = lv_spinbox_get_value(altimeterScreen->altitudeOffset_spinbox); int32_t spinbox_value = lv_spinbox_get_value(altimeterScreen->altitudeOffset_spinbox);
destroy_altitude_setting_content(altimeterScreen); destroy_altitude_setting_content(altimeterScreen);
//Show the main value //Show the main value

View File

@ -356,14 +356,14 @@ static void load_connectivity_side_screen(SettingsScreen_t *settingsScreen)
lv_obj_align_to(label, ble_switch, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5); lv_obj_align_to(label, ble_switch, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5);
lv_obj_t *dev_name_label = lv_label_create(settingsScreen->side_screen); lv_obj_t *dev_name_label = lv_label_create(settingsScreen->side_screen);
lv_label_set_text_static(dev_name_label, "W800SW"); lv_label_set_text_static(dev_name_label, NULL/*"W800SW"*/);
lv_obj_set_style_text_color(dev_name_label, lv_color_make(130, 130, 130), LV_PART_MAIN); lv_obj_set_style_text_color(dev_name_label, lv_color_make(130, 130, 130), LV_PART_MAIN);
lv_obj_align_to(dev_name_label, label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5); lv_obj_align_to(dev_name_label, label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5);
lv_obj_t *wifi_switch = lv_switch_create(settingsScreen->side_screen); lv_obj_t *wifi_switch = lv_switch_create(settingsScreen->side_screen);
lv_obj_align_to(wifi_switch, dev_name_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 10); lv_obj_align_to(wifi_switch, dev_name_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 10);
lv_obj_add_state(wifi_switch, LV_STATE_DISABLED);
label = lv_label_create(settingsScreen->side_screen); label = lv_label_create(settingsScreen->side_screen);
lv_label_set_text_static(label, "WiFi"); lv_label_set_text_static(label, "WiFi");
lv_obj_align_to(label, wifi_switch, LV_ALIGN_OUT_RIGHT_MID, 10, 0); lv_obj_align_to(label, wifi_switch, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
@ -417,9 +417,18 @@ static void load_about_side_screen(SettingsScreen_t *settingsScreen)
lv_obj_set_style_text_color(settingsScreen->currentTime.current_time_label, lv_color_make(130, 130, 130), LV_PART_MAIN); lv_obj_set_style_text_color(settingsScreen->currentTime.current_time_label, lv_color_make(130, 130, 130), LV_PART_MAIN);
lv_obj_align_to(settingsScreen->currentTime.current_time_label, rtc_time, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5); lv_obj_align_to(settingsScreen->currentTime.current_time_label, rtc_time, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5);
lv_obj_t *battery_label = lv_label_create(settingsScreen->side_screen);
lv_label_set_text_static(battery_label, "Battery Voltage :");
lv_obj_align_to(battery_label, settingsScreen->currentTime.current_time_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5);
lv_obj_t *battery_voltage = lv_label_create(settingsScreen->side_screen);
lv_label_set_text_static(battery_voltage, "4277 mV");
lv_obj_set_style_text_color(battery_voltage, lv_color_make(130, 130, 130), LV_PART_MAIN);
lv_obj_align_to(battery_voltage, battery_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5);
label = lv_label_create(settingsScreen->side_screen); label = lv_label_create(settingsScreen->side_screen);
lv_label_set_text_static(label, "Factory Reset :"); lv_label_set_text_static(label, "Factory Reset :");
lv_obj_align_to(label, settingsScreen->currentTime.current_time_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5); lv_obj_align_to(label, battery_voltage, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5);
lv_obj_t *factory_rst_btn = lv_btn_create(settingsScreen->side_screen); lv_obj_t *factory_rst_btn = lv_btn_create(settingsScreen->side_screen);
lv_obj_align_to(factory_rst_btn, label, LV_ALIGN_OUT_BOTTOM_MID, 0, 5); lv_obj_align_to(factory_rst_btn, label, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);

View File

@ -180,7 +180,18 @@ static void hide_hour_and_minutes_hand_cb(lv_event_t *e)
{ {
WatchFace_t *watchFace = e->user_data; WatchFace_t *watchFace = e->user_data;
if(lv_obj_has_flag(watchFace->hourHand.handImg, LV_OBJ_FLAG_HIDDEN)) if(255 == lv_obj_get_style_opa(watchFace->hourHand.handImg, LV_PART_MAIN))
{
lv_obj_set_style_opa(watchFace->hourHand.handImg, 120, LV_PART_MAIN);
lv_obj_set_style_opa(watchFace->minuteHand.handImg, 120, LV_PART_MAIN);
}
else
{
lv_obj_set_style_opa(watchFace->hourHand.handImg, 255, LV_PART_MAIN);
lv_obj_set_style_opa(watchFace->minuteHand.handImg, 255, LV_PART_MAIN);
}
/*if(lv_obj_has_flag(watchFace->hourHand.handImg, LV_OBJ_FLAG_HIDDEN))
{ {
lv_obj_clear_flag(watchFace->hourHand.handImg, LV_OBJ_FLAG_HIDDEN); lv_obj_clear_flag(watchFace->hourHand.handImg, LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_flag(watchFace->minuteHand.handImg, LV_OBJ_FLAG_HIDDEN); lv_obj_clear_flag(watchFace->minuteHand.handImg, LV_OBJ_FLAG_HIDDEN);
@ -189,7 +200,7 @@ static void hide_hour_and_minutes_hand_cb(lv_event_t *e)
{ {
lv_obj_add_flag(watchFace->hourHand.handImg, LV_OBJ_FLAG_HIDDEN); lv_obj_add_flag(watchFace->hourHand.handImg, LV_OBJ_FLAG_HIDDEN);
lv_obj_add_flag(watchFace->minuteHand.handImg, LV_OBJ_FLAG_HIDDEN); lv_obj_add_flag(watchFace->minuteHand.handImg, LV_OBJ_FLAG_HIDDEN);
} }*/
} }
void watch_face_init(WatchFace_t * const watchFace) void watch_face_init(WatchFace_t * const watchFace)