Generate pinetime-recovery : a light version of InfiniTime design to be used as a recovery firmware : it only provides basic UI and BLE connectivity for OTA.

This new FW is build on the same codebasse than the actual InfiniTime. Only the display task is different (this allows to remove lvgl from the recovery fw, which is very heavy).

CMake builds and docker have been modified accordingly.
Note than the fw is converted into an image and then into a DFU in the cmake build (previously, it was only done in the
This commit is contained in:
Jean-François Milants
2021-01-26 20:31:45 +01:00
parent 80838d1e42
commit 25f35c7d0e
45 changed files with 3580 additions and 81 deletions

View File

@@ -488,7 +488,58 @@ list(APPEND SOURCE_FILES
components/heartrate/HeartRateController.cpp
)
list(APPEND GRAPHICS_SOURCE_FILES
list(APPEND RECOVERY_SOURCE_FILES
BootloaderVersion.cpp
logging/NrfLogger.cpp
displayapp/DisplayAppRecovery.cpp
main.cpp
drivers/St7789.cpp
drivers/SpiNorFlash.cpp
drivers/SpiMaster.cpp
drivers/Spi.cpp
drivers/Watchdog.cpp
drivers/DebugPins.cpp
drivers/InternalFlash.cpp
drivers/Hrs3300.cpp
components/battery/BatteryController.cpp
components/ble/BleController.cpp
components/ble/NotificationManager.cpp
components/datetime/DateTimeController.cpp
components/brightness/BrightnessController.cpp
components/ble/NimbleController.cpp
components/ble/DeviceInformationService.cpp
components/ble/CurrentTimeClient.cpp
components/ble/AlertNotificationClient.cpp
components/ble/DfuService.cpp
components/ble/CurrentTimeService.cpp
components/ble/AlertNotificationService.cpp
components/ble/MusicService.cpp
components/ble/BatteryInformationService.cpp
components/ble/ImmediateAlertService.cpp
components/ble/ServiceDiscovery.cpp
components/ble/NavigationService.cpp
components/ble/HeartRateService.cpp
components/firmwarevalidator/FirmwareValidator.cpp
drivers/Cst816s.cpp
FreeRTOS/port.c
FreeRTOS/port_cmsis_systick.c
FreeRTOS/port_cmsis.c
systemtask/SystemTask.cpp
drivers/TwiMaster.cpp
components/gfx/Gfx.cpp
displayapp/icons/infinitime/infinitime-nb.c
components/rle/RleDecoder.cpp
components/heartrate/HeartRateController.cpp
heartratetask/HeartRateTask.cpp
components/heartrate/Ppg.cpp
components/heartrate/Biquad.cpp
components/heartrate/Ptagc.cpp
)
list(APPEND RECOVERYLOADER_SOURCE_FILES
# FreeRTOS
FreeRTOS/port.c
FreeRTOS/port_cmsis_systick.c
@@ -499,18 +550,23 @@ list(APPEND GRAPHICS_SOURCE_FILES
drivers/Spi.cpp
logging/NrfLogger.cpp
components/rle/RleDecoder.cpp
components/gfx/Gfx.cpp
drivers/St7789.cpp
components/brightness/BrightnessController.cpp
graphics.cpp
displayapp/icons/infinitime/infinitime-nb.c
recoveryLoader.cpp
)
set(INCLUDE_FILES
BootloaderVersion.h
logging/Logger.h
logging/NrfLogger.h
displayapp/DisplayApp.h
displayapp/Messages.h
displayapp/TouchEvents.h
displayapp/screens/Screen.h
displayapp/screens/Clock.h
@@ -569,7 +625,6 @@ set(INCLUDE_FILES
libs/date/includes/date/julian.h
libs/date/includes/date/ptz.h
libs/date/includes/date/tz_private.h
displayapp/LittleVgl.h
systemtask/SystemTask.h
systemtask/SystemMonitor.h
displayapp/screens/Symbols.h
@@ -760,8 +815,8 @@ add_custom_command(TARGET ${EXECUTABLE_NAME}
# Build binary intended to be used by bootloader
set(EXECUTABLE_MCUBOOT_NAME "pinetime-mcuboot-app")
set(EXECUTABLE_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
set(IMAGE_MCUBOOT_FILE_NAME image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.bin)
set(DFU_FILE_NAME dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip)
set(IMAGE_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.bin)
set(DFU_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip)
set(NRF5_LINKER_SCRIPT_MCUBOOT "${CMAKE_SOURCE_DIR}/gcc_nrf52-mcuboot.ld")
add_executable(${EXECUTABLE_MCUBOOT_NAME} ${SOURCE_FILES})
target_link_libraries(${EXECUTABLE_MCUBOOT_NAME} nimble nrf-sdk lvgl)
@@ -786,16 +841,19 @@ add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_NAME}
COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_MCUBOOT_FILE_NAME}.out
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_MCUBOOT_FILE_NAME}.out "${EXECUTABLE_MCUBOOT_FILE_NAME}.bin"
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_MCUBOOT_FILE_NAME}.out "${EXECUTABLE_MCUBOOT_FILE_NAME}.hex"
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_MCUBOOT_FILE_NAME}.bin ${IMAGE_MCUBOOT_FILE_NAME}
COMMAND adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application ${IMAGE_MCUBOOT_FILE_NAME} ${DFU_MCUBOOT_FILE_NAME}
COMMENT "post build steps for ${EXECUTABLE_MCUBOOT_FILE_NAME}"
)
# Build binary that writes the graphic assets for the bootloader
set(EXECUTABLE_GRAPHICS_NAME "pinetime-graphics")
set(EXECUTABLE_GRAPHICS_FILE_NAME ${EXECUTABLE_GRAPHICS_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
add_executable(${EXECUTABLE_GRAPHICS_NAME} ${GRAPHICS_SOURCE_FILES})
target_link_libraries(${EXECUTABLE_GRAPHICS_NAME} nrf-sdk)
set_target_properties(${EXECUTABLE_GRAPHICS_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_GRAPHICS_FILE_NAME})
target_compile_options(${EXECUTABLE_GRAPHICS_NAME} PUBLIC
# InfiniTime recovery firmware (autonomous)
set(EXECUTABLE_RECOVERY_NAME "pinetime-recovery")
set(EXECUTABLE_RECOVERY_FILE_NAME ${EXECUTABLE_RECOVERY_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
add_executable(${EXECUTABLE_RECOVERY_NAME} ${RECOVERY_SOURCE_FILES})
target_link_libraries(${EXECUTABLE_RECOVERY_NAME} nimble nrf-sdk)
set_target_properties(${EXECUTABLE_RECOVERY_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERY_FILE_NAME})
target_compile_definitions(${EXECUTABLE_RECOVERY_NAME} PUBLIC "PINETIME_IS_RECOVERY")
target_compile_options(${EXECUTABLE_RECOVERY_NAME} PUBLIC
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3>
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3>
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3>
@@ -803,21 +861,128 @@ target_compile_options(${EXECUTABLE_GRAPHICS_NAME} PUBLIC
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -std=c99 -x assembler-with-cpp>
)
set_target_properties(${EXECUTABLE_GRAPHICS_NAME} PROPERTIES
set_target_properties(${EXECUTABLE_RECOVERY_NAME} PROPERTIES
SUFFIX ".out"
LINK_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_GRAPHICS_FILE_NAME}.map"
LINK_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERY_FILE_NAME}.map"
CXX_STANDARD 11
C_STANDARD 99
)
add_custom_command(TARGET ${EXECUTABLE_GRAPHICS_NAME}
add_custom_command(TARGET ${EXECUTABLE_RECOVERY_NAME}
POST_BUILD
COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_GRAPHICS_FILE_NAME}.out
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_GRAPHICS_FILE_NAME}.out "${EXECUTABLE_GRAPHICS_FILE_NAME}.bin"
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_GRAPHICS_FILE_NAME}.out "${EXECUTABLE_GRAPHICS_FILE_NAME}.hex"
COMMENT "post build steps for ${EXECUTABLE_GRAPHICS_FILE_NAME}"
COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_RECOVERY_FILE_NAME}.out
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_RECOVERY_FILE_NAME}.out "${EXECUTABLE_RECOVERY_FILE_NAME}.bin"
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_RECOVERY_FILE_NAME}.out "${EXECUTABLE_RECOVERY_FILE_NAME}.hex"
COMMENT "post build steps for ${EXECUTABLE_RECOVERY_FILE_NAME}"
)
# InfiniTime recovery firmware (mcuboot)
set(EXECUTABLE_RECOVERY_MCUBOOT_NAME "pinetime-mcuboot-recovery")
set(EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
set(IMAGE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.bin)
set(DFU_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip)
add_executable(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} ${RECOVERY_SOURCE_FILES})
target_link_libraries(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} nimble nrf-sdk)
set_target_properties(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME})
target_compile_definitions(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC "PINETIME_IS_RECOVERY")
target_compile_options(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3>
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3>
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3>
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3>
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -std=c99 -x assembler-with-cpp>
)
set_target_properties(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PROPERTIES
SUFFIX ".out"
LINK_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.map"
CXX_STANDARD 11
C_STANDARD 99
)
add_custom_command(TARGET ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}
POST_BUILD
COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.out
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.out "${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.bin"
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.out "${EXECUTABLE_RECOVERYY_MCUBOOT_FILE_NAME}.hex"
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.bin ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME}
COMMAND python ${CMAKE_SOURCE_DIR}/tools/bin2c.py ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME} recoveryImage > recoveryImage.h
COMMAND adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME} ${DFU_RECOVERY_MCUBOOT_FILE_NAME}
COMMENT "post build steps for ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}"
)
# Build binary that writes the recovery image into the SPI flash memory
set(EXECUTABLE_RECOVERYLOADER_NAME "pinetime-recovery-loader")
set(EXECUTABLE_RECOVERYLOADER_FILE_NAME ${EXECUTABLE_RECOVERYLOADER_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
add_executable(${EXECUTABLE_RECOVERYLOADER_NAME} ${RECOVERYLOADER_SOURCE_FILES})
target_link_libraries(${EXECUTABLE_RECOVERYLOADER_NAME} nrf-sdk)
set_target_properties(${EXECUTABLE_RECOVERYLOADER_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERYLOADER_FILE_NAME})
target_compile_options(${EXECUTABLE_RECOVERYLOADER_NAME} PUBLIC
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3>
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3>
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3>
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3>
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -std=c99 -x assembler-with-cpp>
)
target_include_directories(${EXECUTABLE_RECOVERYLOADER_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src>
)
add_dependencies(${EXECUTABLE_RECOVERYLOADER_NAME} ${EXECUTABLE_RECOVERY_MCUBOOT_NAME})
set_target_properties(${EXECUTABLE_RECOVERYLOADER_NAME} PROPERTIES
SUFFIX ".out"
LINK_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERYLOADER_FILE_NAME}.map"
CXX_STANDARD 11
C_STANDARD 99
)
add_custom_command(TARGET ${EXECUTABLE_RECOVERYLOADER_NAME}
POST_BUILD
COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_RECOVERYLOADER_FILE_NAME}.out
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_RECOVERYLOADER_FILE_NAME}.out "${EXECUTABLE_RECOVERYLOADER_FILE_NAME}.bin"
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_RECOVERYLOADER_FILE_NAME}.out "${EXECUTABLE_RECOVERYLOADER_FILE_NAME}.hex"
COMMENT "post build steps for ${EXECUTABLE_RECOVERYLOADER_FILE_NAME}"
)
# Build binary that writes the recovery image (MCUBoot version)
set(EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME "pinetime-mcuboot-recovery-loader")
set(EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
set(IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.bin)
set(DFU_MCUBOOT_RECOVERYLOADER_FILE_NAME ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip)
add_executable(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} ${RECOVERYLOADER_SOURCE_FILES})
target_link_libraries(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} nrf-sdk)
set_target_properties(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME})
target_compile_options(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} PUBLIC
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3>
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3>
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3>
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3>
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -std=c99 -x assembler-with-cpp>
)
target_include_directories(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src>
)
add_dependencies(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} ${EXECUTABLE_RECOVERY_MCUBOOT_NAME})
set_target_properties(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} PROPERTIES
SUFFIX ".out"
LINK_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.map"
CXX_STANDARD 11
C_STANDARD 99
)
add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}
POST_BUILD
COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.out
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.out "${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.bin"
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.out "${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.hex"
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.bin ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME}
COMMAND python ${CMAKE_SOURCE_DIR}/tools/bin2c.py ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME} recoveryLoaderImage > recoveryLoaderImage.h
COMMAND adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME} ${DFU_MCUBOOT_RECOVERYLOADER_FILE_NAME}
COMMENT "post build steps for ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}"
)
# FLASH
if (USE_JLINK)
add_custom_target(FLASH_ERASE

View File

@@ -0,0 +1,39 @@
#include "RleDecoder.h"
using namespace Pinetime::Tools;
RleDecoder::RleDecoder(const uint8_t *buffer, size_t size) : buffer{buffer}, size{size} {
}
RleDecoder::RleDecoder(const uint8_t *buffer, size_t size, uint16_t foregroundColor, uint16_t backgroundColor) : RleDecoder{buffer, size} {
this->foregroundColor = foregroundColor;
this->backgroundColor = backgroundColor;
}
void RleDecoder::DecodeNext(uint8_t *output, size_t maxBytes) {
for (;encodedBufferIndex<size; encodedBufferIndex++) {
uint8_t rl = buffer[encodedBufferIndex] - processedCount;
while (rl) {
output[bp] = color >> 8;
output[bp + 1] = color & 0xff;
bp += 2;
rl -= 1;
processedCount++;
if (bp >= maxBytes) {
bp = 0;
y += 1;
return;
}
}
processedCount = 0;
if (color == backgroundColor)
color = foregroundColor;
else
color = backgroundColor;
}
}

View File

@@ -0,0 +1,33 @@
#pragma once
#include <cstdint>
#include <cstddef>
namespace Pinetime {
namespace Tools {
/* 1-bit RLE decoder. Provide the encoded buffer to the constructor and then call DecodeNext() by
* specifying the output (decoded) buffer and the maximum number of bytes this buffer can handle.
*
* Code from https://github.com/daniel-thompson/wasp-bootloader by Daniel Thompson released under the MIT license.
*/
class RleDecoder {
public:
RleDecoder(const uint8_t* buffer, size_t size);
RleDecoder(const uint8_t* buffer, size_t size, uint16_t foregroundColor, uint16_t backgroundColor);
void DecodeNext(uint8_t* output, size_t maxBytes);
private:
const uint8_t* buffer;
size_t size;
int encodedBufferIndex = 0;
int y = 0;
uint16_t bp = 0;
uint16_t foregroundColor = 0xffff;
uint16_t backgroundColor = 0;
uint16_t color = backgroundColor;
int processedCount = 0;
};
}
}

View File

@@ -26,6 +26,7 @@
#include "systemtask/SystemTask.h"
using namespace Pinetime::Applications;
using namespace Pinetime::Applications::Display;
DisplayApp::DisplayApp(Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Drivers::Cst816S &touchPanel,
Controllers::Battery &batteryController, Controllers::Ble &bleController,
@@ -227,7 +228,7 @@ void DisplayApp::IdleState() {
}
void DisplayApp::PushMessage(DisplayApp::Messages msg) {
void DisplayApp::PushMessage(Messages msg) {
BaseType_t xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR(msgQueue, &msg, &xHigherPriorityTaskWoken);

View File

@@ -10,6 +10,7 @@
#include "components/brightness/BrightnessController.h"
#include "components/firmwarevalidator/FirmwareValidator.h"
#include "displayapp/screens/Modal.h"
#include "Messages.h"
namespace Pinetime {
@@ -33,9 +34,6 @@ namespace Pinetime {
class DisplayApp {
public:
enum class States {Idle, Running};
enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent, ButtonPushed,
NewNotification, BleFirmwareUpdateStarted };
enum class FullRefreshDirections { None, Up, Down };
enum class TouchModes { Gestures, Polling };
@@ -46,7 +44,7 @@ namespace Pinetime {
Pinetime::Controllers::NotificationManager& notificationManager,
Pinetime::Controllers::HeartRateController& heartRateController);
void Start();
void PushMessage(Messages msg);
void PushMessage(Display::Messages msg);
void StartApp(Apps app);

View File

@@ -0,0 +1,110 @@
#include "DisplayAppRecovery.h"
#include "DisplayAppRecovery.h"
#include <FreeRTOS.h>
#include <task.h>
#include <libraries/log/nrf_log.h>
#include <components/rle/RleDecoder.h>
#include "displayapp/icons/infinitime/infinitime-nb.c"
using namespace Pinetime::Applications;
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,
Pinetime::Controllers::HeartRateController& heartRateController):
lcd{lcd}, bleController{bleController} {
msgQueue = xQueueCreate(queueSize, itemSize);
}
void DisplayApp::Start() {
if (pdPASS != xTaskCreate(DisplayApp::Process, "displayapp", 512, this, 0, &taskHandle))
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
}
void DisplayApp::Process(void *instance) {
auto *app = static_cast<DisplayApp *>(instance);
NRF_LOG_INFO("displayapp task started!");
// Send a dummy notification to unlock the lvgl display driver for the first iteration
xTaskNotifyGive(xTaskGetCurrentTaskHandle());
app->InitHw();
while (1) {
app->Refresh();
}
}
void DisplayApp::InitHw() {
DisplayLogo(colorWhite);
}
void DisplayApp::Refresh() {
Display::Messages msg;
if (xQueueReceive(msgQueue, &msg, 200)) {
switch (msg) {
case Display::Messages::UpdateBleConnection:
if (bleController.IsConnected())
DisplayLogo(colorBlue);
else
DisplayLogo(colorWhite);
break;
case Display::Messages::BleFirmwareUpdateStarted:
DisplayLogo(colorGreen);
break;
default:
break;
}
}
if (bleController.IsFirmwareUpdating()) {
uint8_t percent = (static_cast<float>(bleController.FirmwareUpdateCurrentBytes()) /
static_cast<float>(bleController.FirmwareUpdateTotalBytes())) * 100.0f;
switch (bleController.State()) {
case Controllers::Ble::FirmwareUpdateStates::Running:
DisplayOtaProgress(percent, colorWhite);
break;
case Controllers::Ble::FirmwareUpdateStates::Validated:
DisplayOtaProgress(100, colorGreenSwapped);
break;
case Controllers::Ble::FirmwareUpdateStates::Error:
DisplayOtaProgress(100, colorRedSwapped);
break;
default:
break;
}
}
}
void DisplayApp::DisplayLogo(uint16_t color) {
Pinetime::Tools::RleDecoder rleDecoder(infinitime_nb, sizeof(infinitime_nb), color, colorBlack);
for(int i = 0; i < displayWidth; i++) {
rleDecoder.DecodeNext(displayBuffer, displayWidth * bytesPerPixel);
ulTaskNotifyTake(pdTRUE, 500);
lcd.BeginDrawBuffer(0, i, displayWidth, 1);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(displayBuffer), displayWidth * bytesPerPixel);
}
}
void DisplayApp::DisplayOtaProgress(uint8_t percent, uint16_t color) {
const uint8_t barHeight = 20;
std::fill(displayBuffer, displayBuffer+(displayWidth * bytesPerPixel), color);
for(int i = 0; i < barHeight; i++) {
ulTaskNotifyTake(pdTRUE, 500);
uint16_t barWidth = std::min(static_cast<float>(percent) * 2.4f, static_cast<float>(displayWidth));
lcd.BeginDrawBuffer(0, displayWidth - barHeight + i, barWidth, 1);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(displayBuffer), barWidth * bytesPerPixel);
}
}
void DisplayApp::PushMessage(Display::Messages msg) {
BaseType_t xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR(msgQueue, &msg, &xHigherPriorityTaskWoken);
if (xHigherPriorityTaskWoken) {
/* Actual macro used here is port specific. */
// TODO : should I do something here?
}
}

View File

@@ -0,0 +1,72 @@
#pragma once
#include <FreeRTOS.h>
#include <task.h>
#include <drivers/St7789.h>
#include <drivers/SpiMaster.h>
#include <bits/unique_ptr.h>
#include <queue.h>
#include "components/gfx/Gfx.h"
#include "components/battery/BatteryController.h"
#include "components/brightness/BrightnessController.h"
#include "components/ble/BleController.h"
#include "components/datetime/DateTimeController.h"
#include "components/ble/NotificationManager.h"
#include "components/firmwarevalidator/FirmwareValidator.h"
#include "drivers/Cst816s.h"
#include <date/date.h>
#include "displayapp/screens/Clock.h"
#include "displayapp/screens/Modal.h"
#include <drivers/Watchdog.h>
#include "TouchEvents.h"
#include "Apps.h"
#include "Messages.h"
#include "DummyLittleVgl.h"
namespace Pinetime {
namespace System {
class SystemTask;
};
namespace Applications {
class DisplayApp {
public:
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,
Pinetime::Controllers::HeartRateController& heartRateController);
void Start();
void PushMessage(Pinetime::Applications::Display::Messages msg);
private:
TaskHandle_t taskHandle;
static void Process(void* instance);
void DisplayLogo(uint16_t color);
void DisplayOtaProgress(uint8_t percent, uint16_t color);
void InitHw();
void Refresh();
Pinetime::Drivers::St7789& lcd;
Controllers::Ble &bleController;
static constexpr uint8_t queueSize = 10;
static constexpr uint8_t itemSize = 1;
QueueHandle_t msgQueue;
static constexpr uint8_t displayWidth = 240;
static constexpr uint8_t displayHeight = 240;
static constexpr uint8_t bytesPerPixel = 2;
static constexpr uint16_t colorWhite = 0xFFFF;
static constexpr uint16_t colorGreen = 0x07E0;
static constexpr uint16_t colorGreenSwapped = 0xE007;
static constexpr uint16_t colorBlue = 0x0000ff;
static constexpr uint16_t colorRed = 0xff00;
static constexpr uint16_t colorRedSwapped = 0x00ff;
static constexpr uint16_t colorBlack = 0x0000;
uint8_t displayBuffer[displayWidth * bytesPerPixel];
};
}
}

View File

@@ -0,0 +1,30 @@
#pragma once
#include <libs/lvgl/src/lv_core/lv_style.h>
#include <libs/lvgl/src/lv_themes/lv_theme.h>
#include <libs/lvgl/src/lv_hal/lv_hal.h>
#include <drivers/St7789.h>
#include <drivers/Cst816s.h>
namespace Pinetime {
namespace Components {
class LittleVgl {
public:
enum class FullRefreshDirections { None, Up, Down };
LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel) {}
LittleVgl(const LittleVgl&) = delete;
LittleVgl& operator=(const LittleVgl&) = delete;
LittleVgl(LittleVgl&&) = delete;
LittleVgl& operator=(LittleVgl&&) = delete;
void FlushDisplay(const lv_area_t * area, lv_color_t * color_p) {}
bool GetTouchPadInfo(lv_indev_data_t *ptr) {return false;}
void SetFullRefresh(FullRefreshDirections direction) {}
void SetNewTapEvent(uint16_t x, uint16_t y) {}
};
}
}

11
src/displayapp/Messages.h Normal file
View File

@@ -0,0 +1,11 @@
#pragma once
namespace Pinetime {
namespace Applications {
namespace Display {
enum class Messages : uint8_t {
GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent, ButtonPushed,
NewNotification, BleFirmwareUpdateStarted
};
}
}
}

View File

@@ -0,0 +1,127 @@
#include <unistd.h>
// 1-bit RLE, generated from ./infinitime-nb.png, 1445 bytes
static const uint8_t infinitime_nb[] = {
0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0,
0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0,
0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0x66, 0x2, 0xed, 0x4, 0xec, 0x5,
0xea, 0x7, 0xe8, 0x9, 0xe6, 0xa, 0xe5, 0xc, 0xe3, 0xe, 0xe1, 0x10,
0xdf, 0x12, 0xde, 0x12, 0xdd, 0x14, 0xdb, 0x16, 0xd9, 0x18, 0xd7, 0x1a,
0xd5, 0x1b, 0xd4, 0x1d, 0xd3, 0xd, 0x3, 0xe, 0xd1, 0xd, 0x5, 0xe,
0xcf, 0xe, 0x5, 0xf, 0xcd, 0xf, 0x5, 0xf, 0xcc, 0x10, 0x5, 0x10,
0xca, 0x11, 0x5, 0x11, 0xc8, 0x12, 0x5, 0x12, 0xc6, 0x13, 0x5, 0x13,
0xc5, 0x13, 0x5, 0x13, 0xc4, 0x14, 0x5, 0x14, 0xc2, 0x15, 0x5, 0x15,
0xc0, 0x17, 0x3, 0x17, 0xbe, 0x33, 0xbc, 0x34, 0xbb, 0x36, 0xba, 0x37,
0xb8, 0x39, 0xb6, 0x3b, 0xb4, 0x3c, 0xb3, 0x3e, 0xb1, 0x40, 0xaf, 0x9,
0x2, 0x2e, 0x1, 0x8, 0xad, 0x9, 0x4, 0x2c, 0x3, 0x8, 0xac, 0x8,
0x6, 0x2a, 0x5, 0x7, 0xab, 0x9, 0x6, 0x29, 0x6, 0x8, 0xa9, 0xb,
0x5, 0x29, 0x5, 0xa, 0xa7, 0xd, 0x3, 0x2b, 0x3, 0xc, 0xa5, 0x4c,
0xa3, 0x4d, 0xa2, 0x4f, 0xa0, 0x51, 0x9f, 0x52, 0x9d, 0x54, 0x9b, 0x55,
0x9a, 0x57, 0x98, 0x59, 0x96, 0x5b, 0x94, 0x5d, 0x93, 0x5d, 0x92, 0x5f,
0x90, 0x61, 0x8e, 0x63, 0x8c, 0x65, 0x8a, 0x66, 0x89, 0x68, 0x87, 0x8,
0x2, 0x59, 0x2, 0x5, 0x86, 0x7, 0x4, 0x57, 0x4, 0x5, 0x84, 0x8,
0x5, 0x55, 0x6, 0x5, 0x82, 0x9, 0x6, 0x54, 0x6, 0x5, 0x81, 0xa,
0x5, 0x55, 0x5, 0x7, 0x7f, 0xc, 0x4, 0x56, 0x3, 0x9, 0x7d, 0x74,
0x7b, 0x76, 0x79, 0x77, 0x79, 0x78, 0x77, 0x7a, 0x75, 0x7c, 0x73, 0x7e,
0x71, 0x7f, 0x70, 0x81, 0x6e, 0x83, 0x6c, 0x85, 0x6b, 0x86, 0x69, 0x87,
0x68, 0x89, 0x66, 0x8b, 0x64, 0x8d, 0x62, 0x8f, 0x60, 0x90, 0x60, 0x91,
0x5e, 0x93, 0x5c, 0x95, 0x5a, 0xe, 0x7, 0x71, 0x7, 0xa, 0x58, 0xd,
0xb, 0x6d, 0xb, 0x8, 0x57, 0xe, 0xc, 0x6c, 0xc, 0x8, 0x55, 0xf,
0xc, 0x6c, 0xb, 0xa, 0x53, 0x11, 0xa, 0x6d, 0xb, 0xb, 0x52, 0x9f,
0x50, 0xa0, 0x4f, 0xa2, 0x4d, 0xa4, 0x4b, 0xa6, 0x49, 0xa8, 0x48, 0xa8,
0xff, 0x0, 0xe3, 0x44, 0xad, 0x43, 0xae, 0x41, 0xb0, 0x40, 0xb1, 0x3e,
0xb2, 0x3e, 0xb3, 0x3c, 0xb5, 0x3a, 0xb7, 0x39, 0xb8, 0x37, 0xb9, 0x36,
0xbb, 0x35, 0xe, 0x1, 0x66, 0x1, 0x3c, 0x1, 0x9, 0x33, 0xe, 0x3,
0x15, 0x5, 0xe, 0x4, 0x16, 0x15, 0xd, 0x3, 0x11, 0x5, 0xe, 0x4,
0x12, 0x3, 0x9, 0x31, 0xf, 0x4, 0x14, 0x6, 0xd, 0x4, 0x16, 0x15,
0xd, 0x4, 0x10, 0x5, 0xe, 0x4, 0x12, 0x4, 0x9, 0x30, 0xf, 0x4,
0x14, 0x6, 0xd, 0x4, 0x16, 0x15, 0xd, 0x4, 0x10, 0x6, 0xd, 0x4,
0x12, 0x4, 0x9, 0x2f, 0x10, 0x4, 0x14, 0x7, 0xc, 0x4, 0x16, 0x15,
0xd, 0x4, 0x10, 0x6, 0xd, 0x4, 0x12, 0x4, 0xa, 0x2d, 0x11, 0x4,
0x14, 0x7, 0xc, 0x4, 0x16, 0x4, 0x1e, 0x4, 0x10, 0x7, 0xc, 0x4,
0x12, 0x4, 0xb, 0x2c, 0x11, 0x4, 0x14, 0x8, 0xb, 0x4, 0x16, 0x4,
0x1e, 0x4, 0x10, 0x7, 0xc, 0x4, 0x12, 0x4, 0xc, 0x2a, 0x12, 0x4,
0x14, 0x8, 0xb, 0x4, 0x16, 0x4, 0x1e, 0x4, 0x10, 0x8, 0xb, 0x4,
0x12, 0x4, 0xd, 0x28, 0x13, 0x4, 0x14, 0x4, 0x1, 0x4, 0xa, 0x4,
0x16, 0x4, 0x1e, 0x4, 0x10, 0x4, 0x1, 0x3, 0xb, 0x4, 0x12, 0x4,
0xd, 0x28, 0x13, 0x4, 0x14, 0x4, 0x1, 0x4, 0xa, 0x4, 0x16, 0x4,
0x1e, 0x4, 0x10, 0x4, 0x1, 0x4, 0xa, 0x4, 0x12, 0x4, 0xe, 0x26,
0x14, 0x4, 0x14, 0x4, 0x2, 0x4, 0x9, 0x4, 0x16, 0x4, 0x1e, 0x4,
0x10, 0x4, 0x2, 0x3, 0xa, 0x4, 0x12, 0x4, 0xf, 0x24, 0x15, 0x4,
0x14, 0x4, 0x2, 0x4, 0x9, 0x4, 0x16, 0x4, 0x1e, 0x4, 0x10, 0x4,
0x2, 0x4, 0x9, 0x4, 0x12, 0x4, 0x10, 0x23, 0x15, 0x4, 0x14, 0x4,
0x3, 0x4, 0x8, 0x4, 0x16, 0x4, 0x1e, 0x4, 0x10, 0x4, 0x2, 0x4,
0x9, 0x4, 0x12, 0x4, 0x11, 0x21, 0x16, 0x4, 0x14, 0x4, 0x3, 0x4,
0x8, 0x4, 0x16, 0x4, 0x1e, 0x4, 0x10, 0x4, 0x3, 0x4, 0x8, 0x4,
0x12, 0x4, 0x11, 0x20, 0x17, 0x4, 0x14, 0x4, 0x4, 0x3, 0x8, 0x4,
0x16, 0x4, 0x1e, 0x4, 0x10, 0x4, 0x3, 0x4, 0x8, 0x4, 0x12, 0x4,
0x12, 0x1f, 0x17, 0x4, 0x14, 0x4, 0x4, 0x4, 0x7, 0x4, 0x16, 0x4,
0x1e, 0x4, 0x10, 0x4, 0x4, 0x3, 0x8, 0x4, 0x12, 0x4, 0x13, 0x1d,
0x18, 0x4, 0x14, 0x4, 0x5, 0x3, 0x7, 0x4, 0x16, 0x13, 0xf, 0x4,
0x10, 0x4, 0x4, 0x4, 0x7, 0x4, 0x12, 0x4, 0x14, 0x1b, 0x1a, 0x3,
0x14, 0x4, 0x5, 0x4, 0x6, 0x4, 0x16, 0x13, 0x10, 0x3, 0x10, 0x4,
0x5, 0x3, 0x7, 0x4, 0x13, 0x3, 0x15, 0x1a, 0x1b, 0x1, 0x15, 0x4,
0x6, 0x3, 0x6, 0x4, 0x16, 0x13, 0x11, 0x1, 0x11, 0x4, 0x5, 0x4,
0x6, 0x4, 0x14, 0x1, 0x16, 0x19, 0x32, 0x4, 0x6, 0x4, 0x5, 0x4,
0x16, 0x13, 0x23, 0x4, 0x6, 0x3, 0x6, 0x4, 0x2c, 0x17, 0x33, 0x4,
0x7, 0x3, 0x5, 0x4, 0x16, 0x4, 0x32, 0x4, 0x6, 0x4, 0x5, 0x4,
0x2d, 0x16, 0x1d, 0x1, 0x15, 0x4, 0x7, 0x4, 0x4, 0x4, 0x16, 0x4,
0x20, 0x1, 0x11, 0x4, 0x7, 0x3, 0x5, 0x4, 0x14, 0x1, 0x19, 0x14,
0x1d, 0x3, 0x14, 0x4, 0x7, 0x4, 0x4, 0x4, 0x16, 0x4, 0x1f, 0x3,
0x10, 0x4, 0x7, 0x4, 0x4, 0x4, 0x13, 0x3, 0x19, 0x12, 0x1d, 0x4,
0x14, 0x4, 0x8, 0x4, 0x3, 0x4, 0x16, 0x4, 0x1e, 0x4, 0x10, 0x4,
0x8, 0x3, 0x4, 0x4, 0x12, 0x4, 0x19, 0x12, 0x1d, 0x4, 0x14, 0x4,
0x8, 0x4, 0x3, 0x4, 0x16, 0x4, 0x1e, 0x4, 0x10, 0x4, 0x8, 0x4,
0x3, 0x4, 0x12, 0x4, 0x1a, 0x10, 0x1e, 0x4, 0x14, 0x4, 0x9, 0x3,
0x3, 0x4, 0x16, 0x4, 0x1e, 0x4, 0x10, 0x4, 0x8, 0x4, 0x3, 0x4,
0x12, 0x4, 0x1b, 0xe, 0x1f, 0x4, 0x14, 0x4, 0x9, 0x4, 0x2, 0x4,
0x16, 0x4, 0x1e, 0x4, 0x10, 0x4, 0x9, 0x4, 0x2, 0x4, 0x12, 0x4,
0x1c, 0xd, 0x1f, 0x4, 0x14, 0x4, 0xa, 0x3, 0x2, 0x4, 0x16, 0x4,
0x1e, 0x4, 0x10, 0x4, 0x9, 0x4, 0x2, 0x4, 0x12, 0x4, 0x1d, 0xb,
0x20, 0x4, 0x14, 0x4, 0xa, 0x4, 0x1, 0x4, 0x16, 0x4, 0x1e, 0x4,
0x10, 0x4, 0xa, 0x3, 0x2, 0x4, 0x12, 0x4, 0x1d, 0xb, 0x20, 0x4,
0x14, 0x4, 0xb, 0x3, 0x1, 0x4, 0x16, 0x4, 0x1e, 0x4, 0x10, 0x4,
0xa, 0x4, 0x1, 0x4, 0x12, 0x4, 0x1e, 0x9, 0x21, 0x4, 0x14, 0x4,
0xb, 0x8, 0x16, 0x4, 0x1e, 0x4, 0x10, 0x4, 0xb, 0x3, 0x1, 0x4,
0x12, 0x4, 0x1f, 0x7, 0x22, 0x4, 0x14, 0x4, 0xc, 0x7, 0x16, 0x4,
0x1e, 0x4, 0x10, 0x4, 0xb, 0x8, 0x12, 0x4, 0x20, 0x6, 0x22, 0x4,
0x14, 0x4, 0xc, 0x7, 0x16, 0x4, 0x1e, 0x4, 0x10, 0x4, 0xc, 0x7,
0x12, 0x4, 0x21, 0x4, 0x23, 0x4, 0x14, 0x4, 0xd, 0x6, 0x16, 0x4,
0x1e, 0x4, 0x10, 0x4, 0xc, 0x7, 0x12, 0x4, 0x21, 0x3, 0x24, 0x4,
0x14, 0x4, 0xd, 0x6, 0x16, 0x4, 0x1e, 0x4, 0x10, 0x4, 0xd, 0x6,
0x12, 0x4, 0x22, 0x2, 0x24, 0x4, 0x14, 0x4, 0xd, 0x6, 0x16, 0x4,
0x1e, 0x4, 0x10, 0x4, 0xd, 0x6, 0x12, 0x4, 0x48, 0x3, 0x15, 0x4,
0xe, 0x5, 0x16, 0x4, 0x1e, 0x3, 0x11, 0x4, 0xd, 0x6, 0x12, 0x3,
0x4a, 0x1, 0x66, 0x1, 0x3c, 0x1, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0,
0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0x10, 0x11,
0xf, 0x9, 0xf, 0x4, 0x9, 0x4, 0xd, 0xf, 0x8b, 0x11, 0xf, 0x9,
0xf, 0x5, 0x7, 0x5, 0xd, 0xf, 0x8b, 0x11, 0xf, 0x9, 0xf, 0x5,
0x7, 0x5, 0xd, 0xf, 0x92, 0x3, 0x19, 0x3, 0x12, 0x6, 0x5, 0x6,
0xd, 0x3, 0x9e, 0x3, 0x19, 0x3, 0x12, 0x6, 0x5, 0x6, 0xd, 0x3,
0x9e, 0x3, 0x19, 0x3, 0x12, 0x6, 0x5, 0x6, 0xd, 0x3, 0x9e, 0x3,
0x19, 0x3, 0x12, 0x3, 0x1, 0x3, 0x3, 0x3, 0x1, 0x3, 0xd, 0x3,
0x9e, 0x3, 0x19, 0x3, 0x12, 0x3, 0x2, 0x2, 0x3, 0x2, 0x2, 0x3,
0xd, 0x3, 0x9e, 0x3, 0x19, 0x3, 0x12, 0x3, 0x2, 0x3, 0x1, 0x3,
0x2, 0x3, 0xd, 0x3, 0x9e, 0x3, 0x19, 0x3, 0x12, 0x3, 0x2, 0x3,
0x1, 0x3, 0x2, 0x3, 0xd, 0x3, 0x9e, 0x3, 0x19, 0x3, 0x12, 0x3,
0x3, 0x5, 0x3, 0x3, 0xd, 0xd, 0x94, 0x3, 0x19, 0x3, 0x12, 0x3,
0x3, 0x5, 0x3, 0x3, 0xd, 0xd, 0x94, 0x3, 0x19, 0x3, 0x12, 0x3,
0x4, 0x3, 0x4, 0x3, 0xd, 0xd, 0x94, 0x3, 0x19, 0x3, 0x12, 0x3,
0x4, 0x3, 0x4, 0x3, 0xd, 0x3, 0x9e, 0x3, 0x19, 0x3, 0x12, 0x3,
0x5, 0x1, 0x5, 0x3, 0xd, 0x3, 0x9e, 0x3, 0x19, 0x3, 0x12, 0x3,
0x5, 0x1, 0x5, 0x3, 0xd, 0x3, 0x9e, 0x3, 0x19, 0x3, 0x12, 0x3,
0xb, 0x3, 0xd, 0x3, 0x9e, 0x3, 0x19, 0x3, 0x12, 0x3, 0xb, 0x3,
0xd, 0x3, 0x9e, 0x3, 0x19, 0x3, 0x12, 0x3, 0xb, 0x3, 0xd, 0x3,
0x9e, 0x3, 0x19, 0x3, 0x12, 0x3, 0xb, 0x3, 0xd, 0x3, 0x9e, 0x3,
0x19, 0x3, 0x12, 0x3, 0xb, 0x3, 0xd, 0x3, 0x9e, 0x3, 0x19, 0x3,
0x12, 0x3, 0xb, 0x3, 0xd, 0xf, 0x92, 0x3, 0x16, 0x9, 0xf, 0x3,
0xb, 0x3, 0xd, 0xf, 0x92, 0x3, 0x16, 0x9, 0xf, 0x3, 0xb, 0x3,
0xd, 0xf, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0,
0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0,
0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0,
0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0,
0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0,
0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0,
0xff, 0x0, 0xff, 0x0, 0xec,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -659,11 +659,11 @@
#endif
#ifndef MYNEWT_VAL_BLE_MONITOR_RTT
#define MYNEWT_VAL_BLE_MONITOR_RTT (0)
#define MYNEWT_VAL_BLE_MONITOR_RTT (1)
#endif
#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED
#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (0)
#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1)
#endif
#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME

View File

@@ -31,8 +31,6 @@
#include "components/ble/BleController.h"
#include "components/ble/NotificationManager.h"
#include "components/datetime/DateTimeController.h"
#include "displayapp/DisplayApp.h"
#include "displayapp/LittleVgl.h"
#include "drivers/Spi.h"
#include "drivers/SpiMaster.h"
#include "drivers/SpiNorFlash.h"
@@ -84,7 +82,18 @@ Pinetime::Drivers::TwiMaster twiMaster{Pinetime::Drivers::TwiMaster::Modules::TW
Pinetime::Drivers::TwiMaster::Parameters {
MaxTwiFrequencyWithoutHardwareBug, pinTwiSda, pinTwiScl}};
Pinetime::Drivers::Cst816S touchPanel {twiMaster, touchPanelTwiAddress};
#ifdef PINETIME_IS_RECOVERY
static constexpr bool isFactory = true;
#include "displayapp/DummyLittleVgl.h"
#include "displayapp/DisplayAppRecovery.h"
Pinetime::Components::LittleVgl lvgl {lcd, touchPanel};
#else
static constexpr bool isFactory = false;
#include "displayapp/LittleVgl.h"
#include "displayapp/DisplayApp.h"
Pinetime::Components::LittleVgl lvgl {lcd, touchPanel};
#endif
Pinetime::Drivers::Hrs3300 heartRateSensor {twiMaster, heartRateSensorTwiAddress};
@@ -113,7 +122,8 @@ void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action
extern "C" {
void vApplicationIdleHook(void) {
lv_tick_inc(1);
if(!isFactory)
lv_tick_inc(1);
}
}

View File

@@ -4,7 +4,6 @@
#include <drivers/Spi.h>
#include <drivers/SpiNorFlash.h>
#include <libraries/log/nrf_log.h>
#include "bootloader/boot_graphics.h"
#include <FreeRTOS.h>
#include <task.h>
#include <legacy/nrf_drv_gpiote.h>
@@ -14,6 +13,12 @@
#include <components/gfx/Gfx.h>
#include <drivers/St7789.h>
#include <components/brightness/BrightnessController.h>
#include <algorithm>
#include "recoveryImage.h"
#include "displayapp/icons/infinitime/infinitime-nb.c"
#include "components/rle/RleDecoder.h"
#if NRF_LOG_ENABLED
#include "logging/NrfLogger.h"
@@ -30,14 +35,21 @@ static constexpr uint8_t pinSpiFlashCsn = 5;
static constexpr uint8_t pinLcdCsn = 25;
static constexpr uint8_t pinLcdDataCommand = 18;
static constexpr uint8_t displayWidth = 240;
static constexpr uint8_t displayHeight = 240;
static constexpr uint8_t bytesPerPixel = 2;
static constexpr uint16_t colorWhite = 0xFFFF;
static constexpr uint16_t colorGreen = 0xE007;
Pinetime::Drivers::SpiMaster spi{Pinetime::Drivers::SpiMaster::SpiModule::SPI0, {
Pinetime::Drivers::SpiMaster::BitOrder::Msb_Lsb,
Pinetime::Drivers::SpiMaster::Modes::Mode3,
Pinetime::Drivers::SpiMaster::Frequencies::Freq8Mhz,
pinSpiSck,
pinSpiMosi,
pinSpiMiso
}
Pinetime::Drivers::SpiMaster::BitOrder::Msb_Lsb,
Pinetime::Drivers::SpiMaster::Modes::Mode3,
Pinetime::Drivers::SpiMaster::Frequencies::Freq8Mhz,
pinSpiSck,
pinSpiMosi,
pinSpiMiso
}
};
Pinetime::Drivers::Spi flashSpi{spi, pinSpiFlashCsn};
Pinetime::Drivers::SpiNorFlash spiNorFlash{flashSpi};
@@ -48,6 +60,10 @@ Pinetime::Drivers::St7789 lcd {lcdSpi, pinLcdDataCommand};
Pinetime::Components::Gfx gfx{lcd};
Pinetime::Controllers::BrightnessController brightnessController;
void DisplayProgressBar(uint8_t percent, uint16_t color);
void DisplayLogo();
extern "C" {
void vApplicationIdleHook(void) {
@@ -70,10 +86,13 @@ void SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler(void) {
}
}
void Process(void* instance) {
// Wait before erasing the memory to let the time to the SWD debugger to flash a new firmware before running this one.
vTaskDelay(5000);
void RefreshWatchdog() {
NRF_WDT->RR[0] = WDT_RR_RR_Reload;
}
uint8_t displayBuffer[displayWidth * bytesPerPixel];
void Process(void* instance) {
RefreshWatchdog();
APP_GPIOTE_INIT(2);
NRF_LOG_INFO("Init...");
@@ -83,45 +102,57 @@ void Process(void* instance) {
brightnessController.Init();
lcd.Init();
gfx.Init();
NRF_LOG_INFO("Init Done!")
NRF_LOG_INFO("Display logo")
DisplayLogo();
NRF_LOG_INFO("Erasing...");
for (uint32_t erased = 0; erased < graphicSize; erased += 0x1000) {
for (uint32_t erased = 0; erased < sizeof(recoveryImage); erased += 0x1000) {
spiNorFlash.SectorErase(erased);
RefreshWatchdog();
}
NRF_LOG_INFO("Erase done!");
NRF_LOG_INFO("Writing graphic...");
NRF_LOG_INFO("Writing factory image...");
static constexpr uint32_t memoryChunkSize = 200;
uint8_t writeBuffer[memoryChunkSize];
for(int offset = 0; offset < 115200; offset+=memoryChunkSize) {
std::memcpy(writeBuffer, &graphicBuffer[offset], memoryChunkSize);
for(size_t offset = 0; offset < sizeof(recoveryImage); offset+=memoryChunkSize) {
std::memcpy(writeBuffer, &recoveryImage[offset], memoryChunkSize);
spiNorFlash.Write(offset, writeBuffer, memoryChunkSize);
DisplayProgressBar((static_cast<float>(offset) / static_cast<float>(sizeof(recoveryImage))) * 100.0f, colorWhite);
RefreshWatchdog();
}
NRF_LOG_INFO("Writing graphic done!");
NRF_LOG_INFO("Read memory and display the graphic...");
static constexpr uint32_t screenWidth = 240;
static constexpr uint32_t screenWidthInBytes = screenWidth*2; // LCD display 16bits color (1 pixel = 2 bytes)
uint16_t displayLineBuffer[screenWidth];
for(uint32_t line = 0; line < screenWidth; line++) {
spiNorFlash.Read(line*screenWidthInBytes, reinterpret_cast<uint8_t *>(displayLineBuffer), screenWidth);
spiNorFlash.Read((line*screenWidthInBytes)+screenWidth, reinterpret_cast<uint8_t *>(displayLineBuffer) + screenWidth, screenWidth);
for(uint32_t col = 0; col < screenWidth; col++) {
gfx.pixel_draw(col, line, displayLineBuffer[col]);
}
}
NRF_LOG_INFO("Done!");
NRF_LOG_INFO("Writing factory image done!");
DisplayProgressBar(100.0f, colorGreen);
while(1) {
asm("nop" );
}
}
void DisplayLogo() {
Pinetime::Tools::RleDecoder rleDecoder(infinitime_nb, sizeof(infinitime_nb));
for(int i = 0; i < displayWidth; i++) {
rleDecoder.DecodeNext(displayBuffer, displayWidth * bytesPerPixel);
ulTaskNotifyTake(pdTRUE, 500);
lcd.BeginDrawBuffer(0, i, displayWidth, 1);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(displayBuffer), displayWidth * bytesPerPixel);
}
}
void DisplayProgressBar(uint8_t percent, uint16_t color) {
static constexpr uint8_t barHeight = 20;
std::fill(displayBuffer, displayBuffer+(displayWidth * bytesPerPixel), color);
for(int i = 0; i < barHeight; i++) {
ulTaskNotifyTake(pdTRUE, 500);
uint16_t barWidth = std::min(static_cast<float>(percent) * 2.4f, static_cast<float>(displayWidth));
lcd.BeginDrawBuffer(0, displayWidth - barHeight + i, barWidth, 1);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(displayBuffer), barWidth * bytesPerPixel);
}
}
int main(void) {
TaskHandle_t taskHandle;
RefreshWatchdog();
logger.Init();
nrf_drv_clock_init();

View File

@@ -14,7 +14,6 @@
#include "BootloaderVersion.h"
#include "components/ble/BleController.h"
#include "displayapp/LittleVgl.h"
#include "drivers/Cst816s.h"
#include "drivers/St7789.h"
#include "drivers/InternalFlash.h"
@@ -74,6 +73,7 @@ void SystemTask::Work() {
spiNorFlash.Wakeup();
nimbleController.Init();
nimbleController.StartAdvertising();
brightnessController.Init();
lcd.Init();
twiMaster.Init();
@@ -85,8 +85,7 @@ void SystemTask::Work() {
displayApp->Start();
batteryController.Update();
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBatteryLevel);
displayApp->PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel);
heartRateSensor.Init();
heartRateSensor.Disable();
@@ -139,8 +138,8 @@ void SystemTask::Work() {
touchPanel.Wakeup();
lcd.Wakeup();
displayApp->PushMessage(Applications::DisplayApp::Messages::GoToRunning);
displayApp->PushMessage(Applications::DisplayApp::Messages::UpdateBatteryLevel);
displayApp->PushMessage(Pinetime::Applications::Display::Messages::GoToRunning);
displayApp->PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel);
heartRateApp->PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp);
isSleeping = false;
@@ -150,16 +149,16 @@ void SystemTask::Work() {
isGoingToSleep = true;
NRF_LOG_INFO("[systemtask] Going to sleep");
xTimerStop(idleTimer, 0);
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep);
displayApp->PushMessage(Pinetime::Applications::Display::Messages::GoToSleep);
heartRateApp->PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep);
break;
case Messages::OnNewTime:
ReloadIdleTimer();
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateDateTime);
displayApp->PushMessage(Pinetime::Applications::Display::Messages::UpdateDateTime);
break;
case Messages::OnNewNotification:
if(isSleeping && !isWakingUp) GoToRunning();
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::NewNotification);
displayApp->PushMessage(Pinetime::Applications::Display::Messages::NewNotification);
break;
case Messages::BleConnected:
ReloadIdleTimer();
@@ -169,7 +168,7 @@ void SystemTask::Work() {
case Messages::BleFirmwareUpdateStarted:
doNotGoToSleep = true;
if(isSleeping && !isWakingUp) GoToRunning();
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::BleFirmwareUpdateStarted);
displayApp->PushMessage(Pinetime::Applications::Display::Messages::BleFirmwareUpdateStarted);
break;
case Messages::BleFirmwareUpdateFinished:
doNotGoToSleep = false;
@@ -227,7 +226,7 @@ void SystemTask::OnButtonPushed() {
if(!isSleeping) {
NRF_LOG_INFO("[systemtask] Button pushed");
PushMessage(Messages::OnButtonEvent);
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::ButtonPushed);
displayApp->PushMessage(Pinetime::Applications::Display::Messages::ButtonPushed);
}
else {
if(!isWakingUp) {
@@ -247,7 +246,7 @@ void SystemTask::OnTouchEvent() {
NRF_LOG_INFO("[systemtask] Touch event");
if(!isSleeping) {
PushMessage(Messages::OnTouchEvent);
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::TouchEvent);
displayApp->PushMessage(Pinetime::Applications::Display::Messages::TouchEvent);
}
}

View File

@@ -12,7 +12,15 @@
#include "components/battery/BatteryController.h"
#include "components/ble/NimbleController.h"
#include "components/ble/NotificationManager.h"
#ifdef PINETIME_IS_RECOVERY
#include "displayapp/DisplayAppRecovery.h"
#include "displayapp/DummyLittleVgl.h"
#else
#include "displayapp/DisplayApp.h"
#include "displayapp/LittleVgl.h"
#endif
#include "drivers/Watchdog.h"
namespace Pinetime {
@@ -76,6 +84,7 @@ namespace Pinetime {
Pinetime::Controllers::NotificationManager& notificationManager;
Pinetime::Drivers::Hrs3300& heartRateSensor;
Pinetime::Controllers::NimbleController nimbleController;
Controllers::BrightnessController brightnessController;
static constexpr uint8_t pinSpiSck = 2;
static constexpr uint8_t pinSpiMosi = 3;