diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/BlinkApp/BlinkApp.cpp | 25 | ||||
| -rw-r--r-- | src/BlinkApp/BlinkApp.h | 15 | ||||
| -rw-r--r-- | src/BootloaderVersion.cpp | 26 | ||||
| -rw-r--r-- | src/BootloaderVersion.h | 12 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 928 | ||||
| -rw-r--r-- | src/Components/Ble/AlertNotificationClient.cpp | 145 | ||||
| -rw-r--r-- | src/Components/Ble/CurrentTimeClient.cpp | 77 | ||||
| -rw-r--r-- | src/Components/Ble/MusicService.cpp | 130 | ||||
| -rw-r--r-- | src/Components/Ble/MusicService.h | 92 | ||||
| -rw-r--r-- | src/Components/Ble/NotificationManager.cpp | 30 | ||||
| -rw-r--r-- | src/Components/Ble/NotificationManager.h | 29 | ||||
| -rw-r--r-- | src/DisplayApp/Screens/Message.cpp | 81 | ||||
| -rw-r--r-- | src/DisplayApp/Screens/Message.h | 31 | ||||
| -rw-r--r-- | src/DisplayApp/Screens/Music.cpp | 125 | ||||
| -rw-r--r-- | src/DisplayApp/Screens/Music.h | 49 | ||||
| -rw-r--r-- | src/DisplayApp/Screens/Screen.h | 27 | ||||
| -rw-r--r-- | src/DisplayApp/Screens/ScreenList.cpp | 139 | ||||
| -rw-r--r-- | src/DisplayApp/Screens/Symbols.h | 24 | ||||
| -rw-r--r-- | src/DisplayApp/Screens/Tile.cpp | 101 | ||||
| -rw-r--r-- | src/DisplayApp/Screens/Tile.h | 60 | ||||
| -rw-r--r-- | src/Version.h.in | 8 | ||||
| -rw-r--r-- | src/components/battery/BatteryController.cpp (renamed from src/Components/Battery/BatteryController.cpp) | 5 | ||||
| -rw-r--r-- | src/components/battery/BatteryController.h (renamed from src/Components/Battery/BatteryController.h) | 0 | ||||
| -rw-r--r-- | src/components/ble/AlertNotificationClient.cpp | 194 | ||||
| -rw-r--r-- | src/components/ble/AlertNotificationClient.h (renamed from src/Components/Ble/AlertNotificationClient.h) | 35 | ||||
| -rw-r--r-- | src/components/ble/AlertNotificationService.cpp (renamed from src/Components/Ble/AlertNotificationService.cpp) | 42 | ||||
| -rw-r--r-- | src/components/ble/AlertNotificationService.h (renamed from src/Components/Ble/AlertNotificationService.h) | 4 | ||||
| -rw-r--r-- | src/components/ble/BatteryInformationService.cpp | 62 | ||||
| -rw-r--r-- | src/components/ble/BatteryInformationService.h | 40 | ||||
| -rw-r--r-- | src/components/ble/BleClient.h | 12 | ||||
| -rw-r--r-- | src/components/ble/BleController.cpp (renamed from src/Components/Ble/BleController.cpp) | 0 | ||||
| -rw-r--r-- | src/components/ble/BleController.h (renamed from src/Components/Ble/BleController.h) | 0 | ||||
| -rw-r--r-- | src/components/ble/CurrentTimeClient.cpp | 111 | ||||
| -rw-r--r-- | src/components/ble/CurrentTimeClient.h (renamed from src/Components/Ble/CurrentTimeClient.h) | 20 | ||||
| -rw-r--r-- | src/components/ble/CurrentTimeService.cpp (renamed from src/Components/Ble/CurrentTimeService.cpp) | 5 | ||||
| -rw-r--r-- | src/components/ble/CurrentTimeService.h (renamed from src/Components/Ble/CurrentTimeService.h) | 3 | ||||
| -rw-r--r-- | src/components/ble/DeviceInformationService.cpp (renamed from src/Components/Ble/DeviceInformationService.cpp) | 11 | ||||
| -rw-r--r-- | src/components/ble/DeviceInformationService.h (renamed from src/Components/Ble/DeviceInformationService.h) | 21 | ||||
| -rw-r--r-- | src/components/ble/DfuService.cpp (renamed from src/Components/Ble/DfuService.cpp) | 9 | ||||
| -rw-r--r-- | src/components/ble/DfuService.h (renamed from src/Components/Ble/DfuService.h) | 0 | ||||
| -rw-r--r-- | src/components/ble/ImmediateAlertService.cpp | 82 | ||||
| -rw-r--r-- | src/components/ble/ImmediateAlertService.h | 46 | ||||
| -rw-r--r-- | src/components/ble/MusicService.cpp | 225 | ||||
| -rw-r--r-- | src/components/ble/MusicService.h | 166 | ||||
| -rw-r--r-- | src/components/ble/NimbleController.cpp (renamed from src/Components/Ble/NimbleController.cpp) | 138 | ||||
| -rw-r--r-- | src/components/ble/NimbleController.h (renamed from src/Components/Ble/NimbleController.h) | 12 | ||||
| -rw-r--r-- | src/components/ble/NotificationManager.cpp | 81 | ||||
| -rw-r--r-- | src/components/ble/NotificationManager.h | 43 | ||||
| -rw-r--r-- | src/components/ble/ServiceDiscovery.cpp | 31 | ||||
| -rw-r--r-- | src/components/ble/ServiceDiscovery.h | 24 | ||||
| -rw-r--r-- | src/components/brightness/BrightnessController.cpp (renamed from src/Components/Brightness/BrightnessController.cpp) | 0 | ||||
| -rw-r--r-- | src/components/brightness/BrightnessController.h (renamed from src/Components/Brightness/BrightnessController.h) | 0 | ||||
| -rw-r--r-- | src/components/datetime/DateTimeController.cpp (renamed from src/Components/DateTime/DateTimeController.cpp) | 0 | ||||
| -rw-r--r-- | src/components/datetime/DateTimeController.h (renamed from src/Components/DateTime/DateTimeController.h) | 0 | ||||
| -rw-r--r-- | src/components/firmwarevalidator/FirmwareValidator.cpp | 20 | ||||
| -rw-r--r-- | src/components/firmwarevalidator/FirmwareValidator.h | 18 | ||||
| -rw-r--r-- | src/components/gfx/Gfx.cpp (renamed from src/Components/Gfx/Gfx.cpp) | 15 | ||||
| -rw-r--r-- | src/components/gfx/Gfx.h (renamed from src/Components/Gfx/Gfx.h) | 4 | ||||
| -rw-r--r-- | src/displayapp/Apps.h | 7 | ||||
| -rw-r--r-- | src/displayapp/DisplayApp.cpp (renamed from src/DisplayApp/DisplayApp.cpp) | 82 | ||||
| -rw-r--r-- | src/displayapp/DisplayApp.h (renamed from src/DisplayApp/DisplayApp.h) | 33 | ||||
| -rw-r--r-- | src/displayapp/LittleVgl.cpp (renamed from src/DisplayApp/LittleVgl.cpp) | 7 | ||||
| -rw-r--r-- | src/displayapp/LittleVgl.h (renamed from src/DisplayApp/LittleVgl.h) | 4 | ||||
| -rw-r--r-- | src/displayapp/TouchEvents.h (renamed from src/DisplayApp/TouchEvents.h) | 0 | ||||
| -rw-r--r-- | src/displayapp/fonts/Readme.md (renamed from src/DisplayApp/Fonts/Readme.md) | 2 | ||||
| -rw-r--r-- | src/displayapp/fonts/jetbrains_mono_bold_20.c (renamed from src/DisplayApp/Fonts/jetbrains_mono_bold_20.c) | 87 | ||||
| -rw-r--r-- | src/displayapp/fonts/jetbrains_mono_extrabold_compressed.c (renamed from src/DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_005.c (renamed from src/DisplayApp/Icons/battery/os_battery_005.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_005.png (renamed from src/DisplayApp/Icons/battery/os_battery_005.png) | bin | 1540 -> 1540 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_010.c (renamed from src/DisplayApp/Icons/battery/os_battery_010.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_010.png (renamed from src/DisplayApp/Icons/battery/os_battery_010.png) | bin | 1859 -> 1859 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_020.c (renamed from src/DisplayApp/Icons/battery/os_battery_020.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_020.png (renamed from src/DisplayApp/Icons/battery/os_battery_020.png) | bin | 1558 -> 1558 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_030.c (renamed from src/DisplayApp/Icons/battery/os_battery_030.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_030.png (renamed from src/DisplayApp/Icons/battery/os_battery_030.png) | bin | 1553 -> 1553 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_040.c (renamed from src/DisplayApp/Icons/battery/os_battery_040.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_040.png (renamed from src/DisplayApp/Icons/battery/os_battery_040.png) | bin | 1542 -> 1542 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_050.c (renamed from src/DisplayApp/Icons/battery/os_battery_050.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_050.png (renamed from src/DisplayApp/Icons/battery/os_battery_050.png) | bin | 1539 -> 1539 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_060.c (renamed from src/DisplayApp/Icons/battery/os_battery_060.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_060.png (renamed from src/DisplayApp/Icons/battery/os_battery_060.png) | bin | 1543 -> 1543 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_070.c (renamed from src/DisplayApp/Icons/battery/os_battery_070.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_070.png (renamed from src/DisplayApp/Icons/battery/os_battery_070.png) | bin | 1545 -> 1545 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_080.c (renamed from src/DisplayApp/Icons/battery/os_battery_080.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_080.png (renamed from src/DisplayApp/Icons/battery/os_battery_080.png) | bin | 1549 -> 1549 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_090.c (renamed from src/DisplayApp/Icons/battery/os_battery_090.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_090.png (renamed from src/DisplayApp/Icons/battery/os_battery_090.png) | bin | 1554 -> 1554 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_100.c (renamed from src/DisplayApp/Icons/battery/os_battery_100.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_100.png (renamed from src/DisplayApp/Icons/battery/os_battery_100.png) | bin | 1574 -> 1574 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_error.c (renamed from src/DisplayApp/Icons/battery/os_battery_error.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_battery_error.png (renamed from src/DisplayApp/Icons/battery/os_battery_error.png) | bin | 2128 -> 2128 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_005.c (renamed from src/DisplayApp/Icons/battery/os_batterycharging_005.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_005.png (renamed from src/DisplayApp/Icons/battery/os_batterycharging_005.png) | bin | 1952 -> 1952 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_010.c (renamed from src/DisplayApp/Icons/battery/os_batterycharging_010.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_010.png (renamed from src/DisplayApp/Icons/battery/os_batterycharging_010.png) | bin | 1983 -> 1983 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_020.c (renamed from src/DisplayApp/Icons/battery/os_batterycharging_020.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_020.png (renamed from src/DisplayApp/Icons/battery/os_batterycharging_020.png) | bin | 1982 -> 1982 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_030.c (renamed from src/DisplayApp/Icons/battery/os_batterycharging_030.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_030.png (renamed from src/DisplayApp/Icons/battery/os_batterycharging_030.png) | bin | 1997 -> 1997 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_040.c (renamed from src/DisplayApp/Icons/battery/os_batterycharging_040.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_040.png (renamed from src/DisplayApp/Icons/battery/os_batterycharging_040.png) | bin | 1993 -> 1993 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_050.c (renamed from src/DisplayApp/Icons/battery/os_batterycharging_050.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_050.png (renamed from src/DisplayApp/Icons/battery/os_batterycharging_050.png) | bin | 2036 -> 2036 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_060.c (renamed from src/DisplayApp/Icons/battery/os_batterycharging_060.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_060.png (renamed from src/DisplayApp/Icons/battery/os_batterycharging_060.png) | bin | 2035 -> 2035 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_070.c (renamed from src/DisplayApp/Icons/battery/os_batterycharging_070.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_070.png (renamed from src/DisplayApp/Icons/battery/os_batterycharging_070.png) | bin | 2035 -> 2035 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_080.c (renamed from src/DisplayApp/Icons/battery/os_batterycharging_080.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_080.png (renamed from src/DisplayApp/Icons/battery/os_batterycharging_080.png) | bin | 2087 -> 2087 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_090.c (renamed from src/DisplayApp/Icons/battery/os_batterycharging_090.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_090.png (renamed from src/DisplayApp/Icons/battery/os_batterycharging_090.png) | bin | 2100 -> 2100 bytes | |||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_100.c (renamed from src/DisplayApp/Icons/battery/os_batterycharging_100.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/battery/os_batterycharging_100.png (renamed from src/DisplayApp/Icons/battery/os_batterycharging_100.png) | bin | 1919 -> 1919 bytes | |||
| -rw-r--r-- | src/displayapp/icons/bluetooth/ck_os_bt_connected.png (renamed from src/DisplayApp/Icons/bluetooth/ck_os_bt_connected.png) | bin | 2237 -> 2237 bytes | |||
| -rw-r--r-- | src/displayapp/icons/bluetooth/ck_os_bt_disconnected.png (renamed from src/DisplayApp/Icons/bluetooth/ck_os_bt_disconnected.png) | bin | 2441 -> 2441 bytes | |||
| -rw-r--r-- | src/displayapp/icons/bluetooth/os_bt_connected.c (renamed from src/DisplayApp/Icons/bluetooth/os_bt_connected.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/bluetooth/os_bt_connected.png (renamed from src/DisplayApp/Icons/bluetooth/os_bt_connected.png) | bin | 2237 -> 2237 bytes | |||
| -rw-r--r-- | src/displayapp/icons/bluetooth/os_bt_disconnected.c (renamed from src/DisplayApp/Icons/bluetooth/os_bt_disconnected.c) | 0 | ||||
| -rw-r--r-- | src/displayapp/icons/bluetooth/os_bt_disconnected.png (renamed from src/DisplayApp/Icons/bluetooth/os_bt_disconnected.png) | bin | 2441 -> 2441 bytes | |||
| -rw-r--r-- | src/displayapp/icons/music/disc.cpp | 110 | ||||
| -rw-r--r-- | src/displayapp/icons/music/disc.png | bin | 0 -> 516 bytes | |||
| -rw-r--r-- | src/displayapp/icons/music/disc_f_1.cpp | 79 | ||||
| -rw-r--r-- | src/displayapp/icons/music/disc_f_1.png | bin | 0 -> 200 bytes | |||
| -rw-r--r-- | src/displayapp/icons/music/disc_f_2.cpp | 79 | ||||
| -rw-r--r-- | src/displayapp/icons/music/disc_f_2.png | bin | 0 -> 197 bytes | |||
| -rw-r--r-- | src/displayapp/screens/ApplicationList.cpp | 82 | ||||
| -rw-r--r-- | src/displayapp/screens/ApplicationList.h | 33 | ||||
| -rw-r--r-- | src/displayapp/screens/BatteryIcon.cpp (renamed from src/DisplayApp/Screens/BatteryIcon.cpp) | 0 | ||||
| -rw-r--r-- | src/displayapp/screens/BatteryIcon.h (renamed from src/DisplayApp/Screens/BatteryIcon.h) | 0 | ||||
| -rw-r--r-- | src/displayapp/screens/BleIcon.cpp (renamed from src/DisplayApp/Screens/BleIcon.cpp) | 0 | ||||
| -rw-r--r-- | src/displayapp/screens/BleIcon.h (renamed from src/DisplayApp/Screens/BleIcon.h) | 0 | ||||
| -rw-r--r-- | src/displayapp/screens/Brightness.cpp (renamed from src/DisplayApp/Screens/Brightness.cpp) | 6 | ||||
| -rw-r--r-- | src/displayapp/screens/Brightness.h (renamed from src/DisplayApp/Screens/Brightness.h) | 2 | ||||
| -rw-r--r-- | src/displayapp/screens/Clock.cpp (renamed from src/DisplayApp/Screens/Clock.cpp) | 50 | ||||
| -rw-r--r-- | src/displayapp/screens/Clock.h (renamed from src/DisplayApp/Screens/Clock.h) | 19 | ||||
| -rw-r--r-- | src/displayapp/screens/DropDownDemo.cpp | 64 | ||||
| -rw-r--r-- | src/displayapp/screens/DropDownDemo.h | 29 | ||||
| -rw-r--r-- | src/displayapp/screens/FirmwareUpdate.cpp (renamed from src/DisplayApp/Screens/FirmwareUpdate.cpp) | 10 | ||||
| -rw-r--r-- | src/displayapp/screens/FirmwareUpdate.h (renamed from src/DisplayApp/Screens/FirmwareUpdate.h) | 3 | ||||
| -rw-r--r-- | src/displayapp/screens/FirmwareValidation.cpp | 91 | ||||
| -rw-r--r-- | src/displayapp/screens/FirmwareValidation.h | 42 | ||||
| -rw-r--r-- | src/displayapp/screens/Gauge.cpp (renamed from src/DisplayApp/Screens/Gauge.cpp) | 4 | ||||
| -rw-r--r-- | src/displayapp/screens/Gauge.h (renamed from src/DisplayApp/Screens/Gauge.h) | 0 | ||||
| -rw-r--r-- | src/displayapp/screens/InfiniPaint.cpp | 44 | ||||
| -rw-r--r-- | src/displayapp/screens/InfiniPaint.h | 39 | ||||
| -rw-r--r-- | src/displayapp/screens/Label.cpp (renamed from src/DisplayApp/Screens/Label.cpp) | 19 | ||||
| -rw-r--r-- | src/displayapp/screens/Label.h (renamed from src/DisplayApp/Screens/Label.h) | 13 | ||||
| -rw-r--r-- | src/displayapp/screens/Meter.cpp (renamed from src/DisplayApp/Screens/Meter.cpp) | 4 | ||||
| -rw-r--r-- | src/displayapp/screens/Meter.h (renamed from src/DisplayApp/Screens/Meter.h) | 0 | ||||
| -rw-r--r-- | src/displayapp/screens/Modal.cpp (renamed from src/DisplayApp/Screens/Modal.cpp) | 6 | ||||
| -rw-r--r-- | src/displayapp/screens/Modal.h (renamed from src/DisplayApp/Screens/Modal.h) | 0 | ||||
| -rw-r--r-- | src/displayapp/screens/Music.cpp | 292 | ||||
| -rw-r--r-- | src/displayapp/screens/Music.h | 96 | ||||
| -rw-r--r-- | src/displayapp/screens/NotificationIcon.cpp | 8 | ||||
| -rw-r--r-- | src/displayapp/screens/NotificationIcon.h | 12 | ||||
| -rw-r--r-- | src/displayapp/screens/Notifications.cpp | 174 | ||||
| -rw-r--r-- | src/displayapp/screens/Notifications.h | 61 | ||||
| -rw-r--r-- | src/displayapp/screens/Screen.cpp (renamed from src/DisplayApp/Screens/Screen.cpp) | 0 | ||||
| -rw-r--r-- | src/displayapp/screens/Screen.h | 42 | ||||
| -rw-r--r-- | src/displayapp/screens/ScreenList.h | 66 | ||||
| -rw-r--r-- | src/displayapp/screens/Symbols.h | 30 | ||||
| -rw-r--r-- | src/displayapp/screens/SystemInfo.cpp | 116 | ||||
| -rw-r--r-- | src/displayapp/screens/SystemInfo.h (renamed from src/DisplayApp/Screens/ScreenList.h) | 22 | ||||
| -rw-r--r-- | src/displayapp/screens/Tab.cpp (renamed from src/DisplayApp/Screens/Tab.cpp) | 4 | ||||
| -rw-r--r-- | src/displayapp/screens/Tab.h (renamed from src/DisplayApp/Screens/Tab.h) | 0 | ||||
| -rw-r--r-- | src/displayapp/screens/Tile.cpp | 62 | ||||
| -rw-r--r-- | src/displayapp/screens/Tile.h | 39 | ||||
| -rw-r--r-- | src/drivers/Cst816s.cpp | 24 | ||||
| -rw-r--r-- | src/drivers/Cst816s.h | 14 | ||||
| -rw-r--r-- | src/drivers/Spi.cpp | 13 | ||||
| -rw-r--r-- | src/drivers/SpiMaster.cpp | 6 | ||||
| -rw-r--r-- | src/drivers/SpiNorFlash.cpp | 22 | ||||
| -rw-r--r-- | src/drivers/SpiNorFlash.h | 4 | ||||
| -rw-r--r-- | src/drivers/St7789.cpp | 6 | ||||
| -rw-r--r-- | src/drivers/TwiMaster.cpp | 111 | ||||
| -rw-r--r-- | src/drivers/TwiMaster.h | 19 | ||||
| -rw-r--r-- | src/graphics.cpp | 13 | ||||
| -rw-r--r-- | src/libs/lvgl/src/lv_core/lv_obj.c | 2 | ||||
| -rw-r--r-- | src/libs/mynewt-nimble/nimble/host/src/ble_gap.c | 2 | ||||
| -rw-r--r-- | src/logging/DummyLogger.h (renamed from src/Logging/DummyLogger.h) | 0 | ||||
| -rw-r--r-- | src/logging/Logger.h (renamed from src/Logging/Logger.h) | 0 | ||||
| -rw-r--r-- | src/logging/NrfLogger.cpp (renamed from src/Logging/NrfLogger.cpp) | 5 | ||||
| -rw-r--r-- | src/logging/NrfLogger.h (renamed from src/Logging/NrfLogger.h) | 0 | ||||
| -rw-r--r-- | src/main.cpp | 26 | ||||
| -rw-r--r-- | src/systemtask/SystemMonitor.h (renamed from src/SystemTask/SystemMonitor.h) | 4 | ||||
| -rw-r--r-- | src/systemtask/SystemTask.cpp (renamed from src/SystemTask/SystemTask.cpp) | 91 | ||||
| -rw-r--r-- | src/systemtask/SystemTask.h (renamed from src/SystemTask/SystemTask.h) | 17 |
187 files changed, 4033 insertions, 2053 deletions
diff --git a/src/BlinkApp/BlinkApp.cpp b/src/BlinkApp/BlinkApp.cpp deleted file mode 100644 index a988dfd3..00000000 --- a/src/BlinkApp/BlinkApp.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "BlinkApp.h" -#include <FreeRTOS.h> -#include <task.h> -#include <libraries/log/nrf_log.h> -#include <boards.h> - -using namespace Pinetime::Applications; - -void BlinkApp::Start() { - if (pdPASS != xTaskCreate(BlinkApp::Process, "BlinkApp", 256, this, 0, &taskHandle)) - APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); -} - -void BlinkApp::Process(void *instance) { - auto* app = static_cast<BlinkApp*>(instance); - - NRF_LOG_INFO("BlinkApp task started!"); - while (1) { -// NRF_LOG_INFO("BlinkApp task running!"); -// nrf_gpio_pin_toggle(22); -// nrf_gpio_pin_toggle(23); -// nrf_gpio_pin_toggle(14); - vTaskDelay(1000); - } -} diff --git a/src/BlinkApp/BlinkApp.h b/src/BlinkApp/BlinkApp.h deleted file mode 100644 index 15c863a3..00000000 --- a/src/BlinkApp/BlinkApp.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include <FreeRTOS.h> -#include <task.h> - -namespace Pinetime { - namespace Applications { - class BlinkApp { - public: - void Start(); - private: - TaskHandle_t taskHandle; - static void Process(void* instance); - }; - } -} diff --git a/src/BootloaderVersion.cpp b/src/BootloaderVersion.cpp new file mode 100644 index 00000000..8555593f --- /dev/null +++ b/src/BootloaderVersion.cpp @@ -0,0 +1,26 @@ +#include <cstdint> +#include "BootloaderVersion.h" + +using namespace Pinetime; + +// NOTE : current bootloader does not export its version to the application firmware. + +uint32_t BootloaderVersion::Major() { + return 0; +} + +uint32_t BootloaderVersion::Minor() { + return 0; +} + +uint32_t BootloaderVersion::Patch() { + return 0; +} + +const char *BootloaderVersion::VersionString() { + return "0.0.0"; +} + +bool BootloaderVersion::IsValid() { + return false; +} diff --git a/src/BootloaderVersion.h b/src/BootloaderVersion.h new file mode 100644 index 00000000..c7fcbd98 --- /dev/null +++ b/src/BootloaderVersion.h @@ -0,0 +1,12 @@ +#pragma once + +namespace Pinetime { + class BootloaderVersion { + public: + static uint32_t Major(); + static uint32_t Minor(); + static uint32_t Patch(); + static const char* VersionString(); + static bool IsValid(); + }; +}
\ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2d6d6e8e..254fabcf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,20 +10,20 @@ set(NRF_BOARD pca10040) if (NOT NRF5_SDK_PATH) message(FATAL_ERROR "The path to the nRF5 SDK (NRF5_SDK_PATH) must be set.") endif () -if(DEFINED ARM_NONE_EABI_TOOLCHAIN_PATH) +if (DEFINED ARM_NONE_EABI_TOOLCHAIN_PATH) set(ARM_NONE_EABI_TOOLCHAIN_BIN_PATH ${ARM_NONE_EABI_TOOLCHAIN_PATH}/bin) -endif() +endif () if (NOT NRF_TARGET MATCHES "nrf52") message(FATAL_ERROR "Only rRF52 boards are supported right now") -endif() +endif () # Setup toolchain include(${CMAKE_SOURCE_DIR}/cmake-nRF5x/arm-gcc-toolchain.cmake) -if(NOT DEFINED ARM_GCC_TOOLCHAIN) +if (NOT DEFINED ARM_GCC_TOOLCHAIN) message(FATAL_ERROR "The toolchain must be set up before calling this macro") -endif() +endif () set(CMAKE_OSX_SYSROOT "/") set(CMAKE_OSX_DEPLOYMENT_TARGET "") @@ -84,392 +84,410 @@ set(SDK_SOURCE_FILES # GPIOTE "${NRF5_SDK_PATH}/components/libraries/gpiote/app_gpiote.c" -) + ) set(TINYCRYPT_SRC - libs/mynewt-nimble/ext/tinycrypt/src/aes_encrypt.c - libs/mynewt-nimble/ext/tinycrypt/src/utils.c - ) + libs/mynewt-nimble/ext/tinycrypt/src/aes_encrypt.c + libs/mynewt-nimble/ext/tinycrypt/src/utils.c + ) set(NIMBLE_SRC - libs/mynewt-nimble/porting/npl/freertos/src/nimble_port_freertos.c - libs/mynewt-nimble/porting/npl/freertos/src/npl_os_freertos.c - libs/mynewt-nimble/nimble/host/src/ble_hs.c - libs/mynewt-nimble/nimble/host/src/ble_hs_hci_evt.c - libs/mynewt-nimble/nimble/host/src/ble_l2cap_sig_cmd.c - libs/mynewt-nimble/nimble/host/src/ble_l2cap_sig.c - libs/mynewt-nimble/nimble/host/src/ble_l2cap.c - libs/mynewt-nimble/nimble/host/src/ble_hs_mbuf.c - libs/mynewt-nimble/nimble/host/src/ble_sm.c - libs/mynewt-nimble/nimble/host/src/ble_gap.c - libs/mynewt-nimble/nimble/host/src/ble_gatts.c - libs/mynewt-nimble/nimble/host/src/ble_gattc.c - libs/mynewt-nimble/nimble/host/src/ble_hs_conn.c - libs/mynewt-nimble/nimble/host/src/ble_att_svr.c - libs/mynewt-nimble/nimble/host/src/ble_store.c - libs/mynewt-nimble/nimble/host/src/ble_store_util.c - libs/mynewt-nimble/nimble/host/src/ble_hs_pvcy.c - libs/mynewt-nimble/nimble/host/src/ble_hs_hci.c - libs/mynewt-nimble/nimble/host/src/ble_hs_log.c - libs/mynewt-nimble/nimble/host/src/ble_hs_hci_util.c - libs/mynewt-nimble/nimble/host/src/ble_hs_hci_cmd.c - libs/mynewt-nimble/nimble/host/src/ble_hs_cfg.c - libs/mynewt-nimble/nimble/host/src/ble_uuid.c - libs/mynewt-nimble/nimble/host/src/ble_hs_id.c - libs/mynewt-nimble/nimble/host/src/ble_hs_misc.c - libs/mynewt-nimble/nimble/host/src/ble_att.c - libs/mynewt-nimble/nimble/host/src/ble_att_clt.c - libs/mynewt-nimble/nimble/host/src/ble_att_svr.c - libs/mynewt-nimble/nimble/host/src/ble_att_cmd.c - libs/mynewt-nimble/nimble/host/src/ble_hs_atomic.c - libs/mynewt-nimble/nimble/host/src/ble_hs_adv.c - libs/mynewt-nimble/nimble/host/src/ble_hs_flow.c - libs/mynewt-nimble/nimble/host/src/ble_sm.c - libs/mynewt-nimble/nimble/host/src/ble_sm_cmd.c - libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c - libs/mynewt-nimble/nimble/host/src/ble_sm_alg.c - libs/mynewt-nimble/nimble/host/src/ble_hs_mqueue.c - libs/mynewt-nimble/nimble/host/src/ble_hs_stop.c - libs/mynewt-nimble/nimble/host/src/ble_hs_startup.c - libs/mynewt-nimble/nimble/host/store/ram/src/ble_store_ram.c - libs/mynewt-nimble/nimble/host/src/ble_monitor.c - libs/mynewt-nimble/nimble/transport/ram/src/ble_hci_ram.c - libs/mynewt-nimble/nimble/controller/src/ble_ll.c - libs/mynewt-nimble/nimble/controller/src/ble_ll_rand.c - libs/mynewt-nimble/nimble/controller/src/ble_ll_conn.c - libs/mynewt-nimble/nimble/controller/src/ble_ll_ctrl.c - libs/mynewt-nimble/nimble/controller/src/ble_ll_hci.c - libs/mynewt-nimble/nimble/controller/src/ble_ll_conn_hci.c - libs/mynewt-nimble/nimble/controller/src/ble_ll_utils.c - libs/mynewt-nimble/nimble/controller/src/ble_ll_scan.c - libs/mynewt-nimble/nimble/controller/src/ble_ll_whitelist.c - libs/mynewt-nimble/nimble/controller/src/ble_ll_adv.c - libs/mynewt-nimble/nimble/controller/src/ble_ll_sched.c - libs/mynewt-nimble/nimble/controller/src/ble_ll_supp_cmd.c - libs/mynewt-nimble/nimble/controller/src/ble_ll_hci_ev.c - libs/mynewt-nimble/nimble/controller/src/ble_ll_rfmgmt.c - libs/mynewt-nimble/porting/nimble/src/os_cputime.c - libs/mynewt-nimble/porting/nimble/src/os_cputime_pwr2.c - libs/mynewt-nimble/porting/nimble/src/os_mbuf.c - libs/mynewt-nimble/porting/nimble/src/os_mempool.c - libs/mynewt-nimble/porting/nimble/src/hal_timer.c - libs/mynewt-nimble/porting/nimble/src/mem.c - libs/mynewt-nimble/porting/nimble/src/endian.c - libs/mynewt-nimble/porting/nimble/src/os_msys_init.c - libs/mynewt-nimble/nimble/drivers/nrf52/src/ble_hw.c - libs/mynewt-nimble/nimble/drivers/nrf52/src/ble_phy.c - libs/mynewt-nimble/nimble/host/services/gap/src/ble_svc_gap.c - libs/mynewt-nimble/nimble/host/services/gatt/src/ble_svc_gatt.c - libs/mynewt-nimble/nimble/host/util/src/addr.c - ) + libs/mynewt-nimble/porting/npl/freertos/src/nimble_port_freertos.c + libs/mynewt-nimble/porting/npl/freertos/src/npl_os_freertos.c + libs/mynewt-nimble/nimble/host/src/ble_hs.c + libs/mynewt-nimble/nimble/host/src/ble_hs_hci_evt.c + libs/mynewt-nimble/nimble/host/src/ble_l2cap_sig_cmd.c + libs/mynewt-nimble/nimble/host/src/ble_l2cap_sig.c + libs/mynewt-nimble/nimble/host/src/ble_l2cap.c + libs/mynewt-nimble/nimble/host/src/ble_hs_mbuf.c + libs/mynewt-nimble/nimble/host/src/ble_sm.c + libs/mynewt-nimble/nimble/host/src/ble_gap.c + libs/mynewt-nimble/nimble/host/src/ble_gatts.c + libs/mynewt-nimble/nimble/host/src/ble_gattc.c + libs/mynewt-nimble/nimble/host/src/ble_hs_conn.c + libs/mynewt-nimble/nimble/host/src/ble_att_svr.c + libs/mynewt-nimble/nimble/host/src/ble_store.c + libs/mynewt-nimble/nimble/host/src/ble_store_util.c + libs/mynewt-nimble/nimble/host/src/ble_hs_pvcy.c + libs/mynewt-nimble/nimble/host/src/ble_hs_hci.c + libs/mynewt-nimble/nimble/host/src/ble_hs_log.c + libs/mynewt-nimble/nimble/host/src/ble_hs_hci_util.c + libs/mynewt-nimble/nimble/host/src/ble_hs_hci_cmd.c + libs/mynewt-nimble/nimble/host/src/ble_hs_cfg.c + libs/mynewt-nimble/nimble/host/src/ble_uuid.c + libs/mynewt-nimble/nimble/host/src/ble_hs_id.c + libs/mynewt-nimble/nimble/host/src/ble_hs_misc.c + libs/mynewt-nimble/nimble/host/src/ble_att.c + libs/mynewt-nimble/nimble/host/src/ble_att_clt.c + libs/mynewt-nimble/nimble/host/src/ble_att_svr.c + libs/mynewt-nimble/nimble/host/src/ble_att_cmd.c + libs/mynewt-nimble/nimble/host/src/ble_hs_atomic.c + libs/mynewt-nimble/nimble/host/src/ble_hs_adv.c + libs/mynewt-nimble/nimble/host/src/ble_hs_flow.c + libs/mynewt-nimble/nimble/host/src/ble_sm.c + libs/mynewt-nimble/nimble/host/src/ble_sm_cmd.c + libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c + libs/mynewt-nimble/nimble/host/src/ble_sm_alg.c + libs/mynewt-nimble/nimble/host/src/ble_hs_mqueue.c + libs/mynewt-nimble/nimble/host/src/ble_hs_stop.c + libs/mynewt-nimble/nimble/host/src/ble_hs_startup.c + libs/mynewt-nimble/nimble/host/store/ram/src/ble_store_ram.c + libs/mynewt-nimble/nimble/host/src/ble_monitor.c + libs/mynewt-nimble/nimble/transport/ram/src/ble_hci_ram.c + libs/mynewt-nimble/nimble/controller/src/ble_ll.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_rand.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_conn.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_ctrl.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_hci.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_conn_hci.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_utils.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_scan.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_whitelist.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_adv.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_sched.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_supp_cmd.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_hci_ev.c + libs/mynewt-nimble/nimble/controller/src/ble_ll_rfmgmt.c + libs/mynewt-nimble/porting/nimble/src/os_cputime.c + libs/mynewt-nimble/porting/nimble/src/os_cputime_pwr2.c + libs/mynewt-nimble/porting/nimble/src/os_mbuf.c + libs/mynewt-nimble/porting/nimble/src/os_mempool.c + libs/mynewt-nimble/porting/nimble/src/hal_timer.c + libs/mynewt-nimble/porting/nimble/src/mem.c + libs/mynewt-nimble/porting/nimble/src/endian.c + libs/mynewt-nimble/porting/nimble/src/os_msys_init.c + libs/mynewt-nimble/nimble/drivers/nrf52/src/ble_hw.c + libs/mynewt-nimble/nimble/drivers/nrf52/src/ble_phy.c + libs/mynewt-nimble/nimble/host/services/gap/src/ble_svc_gap.c + libs/mynewt-nimble/nimble/host/services/gatt/src/ble_svc_gatt.c + libs/mynewt-nimble/nimble/host/util/src/addr.c + ) set(LVGL_SRC - libs/lv_conf.h - libs/lvgl/lvgl.h - libs/lvgl/src/lv_core/lv_obj.c - libs/lvgl/src/lv_core/lv_obj.h - libs/lvgl/src/lv_core/lv_group.c - libs/lvgl/src/lv_core/lv_group.h - libs/lvgl/src/lv_core/lv_disp.c - libs/lvgl/src/lv_core/lv_disp.h - libs/lvgl/src/lv_core/lv_debug.h - libs/lvgl/src/lv_core/lv_debug.c - libs/lvgl/src/lv_core/lv_indev.c - libs/lvgl/src/lv_core/lv_indev.h - libs/lvgl/src/lv_core/lv_refr.c - libs/lvgl/src/lv_core/lv_refr.h - libs/lvgl/src/lv_core/lv_style.c - libs/lvgl/src/lv_core/lv_style.h - libs/lvgl/src/lv_misc/lv_anim.c - libs/lvgl/src/lv_misc/lv_anim.h - libs/lvgl/src/lv_misc/lv_async.h - libs/lvgl/src/lv_misc/lv_async.c - libs/lvgl/src/lv_misc/lv_fs.c - libs/lvgl/src/lv_misc/lv_fs.h - libs/lvgl/src/lv_misc/lv_task.c - libs/lvgl/src/lv_misc/lv_task.h - libs/lvgl/src/lv_misc/lv_area.c - libs/lvgl/src/lv_misc/lv_area.h - libs/lvgl/src/lv_misc/lv_bidi.c - libs/lvgl/src/lv_misc/lv_bidi.h - libs/lvgl/src/lv_misc/lv_circ.c - libs/lvgl/src/lv_misc/lv_circ.h - libs/lvgl/src/lv_misc/lv_color.c - libs/lvgl/src/lv_misc/lv_color.h - libs/lvgl/src/lv_misc/lv_fs.c - libs/lvgl/src/lv_misc/lv_fs.h - libs/lvgl/src/lv_misc/lv_gc.c - libs/lvgl/src/lv_misc/lv_gc.h - libs/lvgl/src/lv_misc/lv_ll.c - libs/lvgl/src/lv_misc/lv_ll.h - libs/lvgl/src/lv_misc/lv_log.c - libs/lvgl/src/lv_misc/lv_log.h - libs/lvgl/src/lv_misc/lv_math.c - libs/lvgl/src/lv_misc/lv_math.h - libs/lvgl/src/lv_misc/lv_mem.c - libs/lvgl/src/lv_misc/lv_mem.h - libs/lvgl/src/lv_misc/lv_printf.c - libs/lvgl/src/lv_misc/lv_printf.h - libs/lvgl/src/lv_misc/lv_task.c - libs/lvgl/src/lv_misc/lv_task.h - libs/lvgl/src/lv_misc/lv_templ.c - libs/lvgl/src/lv_misc/lv_templ.h - libs/lvgl/src/lv_misc/lv_txt.c - libs/lvgl/src/lv_misc/lv_txt.h - libs/lvgl/src/lv_misc/lv_types.h - libs/lvgl/src/lv_misc/lv_utils.c - libs/lvgl/src/lv_misc/lv_utils.h - libs/lvgl/src/lv_draw/lv_draw.c - libs/lvgl/src/lv_draw/lv_draw.h - libs/lvgl/src/lv_draw/lv_draw_arc.c - libs/lvgl/src/lv_draw/lv_draw_arc.h - libs/lvgl/src/lv_draw/lv_draw_basic.c - libs/lvgl/src/lv_draw/lv_draw_basic.h - libs/lvgl/src/lv_draw/lv_draw_img.c - libs/lvgl/src/lv_draw/lv_draw_img.h - libs/lvgl/src/lv_draw/lv_draw_label.c - libs/lvgl/src/lv_draw/lv_draw_label.h - libs/lvgl/src/lv_draw/lv_draw_line.c - libs/lvgl/src/lv_draw/lv_draw_line.h - libs/lvgl/src/lv_draw/lv_draw_rect.c - libs/lvgl/src/lv_draw/lv_draw_rect.h - libs/lvgl/src/lv_draw/lv_draw_triangle.c - libs/lvgl/src/lv_draw/lv_draw_triangle.h - libs/lvgl/src/lv_draw/lv_img_cache.c - libs/lvgl/src/lv_draw/lv_img_cache.h - libs/lvgl/src/lv_draw/lv_img_decoder.c - libs/lvgl/src/lv_draw/lv_img_decoder.h - libs/lvgl/src/lv_hal/lv_hal.h - libs/lvgl/src/lv_hal/lv_hal_disp.c - libs/lvgl/src/lv_hal/lv_hal_disp.h - libs/lvgl/src/lv_hal/lv_hal_indev.c - libs/lvgl/src/lv_hal/lv_hal_indev.h - libs/lvgl/src/lv_hal/lv_hal_tick.c - libs/lvgl/src/lv_hal/lv_hal_tick.h - libs/lvgl/src/lv_font/lv_font.c - libs/lvgl/src/lv_font/lv_font.h - libs/lvgl/src/lv_font/lv_font_fmt_txt.c - libs/lvgl/src/lv_font/lv_font_fmt_txt.h - libs/lvgl/src/lv_font/lv_symbol_def.h - libs/lvgl/src/lv_themes/lv_theme.c - libs/lvgl/src/lv_themes/lv_theme.h - libs/lvgl/src/lv_objx/lv_btn.h - libs/lvgl/src/lv_objx/lv_btn.c - libs/lvgl/src/lv_objx/lv_cont.h - libs/lvgl/src/lv_objx/lv_cont.c - libs/lvgl/src/lv_objx/lv_label.h - libs/lvgl/src/lv_objx/lv_label.c - libs/lvgl/src/lv_themes/lv_theme.c - libs/lvgl/src/lv_themes/lv_theme.h - libs/lvgl/src/lv_themes/lv_theme_night.h - libs/lvgl/src/lv_themes/lv_theme_night.c - libs/lvgl/src/lv_objx/lv_list.c - libs/lvgl/src/lv_objx/lv_list.h - libs/lvgl/src/lv_objx/lv_tileview.c - libs/lvgl/src/lv_objx/lv_tileview.h - libs/lvgl/src/lv_objx/lv_tabview.c - libs/lvgl/src/lv_objx/lv_tabview.h - libs/lvgl/src/lv_objx/lv_btnm.c - libs/lvgl/src/lv_objx/lv_btnm.h - libs/lvgl/src/lv_objx/lv_page.c - libs/lvgl/src/lv_objx/lv_page.h - libs/lvgl/src/lv_objx/lv_img.c - libs/lvgl/src/lv_objx/lv_img.h - libs/lvgl/src/lv_objx/lv_lmeter.c - libs/lvgl/src/lv_objx/lv_lmeter.h - libs/lvgl/src/lv_objx/lv_arc.c - libs/lvgl/src/lv_objx/lv_arc.h - libs/lvgl/src/lv_objx/lv_gauge.c - libs/lvgl/src/lv_objx/lv_gauge.h - 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 - ) + libs/lv_conf.h + libs/lvgl/lvgl.h + libs/lvgl/src/lv_core/lv_obj.c + libs/lvgl/src/lv_core/lv_obj.h + libs/lvgl/src/lv_core/lv_group.c + libs/lvgl/src/lv_core/lv_group.h + libs/lvgl/src/lv_core/lv_disp.c + libs/lvgl/src/lv_core/lv_disp.h + libs/lvgl/src/lv_core/lv_debug.h + libs/lvgl/src/lv_core/lv_debug.c + libs/lvgl/src/lv_core/lv_indev.c + libs/lvgl/src/lv_core/lv_indev.h + libs/lvgl/src/lv_core/lv_refr.c + libs/lvgl/src/lv_core/lv_refr.h + libs/lvgl/src/lv_core/lv_style.c + libs/lvgl/src/lv_core/lv_style.h + libs/lvgl/src/lv_misc/lv_anim.c + libs/lvgl/src/lv_misc/lv_anim.h + libs/lvgl/src/lv_misc/lv_async.h + libs/lvgl/src/lv_misc/lv_async.c + libs/lvgl/src/lv_misc/lv_fs.c + libs/lvgl/src/lv_misc/lv_fs.h + libs/lvgl/src/lv_misc/lv_task.c + libs/lvgl/src/lv_misc/lv_task.h + libs/lvgl/src/lv_misc/lv_area.c + libs/lvgl/src/lv_misc/lv_area.h + libs/lvgl/src/lv_misc/lv_bidi.c + libs/lvgl/src/lv_misc/lv_bidi.h + libs/lvgl/src/lv_misc/lv_circ.c + libs/lvgl/src/lv_misc/lv_circ.h + libs/lvgl/src/lv_misc/lv_color.c + libs/lvgl/src/lv_misc/lv_color.h + libs/lvgl/src/lv_misc/lv_fs.c + libs/lvgl/src/lv_misc/lv_fs.h + libs/lvgl/src/lv_misc/lv_gc.c + libs/lvgl/src/lv_misc/lv_gc.h + libs/lvgl/src/lv_misc/lv_ll.c + libs/lvgl/src/lv_misc/lv_ll.h + libs/lvgl/src/lv_misc/lv_log.c + libs/lvgl/src/lv_misc/lv_log.h + libs/lvgl/src/lv_misc/lv_math.c + libs/lvgl/src/lv_misc/lv_math.h + libs/lvgl/src/lv_misc/lv_mem.c + libs/lvgl/src/lv_misc/lv_mem.h + libs/lvgl/src/lv_misc/lv_printf.c + libs/lvgl/src/lv_misc/lv_printf.h + libs/lvgl/src/lv_misc/lv_task.c + libs/lvgl/src/lv_misc/lv_task.h + libs/lvgl/src/lv_misc/lv_templ.c + libs/lvgl/src/lv_misc/lv_templ.h + libs/lvgl/src/lv_misc/lv_txt.c + libs/lvgl/src/lv_misc/lv_txt.h + libs/lvgl/src/lv_misc/lv_types.h + libs/lvgl/src/lv_misc/lv_utils.c + libs/lvgl/src/lv_misc/lv_utils.h + libs/lvgl/src/lv_draw/lv_draw.c + libs/lvgl/src/lv_draw/lv_draw.h + libs/lvgl/src/lv_draw/lv_draw_arc.c + libs/lvgl/src/lv_draw/lv_draw_arc.h + libs/lvgl/src/lv_draw/lv_draw_basic.c + libs/lvgl/src/lv_draw/lv_draw_basic.h + libs/lvgl/src/lv_draw/lv_draw_img.c + libs/lvgl/src/lv_draw/lv_draw_img.h + libs/lvgl/src/lv_draw/lv_draw_label.c + libs/lvgl/src/lv_draw/lv_draw_label.h + libs/lvgl/src/lv_draw/lv_draw_line.c + libs/lvgl/src/lv_draw/lv_draw_line.h + libs/lvgl/src/lv_draw/lv_draw_rect.c + libs/lvgl/src/lv_draw/lv_draw_rect.h + libs/lvgl/src/lv_draw/lv_draw_triangle.c + libs/lvgl/src/lv_draw/lv_draw_triangle.h + libs/lvgl/src/lv_draw/lv_img_cache.c + libs/lvgl/src/lv_draw/lv_img_cache.h + libs/lvgl/src/lv_draw/lv_img_decoder.c + libs/lvgl/src/lv_draw/lv_img_decoder.h + libs/lvgl/src/lv_hal/lv_hal.h + libs/lvgl/src/lv_hal/lv_hal_disp.c + libs/lvgl/src/lv_hal/lv_hal_disp.h + libs/lvgl/src/lv_hal/lv_hal_indev.c + libs/lvgl/src/lv_hal/lv_hal_indev.h + libs/lvgl/src/lv_hal/lv_hal_tick.c + libs/lvgl/src/lv_hal/lv_hal_tick.h + libs/lvgl/src/lv_font/lv_font.c + libs/lvgl/src/lv_font/lv_font.h + libs/lvgl/src/lv_font/lv_font_fmt_txt.c + libs/lvgl/src/lv_font/lv_font_fmt_txt.h + libs/lvgl/src/lv_font/lv_symbol_def.h + libs/lvgl/src/lv_themes/lv_theme.c + libs/lvgl/src/lv_themes/lv_theme.h + libs/lvgl/src/lv_objx/lv_btn.h + libs/lvgl/src/lv_objx/lv_btn.c + libs/lvgl/src/lv_objx/lv_cont.h + libs/lvgl/src/lv_objx/lv_cont.c + libs/lvgl/src/lv_objx/lv_label.h + libs/lvgl/src/lv_objx/lv_label.c + libs/lvgl/src/lv_themes/lv_theme.c + libs/lvgl/src/lv_themes/lv_theme.h + libs/lvgl/src/lv_themes/lv_theme_night.h + libs/lvgl/src/lv_themes/lv_theme_night.c + libs/lvgl/src/lv_objx/lv_list.c + libs/lvgl/src/lv_objx/lv_list.h + libs/lvgl/src/lv_objx/lv_tileview.c + libs/lvgl/src/lv_objx/lv_tileview.h + libs/lvgl/src/lv_objx/lv_tabview.c + libs/lvgl/src/lv_objx/lv_tabview.h + libs/lvgl/src/lv_objx/lv_btnm.c + libs/lvgl/src/lv_objx/lv_btnm.h + libs/lvgl/src/lv_objx/lv_page.c + libs/lvgl/src/lv_objx/lv_page.h + libs/lvgl/src/lv_objx/lv_img.c + libs/lvgl/src/lv_objx/lv_img.h + libs/lvgl/src/lv_objx/lv_lmeter.c + libs/lvgl/src/lv_objx/lv_lmeter.h + libs/lvgl/src/lv_objx/lv_arc.c + libs/lvgl/src/lv_objx/lv_arc.h + libs/lvgl/src/lv_objx/lv_gauge.c + libs/lvgl/src/lv_objx/lv_gauge.h + 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 + libs/lvgl/src/lv_objx/lv_ddlist.c + libs/lvgl/src/lv_objx/lv_ddlist.h + libs/lvgl/src/lv_objx/lv_line.c + libs/lvgl/src/lv_objx/lv_line.h + ) 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_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/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 - ) + displayapp/icons/bluetooth/os_bt_connected.c + displayapp/icons/bluetooth/os_bt_disconnected.c + ) list(APPEND SOURCE_FILES - Logging/NrfLogger.cpp - BlinkApp/BlinkApp.cpp - DisplayApp/DisplayApp.cpp - DisplayApp/Screens/Screen.cpp - DisplayApp/Screens/Clock.cpp - DisplayApp/Screens/Message.cpp - DisplayApp/Screens/Tile.cpp - 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 - DisplayApp/Screens/FirmwareUpdate.cpp - DisplayApp/Screens/Music.cpp - main.cpp - drivers/St7789.cpp - drivers/SpiNorFlash.cpp - drivers/SpiMaster.cpp - drivers/Spi.cpp - drivers/Watchdog.cpp - drivers/DebugPins.cpp - drivers/InternalFlash.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 - drivers/Cst816s.cpp - FreeRTOS/port.c - FreeRTOS/port_cmsis_systick.c - FreeRTOS/port_cmsis.c - ${TINYCRYPT_SRC} - ${NIMBLE_SRC} - ${LVGL_SRC} - #${IMAGE_FILES} - ${SDK_SOURCE_FILES} + BootloaderVersion.cpp + logging/NrfLogger.cpp + displayapp/DisplayApp.cpp + displayapp/screens/Screen.cpp + displayapp/screens/Clock.cpp + displayapp/screens/Tile.cpp + displayapp/screens/Meter.cpp + displayapp/screens/Gauge.cpp + displayapp/screens/InfiniPaint.cpp + displayapp/screens/DropDownDemo.cpp + displayapp/screens/Modal.cpp + displayapp/screens/BatteryIcon.cpp + displayapp/screens/BleIcon.cpp + displayapp/screens/NotificationIcon.cpp + displayapp/screens/Brightness.cpp + displayapp/screens/SystemInfo.cpp + displayapp/screens/Label.cpp + displayapp/screens/FirmwareUpdate.cpp + displayapp/screens/Music.cpp + displayapp/screens/FirmwareValidation.cpp + displayapp/screens/ApplicationList.cpp + displayapp/screens/Notifications.cpp + main.cpp + drivers/St7789.cpp + drivers/SpiNorFlash.cpp + drivers/SpiMaster.cpp + drivers/Spi.cpp + drivers/Watchdog.cpp + drivers/DebugPins.cpp + drivers/InternalFlash.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/firmwarevalidator/FirmwareValidator.cpp + drivers/Cst816s.cpp + FreeRTOS/port.c + FreeRTOS/port_cmsis_systick.c + FreeRTOS/port_cmsis.c - DisplayApp/LittleVgl.cpp - DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c - DisplayApp/Fonts/jetbrains_mono_bold_20.c + displayapp/LittleVgl.cpp + displayapp/fonts/jetbrains_mono_extrabold_compressed.c + displayapp/fonts/jetbrains_mono_bold_20.c - SystemTask/SystemTask.cpp - drivers/TwiMaster.cpp -) + systemtask/SystemTask.cpp + drivers/TwiMaster.cpp + ) list(APPEND GRAPHICS_SOURCE_FILES - ${SDK_SOURCE_FILES} - - # FreeRTOS - FreeRTOS/port.c - FreeRTOS/port_cmsis_systick.c - FreeRTOS/port_cmsis.c + # FreeRTOS + FreeRTOS/port.c + FreeRTOS/port_cmsis_systick.c + FreeRTOS/port_cmsis.c - drivers/SpiNorFlash.cpp - drivers/SpiMaster.cpp - drivers/Spi.cpp - Logging/NrfLogger.cpp + drivers/SpiNorFlash.cpp + drivers/SpiMaster.cpp + drivers/Spi.cpp + logging/NrfLogger.cpp - Components/Gfx/Gfx.cpp - drivers/St7789.cpp - Components/Brightness/BrightnessController.cpp + components/gfx/Gfx.cpp + drivers/St7789.cpp + components/brightness/BrightnessController.cpp - graphics.cpp -) + graphics.cpp + ) set(INCLUDE_FILES - Logging/Logger.h - Logging/NrfLogger.h - BlinkApp/BlinkApp.h - DisplayApp/DisplayApp.h - DisplayApp/TouchEvents.h - DisplayApp/Screens/Screen.h - DisplayApp/Screens/Clock.h - DisplayApp/Screens/Message.h - DisplayApp/Screens/Tile.h - DisplayApp/Screens/Meter.h - DisplayApp/Screens/Gauge.h - DisplayApp/Screens/Modal.h - DisplayApp/Screens/BatteryIcon.h - DisplayApp/Screens/BleIcon.cpp - DisplayApp/Screens/Brightness.h - DisplayApp/Screens/ScreenList.h - DisplayApp/Screens/Label.h - DisplayApp/Screens/FirmwareUpdate.h - drivers/St7789.h - drivers/SpiNorFlash.h - drivers/SpiMaster.h - drivers/Spi.h - drivers/Watchdog.h - drivers/DebugPins.h - drivers/InternalFlash.h - Components/Battery/BatteryController.h - Components/Ble/BleController.h - Components/Ble/NotificationManager.h - Components/DateTime/DateTimeController.h - Components/Brightness/BrightnessController.h - Components/Ble/NimbleController.h - Components/Ble/DeviceInformationService.h - Components/Ble/CurrentTimeClient.h - Components/Ble/AlertNotificationClient.h - Components/Ble/DfuService.h - drivers/Cst816s.h - FreeRTOS/portmacro.h - FreeRTOS/portmacro_cmsis.h - libs/date/includes/date/tz.h - libs/date/includes/date/chrono_io.h - libs/date/includes/date/date.h - libs/date/includes/date/islamic.h - libs/date/includes/date/iso_week.h - 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 - drivers/TwiMaster.h -) + BootloaderVersion.h + logging/Logger.h + logging/NrfLogger.h + displayapp/DisplayApp.h + displayapp/TouchEvents.h + displayapp/screens/Screen.h + displayapp/screens/Clock.h + displayapp/screens/Tile.h + displayapp/screens/Meter.h + displayapp/screens/Gauge.h + displayapp/screens/InfiniPaint.h + displayapp/screens/DropDownDemo.h + displayapp/screens/Modal.h + displayapp/screens/BatteryIcon.h + displayapp/screens/BleIcon.h + displayapp/screens/NotificationIcon.h + displayapp/screens/Brightness.h + displayapp/screens/SystemInfo.h + displayapp/screens/ScreenList.h + displayapp/screens/Label.h + displayapp/screens/FirmwareUpdate.h + displayapp/screens/FirmwareValidation.h + displayapp/screens/ApplicationList.h + displayapp/Apps.h + displayapp/screens/Notifications.h + drivers/St7789.h + drivers/SpiNorFlash.h + drivers/SpiMaster.h + drivers/Spi.h + drivers/Watchdog.h + drivers/DebugPins.h + drivers/InternalFlash.h + components/battery/BatteryController.h + components/ble/BleController.h + components/ble/NotificationManager.h + components/datetime/DateTimeController.h + components/brightness/BrightnessController.h + components/ble/NimbleController.h + components/ble/DeviceInformationService.h + components/ble/CurrentTimeClient.h + components/ble/AlertNotificationClient.h + components/ble/DfuService.h + components/firmwarevalidator/FirmwareValidator.h + components/ble/BatteryInformationService.h + components/ble/ImmediateAlertService.h + components/ble/ServiceDiscovery.h + components/ble/BleClient.h + drivers/Cst816s.h + FreeRTOS/portmacro.h + FreeRTOS/portmacro_cmsis.h + libs/date/includes/date/tz.h + libs/date/includes/date/chrono_io.h + libs/date/includes/date/date.h + libs/date/includes/date/islamic.h + libs/date/includes/date/iso_week.h + 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 + drivers/TwiMaster.h + ) include_directories( - . - ../ - libs/ - FreeRTOS/ - libs/date/includes - libs/mynewt-nimble/porting/npl/freertos/include - libs/mynewt-nimble/nimble/include - libs/mynewt-nimble/porting/nimble/include - libs/mynewt-nimble/nimble/host/include - libs/mynewt-nimble/nimble/controller/include - libs/mynewt-nimble/nimble/transport/ram/include - libs/mynewt-nimble/nimble/drivers/nrf52/include - libs/mynewt-nimble/ext/tinycrypt/include - libs/mynewt-nimble/nimble/host/services/gap/include - libs/mynewt-nimble/nimble/host/services/gatt/include - libs/mynewt-nimble/nimble/host/util/include - libs/mynewt-nimble/nimble/host/store/ram/include + . + ../ + libs/ + FreeRTOS/ + libs/date/includes + libs/mynewt-nimble/porting/npl/freertos/include + libs/mynewt-nimble/nimble/include + libs/mynewt-nimble/porting/nimble/include + libs/mynewt-nimble/nimble/host/include + libs/mynewt-nimble/nimble/controller/include + libs/mynewt-nimble/nimble/transport/ram/include + libs/mynewt-nimble/nimble/drivers/nrf52/include + libs/mynewt-nimble/ext/tinycrypt/include + libs/mynewt-nimble/nimble/host/services/gap/include + libs/mynewt-nimble/nimble/host/services/gatt/include + libs/mynewt-nimble/nimble/host/util/include + libs/mynewt-nimble/nimble/host/store/ram/include - "${NRF5_SDK_PATH}/components/drivers_nrf/nrf_soc_nosd" + "${NRF5_SDK_PATH}/components/drivers_nrf/nrf_soc_nosd" "${NRF5_SDK_PATH}/components" "${NRF5_SDK_PATH}/components/boards" "${NRF5_SDK_PATH}/components/softdevice/common" @@ -541,11 +559,11 @@ include_directories( ) link_directories( - ../ + ../ ) -set(COMMON_FLAGS -MP -MD -mthumb -mabi=aapcs -Wall -g3 -ffunction-sections -fdata-sections -fno-strict-aliasing -fno-builtin --short-enums -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wreturn-type -Werror=return-type) +set(COMMON_FLAGS -MP -MD -mthumb -mabi=aapcs -Wall -Wno-unknown-pragmas -g3 -ffunction-sections -fdata-sections -fno-strict-aliasing -fno-builtin --short-enums -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wreturn-type -Werror=return-type) add_definitions(-DCONFIG_GPIO_AS_PINRESET) add_definitions(-DDEBUG) add_definitions(-DNIMBLE_CFG_CONTROLLER) @@ -556,42 +574,85 @@ add_definitions(-DDEBUG_NRF_USER) add_definitions(-D__STACK_SIZE=8192) add_definitions(-D__HEAP_SIZE=8192) -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release") -endif() +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release") +endif () + +# NRF SDK +add_library(nrf-sdk STATIC ${SDK_SOURCE_FILES}) +target_include_directories(nrf-sdk SYSTEM PUBLIC . ../) +target_include_directories(nrf-sdk SYSTEM PUBLIC ${INCLUDES_FROM_LIBS}) +target_compile_options(nrf-sdk PRIVATE + $<$<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> + $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3> + $<$<COMPILE_LANGUAGE:ASM>: -MP -MD -std=c99 -x assembler-with-cpp> + ) + +# NimBLE +add_library(nimble STATIC ${NIMBLE_SRC} ${TINYCRYPT_SRC}) +target_include_directories(nimble SYSTEM PUBLIC . ../) +target_include_directories(nimble SYSTEM PUBLIC ${INCLUDES_FROM_LIBS}) +target_compile_options(nimble PRIVATE + $<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3 -Wno-unused-but-set-variable -Wno-maybe-uninitialized> + $<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3 -Wno-unused-but-set-variable -Wno-maybe-uninitialized> + $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3 -Wno-unused-but-set-variable -Wno-maybe-uninitialized> + $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3 -Wno-unused-but-set-variable -Wno-maybe-uninitialized> + $<$<COMPILE_LANGUAGE:ASM>: -MP -MD -std=c99 -x assembler-with-cpp> + ) + +# lvgl +add_library(lvgl STATIC ${LVGL_SRC}) +target_include_directories(lvgl SYSTEM PUBLIC . ../) +target_include_directories(lvgl SYSTEM PUBLIC ${INCLUDES_FROM_LIBS}) +target_compile_options(lvgl PRIVATE + $<$<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> + ) # Build autonomous binary (without support for bootloader) set(EXECUTABLE_NAME "pinetime-app") +set(EXECUTABLE_FILE_NAME ${EXECUTABLE_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}) set(NRF5_LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/gcc_nrf52.ld") add_executable(${EXECUTABLE_NAME} ${SOURCE_FILES}) +set_target_properties(${EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_FILE_NAME}) +target_link_libraries(${EXECUTABLE_NAME} nimble nrf-sdk lvgl) target_compile_options(${EXECUTABLE_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_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_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_FILE_NAME}.map" CXX_STANDARD 11 C_STANDARD 99 ) add_custom_command(TARGET ${EXECUTABLE_NAME} POST_BUILD - COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_NAME}.out - COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_NAME}.out "${EXECUTABLE_NAME}.bin" - COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_NAME}.out "${EXECUTABLE_NAME}.hex" - COMMENT "post build steps for ${EXECUTABLE_NAME}") + COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_FILE_NAME}.out + COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_FILE_NAME}.out "${EXECUTABLE_FILE_NAME}.bin" + COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_FILE_NAME}.out "${EXECUTABLE_FILE_NAME}.hex" + COMMENT "post build steps for ${EXECUTABLE_FILE_NAME}") # Build binary intended to be used by bootloader set(EXECUTABLE_MCUBOOT_NAME "pinetime-mcuboot-app") -set(EXECUTABLE_MCUBOOT_WITH_BOOTLOADER_NAME "pinetime-mcuboot-app-wth-bootloader") +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(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) +set_target_properties(${EXECUTABLE_MCUBOOT_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_MCUBOOT_FILE_NAME}) target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC $<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3> $<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3> @@ -602,78 +663,109 @@ target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC set_target_properties(${EXECUTABLE_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_MCUBOOT_NAME}.map" + 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_FILE_NAME}.map" CXX_STANDARD 11 C_STANDARD 99 ) add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_NAME} POST_BUILD - COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_MCUBOOT_NAME}.out - COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_MCUBOOT_NAME}.out "${EXECUTABLE_MCUBOOT_NAME}.bin" - COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_MCUBOOT_NAME}.out "${EXECUTABLE_MCUBOOT_NAME}.hex" - COMMENT "post build steps for ${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" + 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 - $<$<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> - ) + $<$<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_GRAPHICS_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_NAME}.map" - CXX_STANDARD 11 - C_STANDARD 99 - ) + 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" + CXX_STANDARD 11 + C_STANDARD 99 + ) add_custom_command(TARGET ${EXECUTABLE_GRAPHICS_NAME} - POST_BUILD - COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_GRAPHICS_NAME}.out - COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_GRAPHICS_NAME}.out "${EXECUTABLE_GRAPHICS_NAME}.bin" - COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_GRAPHICS_NAME}.out "${EXECUTABLE_GRAPHICS_NAME}.hex" - COMMENT "post build steps for ${EXECUTABLE_GRAPHICS_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}" + ) # FLASH -if(USE_JLINK) +if (USE_JLINK) add_custom_target(FLASH_ERASE COMMAND ${NRFJPROG} --eraseall -f ${NRF_TARGET} COMMENT "erasing flashing" ) add_custom_target("FLASH_${EXECUTABLE_NAME}" DEPENDS ${EXECUTABLE_NAME} - COMMAND ${NRFJPROG} --program ${EXECUTABLE_NAME}.hex -f ${NRF_TARGET} --sectorerase + COMMAND ${NRFJPROG} --program ${EXECUTABLE_FILE_NAME}.hex -f ${NRF_TARGET} --sectorerase COMMAND sleep 0.5s COMMAND ${NRFJPROG} --reset -f ${NRF_TARGET} COMMENT "flashing ${EXECUTABLE_NAME}.hex" ) -elseif(USE_GDB_CLIENT) +elseif (USE_GDB_CLIENT) add_custom_target(FLASH_ERASE COMMAND ${GDB_CLIENT_BIN_PATH} -nx --batch -ex 'target extended-remote ${GDB_CLIENT_TARGET_REMOTE}' -ex 'monitor swdp_scan' -ex 'attach 1' -ex 'mon erase_mass' COMMENT "erasing flashing" ) add_custom_target("FLASH_${EXECUTABLE_NAME}" DEPENDS ${EXECUTABLE_NAME} - COMMAND ${GDB_CLIENT_BIN_PATH} -nx --batch -ex 'target extended-remote ${GDB_CLIENT_TARGET_REMOTE}' -ex 'monitor swdp_scan' -ex 'attach 1' -ex 'load' -ex 'kill' ${EXECUTABLE_NAME}.hex - COMMENT "flashing ${EXECUTABLE_NAME}.hex" - ) -elseif(USE_OPENOCD) - add_custom_target(FLASH_ERASE - COMMAND ${OPENOCD_BIN_PATH} -f interface/stlink.cfg -c 'transport select hla_swd' -f target/nrf52.cfg -c init -c halt -c 'nrf5 mass_erase' -c reset -c shutdown - COMMENT "erasing flashing" - ) - add_custom_target("FLASH_${EXECUTABLE_NAME}" - DEPENDS ${EXECUTABLE_NAME} - COMMAND ${OPENOCD_BIN_PATH} -c "tcl_port disabled" -c "gdb_port 3333" -c "telnet_port 4444" -f interface/stlink.cfg -c 'transport select hla_swd' -f target/nrf52.cfg -c "program \"${EXECUTABLE_NAME}.hex\"" -c reset -c shutdown + COMMAND ${GDB_CLIENT_BIN_PATH} -nx --batch -ex 'target extended-remote ${GDB_CLIENT_TARGET_REMOTE}' -ex 'monitor swdp_scan' -ex 'attach 1' -ex 'load' -ex 'kill' ${EXECUTABLE_NAME}.hex COMMENT "flashing ${EXECUTABLE_NAME}.hex" ) - -endif() +elseif (USE_OPENOCD) + if (USE_CMSIS_DAP) + add_custom_target(FLASH_ERASE + COMMAND ${OPENOCD_BIN_PATH} -c 'source [find interface/cmsis-dap.cfg]' -c 'transport select swd' + -c 'source [find target/nrf52.cfg]' + -c 'init' + -c 'halt' + -c 'nrf5 mass_erase' + -c 'halt' + -c 'reset' + -c 'exit' + COMMENT "erasing flashing" + ) + add_custom_target("FLASH_${EXECUTABLE_NAME}" + DEPENDS ${EXECUTABLE_NAME} + COMMAND ${OPENOCD_BIN_PATH} + -c 'tcl_port disabled' + -c 'gdb_port 3333' + -c 'telnet_port 4444' + -c 'source [find interface/cmsis-dap.cfg]' + -c 'transport select swd' + -c 'source [find target/nrf52.cfg]' + -c 'halt' + -c "program \"${EXECUTABLE_NAME}.hex\"" + -c 'reset' + -c 'shutdown' + COMMENT "flashing ${EXECUTABLE_NAME}.hex" + ) + else () + add_custom_target(FLASH_ERASE + COMMAND ${OPENOCD_BIN_PATH} -f interface/stlink.cfg -c 'transport select hla_swd' -f target/nrf52.cfg -c init -c halt -c 'nrf5 mass_erase' -c reset -c shutdown + COMMENT "erasing flashing" + ) + add_custom_target("FLASH_${EXECUTABLE_NAME}" + DEPENDS ${EXECUTABLE_NAME} + COMMAND ${OPENOCD_BIN_PATH} -c "tcl_port disabled" -c "gdb_port 3333" -c "telnet_port 4444" -f interface/stlink.cfg -c 'transport select hla_swd' -f target/nrf52.cfg -c "program \"${EXECUTABLE_NAME}.hex\"" -c reset -c shutdown + COMMENT "flashing ${EXECUTABLE_NAME}.hex" + ) + endif () +endif () diff --git a/src/Components/Ble/AlertNotificationClient.cpp b/src/Components/Ble/AlertNotificationClient.cpp deleted file mode 100644 index b65e019d..00000000 --- a/src/Components/Ble/AlertNotificationClient.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#include <SystemTask/SystemTask.h> -#include "NotificationManager.h" - -#include "AlertNotificationClient.h" - - -using namespace Pinetime::Controllers; -constexpr ble_uuid16_t AlertNotificationClient::ansServiceUuid; - -constexpr ble_uuid16_t AlertNotificationClient::supportedNewAlertCategoryUuid; -constexpr ble_uuid16_t AlertNotificationClient::supportedUnreadAlertCategoryUuid ; -constexpr ble_uuid16_t AlertNotificationClient::newAlertUuid; -constexpr ble_uuid16_t AlertNotificationClient::unreadAlertStatusUuid; -constexpr ble_uuid16_t AlertNotificationClient::controlPointUuid; - -int Pinetime::Controllers::NewAlertSubcribeCallback(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) { - auto client = static_cast<AlertNotificationClient*>(arg); - return client->OnNewAlertSubcribe(conn_handle, error, attr); -} - -AlertNotificationClient::AlertNotificationClient(Pinetime::System::SystemTask& systemTask, - Pinetime::Controllers::NotificationManager& notificationManager) : - systemTask{systemTask}, notificationManager{notificationManager}{ - -} - -bool AlertNotificationClient::OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, const ble_gatt_svc *service) { - if(service == nullptr && error->status == BLE_HS_EDONE) { - NRF_LOG_INFO("ANS Discovery complete"); - return true; - } - - if(service != nullptr && ble_uuid_cmp(((ble_uuid_t*)&ansServiceUuid), &service->uuid.u) == 0) { - NRF_LOG_INFO("ANS discovered : 0x%x", service->start_handle); - ansStartHandle = service->start_handle; - ansEndHandle = service->end_handle; - isDiscovered = true; - } - return false; -} - -int AlertNotificationClient::OnCharacteristicsDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, - const ble_gatt_chr *characteristic) { - if(error->status != 0 && error->status != BLE_HS_EDONE) { - NRF_LOG_INFO("ANS Characteristic discovery ERROR"); - return 0; - } - - if(characteristic == nullptr && error->status == BLE_HS_EDONE) { - NRF_LOG_INFO("ANS Characteristic discovery complete"); - } else { - if(characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*)&supportedNewAlertCategoryUuid), &characteristic->uuid.u) == 0) { - NRF_LOG_INFO("ANS Characteristic discovered : supportedNewAlertCategoryUuid"); - supportedNewAlertCategoryHandle = characteristic->val_handle; - } else if(characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*)&supportedUnreadAlertCategoryUuid), &characteristic->uuid.u) == 0) { - NRF_LOG_INFO("ANS Characteristic discovered : supportedUnreadAlertCategoryUuid"); - supportedUnreadAlertCategoryHandle = characteristic->val_handle; - } else if(characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*)&newAlertUuid), &characteristic->uuid.u) == 0) { - NRF_LOG_INFO("ANS Characteristic discovered : newAlertUuid"); - newAlertHandle = characteristic->val_handle; - newAlertDefHandle = characteristic->def_handle; - } else if(characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*)&unreadAlertStatusUuid), &characteristic->uuid.u) == 0) { - NRF_LOG_INFO("ANS Characteristic discovered : unreadAlertStatusUuid"); - unreadAlertStatusHandle = characteristic->val_handle; - } else if(characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*)&controlPointUuid), &characteristic->uuid.u) == 0) { - NRF_LOG_INFO("ANS Characteristic discovered : controlPointUuid"); - controlPointHandle = characteristic->val_handle; - }else - NRF_LOG_INFO("ANS Characteristic discovered : 0x%x", characteristic->val_handle); - } - return 0; -} - -int AlertNotificationClient::OnNewAlertSubcribe(uint16_t connectionHandle, const ble_gatt_error *error, - ble_gatt_attr *attribute) { - if(error->status == 0) { - NRF_LOG_INFO("ANS New alert subscribe OK"); - } else { - NRF_LOG_INFO("ANS New alert subscribe ERROR"); - } - - return 0; -} - -int AlertNotificationClient::OnDescriptorDiscoveryEventCallback(uint16_t connectionHandle, const ble_gatt_error *error, - uint16_t characteristicValueHandle, - const ble_gatt_dsc *descriptor) { - if(error->status == 0) { - if(characteristicValueHandle == newAlertHandle && ble_uuid_cmp(((ble_uuid_t*)&newAlertUuid), &descriptor->uuid.u)) { - if(newAlertDescriptorHandle == 0) { - NRF_LOG_INFO("ANS Descriptor discovered : %d", descriptor->handle); - newAlertDescriptorHandle = descriptor->handle; - uint8_t value[2]; - value[0] = 1; - value[1] = 0; - ble_gattc_write_flat(connectionHandle, newAlertDescriptorHandle, value, sizeof(value), NewAlertSubcribeCallback, this); - } - } - } - return 0; -} - -void AlertNotificationClient::OnNotification(ble_gap_event *event) { - if(event->notify_rx.attr_handle == newAlertHandle) { - // TODO implement this with more memory safety (and constexpr) - static const size_t maxBufferSize{21}; - static const size_t maxMessageSize{18}; - size_t bufferSize = min(OS_MBUF_PKTLEN(event->notify_rx.om), maxBufferSize); - - uint8_t data[bufferSize]; - os_mbuf_copydata(event->notify_rx.om, 0, bufferSize, data); - - char *s = (char *) &data[3]; - auto messageSize = min(maxMessageSize, (bufferSize-3)); - - for (int i = 0; i < messageSize-1; i++) { - if (s[i] == 0x00) { - s[i] = 0x0A; - } - } - s[messageSize-1] = '\0'; - - notificationManager.Push(Pinetime::Controllers::NotificationManager::Categories::SimpleAlert, s, messageSize); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification); - } -} - -bool AlertNotificationClient::IsDiscovered() const { - return isDiscovered; -} - -uint16_t AlertNotificationClient::StartHandle() const { - return ansStartHandle; -} - -uint16_t AlertNotificationClient::EndHandle() const { - return ansEndHandle; -} - -uint16_t AlertNotificationClient::NewAlerthandle() const { - return newAlertHandle; -} diff --git a/src/Components/Ble/CurrentTimeClient.cpp b/src/Components/Ble/CurrentTimeClient.cpp deleted file mode 100644 index 7a225f4b..00000000 --- a/src/Components/Ble/CurrentTimeClient.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include <hal/nrf_rtc.h> -#include "CurrentTimeClient.h" - -using namespace Pinetime::Controllers; - -constexpr ble_uuid16_t CurrentTimeClient::ctsServiceUuid; -constexpr ble_uuid16_t CurrentTimeClient::currentTimeCharacteristicUuid; - -CurrentTimeClient::CurrentTimeClient(DateTime& dateTimeController) : dateTimeController{dateTimeController} { - -} - -void CurrentTimeClient::Init() { - -} - -bool CurrentTimeClient::OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, const ble_gatt_svc *service) { - if(service == nullptr && error->status == BLE_HS_EDONE) { - NRF_LOG_INFO("CTS Discovery complete"); - return true; - } - - if(service != nullptr && ble_uuid_cmp(((ble_uuid_t*)&ctsServiceUuid), &service->uuid.u) == 0) { - NRF_LOG_INFO("CTS discovered : 0x%x", service->start_handle); - isDiscovered = true; - ctsStartHandle = service->start_handle; - ctsEndHandle = service->end_handle; - return false; - } - return false; -} - -int CurrentTimeClient::OnCharacteristicDiscoveryEvent(uint16_t conn_handle, const ble_gatt_error *error, - const ble_gatt_chr *characteristic) { - if(characteristic == nullptr && error->status == BLE_HS_EDONE) { - NRF_LOG_INFO("CTS Characteristic discovery complete"); - return 0; - } - - if(characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*)¤tTimeCharacteristicUuid), &characteristic->uuid.u) == 0) { - NRF_LOG_INFO("CTS Characteristic discovered : 0x%x", characteristic->val_handle); - currentTimeHandle = characteristic->val_handle; - } - return 0; -} - -int CurrentTimeClient::OnCurrentTimeReadResult(uint16_t conn_handle, const ble_gatt_error *error, const ble_gatt_attr *attribute) { - if(error->status == 0) { - // TODO check that attribute->handle equals the handle discovered in OnCharacteristicDiscoveryEvent - CtsData result; - os_mbuf_copydata(attribute->om, 0, sizeof(CtsData), &result); - NRF_LOG_INFO("Received data: %d-%d-%d %d:%d:%d", result.year, - result.month, result.dayofmonth, - result.hour, result.minute, result.second); - dateTimeController.SetTime(result.year, result.month, result.dayofmonth, - 0, result.hour, result.minute, result.second, nrf_rtc_counter_get(portNRF_RTC_REG)); - } else { - NRF_LOG_INFO("Error retrieving current time: %d", error->status); - } - return 0; -} - -bool CurrentTimeClient::IsDiscovered() const { - return isDiscovered; -} - -uint16_t CurrentTimeClient::StartHandle() const { - return ctsStartHandle; -} - -uint16_t CurrentTimeClient::EndHandle() const { - return ctsEndHandle; -} - -uint16_t CurrentTimeClient::CurrentTimeHandle() const { - return currentTimeHandle; -}
\ No newline at end of file diff --git a/src/Components/Ble/MusicService.cpp b/src/Components/Ble/MusicService.cpp deleted file mode 100644 index 5ec76697..00000000 --- a/src/Components/Ble/MusicService.cpp +++ /dev/null @@ -1,130 +0,0 @@ -#include <SystemTask/SystemTask.h> -#include "MusicService.h" - -int MSCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { - auto musicService = static_cast<Pinetime::Controllers::MusicService*>(arg); - return musicService->OnCommand(conn_handle, attr_handle, ctxt); -} - -Pinetime::Controllers::MusicService::MusicService(Pinetime::System::SystemTask &system) : m_system(system) -{ - msUuid.value[11] = msId[0]; - msUuid.value[12] = msId[1]; - msEventCharUuid.value[11] = msEventCharId[0]; - msEventCharUuid.value[12] = msEventCharId[1]; - msStatusCharUuid.value[11] = msStatusCharId[0]; - msStatusCharUuid.value[12] = msStatusCharId[1]; - msTrackCharUuid.value[11] = msTrackCharId[0]; - msTrackCharUuid.value[12] = msTrackCharId[1]; - msArtistCharUuid.value[11] = msArtistCharId[0]; - msArtistCharUuid.value[12] = msArtistCharId[1]; - msAlbumCharUuid.value[11] = msAlbumCharId[0]; - msAlbumCharUuid.value[12] = msAlbumCharId[1]; - - characteristicDefinition[0] = { .uuid = (ble_uuid_t*)(&msEventCharUuid), - .access_cb = MSCallback, - .arg = this, - .flags = BLE_GATT_CHR_F_NOTIFY, - .val_handle = &m_eventHandle - }; - characteristicDefinition[1] = { .uuid = (ble_uuid_t*)(&msStatusCharUuid), - .access_cb = MSCallback, - .arg = this, - .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ - }; - characteristicDefinition[2] = { .uuid = (ble_uuid_t*)(&msTrackCharUuid), - .access_cb = MSCallback, - .arg = this, - .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ - }; - characteristicDefinition[3] = { .uuid = (ble_uuid_t*)(&msArtistCharUuid), - .access_cb = MSCallback, - .arg = this, - .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ - }; - characteristicDefinition[4] = { .uuid = (ble_uuid_t*)(&msAlbumCharUuid), - .access_cb = MSCallback, - .arg = this, - .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ - }; - characteristicDefinition[5] = {0}; - - serviceDefinition[0] = { - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = (ble_uuid_t *) &msUuid, - .characteristics = characteristicDefinition - }; - serviceDefinition[1] = {0}; - - m_artist = "Waiting for"; - m_album = ""; - m_track = "track information..."; -} - -void Pinetime::Controllers::MusicService::Init() -{ - int res = 0; - res = ble_gatts_count_cfg(serviceDefinition); - ASSERT(res == 0); - - res = ble_gatts_add_svcs(serviceDefinition); - ASSERT(res == 0); -} - -int Pinetime::Controllers::MusicService::OnCommand(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt) { - - if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - size_t notifSize = OS_MBUF_PKTLEN(ctxt->om); - uint8_t data[notifSize + 1]; - data[notifSize] = '\0'; - os_mbuf_copydata(ctxt->om, 0, notifSize, data); - char *s = (char *) &data[0]; - NRF_LOG_INFO("DATA : %s", s); - if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *)&msArtistCharUuid) == 0) { - m_artist = s; - } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *)&msTrackCharUuid) == 0) { - m_track = s; - } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *)&msAlbumCharUuid) == 0) { - m_album = s; - } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *)&msStatusCharUuid) == 0) { - m_status = s[0]; - } - } - return 0; -} - -std::string Pinetime::Controllers::MusicService::album() -{ - return m_album; -} - -std::string Pinetime::Controllers::MusicService::artist() -{ - return m_artist; -} - -std::string Pinetime::Controllers::MusicService::track() -{ - return m_track; -} - -unsigned char Pinetime::Controllers::MusicService::status() -{ - return m_status; -} - -void Pinetime::Controllers::MusicService::event(char event) -{ - auto *om = ble_hs_mbuf_from_flat(&event, 1); - int ret; - - uint16_t connectionHandle = m_system.nimble().connHandle(); - - if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) { - return; - } - - ret = ble_gattc_notify_custom(connectionHandle, m_eventHandle, om); -} - diff --git a/src/Components/Ble/MusicService.h b/src/Components/Ble/MusicService.h deleted file mode 100644 index ab6db572..00000000 --- a/src/Components/Ble/MusicService.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include <cstdint> -#include <array> -#include <host/ble_gap.h> -#include <host/ble_uuid.h> -#include <string> - -//c7e50000-78fc-48fe-8e23-43b37a1942d0 -#define MUSIC_SERVICE_UUID_BASE {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, 0x00, 0x00, 0xe5, 0xc7} - -namespace Pinetime { - namespace System { - class SystemTask; - } - namespace Controllers { - - class MusicService { - public: - MusicService(Pinetime::System::SystemTask &system); - void Init(); - int OnCommand(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt); - - std::string artist(); - std::string track(); - std::string album(); - unsigned char status(); - - void event(char event); - - static const char EVENT_MUSIC_OPEN = 0xe0; - static const char EVENT_MUSIC_PLAY = 0x00; - static const char EVENT_MUSIC_PAUSE = 0x01; - static const char EVENT_MUSIC_NEXT = 0x03; - static const char EVENT_MUSIC_PREV = 0x04; - static const char EVENT_MUSIC_VOLUP = 0x05; - static const char EVENT_MUSIC_VOLDOWN = 0x06; - static const char STATUS_MUSIC_PAUSED = 0x00; - static const char STATUS_MUSIC_PLAYING = 0x01; - - private: - static constexpr uint8_t msId[2] = {0x00, 0x01}; - static constexpr uint8_t msEventCharId[2] = {0x00, 0x02}; - static constexpr uint8_t msStatusCharId[2] = {0x00, 0x03}; - static constexpr uint8_t msArtistCharId[2] = {0x00, 0x04}; - static constexpr uint8_t msTrackCharId[2] = {0x00, 0x05}; - static constexpr uint8_t msAlbumCharId[2] = {0x00, 0x06}; - - ble_uuid128_t msUuid { - .u = { .type = BLE_UUID_TYPE_128 }, - .value = MUSIC_SERVICE_UUID_BASE - }; - - ble_uuid128_t msEventCharUuid { - .u = { .type = BLE_UUID_TYPE_128 }, - .value = MUSIC_SERVICE_UUID_BASE - }; - ble_uuid128_t msStatusCharUuid { - .u = { .type = BLE_UUID_TYPE_128 }, - .value = MUSIC_SERVICE_UUID_BASE - }; - ble_uuid128_t msArtistCharUuid { - .u = { .type = BLE_UUID_TYPE_128 }, - .value = MUSIC_SERVICE_UUID_BASE - }; - ble_uuid128_t msTrackCharUuid { - .u = { .type = BLE_UUID_TYPE_128 }, - .value = MUSIC_SERVICE_UUID_BASE - }; - ble_uuid128_t msAlbumCharUuid { - .u = { .type = BLE_UUID_TYPE_128 }, - .value = MUSIC_SERVICE_UUID_BASE - }; - - struct ble_gatt_chr_def characteristicDefinition[6]; - struct ble_gatt_svc_def serviceDefinition[2]; - - uint16_t m_eventHandle; - - std::string m_artist; - std::string m_album; - std::string m_track; - - unsigned char m_status; - - Pinetime::System::SystemTask& m_system; - - }; - } -} - diff --git a/src/Components/Ble/NotificationManager.cpp b/src/Components/Ble/NotificationManager.cpp deleted file mode 100644 index 0aea0697..00000000 --- a/src/Components/Ble/NotificationManager.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include <cstring> -#include "NotificationManager.h" - -using namespace Pinetime::Controllers; - -void NotificationManager::Push(Pinetime::Controllers::NotificationManager::Categories category, - const char *message, uint8_t currentMessageSize) { - // TODO handle edge cases on read/write index - auto checkedSize = std::min(currentMessageSize, uint8_t{18}); - auto& notif = notifications[writeIndex]; - std::memcpy(notif.message.data(), message, checkedSize); - notif.message[checkedSize] = '\0'; - notif.category = category; - - writeIndex = (writeIndex + 1 < TotalNbNotifications) ? writeIndex + 1 : 0; - if(!empty && writeIndex == readIndex) - readIndex = writeIndex + 1; -} - -NotificationManager::Notification Pinetime::Controllers::NotificationManager::Pop() { -// TODO handle edge cases on read/write index - NotificationManager::Notification notification = notifications[readIndex]; - - if(readIndex != writeIndex) { - readIndex = (readIndex + 1 < TotalNbNotifications) ? readIndex + 1 : 0; - } - - // TODO Check move optimization on return - return notification; -} diff --git a/src/Components/Ble/NotificationManager.h b/src/Components/Ble/NotificationManager.h deleted file mode 100644 index daa1571b..00000000 --- a/src/Components/Ble/NotificationManager.h +++ /dev/null @@ -1,29 +0,0 @@ -#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+1> message; - Categories category = Categories::Unknown; - }; - - void Push(Categories category, const char* message, uint8_t messageSize); - Notification Pop(); - - - private: - static constexpr uint8_t TotalNbNotifications = 5; - std::array<Notification, TotalNbNotifications> notifications; - uint8_t readIndex = 0; - uint8_t writeIndex = 0; - bool empty = true; - }; - } -}
\ No newline at end of file diff --git a/src/DisplayApp/Screens/Message.cpp b/src/DisplayApp/Screens/Message.cpp deleted file mode 100644 index b83cb751..00000000 --- a/src/DisplayApp/Screens/Message.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include <cstdio> -#include <libs/date/includes/date/date.h> -#include <Components/DateTime/DateTimeController.h> -#include <Version.h> -#include <libs/lvgl/src/lv_core/lv_obj.h> -#include <libs/lvgl/src/lv_font/lv_font.h> -#include <libs/lvgl/lvgl.h> -#include <libraries/log/nrf_log.h> -#include "Message.h" -#include <DisplayApp/DisplayApp.h> - - -using namespace Pinetime::Applications::Screens; - -extern lv_font_t jetbrains_mono_bold_20; - -static void event_handler(lv_obj_t * obj, lv_event_t event) { - Message* screen = static_cast<Message *>(obj->user_data); - screen->OnObjectEvent(obj, event); -} - -Message::Message(DisplayApp* app) : Screen(app) { - - backgroundLabel = lv_label_create(lv_scr_act(), NULL); - backgroundLabel->user_data = this; - - lv_obj_set_click(backgroundLabel, true); - lv_obj_set_event_cb(backgroundLabel, event_handler); - lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); - lv_obj_set_size(backgroundLabel, 240, 240); - lv_obj_set_pos(backgroundLabel, 0, 0); - lv_label_set_text(backgroundLabel, ""); - - button = lv_btn_create(lv_scr_act(), NULL); - lv_obj_set_event_cb(button, event_handler); - lv_obj_align(button, NULL, LV_ALIGN_CENTER, 0, -40); - button->user_data = this; - - label = lv_label_create(button, NULL); - lv_label_set_text(label, "Hello!"); - - labelClick = lv_label_create(lv_scr_act(), NULL); - lv_obj_align(labelClick, button, LV_ALIGN_OUT_BOTTOM_MID, 0, 30); - lv_label_set_text(labelClick, "0"); -} - -Message::~Message() { - lv_obj_clean(lv_scr_act()); -} - -bool Message::Refresh() { - if(previousClickCount != clickCount) { - lv_label_set_text_fmt(labelClick, "%d", clickCount); - previousClickCount = clickCount; - } - - return running; -} - -void Message::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { - if(obj == backgroundLabel) { - if(event == LV_EVENT_CLICKED) { - app->PushMessage(DisplayApp::Messages::SwitchScreen); - NRF_LOG_INFO("SCREEN"); - } - return ; - } - - if(event == LV_EVENT_CLICKED) { - NRF_LOG_INFO("Clicked"); - clickCount++; - } - else if(event == LV_EVENT_VALUE_CHANGED) { - NRF_LOG_INFO("Toggled"); - } -} - -bool Message::OnButtonPushed() { - running = false; - return true; -} diff --git a/src/DisplayApp/Screens/Message.h b/src/DisplayApp/Screens/Message.h deleted file mode 100644 index 3ace66fe..00000000 --- a/src/DisplayApp/Screens/Message.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include <cstdint> -#include "Screen.h" -#include <bits/unique_ptr.h> -#include <lvgl/src/lv_core/lv_style.h> - -namespace Pinetime { - namespace Applications { - namespace Screens { - class Message : public Screen{ - public: - explicit Message(DisplayApp* app); - ~Message() override; - bool Refresh() override; - bool OnButtonPushed(); - void OnObjectEvent(lv_obj_t* obj, lv_event_t event); - - private: - lv_obj_t * label; - lv_obj_t* backgroundLabel; - lv_obj_t * button; - lv_obj_t * labelClick; - - uint32_t clickCount = 0 ; - uint32_t previousClickCount = 0; - bool running = true; - }; - } - } -} diff --git a/src/DisplayApp/Screens/Music.cpp b/src/DisplayApp/Screens/Music.cpp deleted file mode 100644 index 9b7d198b..00000000 --- a/src/DisplayApp/Screens/Music.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include <libs/lvgl/lvgl.h> -#include "Music.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) -{ - Music* screen = static_cast<Music *>(obj->user_data); - screen->OnObjectEvent(obj, event); -} - -Music::Music(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::MusicService &music) : Screen(app), musicService(music) { - lv_obj_t * label; - - btnVolDown = lv_btn_create(lv_scr_act(), NULL); - btnVolDown->user_data = this; - lv_obj_set_event_cb(btnVolDown, event_handler); - lv_obj_align(btnVolDown, NULL, LV_ALIGN_IN_TOP_LEFT, 10, 10); - label = lv_label_create(btnVolDown, NULL); - lv_label_set_text(label, "v-"); - - btnVolUp = lv_btn_create(lv_scr_act(), NULL); - btnVolUp->user_data = this; - lv_obj_set_event_cb(btnVolUp, event_handler); - lv_obj_align(btnVolUp, NULL, LV_ALIGN_IN_TOP_RIGHT, -10, 10); - label = lv_label_create(btnVolUp, NULL); - lv_label_set_text(label, "v+"); - - btnPrev = lv_btn_create(lv_scr_act(), NULL); - btnPrev->user_data = this; - lv_obj_set_event_cb(btnPrev, event_handler); - lv_obj_set_size(btnPrev, LV_HOR_RES / 4, LV_VER_RES / 4); - lv_obj_align(btnPrev, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 10,-10); - label = lv_label_create(btnPrev, NULL); - lv_label_set_text(label, "<<"); - - btnPlayPause = lv_btn_create(lv_scr_act(), NULL); - btnPlayPause->user_data = this; - lv_obj_set_event_cb(btnPlayPause, event_handler); - lv_obj_set_size(btnPlayPause, LV_HOR_RES / 4, LV_VER_RES / 4); - lv_obj_align(btnPlayPause, NULL, LV_ALIGN_IN_BOTTOM_MID, 0,-10); - txtPlayPause = lv_label_create(btnPlayPause, NULL); - lv_label_set_text(txtPlayPause, ">"); - - btnNext = lv_btn_create(lv_scr_act(), NULL); - btnNext->user_data = this; - lv_obj_set_event_cb(btnNext, event_handler); - lv_obj_set_size(btnNext, LV_HOR_RES / 4, LV_VER_RES / 4); - lv_obj_align(btnNext, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, -10,-10); - label = lv_label_create(btnNext, NULL); - lv_label_set_text(label, ">>"); - - txtArtist = lv_label_create(lv_scr_act(), NULL); - lv_label_set_long_mode(txtArtist, LV_LABEL_LONG_SROLL); - lv_obj_align(txtArtist, NULL, LV_ALIGN_IN_LEFT_MID, 0,-20); - lv_label_set_text(txtArtist, "Artist Name"); - lv_label_set_align(txtArtist, LV_LABEL_ALIGN_CENTER); - lv_obj_set_width(txtArtist, LV_HOR_RES); - - txtTrack = lv_label_create(lv_scr_act(), NULL); - lv_label_set_long_mode(txtTrack, LV_LABEL_LONG_DOT); - lv_obj_align(txtTrack, NULL, LV_ALIGN_IN_LEFT_MID, 0,20); - lv_label_set_text(txtTrack, "This is a very long track name"); - lv_label_set_align(txtTrack, LV_LABEL_ALIGN_CENTER); - lv_obj_set_width(txtTrack, LV_HOR_RES); - - musicService.event(Controllers::MusicService::EVENT_MUSIC_OPEN); -} - -Music::~Music() { - lv_obj_clean(lv_scr_act()); -} - -bool Music::OnButtonPushed() { - running = false; - return true; -} - -bool Music::Refresh() { - - if (m_artist != musicService.artist()) { - m_artist = musicService.artist(); - lv_label_set_text(txtArtist, m_artist.data()); - } - if (m_track != musicService.track()) { - m_track = musicService.track(); - lv_label_set_text(txtTrack, m_track.data()); - } - if (m_album != musicService.album()) { - m_album = musicService.album(); - } - if (m_status != musicService.status()) { - m_status = musicService.status(); - } - if (m_status == Pinetime::Controllers::MusicService::STATUS_MUSIC_PLAYING) { - lv_label_set_text(txtPlayPause, "||"); - } else { - lv_label_set_text(txtPlayPause, ">"); - } - - return running; -} - -void Music::OnObjectEvent(lv_obj_t* obj, lv_event_t event) -{ - if (event == LV_EVENT_CLICKED) { - if (obj == btnVolDown) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLDOWN); - } else if (obj == btnVolUp) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLUP); - } else if (obj == btnPrev) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_PREV); - } else if (obj == btnPlayPause) { - if (m_status == Pinetime::Controllers::MusicService::STATUS_MUSIC_PLAYING) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_PAUSE); - } else { - musicService.event(Controllers::MusicService::EVENT_MUSIC_PLAY); - } - } else if (obj == btnNext) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_NEXT); - } - } -} diff --git a/src/DisplayApp/Screens/Music.h b/src/DisplayApp/Screens/Music.h deleted file mode 100644 index 95cac0f0..00000000 --- a/src/DisplayApp/Screens/Music.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include <cstdint> -#include <chrono> -#include <Components/Gfx/Gfx.h> -#include "Screen.h" -#include <bits/unique_ptr.h> -#include <libs/lvgl/src/lv_core/lv_style.h> -#include <libs/lvgl/src/lv_core/lv_obj.h> -#include <Components/Battery/BatteryController.h> -#include <Components/Ble/BleController.h> -#include "../../Version.h" -#include <Components/Ble/MusicService.h> -#include <string> - -namespace Pinetime { - namespace Applications { - namespace Screens { - - class Music : public Screen{ - public: - Music(DisplayApp* app, Pinetime::Controllers::MusicService &music); - ~Music() override; - - bool Refresh() override; - bool OnButtonPushed() override; - - void OnObjectEvent(lv_obj_t* obj, lv_event_t event); - - private: - lv_obj_t * btnPrev; - lv_obj_t * btnPlayPause; - lv_obj_t * btnNext; - lv_obj_t * btnVolDown; - lv_obj_t * btnVolUp; - lv_obj_t * txtArtist; - lv_obj_t * txtTrack; - lv_obj_t * txtPlayPause; - - bool running = true; - Pinetime::Controllers::MusicService &musicService; - std::string m_artist; - std::string m_album; - std::string m_track; - unsigned char m_status; - }; - } - } -} diff --git a/src/DisplayApp/Screens/Screen.h b/src/DisplayApp/Screens/Screen.h deleted file mode 100644 index d8902317..00000000 --- a/src/DisplayApp/Screens/Screen.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include "../TouchEvents.h" - -namespace Pinetime { - namespace Applications { - class DisplayApp; - namespace Screens { - class Screen { - public: - Screen(DisplayApp* app) : app{app} {} - virtual ~Screen() = default; - - // Return false if the app can be closed, true if it must continue to run - virtual bool Refresh() = 0; - - // Return false if the button hasn't been handled by the app, true if it has been handled - virtual bool OnButtonPushed() { return false; } - - // Return false if the event hasn't been handled by the app, true if it has been handled - virtual bool OnTouchEvent(TouchEvents event) { return false; } - - protected: - DisplayApp* app; - }; - } - } -} diff --git a/src/DisplayApp/Screens/ScreenList.cpp b/src/DisplayApp/Screens/ScreenList.cpp deleted file mode 100644 index 754d5f7e..00000000 --- a/src/DisplayApp/Screens/ScreenList.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include <libs/lvgl/lvgl.h> -#include <DisplayApp/DisplayApp.h> -#include "ScreenList.h" -#include "../../Version.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::Controllers::Ble& bleController, - Pinetime::Drivers::WatchdogView& watchdog) : - Screen(app), - dateTimeController{dateTimeController}, batteryController{batteryController}, - brightnessController{brightnessController}, bleController{bleController}, 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 "?"; - } - }(); - - // uptime - static constexpr uint32_t secondsInADay = 60*60*24; - static constexpr uint32_t secondsInAnHour = 60*60; - static constexpr uint32_t secondsInAMinute = 60; - uint32_t uptimeSeconds = dateTimeController.Uptime().count(); - uint32_t uptimeDays = (uptimeSeconds / secondsInADay); - uptimeSeconds = uptimeSeconds % secondsInADay; - uint32_t uptimeHours = uptimeSeconds / secondsInAnHour; - uptimeSeconds = uptimeSeconds % secondsInAnHour; - uint32_t uptimeMinutes = uptimeSeconds / secondsInAMinute; - uptimeSeconds = uptimeSeconds % secondsInAMinute; - // TODO handle more than 100 days of uptime - - sprintf(t1, "Pinetime\n" - "Version:%d.%d.%d\n" - "Build: %s\n" - " %s\n" - "Date: %02d/%02d/%04d\n" - "Time: %02d:%02d:%02d\n" - "Uptime: %02lud %02lu:%02lu:%02lu\n" - "Battery: %d%%\n" - "Backlight: %d/3\n" - "Last reset: %s\n", - Version::Major(), Version::Minor(), Version::Patch(), - __DATE__, __TIME__, - dateTimeController.Day(), dateTimeController.Month(), dateTimeController.Year(), - dateTimeController.Hours(), dateTimeController.Minutes(), dateTimeController.Seconds(), - uptimeDays, uptimeHours, uptimeMinutes, uptimeSeconds, - batteryPercent, brightness, resetReason); - - screens.emplace_back(t1); - - auto& bleAddr = bleController.Address(); - sprintf(t2, "BLE MAC: \n %2x:%2x:%2x:%2x:%2x:%2x", - bleAddr[5], bleAddr[4], bleAddr[3], bleAddr[2], bleAddr[1], bleAddr[0]); - screens.emplace_back(t2); - - strncpy(t3, "Hello from\nthe developper!", 27); - - screens.emplace_back(t3); - - auto &screen = screens[screenIndex]; - screen.Show(); -} - -ScreenList::~ScreenList() { - lv_obj_clean(lv_scr_act()); -} - -bool ScreenList::Refresh() { - auto &screen = screens[screenIndex]; - screen.Refresh(); - - return running; -} - -bool ScreenList::OnButtonPushed() { - running = false; - return true; -} - -bool ScreenList::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - switch (event) { - case TouchEvents::SwipeDown: - if (screenIndex > 0) { - app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down); - auto &oldScreen = screens[screenIndex]; - oldScreen.Hide(); - screenIndex--; - auto &newScreen = screens[screenIndex]; - newScreen.Show(); - } - return true; - case TouchEvents::SwipeUp: - app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up); - if (screenIndex < screens.size() - 1) { - auto &oldScreen = screens[screenIndex]; - oldScreen.Hide(); - screenIndex++; - auto &newScreen = screens[screenIndex]; - newScreen.Show(); - } - return true; - default: - return false; - } - return false; -} diff --git a/src/DisplayApp/Screens/Symbols.h b/src/DisplayApp/Screens/Symbols.h deleted file mode 100644 index 3104db87..00000000 --- a/src/DisplayApp/Screens/Symbols.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -namespace Pinetime { - namespace Applications { - namespace Screens { - namespace Symbols { - static constexpr char* batteryFull = "\xEF\x89\x80"; - static constexpr char* batteryEmpty = "\xEF\x89\x84"; - static constexpr char* batteryThreeQuarter = "\xEF\x89\x81"; - static constexpr char* batteryHalf = "\xEF\x89\x82"; - static constexpr char* batteryOneQuarter = "\xEF\x89\x83"; - static constexpr char* heartBeat = "\xEF\x88\x9E"; - static constexpr char* bluetoothFull = "\xEF\x8A\x93"; - static constexpr char* bluetooth = "\xEF\x8A\x94"; - static constexpr char* plug = "\xEF\x87\xA6"; - static constexpr char* shoe = "\xEF\x95\x8B"; - static constexpr char* clock = "\xEF\x80\x97"; - static constexpr char* info = "\xEF\x84\xA9"; - static constexpr char* list = "\xEF\x80\xBA"; - static constexpr char* sun = "\xEF\x86\x85"; - } - } - } -}
\ No newline at end of file diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp deleted file mode 100644 index c3a9d380..00000000 --- a/src/DisplayApp/Screens/Tile.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include <libs/lvgl/src/lv_core/lv_obj.h> -#include <libs/lvgl/src/lv_font/lv_font.h> -#include <libs/lvgl/lvgl.h> -#include "Tile.h" -#include <DisplayApp/DisplayApp.h> -#include "Symbols.h" -#include "../../Version.h" - -using namespace Pinetime::Applications::Screens; - -extern lv_font_t jetbrains_mono_bold_20; - -static void event_handler(lv_obj_t * obj, lv_event_t event) { - Tile* screen = static_cast<Tile *>(obj->user_data); - uint32_t* eventDataPtr = (uint32_t*) lv_event_get_data(); - uint32_t eventData = *eventDataPtr; - screen->OnObjectEvent(obj, event, eventData); -} - -static const char * btnm_map1[] = {Symbols::heartBeat, Symbols::shoe, Symbols::clock, "\n", Symbols::info, Symbols::list, Symbols::sun, ""}; - -Tile::Tile(DisplayApp* app) : Screen(app) { - modal.reset(new Modal(app)); - - btnm1 = lv_btnm_create(lv_scr_act(), NULL); - lv_btnm_set_map(btnm1, btnm_map1); - lv_obj_set_size(btnm1, LV_HOR_RES, LV_VER_RES); - - btnm1->user_data = this; - lv_obj_set_event_cb(btnm1, event_handler); -} - -Tile::~Tile() { - lv_obj_clean(lv_scr_act()); -} - -bool Tile::Refresh() { - return running; -} - -void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event, uint32_t buttonId) { - auto* tile = static_cast<Tile*>(obj->user_data); - if(event == LV_EVENT_VALUE_CHANGED) { - switch(buttonId) { - case 0: - tile->StartMeterApp(); - break; - case 1: - tile->StartGaugeApp(); - break; - case 2: - tile->StartClockApp(); - break; - case 3: - 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->StartBrightnessApp(); - - break; - } - clickCount++; - } -} - -bool Tile::OnButtonPushed() { - app->StartApp(DisplayApp::Apps::Clock); - running = false; - return true; -} - -void Tile::StartClockApp() { - app->StartApp(DisplayApp::Apps::Clock); - running = false; -} - -void Tile::StartSysInfoApp() { - app->StartApp(DisplayApp::Apps::SysInfo); - running = false; -} - -void Tile::StartBrightnessApp() { - app->StartApp(DisplayApp::Apps::Brightness); - running = false; -} - -void Tile::StartMeterApp() { - app->StartApp(DisplayApp::Apps::Meter); - running = false; -} - -void Tile::StartGaugeApp() { - app->StartApp(DisplayApp::Apps::Music); - running = false; -} - diff --git a/src/DisplayApp/Screens/Tile.h b/src/DisplayApp/Screens/Tile.h deleted file mode 100644 index a04b58a8..00000000 --- a/src/DisplayApp/Screens/Tile.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include <cstdint> -#include "Screen.h" -#include <bits/unique_ptr.h> -#include "Modal.h" -#include <lvgl/src/lv_core/lv_style.h> - -namespace Pinetime { - namespace Applications { - namespace Screens { - class Tile : public Screen { - public: - explicit Tile(DisplayApp* app); - ~Tile() override; - - bool Refresh() override; - bool OnButtonPushed() override; - - void OnObjectEvent(lv_obj_t* obj, lv_event_t event, uint32_t buttonId); - - private: - - lv_style_t* labelRelStyle; - lv_style_t* labelPrStyle; - lv_obj_t * label1; - lv_obj_t * label2; - lv_obj_t * label3; - - lv_obj_t* backgroundLabel; - lv_obj_t * button; - lv_obj_t * labelClick; - - lv_obj_t *tileview; - lv_obj_t * tile1; - lv_obj_t * tile2; - lv_obj_t * list; - lv_obj_t * list_btn; - lv_obj_t * tile3; - lv_obj_t * btn1; - lv_obj_t * btn2; - lv_obj_t * btn3; - - lv_obj_t * btnm1; - lv_obj_t * btnm2; - - uint32_t clickCount = 0 ; - uint32_t previousClickCount = 0; - void StartClockApp(); - void StartSysInfoApp(); - void StartMeterApp(); - void StartGaugeApp(); - bool running = true; - - std::unique_ptr<Modal> modal; - void StartBrightnessApp(); - }; - } - } -} diff --git a/src/Version.h.in b/src/Version.h.in index c68a03ce..6ff5938e 100644 --- a/src/Version.h.in +++ b/src/Version.h.in @@ -5,12 +5,14 @@ namespace Pinetime { class Version { public: - static uint32_t Major() {return major;} - static uint32_t Minor() {return minor;} - static uint32_t Patch() {return patch;} + static constexpr uint32_t Major() {return major;} + static constexpr uint32_t Minor() {return minor;} + static constexpr uint32_t Patch() {return patch;} + static constexpr const char* VersionString() {return versionString;} private: static constexpr uint32_t major = @PROJECT_VERSION_MAJOR@; static constexpr uint32_t minor = @PROJECT_VERSION_MINOR@; static constexpr uint32_t patch = @PROJECT_VERSION_PATCH@; + static constexpr const char* versionString = "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@"; }; }
\ No newline at end of file diff --git a/src/Components/Battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index 198ce5aa..571efae6 100644 --- a/src/Components/Battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -1,6 +1,7 @@ #include <drivers/include/nrfx_saadc.h> #include <hal/nrf_gpio.h> #include <libraries/log/nrf_log.h> +#include <algorithm> #include "BatteryController.h" using namespace Pinetime::Controllers; @@ -34,7 +35,9 @@ void Battery::Update() { // see https://forum.pine64.org/showthread.php?tid=8147 voltage = (value * 2.0f) / (1024/3.0f); - percentRemaining = ((voltage - 3.55)*100)*3.9; + percentRemaining = ((voltage - 3.55f)*100.0f)*3.9f; + percentRemaining = std::max(percentRemaining, 0.0f); + percentRemaining = std::min(percentRemaining, 100.0f); // 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); diff --git a/src/Components/Battery/BatteryController.h b/src/components/battery/BatteryController.h index f07648a9..f07648a9 100644 --- a/src/Components/Battery/BatteryController.h +++ b/src/components/battery/BatteryController.h diff --git a/src/components/ble/AlertNotificationClient.cpp b/src/components/ble/AlertNotificationClient.cpp new file mode 100644 index 00000000..abe41099 --- /dev/null +++ b/src/components/ble/AlertNotificationClient.cpp @@ -0,0 +1,194 @@ +#include <systemtask/SystemTask.h> +#include "NotificationManager.h" + +#include "AlertNotificationClient.h" + +using namespace Pinetime::Controllers; +constexpr ble_uuid16_t AlertNotificationClient::ansServiceUuid; +constexpr ble_uuid16_t AlertNotificationClient::supportedNewAlertCategoryUuid; +constexpr ble_uuid16_t AlertNotificationClient::supportedUnreadAlertCategoryUuid; +constexpr ble_uuid16_t AlertNotificationClient::newAlertUuid; +constexpr ble_uuid16_t AlertNotificationClient::unreadAlertStatusUuid; +constexpr ble_uuid16_t AlertNotificationClient::controlPointUuid; + +namespace { + int + OnDiscoveryEventCallback(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *service, + void *arg) { + auto client = static_cast<AlertNotificationClient *>(arg); + return client->OnDiscoveryEvent(conn_handle, error, service); + } + + int OnAlertNotificationCharacteristicDiscoveredCallback(uint16_t conn_handle, const struct ble_gatt_error *error, + const struct ble_gatt_chr *chr, void *arg) { + auto client = static_cast<AlertNotificationClient *>(arg); + return client->OnCharacteristicsDiscoveryEvent(conn_handle, error, chr); + } + + int OnAlertNotificationDescriptorDiscoveryEventCallback(uint16_t conn_handle, + const struct ble_gatt_error *error, + uint16_t chr_val_handle, + const struct ble_gatt_dsc *dsc, + void *arg) { + auto client = static_cast<AlertNotificationClient *>(arg); + return client->OnDescriptorDiscoveryEventCallback(conn_handle, error, chr_val_handle, dsc); + } + + int NewAlertSubcribeCallback(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) { + auto client = static_cast<AlertNotificationClient *>(arg); + return client->OnNewAlertSubcribe(conn_handle, error, attr); + } +} + +AlertNotificationClient::AlertNotificationClient(Pinetime::System::SystemTask &systemTask, + Pinetime::Controllers::NotificationManager ¬ificationManager) : + systemTask{systemTask}, notificationManager{notificationManager} { +} + +bool AlertNotificationClient::OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, + const ble_gatt_svc *service) { + if (service == nullptr && error->status == BLE_HS_EDONE) { + if (isDiscovered) { + NRF_LOG_INFO("ANS Discovery found, starting characteristics discovery"); + + ble_gattc_disc_all_chrs(connectionHandle, ansStartHandle, ansEndHandle, + OnAlertNotificationCharacteristicDiscoveredCallback, this); + } else { + NRF_LOG_INFO("ANS not found"); + onServiceDiscovered(connectionHandle); + } + return true; + } + + if (service != nullptr && ble_uuid_cmp(((ble_uuid_t *) &ansServiceUuid), &service->uuid.u) == 0) { + NRF_LOG_INFO("ANS discovered : 0x%x - 0x%x", service->start_handle, service->end_handle); + ansStartHandle = service->start_handle; + ansEndHandle = service->end_handle; + isDiscovered = true; + } + return false; +} + +int AlertNotificationClient::OnCharacteristicsDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, + const ble_gatt_chr *characteristic) { + if (error->status != 0 && error->status != BLE_HS_EDONE) { + NRF_LOG_INFO("ANS Characteristic discovery ERROR"); + onServiceDiscovered(connectionHandle); + return 0; + } + + if (characteristic == nullptr && error->status == BLE_HS_EDONE) { + NRF_LOG_INFO("ANS Characteristic discovery complete"); + if (isCharacteristicDiscovered) { + ble_gattc_disc_all_dscs(connectionHandle, + newAlertHandle, ansEndHandle, + OnAlertNotificationDescriptorDiscoveryEventCallback, this); + } else + onServiceDiscovered(connectionHandle); + } else { + if (characteristic != nullptr && + ble_uuid_cmp(((ble_uuid_t *) &supportedNewAlertCategoryUuid), &characteristic->uuid.u) == 0) { + NRF_LOG_INFO("ANS Characteristic discovered : supportedNewAlertCategoryUuid"); + supportedNewAlertCategoryHandle = characteristic->val_handle; + } else if (characteristic != nullptr && + ble_uuid_cmp(((ble_uuid_t *) &supportedUnreadAlertCategoryUuid), &characteristic->uuid.u) == 0) { + NRF_LOG_INFO("ANS Characteristic discovered : supportedUnreadAlertCategoryUuid"); + supportedUnreadAlertCategoryHandle = characteristic->val_handle; + } else if (characteristic != nullptr && + ble_uuid_cmp(((ble_uuid_t *) &newAlertUuid), &characteristic->uuid.u) == 0) { + NRF_LOG_INFO("ANS Characteristic discovered : newAlertUuid"); + newAlertHandle = characteristic->val_handle; + newAlertDefHandle = characteristic->def_handle; + isCharacteristicDiscovered = true; + } else if (characteristic != nullptr && + ble_uuid_cmp(((ble_uuid_t *) &unreadAlertStatusUuid), &characteristic->uuid.u) == 0) { + NRF_LOG_INFO("ANS Characteristic discovered : unreadAlertStatusUuid"); + unreadAlertStatusHandle = characteristic->val_handle; + } else if (characteristic != nullptr && + ble_uuid_cmp(((ble_uuid_t *) &controlPointUuid), &characteristic->uuid.u) == 0) { + NRF_LOG_INFO("ANS Characteristic discovered : controlPointUuid"); + controlPointHandle = characteristic->val_handle; + } else NRF_LOG_INFO("ANS Characteristic discovered : 0x%x", characteristic->val_handle); + } + return 0; +} + +int AlertNotificationClient::OnNewAlertSubcribe(uint16_t connectionHandle, const ble_gatt_error *error, + ble_gatt_attr *attribute) { + if (error->status == 0) { + NRF_LOG_INFO("ANS New alert subscribe OK"); + } else { + NRF_LOG_INFO("ANS New alert subscribe ERROR"); + } + onServiceDiscovered(connectionHandle); + + return 0; +} + +int AlertNotificationClient::OnDescriptorDiscoveryEventCallback(uint16_t connectionHandle, const ble_gatt_error *error, + uint16_t characteristicValueHandle, + const ble_gatt_dsc *descriptor) { + if (error->status == 0) { + if (characteristicValueHandle == newAlertHandle && + ble_uuid_cmp(((ble_uuid_t *) &newAlertUuid), &descriptor->uuid.u)) { + if (newAlertDescriptorHandle == 0) { + NRF_LOG_INFO("ANS Descriptor discovered : %d", descriptor->handle); + newAlertDescriptorHandle = descriptor->handle; + isDescriptorFound = true; + uint8_t value[2]; + value[0] = 1; + value[1] = 0; + ble_gattc_write_flat(connectionHandle, newAlertDescriptorHandle, value, sizeof(value), NewAlertSubcribeCallback, this); + } + } + } else { + if (!isDescriptorFound) + onServiceDiscovered(connectionHandle); + } + return 0; +} + +void AlertNotificationClient::OnNotification(ble_gap_event *event) { + if (event->notify_rx.attr_handle == newAlertHandle) { + constexpr size_t stringTerminatorSize = 1; // end of string '\0' + constexpr size_t headerSize = 3; + const auto maxMessageSize{NotificationManager::MaximumMessageSize()}; + const auto maxBufferSize{maxMessageSize + headerSize}; + + const auto dbgPacketLen = OS_MBUF_PKTLEN(event->notify_rx.om); + size_t bufferSize = min(dbgPacketLen + stringTerminatorSize, maxBufferSize); + auto messageSize = min(maxMessageSize, (bufferSize - headerSize)); + + NotificationManager::Notification notif; + os_mbuf_copydata(event->notify_rx.om, headerSize, messageSize - 1, notif.message.data()); + notif.message[messageSize - 1] = '\0'; + notif.category = Pinetime::Controllers::NotificationManager::Categories::SimpleAlert; + notificationManager.Push(std::move(notif)); + + systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification); + } +} + +void AlertNotificationClient::Reset() { + ansStartHandle = 0; + ansEndHandle = 0; + supportedNewAlertCategoryHandle = 0; + supportedUnreadAlertCategoryHandle = 0; + newAlertHandle = 0; + newAlertDescriptorHandle = 0; + newAlertDefHandle = 0; + unreadAlertStatusHandle = 0; + controlPointHandle = 0; + isDiscovered = false; + isCharacteristicDiscovered = false; + isDescriptorFound = false; +} + +void AlertNotificationClient::Discover(uint16_t connectionHandle, std::function<void(uint16_t)> onServiceDiscovered) { + NRF_LOG_INFO("[ANS] Starting discovery"); + this->onServiceDiscovered = onServiceDiscovered; + ble_gattc_disc_svc_by_uuid(connectionHandle, &ansServiceUuid.u, OnDiscoveryEventCallback, this); +} diff --git a/src/Components/Ble/AlertNotificationClient.h b/src/components/ble/AlertNotificationClient.h index ca4f4e94..bc0df51e 100644 --- a/src/Components/Ble/AlertNotificationClient.h +++ b/src/components/ble/AlertNotificationClient.h @@ -3,16 +3,12 @@ #include <cstdint> #include <array> #include <host/ble_gap.h> +#include "BleClient.h" namespace Pinetime { namespace Controllers { - int NewAlertSubcribeCallback(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg); - - class AlertNotificationClient { + class AlertNotificationClient : public BleClient { public: explicit AlertNotificationClient(Pinetime::System::SystemTask &systemTask, Pinetime::Controllers::NotificationManager ¬ificationManager); @@ -24,13 +20,9 @@ namespace Pinetime { int OnDescriptorDiscoveryEventCallback(uint16_t connectionHandle, const ble_gatt_error *error, uint16_t characteristicValueHandle, const ble_gatt_dsc *descriptor); void OnNotification(ble_gap_event *event); - bool IsDiscovered() const; - uint16_t StartHandle() const; - uint16_t EndHandle() const; - - static constexpr const ble_uuid16_t &Uuid() { return ansServiceUuid; } + void Reset(); + void Discover(uint16_t connectionHandle, std::function<void(uint16_t)> lambda) override; - uint16_t NewAlerthandle() const; private: static constexpr uint16_t ansServiceId{0x1811}; static constexpr uint16_t supportedNewAlertCategoryId = 0x2a47; @@ -64,18 +56,21 @@ namespace Pinetime { .value = controlPointId }; - uint16_t ansStartHandle; - uint16_t ansEndHandle; - uint16_t supportedNewAlertCategoryHandle; - uint16_t supportedUnreadAlertCategoryHandle; - uint16_t newAlertHandle; + uint16_t ansStartHandle = 0; + uint16_t ansEndHandle = 0; + uint16_t supportedNewAlertCategoryHandle = 0; + uint16_t supportedUnreadAlertCategoryHandle = 0; + uint16_t newAlertHandle = 0; uint16_t newAlertDescriptorHandle = 0; - uint16_t newAlertDefHandle; - uint16_t unreadAlertStatusHandle; - uint16_t controlPointHandle; + uint16_t newAlertDefHandle = 0; + uint16_t unreadAlertStatusHandle = 0; + uint16_t controlPointHandle = 0; bool isDiscovered = false; Pinetime::System::SystemTask &systemTask; Pinetime::Controllers::NotificationManager ¬ificationManager; + std::function<void(uint16_t)> onServiceDiscovered; + bool isCharacteristicDiscovered = false; + bool isDescriptorFound = false; }; } }
\ No newline at end of file diff --git a/src/Components/Ble/AlertNotificationService.cpp b/src/components/ble/AlertNotificationService.cpp index 0faa17c8..32711b92 100644 --- a/src/Components/Ble/AlertNotificationService.cpp +++ b/src/components/ble/AlertNotificationService.cpp @@ -1,7 +1,7 @@ #include <hal/nrf_rtc.h> #include "NotificationManager.h" -#include <SystemTask/SystemTask.h> +#include <systemtask/SystemTask.h> #include "AlertNotificationService.h" #include <cstring> @@ -26,8 +26,8 @@ void AlertNotificationService::Init() { ASSERT(res == 0); } -AlertNotificationService::AlertNotificationService ( Pinetime::System::SystemTask& systemTask, Pinetime::Controllers::NotificationManager& notificationManager ) : m_systemTask{systemTask}, m_notificationManager{notificationManager}, - characteristicDefinition{ +AlertNotificationService::AlertNotificationService ( System::SystemTask& systemTask, NotificationManager& notificationManager ) + : characteristicDefinition{ { .uuid = (ble_uuid_t *) &ansCharUuid, .access_cb = AlertNotificationCallback, @@ -38,7 +38,7 @@ AlertNotificationService::AlertNotificationService ( Pinetime::System::SystemTas 0 } }, - serviceDefinition{ + serviceDefinition{ { /* Device Information Service */ .type = BLE_GATT_SVC_TYPE_PRIMARY, @@ -48,34 +48,28 @@ AlertNotificationService::AlertNotificationService ( Pinetime::System::SystemTas { 0 }, - } -{ + }, systemTask{systemTask}, notificationManager{notificationManager} { } int AlertNotificationService::OnAlert(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt) { - if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - // TODO implement this with more memory safety (and constexpr) - static const size_t maxBufferSize{21}; - static const size_t maxMessageSize{18}; - size_t bufferSize = min(OS_MBUF_PKTLEN(ctxt->om), maxBufferSize); - - uint8_t data[bufferSize]; - os_mbuf_copydata(ctxt->om, 0, bufferSize, data); + constexpr size_t stringTerminatorSize = 1; // end of string '\0' + constexpr size_t headerSize = 3; + const auto maxMessageSize {NotificationManager::MaximumMessageSize()}; + const auto maxBufferSize{maxMessageSize + headerSize}; - char *s = (char *) &data[3]; - auto messageSize = min(maxMessageSize, (bufferSize-3)); + const auto dbgPacketLen = OS_MBUF_PKTLEN(ctxt->om); + size_t bufferSize = min(dbgPacketLen + stringTerminatorSize, maxBufferSize); + auto messageSize = min(maxMessageSize, (bufferSize-headerSize)); - for (int i = 0; i < messageSize-1; i++) { - if (s[i] == 0x00) { - s[i] = 0x0A; - } - } - s[messageSize-1] = '\0'; + NotificationManager::Notification notif; + os_mbuf_copydata(ctxt->om, headerSize, messageSize-1, notif.message.data()); + notif.message[messageSize-1] = '\0'; + notif.category = Pinetime::Controllers::NotificationManager::Categories::SimpleAlert; + notificationManager.Push(std::move(notif)); - m_notificationManager.Push(Pinetime::Controllers::NotificationManager::Categories::SimpleAlert, s, messageSize); - m_systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification); + systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification); } return 0; } diff --git a/src/Components/Ble/AlertNotificationService.h b/src/components/ble/AlertNotificationService.h index 53cb44cc..1b8c4989 100644 --- a/src/Components/Ble/AlertNotificationService.h +++ b/src/components/ble/AlertNotificationService.h @@ -32,8 +32,8 @@ namespace Pinetime { struct ble_gatt_chr_def characteristicDefinition[2]; struct ble_gatt_svc_def serviceDefinition[2]; - Pinetime::System::SystemTask &m_systemTask; - NotificationManager &m_notificationManager; + Pinetime::System::SystemTask &systemTask; + NotificationManager ¬ificationManager; }; } } diff --git a/src/components/ble/BatteryInformationService.cpp b/src/components/ble/BatteryInformationService.cpp new file mode 100644 index 00000000..f7d895c2 --- /dev/null +++ b/src/components/ble/BatteryInformationService.cpp @@ -0,0 +1,62 @@ +#include "BatteryInformationService.h" +#include "components/battery/BatteryController.h" + +using namespace Pinetime::Controllers; + +constexpr ble_uuid16_t BatteryInformationService::batteryInformationServiceUuid; +constexpr ble_uuid16_t BatteryInformationService::batteryLevelUuid; + + + +int BatteryInformationServiceCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { + auto* batteryInformationService = static_cast<BatteryInformationService*>(arg); + return batteryInformationService->OnBatteryServiceRequested(conn_handle, attr_handle, ctxt); +} + +BatteryInformationService::BatteryInformationService(Controllers::Battery& batteryController) : + batteryController{batteryController}, + characteristicDefinition{ + { + .uuid = (ble_uuid_t *) &batteryLevelUuid, + .access_cb = BatteryInformationServiceCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_READ, + .val_handle = &batteryLevelHandle + }, + { + 0 + } + }, + serviceDefinition{ + { + /* Device Information Service */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = (ble_uuid_t *) &batteryInformationServiceUuid, + .characteristics = characteristicDefinition + }, + { + 0 + }, + }{ + +} + +void BatteryInformationService::Init() { + int res = 0; + res = ble_gatts_count_cfg(serviceDefinition); + ASSERT(res == 0); + + res = ble_gatts_add_svcs(serviceDefinition); + ASSERT(res == 0); +} + +int BatteryInformationService::OnBatteryServiceRequested(uint16_t connectionHandle, uint16_t attributeHandle, + ble_gatt_access_ctxt *context) { + if(attributeHandle == batteryLevelHandle) { + NRF_LOG_INFO("BATTERY : handle = %d", batteryLevelHandle); + static uint8_t batteryValue = batteryController.PercentRemaining(); + int res = os_mbuf_append(context->om, &batteryValue, 1); + return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + return 0; +}
\ No newline at end of file diff --git a/src/components/ble/BatteryInformationService.h b/src/components/ble/BatteryInformationService.h new file mode 100644 index 00000000..74b2222c --- /dev/null +++ b/src/components/ble/BatteryInformationService.h @@ -0,0 +1,40 @@ +#pragma once +#include <host/ble_gap.h> + +namespace Pinetime { + namespace System { + class SystemTask; + } + namespace Controllers { + class Battery; + class BatteryInformationService { + public: + BatteryInformationService(Controllers::Battery& batteryController); + void Init(); + + int + OnBatteryServiceRequested(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt *context); + + private: + Controllers::Battery& batteryController; + static constexpr uint16_t batteryInformationServiceId {0x180F}; + static constexpr uint16_t batteryLevelId {0x2A19}; + + static constexpr ble_uuid16_t batteryInformationServiceUuid { + .u {.type = BLE_UUID_TYPE_16}, + .value = batteryInformationServiceId + }; + + static constexpr ble_uuid16_t batteryLevelUuid { + .u {.type = BLE_UUID_TYPE_16}, + .value = batteryLevelId + }; + + struct ble_gatt_chr_def characteristicDefinition[3]; + struct ble_gatt_svc_def serviceDefinition[2]; + + uint16_t batteryLevelHandle; + + }; + } +} diff --git a/src/components/ble/BleClient.h b/src/components/ble/BleClient.h new file mode 100644 index 00000000..559f6c8d --- /dev/null +++ b/src/components/ble/BleClient.h @@ -0,0 +1,12 @@ +#pragma once + +#include <functional> + +namespace Pinetime { + namespace Controllers{ + class BleClient { + public: + virtual void Discover(uint16_t connectionHandle, std::function<void(uint16_t)> lambda) = 0; + }; + } +}
\ No newline at end of file diff --git a/src/Components/Ble/BleController.cpp b/src/components/ble/BleController.cpp index 2b396e12..2b396e12 100644 --- a/src/Components/Ble/BleController.cpp +++ b/src/components/ble/BleController.cpp diff --git a/src/Components/Ble/BleController.h b/src/components/ble/BleController.h index 3f52ea25..3f52ea25 100644 --- a/src/Components/Ble/BleController.h +++ b/src/components/ble/BleController.h diff --git a/src/components/ble/CurrentTimeClient.cpp b/src/components/ble/CurrentTimeClient.cpp new file mode 100644 index 00000000..92f9374b --- /dev/null +++ b/src/components/ble/CurrentTimeClient.cpp @@ -0,0 +1,111 @@ +#include <hal/nrf_rtc.h> +#include "CurrentTimeClient.h" + +using namespace Pinetime::Controllers; + +constexpr ble_uuid16_t CurrentTimeClient::ctsServiceUuid; +constexpr ble_uuid16_t CurrentTimeClient::currentTimeCharacteristicUuid; + +namespace { + int OnDiscoveryEventCallback(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *service, void *arg) { + auto client = static_cast<CurrentTimeClient *>(arg); + return client->OnDiscoveryEvent(conn_handle, error, service); + } + + int OnCurrentTimeCharacteristicDiscoveredCallback(uint16_t conn_handle, const struct ble_gatt_error *error, + const struct ble_gatt_chr *chr, void *arg) { + auto client = static_cast<CurrentTimeClient *>(arg); + return client->OnCharacteristicDiscoveryEvent(conn_handle, error, chr); + } + + int CurrentTimeReadCallback(uint16_t conn_handle, const struct ble_gatt_error *error, struct ble_gatt_attr *attr, void *arg) { + auto client = static_cast<CurrentTimeClient *>(arg); + return client->OnCurrentTimeReadResult(conn_handle, error, attr); + } +} + +CurrentTimeClient::CurrentTimeClient(DateTime &dateTimeController) : dateTimeController{dateTimeController} { + +} + +void CurrentTimeClient::Init() { + +} + +bool CurrentTimeClient::OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, + const ble_gatt_svc *service) { + if (service == nullptr && error->status == BLE_HS_EDONE) { + if (isDiscovered) { + NRF_LOG_INFO("CTS found, starting characteristics discovery"); + + ble_gattc_disc_all_chrs(connectionHandle, ctsStartHandle, ctsEndHandle, + OnCurrentTimeCharacteristicDiscoveredCallback, this); + } else { + NRF_LOG_INFO("CTS not found"); + onServiceDiscovered(connectionHandle); + } + return true; + } + + if (service != nullptr && ble_uuid_cmp(((ble_uuid_t *) &ctsServiceUuid), &service->uuid.u) == 0) { + NRF_LOG_INFO("CTS discovered : 0x%x - 0x%x", service->start_handle, service->end_handle); + isDiscovered = true; + ctsStartHandle = service->start_handle; + ctsEndHandle = service->end_handle; + return false; + } + return false; +} + +int CurrentTimeClient::OnCharacteristicDiscoveryEvent(uint16_t conn_handle, const ble_gatt_error *error, + const ble_gatt_chr *characteristic) { + if (characteristic == nullptr && error->status == BLE_HS_EDONE) { + if (isCharacteristicDiscovered) { + NRF_LOG_INFO("CTS Characteristic discovery complete, fetching time"); + ble_gattc_read(conn_handle, currentTimeHandle, CurrentTimeReadCallback, this); + } else { + NRF_LOG_INFO("CTS Characteristic discovery unsuccessful"); + onServiceDiscovered(conn_handle); + } + + return 0; + } + + if (characteristic != nullptr && + ble_uuid_cmp(((ble_uuid_t *) ¤tTimeCharacteristicUuid), &characteristic->uuid.u) == 0) { + NRF_LOG_INFO("CTS Characteristic discovered : 0x%x", characteristic->val_handle); + isCharacteristicDiscovered = true; + currentTimeHandle = characteristic->val_handle; + } + return 0; +} + +int CurrentTimeClient::OnCurrentTimeReadResult(uint16_t conn_handle, const ble_gatt_error *error, + const ble_gatt_attr *attribute) { + if (error->status == 0) { + // TODO check that attribute->handle equals the handle discovered in OnCharacteristicDiscoveryEvent + CtsData result; + os_mbuf_copydata(attribute->om, 0, sizeof(CtsData), &result); + NRF_LOG_INFO("Received data: %d-%d-%d %d:%d:%d", result.year, + result.month, result.dayofmonth, + result.hour, result.minute, result.second); + dateTimeController.SetTime(result.year, result.month, result.dayofmonth, + 0, result.hour, result.minute, result.second, nrf_rtc_counter_get(portNRF_RTC_REG)); + } else { + NRF_LOG_INFO("Error retrieving current time: %d", error->status); + } + + onServiceDiscovered(conn_handle); + return 0; +} + +void CurrentTimeClient::Reset() { + isDiscovered = false; + isCharacteristicDiscovered = false; +} + +void CurrentTimeClient::Discover(uint16_t connectionHandle, std::function<void(uint16_t)> onServiceDiscovered) { + NRF_LOG_INFO("[CTS] Starting discovery"); + this->onServiceDiscovered = onServiceDiscovered; + ble_gattc_disc_svc_by_uuid(connectionHandle, &ctsServiceUuid.u, OnDiscoveryEventCallback, this); +} diff --git a/src/Components/Ble/CurrentTimeClient.h b/src/components/ble/CurrentTimeClient.h index fabcdaca..93139399 100644 --- a/src/Components/Ble/CurrentTimeClient.h +++ b/src/components/ble/CurrentTimeClient.h @@ -1,27 +1,28 @@ #pragma once #include <cstdint> #include <array> -#include <Components/DateTime/DateTimeController.h> + +#include "components/datetime/DateTimeController.h" +#include "BleClient.h" #include <host/ble_gap.h> namespace Pinetime { namespace Controllers { - class CurrentTimeClient { + class CurrentTimeClient : public BleClient { public: explicit CurrentTimeClient(DateTime& dateTimeController); void Init(); + void Reset(); bool OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, const ble_gatt_svc *service); int OnCharacteristicDiscoveryEvent(uint16_t conn_handle, const ble_gatt_error *error, const ble_gatt_chr *characteristic); int OnCurrentTimeReadResult(uint16_t conn_handle, const ble_gatt_error *error, const ble_gatt_attr *attribute); - bool IsDiscovered() const; - uint16_t StartHandle() const; - uint16_t EndHandle() const; - uint16_t CurrentTimeHandle() const; static constexpr const ble_uuid16_t* Uuid() { return &CurrentTimeClient::ctsServiceUuid; } static constexpr const ble_uuid16_t* CurrentTimeCharacteristicUuid() { return &CurrentTimeClient::currentTimeCharacteristicUuid; } - private: + void Discover(uint16_t connectionHandle, std::function<void(uint16_t)> lambda) override; + + private: typedef struct __attribute__((packed)) { uint16_t year; uint8_t month; @@ -45,11 +46,14 @@ namespace Pinetime { .value = currentTimeCharacteristicId }; - uint16_t currentTimeHandle; DateTime& dateTimeController; bool isDiscovered = false; uint16_t ctsStartHandle; uint16_t ctsEndHandle; + + bool isCharacteristicDiscovered = false; + uint16_t currentTimeHandle; + std::function<void(uint16_t)> onServiceDiscovered; }; } }
\ No newline at end of file diff --git a/src/Components/Ble/CurrentTimeService.cpp b/src/components/ble/CurrentTimeService.cpp index 80ad9c25..3a6264e2 100644 --- a/src/Components/Ble/CurrentTimeService.cpp +++ b/src/components/ble/CurrentTimeService.cpp @@ -57,7 +57,7 @@ int CurrentTimeService::OnTimeAccessed(uint16_t conn_handle, uint16_t attr_handl return 0; } -CurrentTimeService::CurrentTimeService(DateTime &dateTimeController) : m_dateTimeController{dateTimeController}, +CurrentTimeService::CurrentTimeService(DateTime &dateTimeController) : characteristicDefinition{ { .uuid = (ble_uuid_t *) &ctChrUuid, @@ -80,8 +80,7 @@ CurrentTimeService::CurrentTimeService(DateTime &dateTimeController) : m_dateTim { 0 }, - } - { + }, m_dateTimeController{dateTimeController} { } diff --git a/src/Components/Ble/CurrentTimeService.h b/src/components/ble/CurrentTimeService.h index 58bc5ba6..a6be9647 100644 --- a/src/Components/Ble/CurrentTimeService.h +++ b/src/components/ble/CurrentTimeService.h @@ -1,7 +1,8 @@ #pragma once #include <cstdint> #include <array> -#include <Components/DateTime/DateTimeController.h> + +#include "components/datetime/DateTimeController.h" #include <host/ble_gap.h> namespace Pinetime { diff --git a/src/Components/Ble/DeviceInformationService.cpp b/src/components/ble/DeviceInformationService.cpp index c1d55541..406db1cf 100644 --- a/src/Components/Ble/DeviceInformationService.cpp +++ b/src/components/ble/DeviceInformationService.cpp @@ -8,6 +8,8 @@ constexpr ble_uuid16_t DeviceInformationService::serialNumberUuid; constexpr ble_uuid16_t DeviceInformationService::fwRevisionUuid; constexpr ble_uuid16_t DeviceInformationService::deviceInfoUuid; constexpr ble_uuid16_t DeviceInformationService::hwRevisionUuid; +constexpr ble_uuid16_t DeviceInformationService::swRevisionUuid; + int DeviceInformationCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { auto deviceInformationService = static_cast<DeviceInformationService*>(arg); @@ -44,6 +46,9 @@ int DeviceInformationService::OnDeviceInfoRequested(uint16_t conn_handle, uint16 case hwRevisionId: str = hwRevision; break; + case swRevisionId: + str = swRevision; + break; default: return BLE_ATT_ERR_UNLIKELY; } @@ -85,6 +90,12 @@ DeviceInformationService::DeviceInformationService() : .flags = BLE_GATT_CHR_F_READ, }, { + .uuid = (ble_uuid_t *) &swRevisionUuid, + .access_cb = DeviceInformationCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_READ, + }, + { 0 } }, diff --git a/src/Components/Ble/DeviceInformationService.h b/src/components/ble/DeviceInformationService.h index d768da8e..25ab8402 100644 --- a/src/Components/Ble/DeviceInformationService.h +++ b/src/components/ble/DeviceInformationService.h @@ -3,6 +3,7 @@ #include <array> #include <host/ble_gap.h> +#include <Version.h> namespace Pinetime { namespace Controllers { @@ -21,12 +22,15 @@ namespace Pinetime { static constexpr uint16_t serialNumberId {0x2a25}; static constexpr uint16_t fwRevisionId {0x2a26}; static constexpr uint16_t hwRevisionId {0x2a27}; + static constexpr uint16_t swRevisionId {0x2a28}; + + static constexpr const char* manufacturerName = "PINE64"; + static constexpr const char* modelNumber = "PineTime"; + static constexpr const char* hwRevision = "1.0.0"; + static constexpr const char* serialNumber = "0"; + static constexpr const char* fwRevision = Version::VersionString(); + static constexpr const char* swRevision = "InfiniTime"; - static constexpr char* manufacturerName = "Codingfield"; - static constexpr char* modelNumber = "1"; - static constexpr char* serialNumber = "9.8.7.6.5.4"; - static constexpr char* fwRevision = "0.7.0"; - static constexpr char* hwRevision = "1.0.0"; static constexpr ble_uuid16_t deviceInfoUuid { .u { .type = BLE_UUID_TYPE_16 }, @@ -58,7 +62,12 @@ namespace Pinetime { .value = hwRevisionId }; - struct ble_gatt_chr_def characteristicDefinition[6]; + static constexpr ble_uuid16_t swRevisionUuid { + .u {.type = BLE_UUID_TYPE_16}, + .value = swRevisionId + }; + + struct ble_gatt_chr_def characteristicDefinition[7]; struct ble_gatt_svc_def serviceDefinition[2]; diff --git a/src/Components/Ble/DfuService.cpp b/src/components/ble/DfuService.cpp index c6d8493f..4dec5141 100644 --- a/src/Components/Ble/DfuService.cpp +++ b/src/components/ble/DfuService.cpp @@ -1,6 +1,7 @@ -#include <Components/Ble/BleController.h> -#include <SystemTask/SystemTask.h> #include <cstring> + +#include "components/ble/BleController.h" +#include "systemtask/SystemTask.h" #include "DfuService.h" using namespace Pinetime::Controllers; @@ -394,14 +395,14 @@ void DfuService::DfuImage::WriteMagicNumber() { } void DfuService::DfuImage::Erase() { - for (int erased = 0; erased < maxSize; erased += 0x1000) { + for (size_t erased = 0; erased < maxSize; erased += 0x1000) { spiNorFlash.SectorErase(writeOffset + erased); } } bool DfuService::DfuImage::Validate() { uint32_t chunkSize = 200; - int currentOffset = 0; + size_t currentOffset = 0; uint16_t crc = 0; bool first = true; diff --git a/src/Components/Ble/DfuService.h b/src/components/ble/DfuService.h index d7ba460c..d7ba460c 100644 --- a/src/Components/Ble/DfuService.h +++ b/src/components/ble/DfuService.h diff --git a/src/components/ble/ImmediateAlertService.cpp b/src/components/ble/ImmediateAlertService.cpp new file mode 100644 index 00000000..e2cee308 --- /dev/null +++ b/src/components/ble/ImmediateAlertService.cpp @@ -0,0 +1,82 @@ +#include <systemtask/SystemTask.h> +#include <cstring> +#include "ImmediateAlertService.h" +#include "AlertNotificationService.h" + +using namespace Pinetime::Controllers; + +constexpr ble_uuid16_t ImmediateAlertService::immediateAlertServiceUuid; +constexpr ble_uuid16_t ImmediateAlertService::alertLevelUuid; + +namespace { + int AlertLevelCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { + auto *immediateAlertService = static_cast<ImmediateAlertService *>(arg); + return immediateAlertService->OnAlertLevelChanged(conn_handle, attr_handle, ctxt); + } + + const char* ToString(ImmediateAlertService::Levels level) { + switch (level) { + case ImmediateAlertService::Levels::NoAlert: return "Alert : None"; + case ImmediateAlertService::Levels::HighAlert: return "Alert : High"; + case ImmediateAlertService::Levels::MildAlert: return "Alert : Mild"; + default: return ""; + } + } +} + +ImmediateAlertService::ImmediateAlertService(Pinetime::System::SystemTask &systemTask, + Pinetime::Controllers::NotificationManager ¬ificationManager) : + systemTask{systemTask}, + notificationManager{notificationManager}, + characteristicDefinition{ + { + .uuid = (ble_uuid_t *) &alertLevelUuid, + .access_cb = AlertLevelCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + .val_handle = &alertLevelHandle + }, + { + 0 + } + }, + serviceDefinition{ + { + /* Device Information Service */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = (ble_uuid_t *) &immediateAlertServiceUuid, + .characteristics = characteristicDefinition + }, + { + 0 + }, + }{ + +} + +void ImmediateAlertService::Init() { + int res = 0; + res = ble_gatts_count_cfg(serviceDefinition); + ASSERT(res == 0); + + res = ble_gatts_add_svcs(serviceDefinition); + ASSERT(res == 0); +} + +int ImmediateAlertService::OnAlertLevelChanged(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt *context) { + if(attributeHandle == alertLevelHandle) { + if(context->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + auto alertLevel = static_cast<Levels>(context->om->om_data[0]); + auto* alertString = ToString(alertLevel); + + NotificationManager::Notification notif; + std::memcpy(notif.message.data(), alertString, strlen(alertString)); + notif.category = Pinetime::Controllers::NotificationManager::Categories::SimpleAlert; + notificationManager.Push(std::move(notif)); + + systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification); + } + } + + return 0; +}
\ No newline at end of file diff --git a/src/components/ble/ImmediateAlertService.h b/src/components/ble/ImmediateAlertService.h new file mode 100644 index 00000000..c42846c4 --- /dev/null +++ b/src/components/ble/ImmediateAlertService.h @@ -0,0 +1,46 @@ +#pragma once +#include <host/ble_gap.h> + +namespace Pinetime { + namespace System { + class SystemTask; + } + namespace Controllers { + class NotificationManager; + class ImmediateAlertService { + public: + enum class Levels : uint8_t { + NoAlert = 0, + MildAlert = 1, + HighAlert = 2 + }; + + ImmediateAlertService(Pinetime::System::SystemTask &systemTask, + Pinetime::Controllers::NotificationManager ¬ificationManager); + void Init(); + int OnAlertLevelChanged(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt *context); + + private: + Pinetime::System::SystemTask& systemTask; + NotificationManager& notificationManager; + + static constexpr uint16_t immediateAlertServiceId {0x1802}; + static constexpr uint16_t alertLevelId {0x2A06}; + + static constexpr ble_uuid16_t immediateAlertServiceUuid { + .u {.type = BLE_UUID_TYPE_16}, + .value = immediateAlertServiceId + }; + + static constexpr ble_uuid16_t alertLevelUuid { + .u {.type = BLE_UUID_TYPE_16}, + .value = alertLevelId + }; + + struct ble_gatt_chr_def characteristicDefinition[3]; + struct ble_gatt_svc_def serviceDefinition[2]; + + uint16_t alertLevelHandle; + }; + } +} diff --git a/src/components/ble/MusicService.cpp b/src/components/ble/MusicService.cpp new file mode 100644 index 00000000..84f2972b --- /dev/null +++ b/src/components/ble/MusicService.cpp @@ -0,0 +1,225 @@ +/* Copyright (C) 2020 JF, Adam Pigg, Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ +#include <systemtask/SystemTask.h> +#include "MusicService.h" + +int MSCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { + auto musicService = static_cast<Pinetime::Controllers::MusicService *>(arg); + return musicService->OnCommand(conn_handle, attr_handle, ctxt); +} + +Pinetime::Controllers::MusicService::MusicService(Pinetime::System::SystemTask &system) : m_system(system) { + msUuid.value[11] = msId[0]; + msUuid.value[12] = msId[1]; + msEventCharUuid.value[11] = msEventCharId[0]; + msEventCharUuid.value[12] = msEventCharId[1]; + msStatusCharUuid.value[11] = msStatusCharId[0]; + msStatusCharUuid.value[12] = msStatusCharId[1]; + msTrackCharUuid.value[11] = msTrackCharId[0]; + msTrackCharUuid.value[12] = msTrackCharId[1]; + msArtistCharUuid.value[11] = msArtistCharId[0]; + msArtistCharUuid.value[12] = msArtistCharId[1]; + msAlbumCharUuid.value[11] = msAlbumCharId[0]; + msAlbumCharUuid.value[12] = msAlbumCharId[1]; + msPositionCharUuid.value[11] = msPositionCharId[0]; + msPositionCharUuid.value[12] = msPositionCharId[1]; + msTotalLengthCharUuid.value[11] = msTotalLengthCharId[0]; + msTotalLengthCharUuid.value[12] = msTotalLengthCharId[1]; + msTrackNumberCharUuid.value[11] = msTrackNumberCharId[0]; + msTrackNumberCharUuid.value[12] = msTrackNumberCharId[1]; + msTrackTotalCharUuid.value[11] = msTrackTotalCharId[0]; + msTrackTotalCharUuid.value[12] = msTrackTotalCharId[1]; + msPlaybackSpeedCharUuid.value[11] = msPlaybackSpeedCharId[0]; + msPlaybackSpeedCharUuid.value[12] = msPlaybackSpeedCharId[1]; + msRepeatCharUuid.value[11] = msRepeatCharId[0]; + msRepeatCharUuid.value[12] = msRepeatCharId[1]; + msShuffleCharUuid.value[11] = msShuffleCharId[0]; + msShuffleCharUuid.value[12] = msShuffleCharId[1]; + + characteristicDefinition[0] = {.uuid = (ble_uuid_t *) (&msEventCharUuid), + .access_cb = MSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_NOTIFY, + .val_handle = &eventHandle + }; + characteristicDefinition[1] = {.uuid = (ble_uuid_t *) (&msStatusCharUuid), + .access_cb = MSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ + }; + characteristicDefinition[2] = {.uuid = (ble_uuid_t *) (&msTrackCharUuid), + .access_cb = MSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ + }; + characteristicDefinition[3] = {.uuid = (ble_uuid_t *) (&msArtistCharUuid), + .access_cb = MSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ + }; + characteristicDefinition[4] = {.uuid = (ble_uuid_t *) (&msAlbumCharUuid), + .access_cb = MSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ + }; + characteristicDefinition[5] = {.uuid = (ble_uuid_t *) (&msPositionCharUuid), + .access_cb = MSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ + }; + characteristicDefinition[6] = {.uuid = (ble_uuid_t *) (&msTotalLengthCharUuid), + .access_cb = MSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ + }; + characteristicDefinition[7] = {.uuid = (ble_uuid_t *) (&msTotalLengthCharUuid), + .access_cb = MSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ + }; + characteristicDefinition[8] = {.uuid = (ble_uuid_t *) (&msTrackNumberCharUuid), + .access_cb = MSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ + }; + characteristicDefinition[9] = {.uuid = (ble_uuid_t *) (&msTrackTotalCharUuid), + .access_cb = MSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ + }; + characteristicDefinition[10] = {.uuid = (ble_uuid_t *) (&msPlaybackSpeedCharUuid), + .access_cb = MSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ + }; + characteristicDefinition[11] = {.uuid = (ble_uuid_t *) (&msRepeatCharUuid), + .access_cb = MSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ + }; + characteristicDefinition[12] = {.uuid = (ble_uuid_t *) (&msShuffleCharUuid), + .access_cb = MSCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ + }; + characteristicDefinition[13] = {0}; + + serviceDefinition[0] = { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = (ble_uuid_t *) &msUuid, + .characteristics = characteristicDefinition + }; + serviceDefinition[1] = {0}; + + artistName = "Waiting for"; + albumName = ""; + trackName = "track information..."; + playing = false; + repeat = false; + shuffle = false; + playbackSpeed = 1.0f; + trackProgress = 0; + trackLength = 0; +} + +void Pinetime::Controllers::MusicService::Init() { + int res = 0; + res = ble_gatts_count_cfg(serviceDefinition); + ASSERT(res == 0); + + res = ble_gatts_add_svcs(serviceDefinition); + ASSERT(res == 0); +} + +int Pinetime::Controllers::MusicService::OnCommand(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt) { + + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + size_t notifSize = OS_MBUF_PKTLEN(ctxt->om); + uint8_t data[notifSize + 1]; + data[notifSize] = '\0'; + os_mbuf_copydata(ctxt->om, 0, notifSize, data); + char *s = (char *) &data[0]; + NRF_LOG_INFO("DATA : %s", s); + if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *) &msArtistCharUuid) == 0) { + artistName = s; + } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *) &msTrackCharUuid) == 0) { + trackName = s; + } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *) &msAlbumCharUuid) == 0) { + albumName = s; + } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *) &msStatusCharUuid) == 0) { + playing = s[0]; + } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *) &msRepeatCharUuid) == 0) { + repeat = s[0]; + } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *) &msShuffleCharUuid) == 0) { + shuffle = s[0]; + } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *) &msPositionCharUuid) == 0) { + trackProgress = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]; + } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *) &msTotalLengthCharUuid) == 0) { + trackLength = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]; + } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *) &msTrackNumberCharUuid) == 0) { + trackNumber = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]; + } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *) &msTrackTotalCharUuid) == 0) { + tracksTotal = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]; + } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *) &msPlaybackSpeedCharUuid) == 0) { + playbackSpeed = static_cast<float>(((s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3])) / 100.0f; + } + } + return 0; +} + +std::string Pinetime::Controllers::MusicService::getAlbum() { + return albumName; +} + +std::string Pinetime::Controllers::MusicService::getArtist() { + return artistName; +} + +std::string Pinetime::Controllers::MusicService::getTrack() { + return trackName; +} + +bool Pinetime::Controllers::MusicService::isPlaying() { + return playing; +} + +float Pinetime::Controllers::MusicService::getPlaybackSpeed() { + return playbackSpeed; +} + +void Pinetime::Controllers::MusicService::event(char event) { + auto *om = ble_hs_mbuf_from_flat(&event, 1); + + uint16_t connectionHandle = m_system.nimble().connHandle(); + + if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) { + return; + } + + ble_gattc_notify_custom(connectionHandle, eventHandle, om); +} + +int Pinetime::Controllers::MusicService::getProgress() { + return trackProgress; +} + +int Pinetime::Controllers::MusicService::getTrackLength() { + return trackLength; +} + diff --git a/src/components/ble/MusicService.h b/src/components/ble/MusicService.h new file mode 100644 index 00000000..b365909b --- /dev/null +++ b/src/components/ble/MusicService.h @@ -0,0 +1,166 @@ +/* Copyright (C) 2020 JF, Adam Pigg, Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ +#pragma once + +#include <cstdint> +#include <array> +#include <host/ble_gap.h> +#include <host/ble_uuid.h> +#include <string> + +//c7e50000-78fc-48fe-8e23-43b37a1942d0 +#define MUSIC_SERVICE_UUID_BASE {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, 0x00, 0x00, 0xe5, 0xc7} + +namespace Pinetime { + namespace System { + class SystemTask; + } + namespace Controllers { + + class MusicService { + public: + explicit MusicService(Pinetime::System::SystemTask &system); + + void Init(); + + int OnCommand(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt); + + void event(char event); + + std::string getArtist(); + + std::string getTrack(); + + std::string getAlbum(); + + int getProgress(); + + int getTrackLength(); + + float getPlaybackSpeed(); + + bool isPlaying(); + + static const char EVENT_MUSIC_OPEN = 0xe0; + static const char EVENT_MUSIC_PLAY = 0x00; + static const char EVENT_MUSIC_PAUSE = 0x01; + static const char EVENT_MUSIC_NEXT = 0x03; + static const char EVENT_MUSIC_PREV = 0x04; + static const char EVENT_MUSIC_VOLUP = 0x05; + static const char EVENT_MUSIC_VOLDOWN = 0x06; + + enum MusicStatus { + NotPlaying = 0x00, + Playing = 0x01 + }; + private: + static constexpr uint8_t msId[2] = {0x00, 0x01}; + static constexpr uint8_t msEventCharId[2] = {0x00, 0x02}; + static constexpr uint8_t msStatusCharId[2] = {0x00, 0x03}; + static constexpr uint8_t msArtistCharId[2] = {0x00, 0x04}; + static constexpr uint8_t msTrackCharId[2] = {0x00, 0x05}; + static constexpr uint8_t msAlbumCharId[2] = {0x00, 0x06}; + static constexpr uint8_t msPositionCharId[2] = {0x00, 0x07}; + static constexpr uint8_t msTotalLengthCharId[2] = {0x00, 0x08}; + static constexpr uint8_t msTrackNumberCharId[2] = {0x00, 0x09}; + static constexpr uint8_t msTrackTotalCharId[2] = {0x00, 0x0a}; + static constexpr uint8_t msPlaybackSpeedCharId[2] = {0x00, 0x0b}; + static constexpr uint8_t msRepeatCharId[2] = {0x00, 0x0c}; + static constexpr uint8_t msShuffleCharId[2] = {0x00, 0x0d}; + + ble_uuid128_t msUuid{ + .u = {.type = BLE_UUID_TYPE_128}, + .value = MUSIC_SERVICE_UUID_BASE + }; + + ble_uuid128_t msEventCharUuid{ + .u = {.type = BLE_UUID_TYPE_128}, + .value = MUSIC_SERVICE_UUID_BASE + }; + ble_uuid128_t msStatusCharUuid{ + .u = {.type = BLE_UUID_TYPE_128}, + .value = MUSIC_SERVICE_UUID_BASE + }; + ble_uuid128_t msArtistCharUuid{ + .u = {.type = BLE_UUID_TYPE_128}, + .value = MUSIC_SERVICE_UUID_BASE + }; + ble_uuid128_t msTrackCharUuid{ + .u = {.type = BLE_UUID_TYPE_128}, + .value = MUSIC_SERVICE_UUID_BASE + }; + ble_uuid128_t msAlbumCharUuid{ + .u = {.type = BLE_UUID_TYPE_128}, + .value = MUSIC_SERVICE_UUID_BASE + }; + ble_uuid128_t msPositionCharUuid{ + .u = {.type = BLE_UUID_TYPE_128}, + .value = MUSIC_SERVICE_UUID_BASE + }; + ble_uuid128_t msTotalLengthCharUuid{ + .u = {.type = BLE_UUID_TYPE_128}, + .value = MUSIC_SERVICE_UUID_BASE + }; + ble_uuid128_t msTrackNumberCharUuid{ + .u = {.type = BLE_UUID_TYPE_128}, + .value = MUSIC_SERVICE_UUID_BASE + }; + ble_uuid128_t msTrackTotalCharUuid{ + .u = {.type = BLE_UUID_TYPE_128}, + .value = MUSIC_SERVICE_UUID_BASE + }; + ble_uuid128_t msPlaybackSpeedCharUuid{ + .u = {.type = BLE_UUID_TYPE_128}, + .value = MUSIC_SERVICE_UUID_BASE + }; + ble_uuid128_t msRepeatCharUuid{ + .u = {.type = BLE_UUID_TYPE_128}, + .value = MUSIC_SERVICE_UUID_BASE + }; + ble_uuid128_t msShuffleCharUuid{ + .u = {.type = BLE_UUID_TYPE_128}, + .value = MUSIC_SERVICE_UUID_BASE + }; + + struct ble_gatt_chr_def characteristicDefinition[14]; + struct ble_gatt_svc_def serviceDefinition[2]; + + uint16_t eventHandle; + + std::string artistName; + std::string albumName; + std::string trackName; + + bool playing; + + int trackProgress; + int trackLength; + int trackNumber; + int tracksTotal; + + float playbackSpeed; + + bool repeat; + bool shuffle; + + Pinetime::System::SystemTask &m_system; + }; + } +} + diff --git a/src/Components/Ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index d7bbd8be..af7f4029 100644 --- a/src/Components/Ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -1,10 +1,7 @@ - -#include <Components/DateTime/DateTimeController.h> - -#include <SystemTask/SystemTask.h> -#include <Components/Ble/NotificationManager.h> +#include "components/datetime/DateTimeController.h" +#include <systemtask/SystemTask.h> +#include "components/ble/NotificationManager.h" #include <hal/nrf_rtc.h> - #include "NimbleController.h" #include "MusicService.h" #include <services/gatt/ble_svc_gatt.h> @@ -14,18 +11,13 @@ #include <host/ble_hs.h> #include <host/ble_gap.h> - - using namespace Pinetime::Controllers; -// TODO I'm not satisfied by how this code looks like (AlertNotificationClient and CurrentTimeClient must -// expose too much data, too many callbacks -> NimbleController -> CTS/ANS client. -// Let's try to improve this code (and keep it working!) - NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, Pinetime::Controllers::Ble& bleController, DateTime& dateTimeController, Pinetime::Controllers::NotificationManager& notificationManager, + Controllers::Battery& batteryController, Pinetime::Drivers::SpiNorFlash& spiNorFlash) : systemTask{systemTask}, bleController{bleController}, @@ -37,8 +29,10 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, anService{systemTask, notificationManager}, alertNotificationClient{systemTask, notificationManager}, currentTimeService{dateTimeController}, - musicService{systemTask} { - + musicService{systemTask}, + batteryInformationService{batteryController}, + immediateAlertService{systemTask, notificationManager}, + serviceDiscovery({¤tTimeClient, &alertNotificationClient}) { } int GAPEventCallback(struct ble_gap_event *event, void *arg) { @@ -46,33 +40,6 @@ int GAPEventCallback(struct ble_gap_event *event, void *arg) { return nimbleController->OnGAPEvent(event); } -int CurrentTimeCharacteristicDiscoveredCallback(uint16_t conn_handle, const struct ble_gatt_error *error, - const struct ble_gatt_chr *chr, void *arg) { - auto client = static_cast<NimbleController*>(arg); - return client->OnCTSCharacteristicDiscoveryEvent(conn_handle, error, chr); -} - -int AlertNotificationCharacteristicDiscoveredCallback(uint16_t conn_handle, const struct ble_gatt_error *error, - const struct ble_gatt_chr *chr, void *arg) { - auto client = static_cast<NimbleController*>(arg); - return client->OnANSCharacteristicDiscoveryEvent(conn_handle, error, chr); -} - -int CurrentTimeReadCallback(uint16_t conn_handle, const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, void *arg) { - auto client = static_cast<NimbleController*>(arg); - return client->OnCurrentTimeReadResult(conn_handle, error, attr); -} - -int AlertNotificationDescriptorDiscoveryEventCallback(uint16_t conn_handle, - const struct ble_gatt_error *error, - uint16_t chr_val_handle, - const struct ble_gatt_dsc *dsc, - void *arg) { - auto client = static_cast<NimbleController*>(arg); - return client->OnANSDescriptorDiscoveryEventCallback(conn_handle, error, chr_val_handle, dsc); -} - void NimbleController::Init() { while (!ble_hs_synced()) {} @@ -83,10 +50,10 @@ void NimbleController::Init() { currentTimeClient.Init(); currentTimeService.Init(); musicService.Init(); - anService.Init(); - dfuService.Init(); + batteryInformationService.Init(); + immediateAlertService.Init(); int res; res = ble_hs_util_ensure_addr(0); ASSERT(res == 0); @@ -105,9 +72,9 @@ void NimbleController::Init() { } void NimbleController::StartAdvertising() { - if(ble_gap_adv_active()) return; + if(bleController.IsConnected() || ble_gap_conn_active() || ble_gap_adv_active()) return; - ble_svc_gap_device_name_set("Pinetime-JF"); + ble_svc_gap_device_name_set(deviceName); /* set adv parameters */ struct ble_gap_adv_params adv_params; @@ -135,18 +102,17 @@ void NimbleController::StartAdvertising() { fields.uuids128_is_complete = 1; fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; - rsp_fields.name = (uint8_t *)"Pinetime-JF"; - rsp_fields.name_len = strlen("Pinetime-JF"); + rsp_fields.name = (uint8_t *)deviceName; + rsp_fields.name_len = strlen(deviceName); rsp_fields.name_is_complete = 1; - int res; - res = ble_gap_adv_set_fields(&fields); + ble_gap_adv_set_fields(&fields); // ASSERT(res == 0); // TODO this one sometimes fails with error 22 (notsync) - res = ble_gap_adv_rsp_set_fields(&rsp_fields); + ble_gap_adv_rsp_set_fields(&rsp_fields); // ASSERT(res == 0); - res = ble_gap_adv_start(addrType, NULL, 180000, + ble_gap_adv_start(addrType, NULL, 180000, &adv_params, GAPEventCallback, this); // ASSERT(res == 0);// TODO I've disabled these ASSERT as they sometime asserts and reset the mcu. // For now, the advertising is restarted as soon as it ends. There may be a race condition @@ -156,15 +122,6 @@ void NimbleController::StartAdvertising() { // the application has been woken up, for example. } -int OnAllSvrDisco(uint16_t conn_handle, - const struct ble_gatt_error *error, - const struct ble_gatt_svc *service, - void *arg) { - auto nimbleController = static_cast<NimbleController*>(arg); - return nimbleController->OnDiscoveryEvent(conn_handle, error, service); - return 0; -} - int NimbleController::OnGAPEvent(ble_gap_event *event) { switch (event->type) { case BLE_GAP_EVENT_ADV_COMPLETE: @@ -195,6 +152,8 @@ int NimbleController::OnGAPEvent(ble_gap_event *event) { NRF_LOG_INFO("disconnect; reason=%d", event->disconnect.reason); /* Connection terminated; resume advertising. */ + currentTimeClient.Reset(); + alertNotificationClient.Reset(); connectionHandle = BLE_HS_CONN_HANDLE_NONE; bleController.Disconnect(); StartAdvertising(); @@ -267,65 +226,8 @@ int NimbleController::OnGAPEvent(ble_gap_event *event) { return 0; } -int NimbleController::OnDiscoveryEvent(uint16_t i, const ble_gatt_error *error, const ble_gatt_svc *service) { - if(service == nullptr && error->status == BLE_HS_EDONE) { - NRF_LOG_INFO("Service Discovery complete"); - if(currentTimeClient.IsDiscovered()) { - ble_gattc_disc_all_chrs(connectionHandle, currentTimeClient.StartHandle(), currentTimeClient.EndHandle(), - CurrentTimeCharacteristicDiscoveredCallback, this); - - } else if(alertNotificationClient.IsDiscovered()) { - ble_gattc_disc_all_chrs(connectionHandle, alertNotificationClient.StartHandle(), alertNotificationClient.EndHandle(), - AlertNotificationCharacteristicDiscoveredCallback, this); - } - } - - alertNotificationClient.OnDiscoveryEvent(i, error, service); - currentTimeClient.OnDiscoveryEvent(i, error, service); - return 0; -} - -int NimbleController::OnCTSCharacteristicDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, - const ble_gatt_chr *characteristic) { - if(characteristic == nullptr && error->status == BLE_HS_EDONE) { - NRF_LOG_INFO("CTS characteristic Discovery complete"); - ble_gattc_read(connectionHandle, currentTimeClient.CurrentTimeHandle(), CurrentTimeReadCallback, this); - return 0; - } - return currentTimeClient.OnCharacteristicDiscoveryEvent(connectionHandle, error, characteristic); -} - -int NimbleController::OnANSCharacteristicDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, - const ble_gatt_chr *characteristic) { - if(characteristic == nullptr && error->status == BLE_HS_EDONE) { - NRF_LOG_INFO("ANS characteristic Discovery complete"); - ble_gattc_disc_all_dscs(connectionHandle, - alertNotificationClient.NewAlerthandle(), alertNotificationClient.EndHandle(), - AlertNotificationDescriptorDiscoveryEventCallback, this); - return 0; - } - return alertNotificationClient.OnCharacteristicsDiscoveryEvent(connectionHandle, error, characteristic); -} - -int NimbleController::OnCurrentTimeReadResult(uint16_t connectionHandle, const ble_gatt_error *error, ble_gatt_attr *attribute) { - currentTimeClient.OnCurrentTimeReadResult(connectionHandle, error, attribute); - - if (alertNotificationClient.IsDiscovered()) { - ble_gattc_disc_all_chrs(connectionHandle, alertNotificationClient.StartHandle(), - alertNotificationClient.EndHandle(), - AlertNotificationCharacteristicDiscoveredCallback, this); - } - return 0; -} - -int NimbleController::OnANSDescriptorDiscoveryEventCallback(uint16_t connectionHandle, const ble_gatt_error *error, - uint16_t characteristicValueHandle, - const ble_gatt_dsc *descriptor) { - return alertNotificationClient.OnDescriptorDiscoveryEventCallback(connectionHandle, error, characteristicValueHandle, descriptor); -} - void NimbleController::StartDiscovery() { - ble_gattc_disc_all_svcs(connectionHandle, OnAllSvrDisco, this); + serviceDiscovery.StartDiscovery(connectionHandle); } diff --git a/src/Components/Ble/NimbleController.h b/src/components/ble/NimbleController.h index dff93c87..8ddec1f9 100644 --- a/src/Components/Ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -1,6 +1,7 @@ #pragma once #include <cstdint> + #include "AlertNotificationService.h" #include "AlertNotificationClient.h" #include "DeviceInformationService.h" @@ -8,6 +9,9 @@ #include "DfuService.h" #include "CurrentTimeService.h" #include "MusicService.h" +#include "BatteryInformationService.h" +#include "ImmediateAlertService.h" +#include "ServiceDiscovery.h" #include <host/ble_gap.h> namespace Pinetime { @@ -22,7 +26,7 @@ namespace Pinetime { public: NimbleController(Pinetime::System::SystemTask& systemTask, Pinetime::Controllers::Ble& bleController, DateTime& dateTimeController, Pinetime::Controllers::NotificationManager& notificationManager, - Pinetime::Drivers::SpiNorFlash& spiNorFlash); + Controllers::Battery& batteryController, Pinetime::Drivers::SpiNorFlash& spiNorFlash); void Init(); void StartAdvertising(); int OnGAPEvent(ble_gap_event *event); @@ -43,7 +47,7 @@ namespace Pinetime { uint16_t connHandle(); private: - static constexpr char* deviceName = "Pinetime-JF"; + static constexpr const char* deviceName = "InfiniTime"; Pinetime::System::SystemTask& systemTask; Pinetime::Controllers::Ble& bleController; DateTime& dateTimeController; @@ -57,6 +61,8 @@ namespace Pinetime { AlertNotificationClient alertNotificationClient; CurrentTimeService currentTimeService; MusicService musicService; + BatteryInformationService batteryInformationService; + ImmediateAlertService immediateAlertService; uint8_t addrType; // 1 = Random, 0 = PUBLIC uint16_t connectionHandle = 0; @@ -66,6 +72,8 @@ namespace Pinetime { .value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, 0xDE, 0xEF, 0x12, 0x12, 0x30, 0x15, 0x00, 0x00} }; + + ServiceDiscovery serviceDiscovery; }; } } diff --git a/src/components/ble/NotificationManager.cpp b/src/components/ble/NotificationManager.cpp new file mode 100644 index 00000000..67711723 --- /dev/null +++ b/src/components/ble/NotificationManager.cpp @@ -0,0 +1,81 @@ +#include <cstring> +#include <algorithm> +#include "NotificationManager.h" + +using namespace Pinetime::Controllers; + +constexpr uint8_t NotificationManager::MessageSize; + + +void NotificationManager::Push(NotificationManager::Notification &¬if) { + notif.id = GetNextId(); + notif.valid = true; + notifications[writeIndex] = std::move(notif); + writeIndex = (writeIndex + 1 < TotalNbNotifications) ? writeIndex + 1 : 0; + if(!empty) + readIndex = (readIndex + 1 < TotalNbNotifications) ? readIndex + 1 : 0; + else empty = false; + + newNotification = true; +} + +NotificationManager::Notification NotificationManager::GetLastNotification() { + NotificationManager::Notification notification = notifications[readIndex]; + notification.index = 1; + return notification; +} + +NotificationManager::Notification::Id NotificationManager::GetNextId() { + return nextId++; +} + +NotificationManager::Notification NotificationManager::GetNext(NotificationManager::Notification::Id id) { + auto currentIterator = std::find_if(notifications.begin(), notifications.end(), [id](const Notification& n){return n.valid && n.id == id;}); + if(currentIterator == notifications.end() || currentIterator->id != id) return Notification{}; + + auto& lastNotification = notifications[readIndex]; + + NotificationManager::Notification result; + + if(currentIterator == (notifications.end()-1)) + result = *(notifications.begin()); + else + result = *(currentIterator+1); + + if(result.id <= id) return {}; + + result.index = (lastNotification.id - result.id)+1; + return result; +} + +NotificationManager::Notification NotificationManager::GetPrevious(NotificationManager::Notification::Id id) { + auto currentIterator = std::find_if(notifications.begin(), notifications.end(), [id](const Notification& n){return n.valid && n.id == id;}); + if(currentIterator == notifications.end() || currentIterator->id != id) return Notification{}; + + auto& lastNotification = notifications[readIndex]; + + NotificationManager::Notification result; + + if(currentIterator == notifications.begin()) + result = *(notifications.end()-1); + else + result = *(currentIterator-1); + + if(result.id >= id) return {}; + + result.index = (lastNotification.id - result.id)+1; + return result; +} + +bool NotificationManager::AreNewNotificationsAvailable() { + return newNotification; +} + +bool NotificationManager::ClearNewNotificationFlag() { + return newNotification.exchange(false); +} + +size_t NotificationManager::NbNotifications() const { + return std::count_if(notifications.begin(), notifications.end(), [](const Notification& n){ return n.valid;}); +} + diff --git a/src/components/ble/NotificationManager.h b/src/components/ble/NotificationManager.h new file mode 100644 index 00000000..49fe8306 --- /dev/null +++ b/src/components/ble/NotificationManager.h @@ -0,0 +1,43 @@ +#pragma once + +#include <array> +#include <atomic> + +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{100}; + + struct Notification { + using Id = uint8_t; + Id id; + bool valid = false; + uint8_t index; + std::array<char, MessageSize+1> message; + Categories category = Categories::Unknown; + }; + Notification::Id nextId {0}; + + void Push(Notification&& notif); + Notification GetLastNotification(); + Notification GetNext(Notification::Id id); + Notification GetPrevious(Notification::Id id); + bool ClearNewNotificationFlag(); + bool AreNewNotificationsAvailable(); + + static constexpr uint8_t MaximumMessageSize() { return MessageSize; }; + size_t NbNotifications() const; + + private: + Notification::Id GetNextId(); + static constexpr uint8_t TotalNbNotifications = 5; + std::array<Notification, TotalNbNotifications> notifications; + uint8_t readIndex = 0; + uint8_t writeIndex = 0; + bool empty = true; + std::atomic<bool> newNotification{false}; + }; + } +}
\ No newline at end of file diff --git a/src/components/ble/ServiceDiscovery.cpp b/src/components/ble/ServiceDiscovery.cpp new file mode 100644 index 00000000..4b29d89c --- /dev/null +++ b/src/components/ble/ServiceDiscovery.cpp @@ -0,0 +1,31 @@ +#include <libraries/log/nrf_log.h> +#include "ServiceDiscovery.h" +using namespace Pinetime::Controllers; + +ServiceDiscovery::ServiceDiscovery(std::array<BleClient*, 2>&& clients) : clients{clients} { + +} + +void ServiceDiscovery::StartDiscovery(uint16_t connectionHandle) { + NRF_LOG_INFO("[Discovery] Starting discovery"); + clientIterator = clients.begin(); + DiscoverNextService(connectionHandle); +} + +void ServiceDiscovery::OnServiceDiscovered(uint16_t connectionHandle) { + clientIterator++; + if(clientIterator != clients.end()) { + DiscoverNextService(connectionHandle); + } else { + NRF_LOG_INFO("End of service discovery"); + } +} + +void ServiceDiscovery::DiscoverNextService(uint16_t connectionHandle) { + NRF_LOG_INFO("[Discovery] Discover next service"); + + auto discoverNextService = [this](uint16_t connectionHandle){ + this->OnServiceDiscovered(connectionHandle); + }; + (*clientIterator)->Discover(connectionHandle, discoverNextService); +}
\ No newline at end of file diff --git a/src/components/ble/ServiceDiscovery.h b/src/components/ble/ServiceDiscovery.h new file mode 100644 index 00000000..c86fc4ec --- /dev/null +++ b/src/components/ble/ServiceDiscovery.h @@ -0,0 +1,24 @@ +#pragma once + +#include <array> +#include <functional> +#include <memory> +#include "BleClient.h" + +namespace Pinetime { + namespace Controllers { + class ServiceDiscovery { + public: + ServiceDiscovery(std::array<BleClient*, 2>&& bleClients); + + void StartDiscovery(uint16_t connectionHandle); + + + private: + BleClient** clientIterator; + std::array<BleClient*, 2> clients; + void OnServiceDiscovered(uint16_t connectionHandle); + void DiscoverNextService(uint16_t connectionHandle); + }; + } +} diff --git a/src/Components/Brightness/BrightnessController.cpp b/src/components/brightness/BrightnessController.cpp index c8825d68..c8825d68 100644 --- a/src/Components/Brightness/BrightnessController.cpp +++ b/src/components/brightness/BrightnessController.cpp diff --git a/src/Components/Brightness/BrightnessController.h b/src/components/brightness/BrightnessController.h index b8354ec0..b8354ec0 100644 --- a/src/Components/Brightness/BrightnessController.h +++ b/src/components/brightness/BrightnessController.h diff --git a/src/Components/DateTime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp index 30d9c13f..30d9c13f 100644 --- a/src/Components/DateTime/DateTimeController.cpp +++ b/src/components/datetime/DateTimeController.cpp diff --git a/src/Components/DateTime/DateTimeController.h b/src/components/datetime/DateTimeController.h index d6020745..d6020745 100644 --- a/src/Components/DateTime/DateTimeController.h +++ b/src/components/datetime/DateTimeController.h diff --git a/src/components/firmwarevalidator/FirmwareValidator.cpp b/src/components/firmwarevalidator/FirmwareValidator.cpp new file mode 100644 index 00000000..244d5c06 --- /dev/null +++ b/src/components/firmwarevalidator/FirmwareValidator.cpp @@ -0,0 +1,20 @@ +#include <drivers/InternalFlash.h> +#include <hal/nrf_rtc.h> + +#include "FirmwareValidator.h" + +using namespace Pinetime::Controllers; + +bool FirmwareValidator::IsValidated() const { + auto* imageOkPtr = reinterpret_cast<uint32_t *>(validBitAdress); + return (*imageOkPtr) == validBitValue; +} + +void FirmwareValidator::Validate() { + if(!IsValidated()) + Pinetime::Drivers::InternalFlash::WriteWord(validBitAdress, validBitValue); +} + +void FirmwareValidator::Reset() { + NVIC_SystemReset(); +} diff --git a/src/components/firmwarevalidator/FirmwareValidator.h b/src/components/firmwarevalidator/FirmwareValidator.h new file mode 100644 index 00000000..aa576d88 --- /dev/null +++ b/src/components/firmwarevalidator/FirmwareValidator.h @@ -0,0 +1,18 @@ +#pragma once + +#include <cstdint> + +namespace Pinetime { + namespace Controllers { + class FirmwareValidator { + public: + void Validate(); + bool IsValidated() const; + + void Reset(); + private: + static constexpr uint32_t validBitAdress {0x7BFE8}; + static constexpr uint32_t validBitValue {1}; + }; + } +} diff --git a/src/Components/Gfx/Gfx.cpp b/src/components/gfx/Gfx.cpp index 3c5dbfb7..bab7c8d9 100644 --- a/src/Components/Gfx/Gfx.cpp +++ b/src/components/gfx/Gfx.cpp @@ -23,7 +23,7 @@ void Gfx::ClearScreen() { lcd.BeginDrawBuffer(0, 0, width, height); lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(buffer), width * 2); - WaitTransfertFinished(); + WaitTransferFinished(); } @@ -40,7 +40,7 @@ void Gfx::FillRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint16_t col lcd.BeginDrawBuffer(x, y, w, h); lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(buffer), width * 2); - WaitTransfertFinished(); + WaitTransferFinished(); } void Gfx::FillRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t* b) { @@ -54,7 +54,7 @@ void Gfx::FillRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t* b) lcd.BeginDrawBuffer(x, y, w, h); lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(b), width * 2); - WaitTransfertFinished(); + WaitTransferFinished(); } void Gfx::DrawString(uint8_t x, uint8_t y, uint16_t color, const char *text, const FONT_INFO *p_font, bool wrap) { @@ -125,7 +125,7 @@ void Gfx::DrawChar(const FONT_INFO *font, uint8_t c, uint8_t *x, uint8_t y, uint lcd.BeginDrawBuffer(*x, y, bytes_in_line*8, font->height); lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(&buffer), bytes_in_line*8*2); - WaitTransfertFinished(); + WaitTransferFinished(); *x += font->charInfo[char_idx].widthBits + font->spacePixels; } @@ -153,7 +153,7 @@ bool Gfx::GetNextBuffer(uint8_t **data, size_t &size) { state.remainingIterations--; if (state.remainingIterations == 0) { state.busy = false; - NotifyEndOfTransfert(state.taskToNotify); + NotifyEndOfTransfer(state.taskToNotify); return false; } @@ -185,7 +185,7 @@ bool Gfx::GetNextBuffer(uint8_t **data, size_t &size) { return true; } -void Gfx::NotifyEndOfTransfert(TaskHandle_t task) { +void Gfx::NotifyEndOfTransfer(TaskHandle_t task) { if(task != nullptr) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; vTaskNotifyGiveFromISR(task, &xHigherPriorityTaskWoken); @@ -193,7 +193,7 @@ void Gfx::NotifyEndOfTransfert(TaskHandle_t task) { } } -void Gfx::WaitTransfertFinished() const { +void Gfx::WaitTransferFinished() const { ulTaskNotifyTake(pdTRUE, 500); } @@ -204,4 +204,3 @@ void Gfx::SetScrollArea(uint16_t topFixedLines, uint16_t scrollLines, uint16_t b void Gfx::SetScrollStartLine(uint16_t line) { lcd.VerticalScrollStartAddress(line); } - diff --git a/src/Components/Gfx/Gfx.h b/src/components/gfx/Gfx.h index 091f06f5..eba6319f 100644 --- a/src/Components/Gfx/Gfx.h +++ b/src/components/gfx/Gfx.h @@ -53,8 +53,8 @@ namespace Pinetime { Drivers::St7789& lcd; void SetBackgroundColor(uint16_t color); - void WaitTransfertFinished() const; - void NotifyEndOfTransfert(TaskHandle_t task); + void WaitTransferFinished() const; + void NotifyEndOfTransfer(TaskHandle_t task); }; } } diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h new file mode 100644 index 00000000..bfa799ba --- /dev/null +++ b/src/displayapp/Apps.h @@ -0,0 +1,7 @@ +#pragma once + +namespace Pinetime { + namespace Applications { + enum class Apps {None, Launcher, Clock, SysInfo, Meter, Gauge, Brightness, Music, FirmwareValidation, Paint, Notifications}; + } +}
\ No newline at end of file diff --git a/src/DisplayApp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 46a96385..d4d41333 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -1,24 +1,26 @@ +#include <string> + #include "DisplayApp.h" #include <FreeRTOS.h> #include <task.h> #include <libraries/log/nrf_log.h> -#include <boards.h> #include <nrf_font.h> #include <queue.h> -#include <Components/DateTime/DateTimeController.h> +#include "components/datetime/DateTimeController.h" #include <drivers/Cst816s.h> -#include <string> -#include <lvgl/lvgl.h> -#include <DisplayApp/Screens/Tile.h> -#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 <DisplayApp/Screens/Music.h> -#include <Components/Ble/NotificationManager.h> -#include <DisplayApp/Screens/FirmwareUpdate.h> -#include "../SystemTask/SystemTask.h" +#include "displayapp/screens/Notifications.h" +#include "displayapp/screens/Tile.h" +#include "displayapp/screens/Meter.h" +#include "displayapp/screens/Gauge.h" +#include "displayapp/screens/Brightness.h" +#include "displayapp/screens/SystemInfo.h" +#include "displayapp/screens/Music.h" +#include "components/ble/NotificationManager.h" +#include "displayapp/screens/FirmwareUpdate.h" +#include "displayapp/screens/ApplicationList.h" +#include "displayapp/screens/FirmwareValidation.h" +#include "displayapp/screens/InfiniPaint.h" +#include "systemtask/SystemTask.h" using namespace Pinetime::Applications; @@ -34,7 +36,7 @@ DisplayApp::DisplayApp(Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Driver dateTimeController{dateTimeController}, watchdog{watchdog}, touchPanel{touchPanel}, - currentScreen{new Screens::Clock(this, dateTimeController, batteryController, bleController) }, + currentScreen{new Screens::Clock(this, dateTimeController, batteryController, bleController, notificationManager) }, systemTask{systemTask}, notificationManager{notificationManager} { msgQueue = xQueueCreate(queueSize, itemSize); @@ -43,13 +45,13 @@ DisplayApp::DisplayApp(Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Driver } void DisplayApp::Start() { - if (pdPASS != xTaskCreate(DisplayApp::Process, "DisplayApp", 512, this, 0, &taskHandle)) + 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!"); + NRF_LOG_INFO("displayapp task started!"); app->InitHw(); // Send a dummy notification to unlock the lvgl display driver for the first iteration @@ -80,6 +82,9 @@ void DisplayApp::Refresh() { RunningState(); queueTimeout = 20; break; + default: + queueTimeout = portMAX_DELAY; + break; } Messages msg; @@ -92,14 +97,10 @@ void DisplayApp::Refresh() { vTaskDelay(100); } lcd.DisplayOff(); - lcd.Sleep(); - touchPanel.Sleep(); + systemTask.PushMessage(System::SystemTask::Messages::OnDisplayTaskSleeping); state = States::Idle; break; case Messages::GoToRunning: - lcd.Wakeup(); - touchPanel.Wakeup(); - lcd.DisplayOn(); brightnessController.Restore(); state = States::Running; @@ -114,8 +115,12 @@ void DisplayApp::Refresh() { // clockScreen.SetBatteryPercentRemaining(batteryController.PercentRemaining()); break; case Messages::NewNotification: { - auto notification = notificationManager.Pop(); - modal->Show(notification.message.data()); + if(onClockApp) { + currentScreen.reset(nullptr); + lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Up); + onClockApp = false; + currentScreen.reset(new Screens::Notifications(this, notificationManager, Screens::Notifications::Modes::Preview)); + } } break; case Messages::TouchEvent: { @@ -149,7 +154,7 @@ void DisplayApp::Refresh() { } } -// lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Down); +// lvgl.SetFullRefresh(components::LittleVgl::FullRefreshDirections::Down); // currentScreen.reset(nullptr); // if(toggle) { // currentScreen.reset(new Screens::Tile(this)); @@ -169,6 +174,15 @@ void DisplayApp::Refresh() { break; } } + + if(state != States::Idle && touchMode == TouchModes::Polling) { + auto info = touchPanel.GetTouchInfo(); + if(info.action == 2) {// 2 = contact + if(!currentScreen->OnTouchEvent(info.x, info.y)) { + lvgl.SetNewTapEvent(info.x, info.y); + } + } + } } void DisplayApp::RunningState() { @@ -180,17 +194,20 @@ void DisplayApp::RunningState() { onClockApp = false; switch(nextApp) { case Apps::None: - case Apps::Launcher: currentScreen.reset(new Screens::Tile(this)); break; + case Apps::Launcher: currentScreen.reset(new Screens::ApplicationList(this)); break; case Apps::Clock: - currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController)); + currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController, notificationManager)); onClockApp = true; break; // case Apps::Test: currentScreen.reset(new Screens::Message(this)); break; - case Apps::SysInfo: currentScreen.reset(new Screens::ScreenList(this, dateTimeController, batteryController, brightnessController, bleController, watchdog)); break; + case Apps::SysInfo: currentScreen.reset(new Screens::SystemInfo(this, dateTimeController, batteryController, brightnessController, bleController, watchdog)); break; case Apps::Meter: currentScreen.reset(new Screens::Meter(this)); break; case Apps::Gauge: currentScreen.reset(new Screens::Gauge(this)); break; + case Apps::Paint: currentScreen.reset(new Screens::InfiniPaint(this, lvgl)); break; case Apps::Brightness : currentScreen.reset(new Screens::Brightness(this, brightnessController)); break; case Apps::Music : currentScreen.reset(new Screens::Music(this, systemTask.nimble().music())); break; + case Apps::FirmwareValidation: currentScreen.reset(new Screens::FirmwareValidation(this, validator)); break; + case Apps::Notifications: currentScreen.reset(new Screens::Notifications(this, notificationManager, Screens::Notifications::Modes::Normal)); break; } nextApp = Apps::None; } @@ -216,7 +233,8 @@ TouchEvents DisplayApp::OnTouchEvent() { if(info.isTouch) { switch(info.gesture) { case Pinetime::Drivers::Cst816S::Gestures::SingleTap: - lvgl.SetNewTapEvent(info.x, info.y); + if(touchMode == TouchModes::Gestures) + lvgl.SetNewTapEvent(info.x, info.y); return TouchEvents::Tap; case Pinetime::Drivers::Cst816S::Gestures::LongPress: return TouchEvents::LongTap; @@ -238,7 +256,7 @@ TouchEvents DisplayApp::OnTouchEvent() { return TouchEvents::None; } -void DisplayApp::StartApp(DisplayApp::Apps app) { +void DisplayApp::StartApp(Apps app) { nextApp = app; } @@ -254,3 +272,7 @@ void DisplayApp::SetFullRefresh(DisplayApp::FullRefreshDirections direction) { } } + +void DisplayApp::SetTouchMode(DisplayApp::TouchModes mode) { + touchMode = mode; +} diff --git a/src/DisplayApp/DisplayApp.h b/src/displayapp/DisplayApp.h index 23f04937..2a0efde3 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -3,21 +3,23 @@ #include <task.h> #include <drivers/St7789.h> #include <drivers/SpiMaster.h> -#include <Components/Gfx/Gfx.h> #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 "../drivers/Cst816s.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 "LittleVgl.h" #include <date/date.h> -#include <DisplayApp/Screens/Clock.h> +#include "displayapp/screens/Clock.h" +#include "displayapp/screens/Modal.h" #include <drivers/Watchdog.h> -#include <DisplayApp/Screens/Modal.h> -#include <Components/Ble/NotificationManager.h> #include "TouchEvents.h" +#include "Apps.h" namespace Pinetime { @@ -28,11 +30,11 @@ namespace Pinetime { class DisplayApp { public: enum class States {Idle, Running}; - enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent, SwitchScreen,ButtonPushed, - NewNotification, BleFirmwareUpdateStarted, BleFirmwareUpdateFinished - }; - enum class FullRefreshDirections { None, Up, Down }; + 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 }; DisplayApp(Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Drivers::Cst816S &, Controllers::Battery &batteryController, Controllers::Ble &bleController, @@ -42,10 +44,11 @@ namespace Pinetime { void Start(); void PushMessage(Messages msg); - enum class Apps {None, Launcher, Clock, SysInfo, Meter, Gauge, Brightness, Music}; void StartApp(Apps app); void SetFullRefresh(FullRefreshDirections direction); + void SetTouchMode(TouchModes mode); + private: TaskHandle_t taskHandle; static void Process(void* instance); @@ -80,6 +83,8 @@ namespace Pinetime { Controllers::BrightnessController brightnessController; std::unique_ptr<Screens::Modal> modal; Pinetime::Controllers::NotificationManager& notificationManager; + Pinetime::Controllers::FirmwareValidator validator; + TouchModes touchMode = TouchModes::Gestures; }; } } diff --git a/src/DisplayApp/LittleVgl.cpp b/src/displayapp/LittleVgl.cpp index 3483f8e8..7b6275e2 100644 --- a/src/DisplayApp/LittleVgl.cpp +++ b/src/displayapp/LittleVgl.cpp @@ -76,8 +76,8 @@ void LittleVgl::SetFullRefresh(FullRefreshDirections direction) { void LittleVgl::FlushDisplay(const lv_area_t *area, lv_color_t *color_p) { ulTaskNotifyTake(pdTRUE, 500); - // NOtification is still needed (even if there is a mutex on SPI) because of the DataCommand pin - // which cannot be set/clear during a transfert. + // Notification is still needed (even if there is a mutex on SPI) because of the DataCommand pin + // which cannot be set/clear during a transfer. // TODO refactore and remove duplicated code @@ -831,6 +831,3 @@ void LittleVgl::InitThemeWindow() { // theme.style.win.btn.rel = &lv_style_transp; // theme.style.win.btn.pr = &win_btn_pr; } - - - diff --git a/src/DisplayApp/LittleVgl.h b/src/displayapp/LittleVgl.h index 8bd56ddf..5c1c4434 100644 --- a/src/DisplayApp/LittleVgl.h +++ b/src/displayapp/LittleVgl.h @@ -6,10 +6,6 @@ #include <drivers/St7789.h> #include <drivers/Cst816s.h> - -static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p); -static bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); - namespace Pinetime { namespace Components { class LittleVgl { diff --git a/src/DisplayApp/TouchEvents.h b/src/displayapp/TouchEvents.h index cf2f88dd..cf2f88dd 100644 --- a/src/DisplayApp/TouchEvents.h +++ b/src/displayapp/TouchEvents.h diff --git a/src/DisplayApp/Fonts/Readme.md b/src/displayapp/fonts/Readme.md index ddccc820..7ebf2e23 100644 --- a/src/DisplayApp/Fonts/Readme.md +++ b/src/displayapp/fonts/Readme.md @@ -10,7 +10,7 @@ * Bpp : 1 bit-per-pixel * Do not enable font compression and horizontal subpixel hinting * Load the file `JetBrainsMono-Bold.woff` and specify the following range : `0x20-0x7f` - * Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185` + * Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069, 0xf1fc` * Click on Convert, and download the file `jetbrains_mono_bold_20.c` and copy it in `src/DisplayApp/Fonts` Add new symbols: diff --git a/src/DisplayApp/Fonts/jetbrains_mono_bold_20.c b/src/displayapp/fonts/jetbrains_mono_bold_20.c index 96e13d63..27ad0055 100644 --- a/src/DisplayApp/Fonts/jetbrains_mono_bold_20.c +++ b/src/displayapp/fonts/jetbrains_mono_bold_20.c @@ -433,6 +433,15 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { /* U+7E "~" */ 0x78, 0xff, 0x3c, 0xff, 0x1e, + /* U+F001 "" */ + 0x0, 0x0, 0x70, 0x0, 0x7f, 0x0, 0x3f, 0xf0, + 0x1f, 0xff, 0x7, 0xff, 0xf0, 0x7f, 0xff, 0x7, + 0xfc, 0x70, 0x7e, 0x7, 0x7, 0x0, 0x70, 0x70, + 0x7, 0x7, 0x0, 0x70, 0x70, 0x7, 0x7, 0x0, + 0x70, 0x70, 0x7f, 0x7, 0xf, 0xf7, 0xf0, 0xff, + 0xff, 0x7, 0xef, 0xf0, 0x0, 0xff, 0x0, 0x3, + 0xc0, 0x0, + /* U+F017 "" */ 0x3, 0xf8, 0x1, 0xff, 0xc0, 0x7f, 0xfc, 0x1f, 0xff, 0xc7, 0xf1, 0xfc, 0xfe, 0x3f, 0x9f, 0xc7, @@ -449,6 +458,14 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { 0xf, 0x0, 0x0, 0xf3, 0xff, 0xff, 0x3f, 0xff, 0xf0, 0x0, 0x0, + /* U+F069 "" */ + 0x0, 0xe0, 0x0, 0x1c, 0x0, 0x3, 0x80, 0x0, + 0x70, 0x6, 0xe, 0xc, 0xf1, 0xc7, 0x9f, 0xbb, + 0xf1, 0xff, 0xfc, 0xf, 0xfe, 0x0, 0x7f, 0x0, + 0xf, 0xe0, 0x7, 0xff, 0x3, 0xff, 0xf8, 0xfd, + 0xdf, 0x9e, 0x38, 0xf3, 0x7, 0x6, 0x0, 0xe0, + 0x0, 0x1c, 0x0, 0x3, 0x80, 0x0, 0x70, 0x0, + /* U+F129 "" */ 0x3c, 0x7e, 0x7e, 0x7e, 0x3c, 0x0, 0x0, 0xfc, 0xfc, 0xfc, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, @@ -470,6 +487,14 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { 0x83, 0xfe, 0x3, 0xf8, 0x1, 0xc0, 0x3, 0x80, 0x7, 0x0, 0xe, 0x0, + /* U+F1FC "" */ + 0x0, 0x0, 0xf0, 0x0, 0x1f, 0x0, 0x3, 0xf0, + 0x0, 0x7e, 0x0, 0xf, 0xe0, 0x3, 0xfc, 0x0, + 0x7f, 0xc0, 0xf, 0xf8, 0x0, 0xff, 0x80, 0x1f, + 0xf0, 0x0, 0xfe, 0x0, 0xf, 0xe0, 0xe, 0x7c, + 0x1, 0xf8, 0x0, 0x9f, 0xc0, 0xf, 0xfc, 0x0, + 0x7f, 0xc0, 0x7, 0xf8, 0x0, 0x1f, 0x0, 0x0, + /* U+F21E "" */ 0x1e, 0x7, 0x83, 0xf9, 0xfe, 0x7f, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xfc, @@ -526,6 +551,15 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { 0x81, 0xf8, 0x6d, 0x99, 0x9a, 0x36, 0x7, 0x80, 0xe0, 0x18, 0x2, 0x0, 0x0, + /* U+F3FD "" */ + 0x0, 0xfe, 0x0, 0x7, 0xff, 0x0, 0x3f, 0xbf, + 0x80, 0xfe, 0x2f, 0x83, 0xfe, 0xcf, 0x8f, 0x3f, + 0x27, 0x9e, 0x7e, 0x4f, 0x3f, 0xfc, 0xfe, 0xff, + 0xf3, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xcf, 0xff, + 0xfe, 0x3f, 0xfe, 0x78, 0x3c, 0xff, 0xf0, 0x7f, + 0xdf, 0xe0, 0xff, 0x3f, 0xff, 0xfe, 0x3f, 0xff, + 0xf8, + /* U+F54B "" */ 0x0, 0xf, 0xf8, 0x1, 0xdf, 0xff, 0x1, 0xef, 0xff, 0xc0, 0xf7, 0xff, 0xf0, 0x7b, 0xff, 0xf8, @@ -534,7 +568,16 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { 0x0, 0x0, 0x0, 0x7, 0xf8, 0x0, 0xf, 0xfe, 0x3, 0xbf, 0xff, 0x83, 0xdf, 0xff, 0xc1, 0xef, 0xff, 0xe0, 0xf7, 0xff, 0xe0, 0x3b, 0xff, 0xe0, - 0x0, 0x7f, 0xc0, 0x0 + 0x0, 0x7f, 0xc0, 0x0, + + /* U+F560 "" */ + 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0xf, 0x0, + 0x1, 0xf0, 0x8, 0x3e, 0x1, 0xc7, 0xc4, 0x1e, + 0xf8, 0xe1, 0xff, 0x1f, 0xf, 0xe3, 0xf0, 0x7c, + 0x7e, 0x23, 0x8f, 0xc7, 0x11, 0xf8, 0xf8, 0x3f, + 0xf, 0xc7, 0xe0, 0x7e, 0xfc, 0x3, 0xff, 0x80, + 0x1f, 0xf0, 0x0, 0xfe, 0x0, 0x7, 0xc0, 0x0, + 0x38, 0x0, 0x1, 0x0, 0x0 }; @@ -639,20 +682,25 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { {.bitmap_index = 1423, .adv_w = 192, .box_w = 3, .box_h = 18, .ofs_x = 5, .ofs_y = -2}, {.bitmap_index = 1430, .adv_w = 192, .box_w = 10, .box_h = 18, .ofs_x = 1, .ofs_y = -2}, {.bitmap_index = 1453, .adv_w = 192, .box_w = 10, .box_h = 4, .ofs_x = 1, .ofs_y = 5}, - {.bitmap_index = 1458, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 1506, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 1549, .adv_w = 120, .box_w = 8, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1568, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 1618, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1654, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 1697, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 1735, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 1773, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 1811, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 1849, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 1887, .adv_w = 280, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 1925, .adv_w = 200, .box_w = 11, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 1954, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2} + {.bitmap_index = 1458, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 1508, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 1556, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1599, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 1647, .adv_w = 120, .box_w = 8, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1666, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 1716, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1752, .adv_w = 320, .box_w = 20, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1800, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1843, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 1881, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 1919, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 1957, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 1995, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 2033, .adv_w = 280, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 2071, .adv_w = 200, .box_w = 11, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2100, .adv_w = 360, .box_w = 23, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2149, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2209, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3} }; /*--------------------- @@ -660,8 +708,9 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { *--------------------*/ static const uint16_t unicode_list_1[] = { - 0x0, 0x23, 0x112, 0x16e, 0x1cf, 0x207, 0x229, 0x22a, - 0x22b, 0x22c, 0x22d, 0x27c, 0x27d, 0x534 + 0x0, 0x16, 0x39, 0x68, 0x128, 0x184, 0x1e5, 0x1fb, + 0x21d, 0x23f, 0x240, 0x241, 0x242, 0x243, 0x292, 0x293, + 0x3fc, 0x54a, 0x55f }; /*Collect the unicode lists and glyph_id offsets*/ @@ -672,8 +721,8 @@ static const lv_font_fmt_txt_cmap_t cmaps[] = .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY }, { - .range_start = 61463, .range_length = 1333, .glyph_id_start = 96, - .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 14, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + .range_start = 61441, .range_length = 1376, .glyph_id_start = 96, + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 19, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY } }; diff --git a/src/DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c b/src/displayapp/fonts/jetbrains_mono_extrabold_compressed.c index c9917e40..c9917e40 100644 --- a/src/DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c +++ b/src/displayapp/fonts/jetbrains_mono_extrabold_compressed.c diff --git a/src/DisplayApp/Icons/battery/os_battery_005.c b/src/displayapp/icons/battery/os_battery_005.c index 64832b5c..64832b5c 100644 --- a/src/DisplayApp/Icons/battery/os_battery_005.c +++ b/src/displayapp/icons/battery/os_battery_005.c diff --git a/src/DisplayApp/Icons/battery/os_battery_005.png b/src/displayapp/icons/battery/os_battery_005.png Binary files differindex 963767be..963767be 100644 --- a/src/DisplayApp/Icons/battery/os_battery_005.png +++ b/src/displayapp/icons/battery/os_battery_005.png diff --git a/src/DisplayApp/Icons/battery/os_battery_010.c b/src/displayapp/icons/battery/os_battery_010.c index f36b684b..f36b684b 100644 --- a/src/DisplayApp/Icons/battery/os_battery_010.c +++ b/src/displayapp/icons/battery/os_battery_010.c diff --git a/src/DisplayApp/Icons/battery/os_battery_010.png b/src/displayapp/icons/battery/os_battery_010.png Binary files differindex 68a9f406..68a9f406 100644 --- a/src/DisplayApp/Icons/battery/os_battery_010.png +++ b/src/displayapp/icons/battery/os_battery_010.png diff --git a/src/DisplayApp/Icons/battery/os_battery_020.c b/src/displayapp/icons/battery/os_battery_020.c index 3f648fb9..3f648fb9 100644 --- a/src/DisplayApp/Icons/battery/os_battery_020.c +++ b/src/displayapp/icons/battery/os_battery_020.c diff --git a/src/DisplayApp/Icons/battery/os_battery_020.png b/src/displayapp/icons/battery/os_battery_020.png Binary files differindex 32eca651..32eca651 100644 --- a/src/DisplayApp/Icons/battery/os_battery_020.png +++ b/src/displayapp/icons/battery/os_battery_020.png diff --git a/src/DisplayApp/Icons/battery/os_battery_030.c b/src/displayapp/icons/battery/os_battery_030.c index 4d5719b7..4d5719b7 100644 --- a/src/DisplayApp/Icons/battery/os_battery_030.c +++ b/src/displayapp/icons/battery/os_battery_030.c diff --git a/src/DisplayApp/Icons/battery/os_battery_030.png b/src/displayapp/icons/battery/os_battery_030.png Binary files differindex aeb5eb1f..aeb5eb1f 100644 --- a/src/DisplayApp/Icons/battery/os_battery_030.png +++ b/src/displayapp/icons/battery/os_battery_030.png diff --git a/src/DisplayApp/Icons/battery/os_battery_040.c b/src/displayapp/icons/battery/os_battery_040.c index 0606fc35..0606fc35 100644 --- a/src/DisplayApp/Icons/battery/os_battery_040.c +++ b/src/displayapp/icons/battery/os_battery_040.c diff --git a/src/DisplayApp/Icons/battery/os_battery_040.png b/src/displayapp/icons/battery/os_battery_040.png Binary files differindex d84fda40..d84fda40 100644 --- a/src/DisplayApp/Icons/battery/os_battery_040.png +++ b/src/displayapp/icons/battery/os_battery_040.png diff --git a/src/DisplayApp/Icons/battery/os_battery_050.c b/src/displayapp/icons/battery/os_battery_050.c index 8732dc7a..8732dc7a 100644 --- a/src/DisplayApp/Icons/battery/os_battery_050.c +++ b/src/displayapp/icons/battery/os_battery_050.c diff --git a/src/DisplayApp/Icons/battery/os_battery_050.png b/src/displayapp/icons/battery/os_battery_050.png Binary files differindex 224d38d6..224d38d6 100644 --- a/src/DisplayApp/Icons/battery/os_battery_050.png +++ b/src/displayapp/icons/battery/os_battery_050.png diff --git a/src/DisplayApp/Icons/battery/os_battery_060.c b/src/displayapp/icons/battery/os_battery_060.c index a65936bf..a65936bf 100644 --- a/src/DisplayApp/Icons/battery/os_battery_060.c +++ b/src/displayapp/icons/battery/os_battery_060.c diff --git a/src/DisplayApp/Icons/battery/os_battery_060.png b/src/displayapp/icons/battery/os_battery_060.png Binary files differindex e5e00eda..e5e00eda 100644 --- a/src/DisplayApp/Icons/battery/os_battery_060.png +++ b/src/displayapp/icons/battery/os_battery_060.png diff --git a/src/DisplayApp/Icons/battery/os_battery_070.c b/src/displayapp/icons/battery/os_battery_070.c index 949c0b8b..949c0b8b 100644 --- a/src/DisplayApp/Icons/battery/os_battery_070.c +++ b/src/displayapp/icons/battery/os_battery_070.c diff --git a/src/DisplayApp/Icons/battery/os_battery_070.png b/src/displayapp/icons/battery/os_battery_070.png Binary files differindex dee969b8..dee969b8 100644 --- a/src/DisplayApp/Icons/battery/os_battery_070.png +++ b/src/displayapp/icons/battery/os_battery_070.png diff --git a/src/DisplayApp/Icons/battery/os_battery_080.c b/src/displayapp/icons/battery/os_battery_080.c index f447370e..f447370e 100644 --- a/src/DisplayApp/Icons/battery/os_battery_080.c +++ b/src/displayapp/icons/battery/os_battery_080.c diff --git a/src/DisplayApp/Icons/battery/os_battery_080.png b/src/displayapp/icons/battery/os_battery_080.png Binary files differindex 3b13fbb2..3b13fbb2 100644 --- a/src/DisplayApp/Icons/battery/os_battery_080.png +++ b/src/displayapp/icons/battery/os_battery_080.png diff --git a/src/DisplayApp/Icons/battery/os_battery_090.c b/src/displayapp/icons/battery/os_battery_090.c index 6fa41b20..6fa41b20 100644 --- a/src/DisplayApp/Icons/battery/os_battery_090.c +++ b/src/displayapp/icons/battery/os_battery_090.c diff --git a/src/DisplayApp/Icons/battery/os_battery_090.png b/src/displayapp/icons/battery/os_battery_090.png Binary files differindex d79f396b..d79f396b 100644 --- a/src/DisplayApp/Icons/battery/os_battery_090.png +++ b/src/displayapp/icons/battery/os_battery_090.png diff --git a/src/DisplayApp/Icons/battery/os_battery_100.c b/src/displayapp/icons/battery/os_battery_100.c index 92cf9a41..92cf9a41 100644 --- a/src/DisplayApp/Icons/battery/os_battery_100.c +++ b/src/displayapp/icons/battery/os_battery_100.c diff --git a/src/DisplayApp/Icons/battery/os_battery_100.png b/src/displayapp/icons/battery/os_battery_100.png Binary files differindex dd0d306f..dd0d306f 100644 --- a/src/DisplayApp/Icons/battery/os_battery_100.png +++ b/src/displayapp/icons/battery/os_battery_100.png diff --git a/src/DisplayApp/Icons/battery/os_battery_error.c b/src/displayapp/icons/battery/os_battery_error.c index af6aba5d..af6aba5d 100644 --- a/src/DisplayApp/Icons/battery/os_battery_error.c +++ b/src/displayapp/icons/battery/os_battery_error.c diff --git a/src/DisplayApp/Icons/battery/os_battery_error.png b/src/displayapp/icons/battery/os_battery_error.png Binary files differindex 4c7632fe..4c7632fe 100644 --- a/src/DisplayApp/Icons/battery/os_battery_error.png +++ b/src/displayapp/icons/battery/os_battery_error.png diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_005.c b/src/displayapp/icons/battery/os_batterycharging_005.c index 1b0c71df..1b0c71df 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_005.c +++ b/src/displayapp/icons/battery/os_batterycharging_005.c diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_005.png b/src/displayapp/icons/battery/os_batterycharging_005.png Binary files differindex f9545bc1..f9545bc1 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_005.png +++ b/src/displayapp/icons/battery/os_batterycharging_005.png diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_010.c b/src/displayapp/icons/battery/os_batterycharging_010.c index 304c0184..304c0184 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_010.c +++ b/src/displayapp/icons/battery/os_batterycharging_010.c diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_010.png b/src/displayapp/icons/battery/os_batterycharging_010.png Binary files differindex 04d5f820..04d5f820 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_010.png +++ b/src/displayapp/icons/battery/os_batterycharging_010.png diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_020.c b/src/displayapp/icons/battery/os_batterycharging_020.c index 1721be15..1721be15 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_020.c +++ b/src/displayapp/icons/battery/os_batterycharging_020.c diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_020.png b/src/displayapp/icons/battery/os_batterycharging_020.png Binary files differindex 6416e1e6..6416e1e6 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_020.png +++ b/src/displayapp/icons/battery/os_batterycharging_020.png diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_030.c b/src/displayapp/icons/battery/os_batterycharging_030.c index 83101fd9..83101fd9 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_030.c +++ b/src/displayapp/icons/battery/os_batterycharging_030.c diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_030.png b/src/displayapp/icons/battery/os_batterycharging_030.png Binary files differindex 96b44d2e..96b44d2e 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_030.png +++ b/src/displayapp/icons/battery/os_batterycharging_030.png diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_040.c b/src/displayapp/icons/battery/os_batterycharging_040.c index 02af00e5..02af00e5 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_040.c +++ b/src/displayapp/icons/battery/os_batterycharging_040.c diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_040.png b/src/displayapp/icons/battery/os_batterycharging_040.png Binary files differindex 5a42caf2..5a42caf2 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_040.png +++ b/src/displayapp/icons/battery/os_batterycharging_040.png diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_050.c b/src/displayapp/icons/battery/os_batterycharging_050.c index d2eea829..d2eea829 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_050.c +++ b/src/displayapp/icons/battery/os_batterycharging_050.c diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_050.png b/src/displayapp/icons/battery/os_batterycharging_050.png Binary files differindex ca0e04dd..ca0e04dd 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_050.png +++ b/src/displayapp/icons/battery/os_batterycharging_050.png diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_060.c b/src/displayapp/icons/battery/os_batterycharging_060.c index 05f8b975..05f8b975 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_060.c +++ b/src/displayapp/icons/battery/os_batterycharging_060.c diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_060.png b/src/displayapp/icons/battery/os_batterycharging_060.png Binary files differindex 2930068a..2930068a 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_060.png +++ b/src/displayapp/icons/battery/os_batterycharging_060.png diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_070.c b/src/displayapp/icons/battery/os_batterycharging_070.c index ac3e319c..ac3e319c 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_070.c +++ b/src/displayapp/icons/battery/os_batterycharging_070.c diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_070.png b/src/displayapp/icons/battery/os_batterycharging_070.png Binary files differindex 7d5f55d7..7d5f55d7 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_070.png +++ b/src/displayapp/icons/battery/os_batterycharging_070.png diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_080.c b/src/displayapp/icons/battery/os_batterycharging_080.c index cc1c1d23..cc1c1d23 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_080.c +++ b/src/displayapp/icons/battery/os_batterycharging_080.c diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_080.png b/src/displayapp/icons/battery/os_batterycharging_080.png Binary files differindex cce5052f..cce5052f 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_080.png +++ b/src/displayapp/icons/battery/os_batterycharging_080.png diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_090.c b/src/displayapp/icons/battery/os_batterycharging_090.c index 85e1c260..85e1c260 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_090.c +++ b/src/displayapp/icons/battery/os_batterycharging_090.c diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_090.png b/src/displayapp/icons/battery/os_batterycharging_090.png Binary files differindex fc7b443d..fc7b443d 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_090.png +++ b/src/displayapp/icons/battery/os_batterycharging_090.png diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_100.c b/src/displayapp/icons/battery/os_batterycharging_100.c index 8dec0cb5..8dec0cb5 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_100.c +++ b/src/displayapp/icons/battery/os_batterycharging_100.c diff --git a/src/DisplayApp/Icons/battery/os_batterycharging_100.png b/src/displayapp/icons/battery/os_batterycharging_100.png Binary files differindex 7c8ce0c4..7c8ce0c4 100644 --- a/src/DisplayApp/Icons/battery/os_batterycharging_100.png +++ b/src/displayapp/icons/battery/os_batterycharging_100.png diff --git a/src/DisplayApp/Icons/bluetooth/ck_os_bt_connected.png b/src/displayapp/icons/bluetooth/ck_os_bt_connected.png Binary files differindex 53716115..53716115 100644 --- a/src/DisplayApp/Icons/bluetooth/ck_os_bt_connected.png +++ b/src/displayapp/icons/bluetooth/ck_os_bt_connected.png diff --git a/src/DisplayApp/Icons/bluetooth/ck_os_bt_disconnected.png b/src/displayapp/icons/bluetooth/ck_os_bt_disconnected.png Binary files differindex 3275895d..3275895d 100644 --- a/src/DisplayApp/Icons/bluetooth/ck_os_bt_disconnected.png +++ b/src/displayapp/icons/bluetooth/ck_os_bt_disconnected.png diff --git a/src/DisplayApp/Icons/bluetooth/os_bt_connected.c b/src/displayapp/icons/bluetooth/os_bt_connected.c index d30dc9d0..d30dc9d0 100644 --- a/src/DisplayApp/Icons/bluetooth/os_bt_connected.c +++ b/src/displayapp/icons/bluetooth/os_bt_connected.c diff --git a/src/DisplayApp/Icons/bluetooth/os_bt_connected.png b/src/displayapp/icons/bluetooth/os_bt_connected.png Binary files differindex 53716115..53716115 100644 --- a/src/DisplayApp/Icons/bluetooth/os_bt_connected.png +++ b/src/displayapp/icons/bluetooth/os_bt_connected.png diff --git a/src/DisplayApp/Icons/bluetooth/os_bt_disconnected.c b/src/displayapp/icons/bluetooth/os_bt_disconnected.c index 930179b6..930179b6 100644 --- a/src/DisplayApp/Icons/bluetooth/os_bt_disconnected.c +++ b/src/displayapp/icons/bluetooth/os_bt_disconnected.c diff --git a/src/DisplayApp/Icons/bluetooth/os_bt_disconnected.png b/src/displayapp/icons/bluetooth/os_bt_disconnected.png Binary files differindex 3275895d..3275895d 100644 --- a/src/DisplayApp/Icons/bluetooth/os_bt_disconnected.png +++ b/src/displayapp/icons/bluetooth/os_bt_disconnected.png diff --git a/src/displayapp/icons/music/disc.cpp b/src/displayapp/icons/music/disc.cpp new file mode 100644 index 00000000..0957873f --- /dev/null +++ b/src/displayapp/icons/music/disc.cpp @@ -0,0 +1,110 @@ +/* Copyright (C) 2020 Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ +#pragma once + +#include "lvgl/lvgl.h" + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMG_DISC +#define LV_ATTRIBUTE_IMG_DISC +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_DISC uint8_t disc_map[] = { + 0xbd, 0xc1, 0xbe, 0xff, /* Color of index 0: foreground */ + 0x00, 0x00, 0x00, 0x00, /* Color of index 1: background */ + + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x0f, 0xf8, 0x07, 0xff, 0xff, + 0xff, 0xff, 0xc0, 0xff, 0xff, 0x81, 0xff, 0xff, + 0xff, 0xff, 0x07, 0xff, 0xff, 0xf0, 0x7f, 0xff, + 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xfc, 0x1f, 0xff, + 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0x0f, 0xff, + 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, + 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, + 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, + 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, + 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, + 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, + 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, + 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, + 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, + 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, + 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, + 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x8f, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xff, 0xf8, + 0x9f, 0xff, 0xff, 0xf0, 0x07, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe3, 0xe3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe7, 0xf3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe7, 0xf3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe7, 0xf3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe7, 0xf3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe7, 0xf3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe3, 0xe3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xf0, 0x07, 0xff, 0xff, 0xfc, + 0x8f, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xff, 0xf8, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, + 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, + 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, + 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, + 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, + 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, + 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, + 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, + 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, + 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, + 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, + 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0x0f, 0xff, + 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xfc, 0x1f, 0xff, + 0xff, 0xff, 0x07, 0xff, 0xff, 0xf0, 0x7f, 0xff, + 0xff, 0xff, 0xc0, 0xff, 0xff, 0x81, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x0f, 0xf8, 0x07, 0xff, 0xff, + 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, +}; + +const lv_img_dsc_t disc = { + { + LV_IMG_CF_INDEXED_1BIT, + 0, + 0, + 64, + 64 + }, + 520, + disc_map +};
\ No newline at end of file diff --git a/src/displayapp/icons/music/disc.png b/src/displayapp/icons/music/disc.png Binary files differnew file mode 100644 index 00000000..699734fb --- /dev/null +++ b/src/displayapp/icons/music/disc.png diff --git a/src/displayapp/icons/music/disc_f_1.cpp b/src/displayapp/icons/music/disc_f_1.cpp new file mode 100644 index 00000000..9b6b7417 --- /dev/null +++ b/src/displayapp/icons/music/disc_f_1.cpp @@ -0,0 +1,79 @@ +/* Copyright (C) 2020 Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ +#pragma once + +#include "lvgl/lvgl.h" + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMG_DISC_F_1 +#define LV_ATTRIBUTE_IMG_DISC_F_1 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_DISC_F_1 uint8_t disc_f_1_map[] = { + 0xbd, 0xc1, 0xbe, 0xff, /* Color of index 0: foreground */ + 0x00, 0x00, 0x00, 0x00, /* Color of index 1: background */ + + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfc, 0x00, + 0xff, 0xff, 0xf0, 0x0f, + 0xff, 0xff, 0xc0, 0xff, + 0xff, 0xff, 0x07, 0xff, + 0xff, 0xfc, 0x1f, 0xff, + 0xff, 0xf8, 0x7f, 0xff, + 0xff, 0xf0, 0xff, 0xff, + 0xff, 0xe3, 0xff, 0xff, + 0xff, 0xc7, 0xf3, 0xff, + 0xff, 0x8f, 0xc3, 0xff, + 0xff, 0x1f, 0x87, 0xff, + 0xfe, 0x3f, 0x0f, 0xff, + 0xfc, 0x7e, 0x1f, 0xff, + 0xfc, 0x7c, 0x3f, 0xff, + 0xf8, 0xfc, 0x7f, 0xff, + 0xf9, 0xfc, 0xff, 0xff, + 0xf1, 0xff, 0xff, 0xff, + 0xf3, 0xff, 0xff, 0xff, + 0xe3, 0xff, 0xff, 0xff, + 0xe7, 0xff, 0xff, 0xff, + 0xc7, 0xff, 0xff, 0xff, + 0xc7, 0xff, 0xff, 0xff, + 0xcf, 0xff, 0xff, 0xff, + 0xcf, 0xff, 0xff, 0xff, + 0x8f, 0xff, 0xff, 0xff, + 0x8f, 0xff, 0xff, 0xf8, + 0x9f, 0xff, 0xff, 0xf0, + 0x9f, 0xff, 0xff, 0xe3, + 0x9f, 0xff, 0xff, 0xe7, + 0x9f, 0xff, 0xff, 0xe7, +}; + +const lv_img_dsc_t disc_f_1 = { + { + LV_IMG_CF_INDEXED_1BIT, + 0, + 0, + 32, + 32 + }, + 136, + disc_f_1_map +}; + diff --git a/src/displayapp/icons/music/disc_f_1.png b/src/displayapp/icons/music/disc_f_1.png Binary files differnew file mode 100644 index 00000000..94657734 --- /dev/null +++ b/src/displayapp/icons/music/disc_f_1.png diff --git a/src/displayapp/icons/music/disc_f_2.cpp b/src/displayapp/icons/music/disc_f_2.cpp new file mode 100644 index 00000000..3d2331d1 --- /dev/null +++ b/src/displayapp/icons/music/disc_f_2.cpp @@ -0,0 +1,79 @@ +/* Copyright (C) 2020 Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ +#pragma once + +#include "lvgl/lvgl.h" + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMG_DISC_F_2 +#define LV_ATTRIBUTE_IMG_DISC_F_2 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_DISC_F_2 uint8_t disc_f_2_map[] = { + 0xbd, 0xc1, 0xbe, 0xff, /* Color of index 0: foreground */ + 0x00, 0x00, 0x00, 0x00, /* Color of index 1: background */ + + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfc, 0x00, + 0xff, 0xff, 0xf0, 0x0f, + 0xff, 0xff, 0xc0, 0xff, + 0xff, 0xff, 0x07, 0xff, + 0xff, 0xfc, 0x1f, 0xff, + 0xff, 0xf8, 0x7f, 0xf1, + 0xff, 0xf0, 0xff, 0x00, + 0xff, 0xe3, 0xfc, 0x03, + 0xff, 0xc7, 0xf0, 0x3f, + 0xff, 0x8f, 0xf0, 0xff, + 0xff, 0x1f, 0xf3, 0xff, + 0xfe, 0x3f, 0xff, 0xff, + 0xfc, 0x7f, 0xff, 0xff, + 0xfc, 0x7f, 0xff, 0xff, + 0xf8, 0xff, 0xff, 0xff, + 0xf9, 0xff, 0xff, 0xff, + 0xf1, 0xff, 0xff, 0xff, + 0xf3, 0xff, 0xff, 0xff, + 0xe3, 0xff, 0xff, 0xff, + 0xe7, 0xff, 0xff, 0xff, + 0xc7, 0xff, 0xff, 0xff, + 0xc7, 0xff, 0xff, 0xff, + 0xcf, 0xff, 0xff, 0xff, + 0xcf, 0xff, 0xff, 0xff, + 0x8f, 0xff, 0xff, 0xff, + 0x8f, 0xff, 0xff, 0xf8, + 0x9f, 0xff, 0xff, 0xf0, + 0x9f, 0xff, 0xff, 0xe3, + 0x9f, 0xff, 0xff, 0xe7, + 0x9f, 0xff, 0xff, 0xe7, +}; + +const lv_img_dsc_t disc_f_2 = { + { + LV_IMG_CF_INDEXED_1BIT, + 0, + 0, + 32, + 32 + }, + 136, + disc_f_2_map +}; + diff --git a/src/displayapp/icons/music/disc_f_2.png b/src/displayapp/icons/music/disc_f_2.png Binary files differnew file mode 100644 index 00000000..4d9a4a38 --- /dev/null +++ b/src/displayapp/icons/music/disc_f_2.png diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp new file mode 100644 index 00000000..7eb97188 --- /dev/null +++ b/src/displayapp/screens/ApplicationList.cpp @@ -0,0 +1,82 @@ +#include <libs/lvgl/lvgl.h> +#include <displayapp/DisplayApp.h> +#include <functional> +#include "ApplicationList.h" +#include "Tile.h" +#include "Symbols.h" + +using namespace Pinetime::Applications::Screens; + +ApplicationList::ApplicationList(Pinetime::Applications::DisplayApp *app) : + Screen(app), + screens{app, { + [this]() -> std::unique_ptr<Screen> { return CreateScreen1(); }, + [this]() -> std::unique_ptr<Screen> { return CreateScreen2(); }, + //[this]() -> std::unique_ptr<Screen> { return CreateScreen3(); } + } + } {} + + +ApplicationList::~ApplicationList() { + lv_obj_clean(lv_scr_act()); +} + +bool ApplicationList::Refresh() { + if(running) + running = screens.Refresh(); + return running; +} + +bool ApplicationList::OnButtonPushed() { + running = false; + app->StartApp(Apps::Clock); + return true; +} + +bool ApplicationList::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return screens.OnTouchEvent(event); +} + +std::unique_ptr<Screen> ApplicationList::CreateScreen1() { + std::array<Screens::Tile::Applications, 6> applications { + {{Symbols::clock, Apps::Clock}, + {Symbols::music, Apps::Music}, + {Symbols::sun, Apps::Brightness}, + {Symbols::list, Apps::SysInfo}, + {Symbols::check, Apps::FirmwareValidation}, + {Symbols::none, Apps::None} + } + + + }; + + return std::unique_ptr<Screen>(new Screens::Tile(app, applications)); +} + +std::unique_ptr<Screen> ApplicationList::CreateScreen2() { + std::array<Screens::Tile::Applications, 6> applications { + {{Symbols::tachometer, Apps::Gauge}, + {Symbols::asterisk, Apps::Meter}, + {Symbols::paintbrush, Apps::Paint}, + {Symbols::info, Apps::Notifications}, + {Symbols::none, Apps::None}, + {Symbols::none, Apps::None} + } + }; + + return std::unique_ptr<Screen>(new Screens::Tile(app, applications)); +} + +std::unique_ptr<Screen> ApplicationList::CreateScreen3() { + std::array<Screens::Tile::Applications, 6> applications { + {{"A", Apps::Meter}, + {"B", Apps::Gauge}, + {"C", Apps::Clock}, + {"D", Apps::Music}, + {"E", Apps::SysInfo}, + {"F", Apps::Brightness} + } + }; + + return std::unique_ptr<Screen>(new Screens::Tile(app, applications)); +} diff --git a/src/displayapp/screens/ApplicationList.h b/src/displayapp/screens/ApplicationList.h new file mode 100644 index 00000000..9c95acb8 --- /dev/null +++ b/src/displayapp/screens/ApplicationList.h @@ -0,0 +1,33 @@ +#pragma once + +#include <functional> +#include <vector> + +#include "components/ble/NimbleController.h" +#include "Screen.h" +#include "Label.h" +#include "ScreenList.h" +#include "Gauge.h" +#include "Meter.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class ApplicationList : public Screen { + public: + explicit ApplicationList(DisplayApp* app); + ~ApplicationList() override; + bool Refresh() override; + bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; + private: + bool running = true; + + ScreenList<2> screens; + std::unique_ptr<Screen> CreateScreen1(); + std::unique_ptr<Screen> CreateScreen2(); + std::unique_ptr<Screen> CreateScreen3(); + }; + } + } +}
\ No newline at end of file diff --git a/src/DisplayApp/Screens/BatteryIcon.cpp b/src/displayapp/screens/BatteryIcon.cpp index 26939d18..26939d18 100644 --- a/src/DisplayApp/Screens/BatteryIcon.cpp +++ b/src/displayapp/screens/BatteryIcon.cpp diff --git a/src/DisplayApp/Screens/BatteryIcon.h b/src/displayapp/screens/BatteryIcon.h index 58f04a87..58f04a87 100644 --- a/src/DisplayApp/Screens/BatteryIcon.h +++ b/src/displayapp/screens/BatteryIcon.h diff --git a/src/DisplayApp/Screens/BleIcon.cpp b/src/displayapp/screens/BleIcon.cpp index 1bbbd053..1bbbd053 100644 --- a/src/DisplayApp/Screens/BleIcon.cpp +++ b/src/displayapp/screens/BleIcon.cpp diff --git a/src/DisplayApp/Screens/BleIcon.h b/src/displayapp/screens/BleIcon.h index c1398d2a..c1398d2a 100644 --- a/src/DisplayApp/Screens/BleIcon.h +++ b/src/displayapp/screens/BleIcon.h diff --git a/src/DisplayApp/Screens/Brightness.cpp b/src/displayapp/screens/Brightness.cpp index 9e3416c0..8ea9a771 100644 --- a/src/DisplayApp/Screens/Brightness.cpp +++ b/src/displayapp/screens/Brightness.cpp @@ -11,15 +11,15 @@ void slider_event_cb(lv_obj_t * slider, lv_event_t event) { } Brightness::Brightness(Pinetime::Applications::DisplayApp *app, Controllers::BrightnessController& brightness) : Screen(app), brightness{brightness} { - slider = lv_slider_create(lv_scr_act(), NULL); + slider = lv_slider_create(lv_scr_act(), nullptr); 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_align(slider, nullptr, 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); + slider_label = lv_label_create(lv_scr_act(), nullptr); 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); diff --git a/src/DisplayApp/Screens/Brightness.h b/src/displayapp/screens/Brightness.h index 37cbcd7e..7d599acf 100644 --- a/src/DisplayApp/Screens/Brightness.h +++ b/src/displayapp/screens/Brightness.h @@ -1,7 +1,7 @@ #pragma once #include <libs/lvgl/src/lv_core/lv_obj.h> -#include <Components/Brightness/BrightnessController.h> +#include "components/brightness/BrightnessController.h" #include "Screen.h" namespace Pinetime { diff --git a/src/DisplayApp/Screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index fc6441e8..977321c1 100644 --- a/src/DisplayApp/Screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -1,12 +1,16 @@ #include <cstdio> + #include <libs/date/includes/date/date.h> -#include <Components/DateTime/DateTimeController.h> +#include "components/datetime/DateTimeController.h" #include <libs/lvgl/lvgl.h> #include "Clock.h" #include "../DisplayApp.h" #include "BatteryIcon.h" #include "BleIcon.h" #include "Symbols.h" +#include "components/ble/NotificationManager.h" +#include "NotificationIcon.h" + using namespace Pinetime::Applications::Screens; extern lv_font_t jetbrains_mono_extrabold_compressed; extern lv_font_t jetbrains_mono_bold_20; @@ -20,36 +24,41 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) { Clock::Clock(DisplayApp* app, Controllers::DateTime& dateTimeController, Controllers::Battery& batteryController, - Controllers::Ble& bleController) : Screen(app), currentDateTime{{}}, - dateTimeController{dateTimeController}, batteryController{batteryController}, bleController{bleController} { + Controllers::Ble& bleController, + Controllers::NotificationManager& notificatioManager) : Screen(app), currentDateTime{{}}, + dateTimeController{dateTimeController}, batteryController{batteryController}, + bleController{bleController}, notificatioManager{notificatioManager} { displayedChar[0] = 0; displayedChar[1] = 0; displayedChar[2] = 0; displayedChar[3] = 0; displayedChar[4] = 0; - batteryIcon = lv_label_create(lv_scr_act(), NULL); + batteryIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(batteryIcon, Symbols::batteryFull); lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 2); - batteryPlug = lv_label_create(lv_scr_act(), NULL); + batteryPlug = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(batteryPlug, Symbols::plug); lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); - bleIcon = lv_label_create(lv_scr_act(), NULL); + bleIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(bleIcon, Symbols::bluetooth); lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); + notificationIcon = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); + lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 10, 0); - label_date = lv_label_create(lv_scr_act(), NULL); + label_date = lv_label_create(lv_scr_act(), nullptr); lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60); - label_time = lv_label_create(lv_scr_act(), NULL); + label_time = lv_label_create(lv_scr_act(), nullptr); 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); - backgroundLabel = lv_label_create(lv_scr_act(), NULL); + backgroundLabel = lv_label_create(lv_scr_act(), nullptr); backgroundLabel->user_data = this; lv_obj_set_click(backgroundLabel, true); lv_obj_set_event_cb(backgroundLabel, event_handler); @@ -59,23 +68,23 @@ Clock::Clock(DisplayApp* app, lv_label_set_text(backgroundLabel, ""); - heartbeatIcon = lv_label_create(lv_scr_act(), NULL); + heartbeatIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(heartbeatIcon, Symbols::heartBeat); lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); - heartbeatValue = lv_label_create(lv_scr_act(), NULL); + heartbeatValue = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(heartbeatValue, "0"); lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); - heartbeatBpm = lv_label_create(lv_scr_act(), NULL); + heartbeatBpm = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(heartbeatBpm, "BPM"); lv_obj_align(heartbeatBpm, heartbeatValue, LV_ALIGN_OUT_RIGHT_MID, 5, 0); - stepValue = lv_label_create(lv_scr_act(), NULL); + stepValue = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(stepValue, "0"); lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2); - stepIcon = lv_label_create(lv_scr_act(), NULL); + stepIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(stepIcon, Symbols::shoe); lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); } @@ -105,6 +114,14 @@ bool Clock::Refresh() { lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); + notificationState = notificatioManager.AreNewNotificationsAvailable(); + if(notificationState.IsUpdated()) { + if(notificationState.Get() == true) + lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(true)); + else + lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); + } + currentDateTime = dateTimeController.CurrentDateTime(); if(currentDateTime.IsUpdated()) { @@ -121,13 +138,12 @@ bool Clock::Refresh() { auto hour = time.hours().count(); auto minute = time.minutes().count(); - auto second = time.seconds().count(); char minutesChar[3]; - sprintf(minutesChar, "%02d", minute); + sprintf(minutesChar, "%02d", static_cast<int>(minute)); char hoursChar[3]; - sprintf(hoursChar, "%02d", hour); + sprintf(hoursChar, "%02d", static_cast<int>(hour)); char timeStr[6]; sprintf(timeStr, "%c%c:%c%c", hoursChar[0],hoursChar[1],minutesChar[0], minutesChar[1]); diff --git a/src/DisplayApp/Screens/Clock.h b/src/displayapp/screens/Clock.h index e1e10bdf..58149a79 100644 --- a/src/DisplayApp/Screens/Clock.h +++ b/src/displayapp/screens/Clock.h @@ -2,12 +2,14 @@ #include <cstdint> #include <chrono> + #include "Screen.h" #include <bits/unique_ptr.h> #include <libs/lvgl/src/lv_core/lv_style.h> #include <libs/lvgl/src/lv_core/lv_obj.h> -#include <Components/Battery/BatteryController.h> -#include <Components/Ble/BleController.h> +#include "components/ble/NotificationManager.h" +#include "components/battery/BatteryController.h" +#include "components/ble/BleController.h" namespace Pinetime { namespace Applications { @@ -37,7 +39,8 @@ namespace Pinetime { Clock(DisplayApp* app, Controllers::DateTime& dateTimeController, Controllers::Battery& batteryController, - Controllers::Ble& bleController); + Controllers::Ble& bleController, + Controllers::NotificationManager& notificatioManager); ~Clock() override; bool Refresh() override; @@ -57,28 +60,30 @@ namespace Pinetime { Pinetime::Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown; uint8_t currentDay = 0; - DirtyValue<uint8_t> batteryPercentRemaining {0}; + DirtyValue<float> batteryPercentRemaining {0}; DirtyValue<bool> bleState {false}; DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime; DirtyValue<uint32_t> stepCount {0}; DirtyValue<uint8_t> heartbeat {0}; - + DirtyValue<bool> notificationState {false}; lv_obj_t* label_time; lv_obj_t* label_date; lv_obj_t* backgroundLabel; - lv_obj_t * batteryIcon; - lv_obj_t * bleIcon; + lv_obj_t* batteryIcon; + lv_obj_t* bleIcon; lv_obj_t* batteryPlug; lv_obj_t* heartbeatIcon; lv_obj_t* heartbeatValue; lv_obj_t* heartbeatBpm; lv_obj_t* stepIcon; lv_obj_t* stepValue; + lv_obj_t* notificationIcon; Controllers::DateTime& dateTimeController; Controllers::Battery& batteryController; Controllers::Ble& bleController; + Controllers::NotificationManager& notificatioManager; bool running = true; diff --git a/src/displayapp/screens/DropDownDemo.cpp b/src/displayapp/screens/DropDownDemo.cpp new file mode 100644 index 00000000..ce3acd53 --- /dev/null +++ b/src/displayapp/screens/DropDownDemo.cpp @@ -0,0 +1,64 @@ +#include <libs/lvgl/lvgl.h> +#include <libraries/log/nrf_log.h> +#include "DropDownDemo.h" +#include "../DisplayApp.h" + +using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + +DropDownDemo::DropDownDemo(Pinetime::Applications::DisplayApp *app) : Screen(app) { + // Create the dropdown object, with many item, and fix its height + ddlist = lv_ddlist_create(lv_scr_act(), nullptr); + lv_ddlist_set_options(ddlist, "Apple\n" + "Banana\n" + "Orange\n" + "Melon\n" + "Grape\n" + "Raspberry\n" + "A\n" + "B\n" + "C\n" + "D\n" + "E"); + lv_ddlist_set_fix_width(ddlist, 150); + lv_ddlist_set_draw_arrow(ddlist, true); + lv_ddlist_set_fix_height(ddlist, 150); + lv_obj_align(ddlist, nullptr, LV_ALIGN_IN_TOP_MID, 0, 20); +} + +DropDownDemo::~DropDownDemo() { + // Reset the touchmode + app->SetTouchMode(DisplayApp::TouchModes::Gestures); + lv_obj_clean(lv_scr_act()); +} + +bool DropDownDemo::Refresh() { + auto* list = static_cast<lv_ddlist_ext_t *>(ddlist->ext_attr); + + // Switch touchmode to Polling if the dropdown is opened. This will allow to scroll inside the + // dropdown while it is opened. + // Disable the polling mode when the dropdown is closed to be able to handle the gestures. + if(list->opened) + app->SetTouchMode(DisplayApp::TouchModes::Polling); + else + app->SetTouchMode(DisplayApp::TouchModes::Gestures); + return running; +} + +bool DropDownDemo::OnButtonPushed() { + running = false; + return true; +} + +bool DropDownDemo::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + // If the dropdown is opened, notify Display app that it doesn't need to handle the event + // (this will prevent displayApp from going back to the menu or clock scree). + auto* list = static_cast<lv_ddlist_ext_t *>(ddlist->ext_attr); + if(list->opened) { + return true; + } else { + return false; + } +} + diff --git a/src/displayapp/screens/DropDownDemo.h b/src/displayapp/screens/DropDownDemo.h new file mode 100644 index 00000000..7c75efc0 --- /dev/null +++ b/src/displayapp/screens/DropDownDemo.h @@ -0,0 +1,29 @@ +#pragma once + +#include <cstdint> +#include "Screen.h" +#include <bits/unique_ptr.h> +#include <libs/lvgl/src/lv_core/lv_style.h> +#include <libs/lvgl/src/lv_core/lv_obj.h> + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class DropDownDemo : public Screen{ + public: + DropDownDemo(DisplayApp* app); + ~DropDownDemo() override; + + bool Refresh() override; + bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; + + private: + lv_obj_t * ddlist; + bool running = true; + bool isDropDownOpened = false; + }; + } + } +} diff --git a/src/DisplayApp/Screens/FirmwareUpdate.cpp b/src/displayapp/screens/FirmwareUpdate.cpp index e831114d..778409eb 100644 --- a/src/DisplayApp/Screens/FirmwareUpdate.cpp +++ b/src/displayapp/screens/FirmwareUpdate.cpp @@ -10,19 +10,19 @@ extern lv_font_t jetbrains_mono_bold_20; FirmwareUpdate::FirmwareUpdate(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::Ble& bleController) : Screen(app), bleController{bleController} { - titleLabel = lv_label_create(lv_scr_act(), NULL); + titleLabel = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(titleLabel, "Firmware update"); lv_obj_set_auto_realign(titleLabel, true); - lv_obj_align(titleLabel, NULL, LV_ALIGN_IN_TOP_MID, 0, 50); + lv_obj_align(titleLabel, nullptr, LV_ALIGN_IN_TOP_MID, 0, 50); - bar1 = lv_bar_create(lv_scr_act(), NULL); + bar1 = lv_bar_create(lv_scr_act(), nullptr); lv_obj_set_size(bar1, 200, 30); - lv_obj_align(bar1, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(bar1, nullptr, LV_ALIGN_CENTER, 0, 0); lv_bar_set_anim_time(bar1, 10); lv_bar_set_range(bar1, 0, 100); lv_bar_set_value(bar1, 0, LV_ANIM_OFF); - percentLabel = lv_label_create(lv_scr_act(), NULL); + percentLabel = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(percentLabel, ""); lv_obj_set_auto_realign(percentLabel, true); lv_obj_align(percentLabel, bar1, LV_ALIGN_OUT_TOP_MID, 0, 60); diff --git a/src/DisplayApp/Screens/FirmwareUpdate.h b/src/displayapp/screens/FirmwareUpdate.h index faaf3953..893fe68c 100644 --- a/src/DisplayApp/Screens/FirmwareUpdate.h +++ b/src/displayapp/screens/FirmwareUpdate.h @@ -2,11 +2,12 @@ #include <cstdint> #include <chrono> + #include "Screen.h" #include <bits/unique_ptr.h> #include <libs/lvgl/src/lv_core/lv_style.h> #include <libs/lvgl/src/lv_core/lv_obj.h> -#include <Components/Ble/BleController.h> +#include "components/ble/BleController.h" namespace Pinetime { namespace Applications { diff --git a/src/displayapp/screens/FirmwareValidation.cpp b/src/displayapp/screens/FirmwareValidation.cpp new file mode 100644 index 00000000..4ac399ff --- /dev/null +++ b/src/displayapp/screens/FirmwareValidation.cpp @@ -0,0 +1,91 @@ +#include <libs/lvgl/lvgl.h> +#include "FirmwareValidation.h" +#include "../DisplayApp.h" +#include "../../Version.h" +#include "components/firmwarevalidator/FirmwareValidator.h" + +using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + +namespace { + static void ButtonEventHandler(lv_obj_t * obj, lv_event_t event) + { + FirmwareValidation* screen = static_cast<FirmwareValidation *>(obj->user_data); + screen->OnButtonEvent(obj, event); + } + +} + +FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp *app, + Pinetime::Controllers::FirmwareValidator &validator) + : Screen{app}, validator{validator} { + labelVersionInfo = lv_label_create(lv_scr_act(), nullptr); + lv_obj_align(labelVersionInfo, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); + lv_label_set_text(labelVersionInfo, "Version : "); + lv_label_set_align(labelVersionInfo, LV_LABEL_ALIGN_LEFT); + + + labelVersionValue = lv_label_create(lv_scr_act(), nullptr); + lv_obj_align(labelVersionValue, labelVersionInfo, LV_ALIGN_OUT_RIGHT_MID, 0, 0); + lv_label_set_recolor(labelVersionValue, true); + sprintf(version, "%ld.%ld.%ld", Version::Major(), Version::Minor(), Version::Patch()); + lv_label_set_text(labelVersionValue, version); + + labelIsValidated = lv_label_create(lv_scr_act(), nullptr); + lv_obj_align(labelIsValidated, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 50); + lv_label_set_recolor(labelIsValidated, true); + lv_label_set_long_mode(labelIsValidated, LV_LABEL_LONG_BREAK); + lv_obj_set_width(labelIsValidated, 240); + + if(validator.IsValidated()) + lv_label_set_text(labelIsValidated, "You have already\n#00ff00 validated# this firmware#"); + else { + lv_label_set_text(labelIsValidated, + "Please #00ff00 Validate# this version or\n#ff0000 Reset# to rollback to the previous version."); + + buttonValidate = lv_btn_create(lv_scr_act(), nullptr); + lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + buttonValidate->user_data = this; + lv_obj_set_event_cb(buttonValidate, ButtonEventHandler); + + labelButtonValidate = lv_label_create(buttonValidate, nullptr); + lv_label_set_recolor(labelButtonValidate, true); + lv_label_set_text(labelButtonValidate, "#00ff00 Validate#"); + + buttonReset = lv_btn_create(lv_scr_act(), nullptr); + buttonReset->user_data = this; + lv_obj_align(buttonReset, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + lv_obj_set_event_cb(buttonReset, ButtonEventHandler); + + labelButtonReset = lv_label_create(buttonReset, nullptr); + lv_label_set_recolor(labelButtonReset, true); + lv_label_set_text(labelButtonReset, "#ff0000 Reset#"); + } +} + + +FirmwareValidation::~FirmwareValidation() { + lv_obj_clean(lv_scr_act()); +} + +bool FirmwareValidation::Refresh() { + return running; +} + +bool FirmwareValidation::OnButtonPushed() { + running = false; + return true; +} + +void FirmwareValidation::OnButtonEvent(lv_obj_t *object, lv_event_t event) { + if(object == buttonValidate && event == LV_EVENT_PRESSED) { + validator.Validate(); + running = false; + } else if(object == buttonReset && event == LV_EVENT_PRESSED) { + validator.Reset(); + } + +} + + diff --git a/src/displayapp/screens/FirmwareValidation.h b/src/displayapp/screens/FirmwareValidation.h new file mode 100644 index 00000000..947f5575 --- /dev/null +++ b/src/displayapp/screens/FirmwareValidation.h @@ -0,0 +1,42 @@ +#pragma once + +#include <cstdint> +#include "Screen.h" +#include <bits/unique_ptr.h> +#include <libs/lvgl/src/lv_core/lv_style.h> +#include <libs/lvgl/src/lv_core/lv_obj.h> + +namespace Pinetime { + namespace Controllers { + class FirmwareValidator; + } + + namespace Applications { + namespace Screens { + + class FirmwareValidation : public Screen{ + public: + FirmwareValidation(DisplayApp* app, Pinetime::Controllers::FirmwareValidator& validator); + ~FirmwareValidation() override; + + bool Refresh() override; + bool OnButtonPushed() override; + + void OnButtonEvent(lv_obj_t *object, lv_event_t event); + + private: + Pinetime::Controllers::FirmwareValidator& validator; + + lv_obj_t* labelVersionInfo; + lv_obj_t* labelVersionValue; + char version[9]; + lv_obj_t* labelIsValidated; + lv_obj_t* buttonValidate; + lv_obj_t* labelButtonValidate; + lv_obj_t* buttonReset; + lv_obj_t* labelButtonReset; + bool running = true; + }; + } + } +} diff --git a/src/DisplayApp/Screens/Gauge.cpp b/src/displayapp/screens/Gauge.cpp index fd905231..81c283ca 100644 --- a/src/DisplayApp/Screens/Gauge.cpp +++ b/src/displayapp/screens/Gauge.cpp @@ -25,11 +25,11 @@ Gauge::Gauge(Pinetime::Applications::DisplayApp *app) : Screen(app) { needle_colors[0] = LV_COLOR_ORANGE; /*Create a gauge*/ - gauge1 = lv_gauge_create(lv_scr_act(), NULL); + gauge1 = lv_gauge_create(lv_scr_act(), nullptr); lv_gauge_set_style(gauge1, LV_GAUGE_STYLE_MAIN, &style); lv_gauge_set_needle_count(gauge1, 1, needle_colors); lv_obj_set_size(gauge1, 180, 180); - lv_obj_align(gauge1, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(gauge1, nullptr, LV_ALIGN_CENTER, 0, 0); lv_gauge_set_scale(gauge1, 360, 60, 0); lv_gauge_set_range(gauge1, 0, 59); diff --git a/src/DisplayApp/Screens/Gauge.h b/src/displayapp/screens/Gauge.h index 03c06bed..03c06bed 100644 --- a/src/DisplayApp/Screens/Gauge.h +++ b/src/displayapp/screens/Gauge.h diff --git a/src/displayapp/screens/InfiniPaint.cpp b/src/displayapp/screens/InfiniPaint.cpp new file mode 100644 index 00000000..3ea75e9e --- /dev/null +++ b/src/displayapp/screens/InfiniPaint.cpp @@ -0,0 +1,44 @@ +#include <libs/lvgl/lvgl.h> +#include <libraries/log/nrf_log.h> +#include "InfiniPaint.h" +#include "../DisplayApp.h" + +using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + +InfiniPaint::InfiniPaint(Pinetime::Applications::DisplayApp* app, Pinetime::Components::LittleVgl& lvgl) : Screen(app), lvgl{lvgl} { + app->SetTouchMode(DisplayApp::TouchModes::Polling); + std::fill(b, b + bufferSize, LV_COLOR_WHITE); +} + +InfiniPaint::~InfiniPaint() { + // Reset the touchmode + app->SetTouchMode(DisplayApp::TouchModes::Gestures); + lv_obj_clean(lv_scr_act()); +} + +bool InfiniPaint::Refresh() { + return running; +} + +bool InfiniPaint::OnButtonPushed() { + running = false; + return true; +} + +bool InfiniPaint::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return true; +} + +bool InfiniPaint::OnTouchEvent(uint16_t x, uint16_t y) { + lv_area_t area; + area.x1 = x - (width / 2); + area.y1 = y - (height / 2); + area.x2 = x + (width / 2) - 1; + area.y2 = y + (height / 2) - 1; + lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::None); + lvgl.FlushDisplay(&area, b); + return true; +} + diff --git a/src/displayapp/screens/InfiniPaint.h b/src/displayapp/screens/InfiniPaint.h new file mode 100644 index 00000000..f29135d5 --- /dev/null +++ b/src/displayapp/screens/InfiniPaint.h @@ -0,0 +1,39 @@ +#pragma once + +#include <cstdint> +#include "Screen.h" +#include <bits/unique_ptr.h> +#include <libs/lvgl/src/lv_core/lv_style.h> +#include <libs/lvgl/src/lv_core/lv_obj.h> +#include <drivers/St7789.h> +#include "displayapp/LittleVgl.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class InfiniPaint : public Screen { + public: + InfiniPaint(DisplayApp* app, Pinetime::Components::LittleVgl& lvgl); + + ~InfiniPaint() override; + + bool Refresh() override; + + bool OnButtonPushed() override; + + bool OnTouchEvent(TouchEvents event) override; + + bool OnTouchEvent(uint16_t x, uint16_t y) override; + + private: + Pinetime::Components::LittleVgl& lvgl; + static constexpr uint16_t width = 10; + static constexpr uint16_t height = 10; + static constexpr uint16_t bufferSize = width * height; + lv_color_t b[bufferSize]; + bool running = true; + }; + } + } +} diff --git a/src/DisplayApp/Screens/Label.cpp b/src/displayapp/screens/Label.cpp index ba35279d..540776cc 100644 --- a/src/DisplayApp/Screens/Label.cpp +++ b/src/displayapp/screens/Label.cpp @@ -3,26 +3,13 @@ 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); +Label::Label(Pinetime::Applications::DisplayApp *app, const char *text) : Screen(app), text{text} { + label = lv_label_create(lv_scr_act(), nullptr); 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() { +Label::~Label() { lv_obj_clean(lv_scr_act()); } diff --git a/src/DisplayApp/Screens/Label.h b/src/displayapp/screens/Label.h index b73540f4..3e7b3797 100644 --- a/src/DisplayApp/Screens/Label.h +++ b/src/displayapp/screens/Label.h @@ -2,19 +2,18 @@ #include <vector> #include "Screen.h" +#include <lvgl/lvgl.h> namespace Pinetime { namespace Applications { namespace Screens { - class Label { + + class Label : public Screen { public: - Label() = default; - explicit Label(const char* text); - ~Label(); - void Refresh(); + Label(DisplayApp* app, const char* text); + ~Label() override; + bool Refresh() override {return false;} - void Hide(); - void Show(); private: lv_obj_t * label = nullptr; const char* text = nullptr; diff --git a/src/DisplayApp/Screens/Meter.cpp b/src/displayapp/screens/Meter.cpp index c74b8bdf..273e111d 100644 --- a/src/DisplayApp/Screens/Meter.cpp +++ b/src/displayapp/screens/Meter.cpp @@ -17,14 +17,14 @@ Meter::Meter(Pinetime::Applications::DisplayApp *app) : Screen(app) { style_lmeter.body.padding.left = 16; /*Line length*/ /*Create a line meter */ - lmeter = lv_lmeter_create(lv_scr_act(), NULL); + lmeter = lv_lmeter_create(lv_scr_act(), nullptr); lv_lmeter_set_range(lmeter, 0, 60); /*Set the range*/ lv_lmeter_set_value(lmeter, value); /*Set the current value*/ lv_lmeter_set_angle_offset(lmeter, 180); lv_lmeter_set_scale(lmeter, 360, 60); /*Set the angle and number of lines*/ lv_lmeter_set_style(lmeter, LV_LMETER_STYLE_MAIN, &style_lmeter); /*Apply the new style*/ lv_obj_set_size(lmeter, 150, 150); - lv_obj_align(lmeter, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(lmeter, nullptr, LV_ALIGN_CENTER, 0, 0); } diff --git a/src/DisplayApp/Screens/Meter.h b/src/displayapp/screens/Meter.h index ddf8be8d..ddf8be8d 100644 --- a/src/DisplayApp/Screens/Meter.h +++ b/src/displayapp/screens/Meter.h diff --git a/src/DisplayApp/Screens/Modal.cpp b/src/displayapp/screens/Modal.cpp index 63ae70c0..29f7bfa7 100644 --- a/src/DisplayApp/Screens/Modal.cpp +++ b/src/displayapp/screens/Modal.cpp @@ -54,7 +54,7 @@ void Modal::Show(const char* msg) { 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); + obj = lv_obj_create(lv_scr_act(), nullptr); 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); @@ -63,10 +63,10 @@ void Modal::Show(const char* msg) { static const char * btns2[] = {"Ok", ""}; /* Create the message box as a child of the modal background */ - mbox = lv_mbox_create(obj, NULL); + mbox = lv_mbox_create(obj, nullptr); lv_mbox_add_btns(mbox, btns2); lv_mbox_set_text(mbox, msg); - lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(mbox, nullptr, LV_ALIGN_CENTER, 0, 0); lv_obj_set_event_cb(mbox, Modal::mbox_event_cb); mbox->user_data = this; diff --git a/src/DisplayApp/Screens/Modal.h b/src/displayapp/screens/Modal.h index c616c294..c616c294 100644 --- a/src/DisplayApp/Screens/Modal.h +++ b/src/displayapp/screens/Modal.h diff --git a/src/displayapp/screens/Music.cpp b/src/displayapp/screens/Music.cpp new file mode 100644 index 00000000..225a15a4 --- /dev/null +++ b/src/displayapp/screens/Music.cpp @@ -0,0 +1,292 @@ +/* Copyright (C) 2020 JF, Adam Pigg, Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ +#include <libs/lvgl/lvgl.h> + +#include "Music.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) { + Music *screen = static_cast<Music *>(obj->user_data); + screen->OnObjectEvent(obj, event); +} + +/** + * Set the pixel array to display by the image + * This just calls lv_img_set_src but adds type safety + * + * @param img pointer to an image object + * @param data the image array + */ +inline void lv_img_set_src_arr(lv_obj_t *img, const lv_img_dsc_t *src_img) { + lv_img_set_src(img, src_img); +} + +/** + * Music control watchapp + * + * TODO: Investigate Apple Media Service and AVRCPv1.6 support for seamless integration + */ +Music::Music(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::MusicService &music) : Screen(app), musicService(music) { + lv_obj_t *label; + + btnVolDown = lv_btn_create(lv_scr_act(), nullptr); + btnVolDown->user_data = this; + lv_obj_set_event_cb(btnVolDown, event_handler); + lv_obj_set_size(btnVolDown, LV_HOR_RES / 3, 80); + lv_obj_align(btnVolDown, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + label = lv_label_create(btnVolDown, nullptr); + lv_label_set_text(label, "V-"); + lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); + + btnVolUp = lv_btn_create(lv_scr_act(), nullptr); + btnVolUp->user_data = this; + lv_obj_set_event_cb(btnVolUp, event_handler); + lv_obj_set_size(btnVolUp, LV_HOR_RES / 3, 80); + lv_obj_align(btnVolUp, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + label = lv_label_create(btnVolUp, nullptr); + lv_label_set_text(label, "V+"); + lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); + + btnPrev = lv_btn_create(lv_scr_act(), nullptr); + btnPrev->user_data = this; + lv_obj_set_event_cb(btnPrev, event_handler); + lv_obj_set_size(btnPrev, LV_HOR_RES / 3, 80); + lv_obj_align(btnPrev, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + label = lv_label_create(btnPrev, nullptr); + lv_label_set_text(label, "<<"); + + btnNext = lv_btn_create(lv_scr_act(), nullptr); + btnNext->user_data = this; + lv_obj_set_event_cb(btnNext, event_handler); + lv_obj_set_size(btnNext, LV_HOR_RES / 3, 80); + lv_obj_align(btnNext, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + label = lv_label_create(btnNext, nullptr); + lv_label_set_text(label, ">>"); + + btnPlayPause = lv_btn_create(lv_scr_act(), nullptr); + btnPlayPause->user_data = this; + lv_obj_set_event_cb(btnPlayPause, event_handler); + lv_obj_set_size(btnPlayPause, LV_HOR_RES / 3, 80); + lv_obj_align(btnPlayPause, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + txtPlayPause = lv_label_create(btnPlayPause, nullptr); + lv_label_set_text(txtPlayPause, ">"); + + txtTrackDuration = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_long_mode(txtTrackDuration, LV_LABEL_LONG_SROLL); + lv_obj_align(txtTrackDuration, nullptr, LV_ALIGN_IN_TOP_LEFT, 12, 20); + lv_label_set_text(txtTrackDuration, "--:--/--:--"); + lv_label_set_align(txtTrackDuration, LV_ALIGN_IN_LEFT_MID); + lv_obj_set_width(txtTrackDuration, LV_HOR_RES); + + constexpr uint8_t FONT_HEIGHT = 12; + constexpr uint8_t LINE_PAD = 15; + constexpr int8_t MIDDLE_OFFSET = -25; + txtArtist = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_long_mode(txtArtist, LV_LABEL_LONG_SROLL); + lv_obj_align(txtArtist, nullptr, LV_ALIGN_IN_LEFT_MID, 12, MIDDLE_OFFSET + 1 * FONT_HEIGHT); + lv_label_set_text(txtArtist, "Artist Name"); + lv_label_set_align(txtArtist, LV_ALIGN_IN_LEFT_MID); + lv_obj_set_width(txtArtist, LV_HOR_RES); + + txtTrack = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_long_mode(txtTrack, LV_LABEL_LONG_SROLL); + lv_obj_align(txtTrack, nullptr, LV_ALIGN_IN_LEFT_MID, 12, MIDDLE_OFFSET + 2 * FONT_HEIGHT + LINE_PAD); + lv_label_set_text(txtTrack, "This is a very long getTrack name"); + lv_label_set_align(txtTrack, LV_ALIGN_IN_LEFT_MID); + lv_obj_set_width(txtTrack, LV_HOR_RES); + + /** Init animation */ + imgDisc = lv_img_create(lv_scr_act(), nullptr); + lv_img_set_src_arr(imgDisc, &disc); + lv_obj_align(imgDisc, nullptr, LV_ALIGN_IN_TOP_RIGHT, -15, 15); + + imgDiscAnim = lv_img_create(lv_scr_act(), nullptr); + lv_img_set_src_arr(imgDiscAnim, &disc_f_1); + lv_obj_align(imgDiscAnim, nullptr, LV_ALIGN_IN_TOP_RIGHT, -15 - 32, 15); + + frameB = false; + + musicService.event(Controllers::MusicService::EVENT_MUSIC_OPEN); +} + +Music::~Music() { + lv_obj_clean(lv_scr_act()); +} + +bool Music::OnButtonPushed() { + running = false; + return true; +} + +bool Music::Refresh() { + if (artist != musicService.getArtist()) { + artist = musicService.getArtist(); + currentLength = 0; + lv_label_set_text(txtArtist, artist.data()); + } + + if (track != musicService.getTrack()) { + track = musicService.getTrack(); + currentLength = 0; + lv_label_set_text(txtTrack, track.data()); + } + + if (album != musicService.getAlbum()) { + album = musicService.getAlbum(); + currentLength = 0; + } + + if (playing != musicService.isPlaying()) { + playing = musicService.isPlaying(); + } + + // Because we increment this ourselves, + // we can't compare with the old data directly + // have to update it when there's actually new data + // just to avoid unnecessary draws that make UI choppy + if (lastLength != musicService.getProgress()) { + currentLength = musicService.getProgress(); + lastLength = currentLength; + UpdateLength(); + } + + if (totalLength != musicService.getTrackLength()) { + totalLength = musicService.getTrackLength(); + UpdateLength(); + } + + if (playing == Pinetime::Controllers::MusicService::MusicStatus::Playing) { + lv_label_set_text(txtPlayPause, "||"); + if (xTaskGetTickCount() - 1024 >= lastIncrement) { + + if (frameB) { + lv_img_set_src(imgDiscAnim, &disc_f_1); + } else { + lv_img_set_src(imgDiscAnim, &disc_f_2); + } + frameB = !frameB; + + if (currentLength < totalLength) { + currentLength += static_cast<int>((static_cast<float>(xTaskGetTickCount() - lastIncrement) / 1024.0f) * + musicService.getPlaybackSpeed()); + } else { + // Let's assume the getTrack finished, paused when the timer ends + // and there's no new getTrack being sent to us + // TODO: ideally this would be configurable + playing = false; + } + lastIncrement = xTaskGetTickCount(); + + UpdateLength(); + } + } else { + lv_label_set_text(txtPlayPause, ">"); + } + + return running; +} + +void Music::UpdateLength() { + if (totalLength > (99 * 60 * 60)) { + lv_label_set_text(txtTrackDuration, "Inf/Inf"); + } else if (totalLength > (99 * 60)) { + char timer[12]; + sprintf(timer, "%02d:%02d/%02d:%02d", + (currentLength / (60 * 60)) % 100, + ((currentLength % (60 * 60)) / 60) % 100, + (totalLength / (60 * 60)) % 100, + ((totalLength % (60 * 60)) / 60) % 100 + ); + lv_label_set_text(txtTrackDuration, timer); + } else { + char timer[12]; + sprintf(timer, "%02d:%02d/%02d:%02d", + (currentLength / 60) % 100, + (currentLength % 60) % 100, + (totalLength / 60) % 100, + (totalLength % 60) % 100 + ); + lv_label_set_text(txtTrackDuration, timer); + } +} + +void Music::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { + if (event == LV_EVENT_CLICKED) { + if (obj == btnVolDown) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLDOWN); + } else if (obj == btnVolUp) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLUP); + } else if (obj == btnPrev) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_PREV); + } else if (obj == btnPlayPause) { + if (playing == Pinetime::Controllers::MusicService::MusicStatus::Playing) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_PAUSE); + + // Let's assume it stops playing instantly + playing = Controllers::MusicService::NotPlaying; + } else { + musicService.event(Controllers::MusicService::EVENT_MUSIC_PLAY); + + // Let's assume it starts playing instantly + // TODO: In the future should check for BT connection for better UX + playing = Controllers::MusicService::Playing; + } + } else if (obj == btnNext) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_NEXT); + } + } +} + + +bool Music::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + switch (event) { + case TouchEvents::SwipeUp: { + displayVolumeButtons = true; + lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); + lv_obj_set_hidden(btnVolUp, !displayVolumeButtons); + + lv_obj_set_hidden(btnNext, displayVolumeButtons); + lv_obj_set_hidden(btnPrev, displayVolumeButtons); + return true; + } + case TouchEvents::SwipeDown: { + displayVolumeButtons = false; + lv_obj_set_hidden(btnNext, displayVolumeButtons); + lv_obj_set_hidden(btnPrev, displayVolumeButtons); + + lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); + lv_obj_set_hidden(btnVolUp, !displayVolumeButtons); + return true; + } + case TouchEvents::SwipeLeft: { + musicService.event(Controllers::MusicService::EVENT_MUSIC_NEXT); + return true; + } + case TouchEvents::SwipeRight: { + musicService.event(Controllers::MusicService::EVENT_MUSIC_PREV); + return true; + } + default: { + return true; + } + } +}
\ No newline at end of file diff --git a/src/displayapp/screens/Music.h b/src/displayapp/screens/Music.h new file mode 100644 index 00000000..81ba7935 --- /dev/null +++ b/src/displayapp/screens/Music.h @@ -0,0 +1,96 @@ +/* Copyright (C) 2020 JF, Adam Pigg, Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ +#pragma once + +#include <cstdint> +#include <chrono> +#include <string> + +#include "components/gfx/Gfx.h" +#include "components/battery/BatteryController.h" +#include "components/ble/BleController.h" +#include "components/ble/MusicService.h" +#include "Screen.h" +#include <bits/unique_ptr.h> +#include <libs/lvgl/src/lv_core/lv_style.h> +#include <libs/lvgl/src/lv_core/lv_obj.h> +#include "../../Version.h" +#include "displayapp/icons/music/disc.cpp" +#include "displayapp/icons/music/disc_f_1.cpp" +#include "displayapp/icons/music/disc_f_2.cpp" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class Music : public Screen { + public: + Music(DisplayApp *app, Pinetime::Controllers::MusicService &music); + + ~Music() override; + + bool Refresh() override; + + bool OnButtonPushed() override; + + void OnObjectEvent(lv_obj_t *obj, lv_event_t event); + + private: + bool OnTouchEvent(TouchEvents event); + + void UpdateLength(); + + lv_obj_t *btnPrev; + lv_obj_t *btnPlayPause; + lv_obj_t *btnNext; + lv_obj_t *btnVolDown; + lv_obj_t *btnVolUp; + lv_obj_t *txtArtist; + lv_obj_t *txtTrack; + lv_obj_t *txtPlayPause; + + lv_obj_t *imgDisc; + lv_obj_t *imgDiscAnim; + lv_obj_t *txtTrackDuration; + + /** For the spinning disc animation */ + bool frameB; + + bool displayVolumeButtons = false; + Pinetime::Controllers::MusicService &musicService; + + std::string artist; + std::string album; + std::string track; + + /** Total length in seconds */ + int totalLength; + /** Current length in seconds */ + int currentLength; + /** Last length */ + int lastLength; + /** Last time an animation update or timer was incremented */ + TickType_t lastIncrement; + + bool playing; + + /** Watchapp */ + bool running = true; + }; + } + } +} diff --git a/src/displayapp/screens/NotificationIcon.cpp b/src/displayapp/screens/NotificationIcon.cpp new file mode 100644 index 00000000..64898c2c --- /dev/null +++ b/src/displayapp/screens/NotificationIcon.cpp @@ -0,0 +1,8 @@ +#include "NotificationIcon.h" +#include "Symbols.h" +using namespace Pinetime::Applications::Screens; + +const char* NotificationIcon::GetIcon(bool newNotificationAvailable) { + if(newNotificationAvailable) return Symbols::info; + else return ""; +}
\ No newline at end of file diff --git a/src/displayapp/screens/NotificationIcon.h b/src/displayapp/screens/NotificationIcon.h new file mode 100644 index 00000000..dc34c3f0 --- /dev/null +++ b/src/displayapp/screens/NotificationIcon.h @@ -0,0 +1,12 @@ +#pragma once + +namespace Pinetime { + namespace Applications { + namespace Screens { + class NotificationIcon { + public: + static const char* GetIcon(bool newNotificationAvailable); + }; + } + } +}
\ No newline at end of file diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp new file mode 100644 index 00000000..85848b2f --- /dev/null +++ b/src/displayapp/screens/Notifications.cpp @@ -0,0 +1,174 @@ +#include <libs/lvgl/lvgl.h> +#include <displayapp/DisplayApp.h> +#include <functional> +#include "Notifications.h" + +using namespace Pinetime::Applications::Screens; + +Notifications::Notifications(DisplayApp *app, Pinetime::Controllers::NotificationManager ¬ificationManager, Modes mode) : + Screen(app), notificationManager{notificationManager}, mode{mode} { + notificationManager.ClearNewNotificationFlag(); + auto notification = notificationManager.GetLastNotification(); + if(notification.valid) { + currentId = notification.id; + currentItem.reset(new NotificationItem("\nNotification", notification.message.data(), notification.index, notificationManager.NbNotifications(), mode)); + validDisplay = true; + } else { + currentItem.reset(new NotificationItem("\nNotification", "No notification to display", 0, notificationManager.NbNotifications(), Modes::Preview)); + } + + if(mode == Modes::Preview) { + static lv_style_t style_line; + lv_style_copy(&style_line, &lv_style_plain); + style_line.line.color = LV_COLOR_WHITE; + style_line.line.width = 3; + style_line.line.rounded = 0; + + + timeoutLine = lv_line_create(lv_scr_act(), nullptr); + lv_line_set_style(timeoutLine, LV_LINE_STYLE_MAIN, &style_line); + lv_line_set_points(timeoutLine, timeoutLinePoints, 2); + timeoutTickCountStart = xTaskGetTickCount(); + timeoutTickCountEnd = timeoutTickCountStart + (5*1024); + } +} + +Notifications::~Notifications() { + lv_obj_clean(lv_scr_act()); +} + +bool Notifications::Refresh() { + if (mode == Modes::Preview) { + auto tick = xTaskGetTickCount(); + int32_t pos = 240 - ((tick - timeoutTickCountStart) / ((timeoutTickCountEnd - timeoutTickCountStart) / 240)); + if (pos < 0) + running = false; + + timeoutLinePoints[1].x = pos; + lv_line_set_points(timeoutLine, timeoutLinePoints, 2); + + if (!running) { + // Start clock app when exiting this one + app->StartApp(Apps::Clock); + } + } + + return running; +} + +bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + switch (event) { + case Pinetime::Applications::TouchEvents::SwipeUp: { + Controllers::NotificationManager::Notification previousNotification; + if(validDisplay) + previousNotification = notificationManager.GetPrevious(currentId); + else + previousNotification = notificationManager.GetLastNotification(); + + if (!previousNotification.valid) return true; + + validDisplay = true; + currentId = previousNotification.id; + currentItem.reset(nullptr); + app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up); + currentItem.reset(new NotificationItem("\nNotification", previousNotification.message.data(), previousNotification.index, notificationManager.NbNotifications(), mode)); + } + return true; + case Pinetime::Applications::TouchEvents::SwipeDown: { + Controllers::NotificationManager::Notification nextNotification; + if(validDisplay) + nextNotification = notificationManager.GetNext(currentId); + else + nextNotification = notificationManager.GetLastNotification(); + + if (!nextNotification.valid) return true; + + validDisplay = true; + currentId = nextNotification.id; + currentItem.reset(nullptr); + app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down); + currentItem.reset(new NotificationItem("\nNotification", nextNotification.message.data(), nextNotification.index, notificationManager.NbNotifications(), mode)); + } + return true; + default: + return false; + } +} + + +bool Notifications::OnButtonPushed() { + running = false; + return true; +} + + +Notifications::NotificationItem::NotificationItem(const char *title, const char *msg, uint8_t notifNr, uint8_t notifNb, Modes mode) + : notifNr{notifNr}, notifNb{notifNb}, mode{mode} { + container1 = lv_cont_create(lv_scr_act(), nullptr); + static lv_style_t contStyle; + lv_style_copy(&contStyle, lv_cont_get_style(container1, LV_CONT_STYLE_MAIN)); + contStyle.body.padding.inner = 20; + lv_cont_set_style(container1, LV_CONT_STYLE_MAIN, &contStyle); + lv_obj_set_width(container1, LV_HOR_RES); + lv_obj_set_height(container1, LV_VER_RES); + lv_obj_set_pos(container1, 0, 0); + lv_cont_set_layout(container1, LV_LAYOUT_OFF); + lv_cont_set_fit2(container1, LV_FIT_FLOOD, LV_FIT_FLOOD); + + t1 = lv_label_create(container1, nullptr); + static lv_style_t titleStyle; + static lv_style_t textStyle; + static lv_style_t bottomStyle; + lv_style_copy(&titleStyle, lv_label_get_style(t1, LV_LABEL_STYLE_MAIN)); + lv_style_copy(&textStyle, lv_label_get_style(t1, LV_LABEL_STYLE_MAIN)); + lv_style_copy(&bottomStyle, lv_label_get_style(t1, LV_LABEL_STYLE_MAIN)); + titleStyle.body.padding.inner = 5; + titleStyle.body.grad_color = LV_COLOR_GRAY; + titleStyle.body.main_color = LV_COLOR_GRAY; + titleStyle.body.radius = 20; + textStyle.body.border.part = LV_BORDER_NONE; + textStyle.body.padding.inner = 5; + + bottomStyle.body.main_color = LV_COLOR_GREEN; + bottomStyle.body.grad_color = LV_COLOR_GREEN; + bottomStyle.body.border.part = LV_BORDER_TOP; + bottomStyle.body.border.color = LV_COLOR_RED; + + lv_label_set_style(t1, LV_LABEL_STYLE_MAIN, &titleStyle); + lv_label_set_long_mode(t1, LV_LABEL_LONG_BREAK); + lv_label_set_body_draw(t1, true); + lv_obj_set_width(t1, LV_HOR_RES - (titleStyle.body.padding.left + titleStyle.body.padding.right)); + lv_label_set_text(t1, title); + static constexpr int16_t offscreenOffset = -20 ; + lv_obj_set_pos(t1, titleStyle.body.padding.left, offscreenOffset); + + auto titleHeight = lv_obj_get_height(t1); + + l1 = lv_label_create(container1, nullptr); + lv_label_set_style(l1, LV_LABEL_STYLE_MAIN, &textStyle); + lv_obj_set_pos(l1, textStyle.body.padding.left, + titleHeight + offscreenOffset + textStyle.body.padding.bottom + + textStyle.body.padding.top); + + lv_label_set_long_mode(l1, LV_LABEL_LONG_BREAK); + lv_label_set_body_draw(l1, true); + lv_obj_set_width(l1, LV_HOR_RES - (textStyle.body.padding.left + textStyle.body.padding.right)); + lv_label_set_text(l1, msg); + + if(mode == Modes::Normal) { + if(notifNr < notifNb) { + bottomPlaceholder = lv_label_create(container1, nullptr); + lv_label_set_style(bottomPlaceholder, LV_LABEL_STYLE_MAIN, &titleStyle); + lv_label_set_long_mode(bottomPlaceholder, LV_LABEL_LONG_BREAK); + lv_label_set_body_draw(bottomPlaceholder, true); + lv_obj_set_width(bottomPlaceholder, LV_HOR_RES - (titleStyle.body.padding.left + titleStyle.body.padding.right)); + lv_label_set_text(bottomPlaceholder, " "); + lv_obj_set_pos(bottomPlaceholder, titleStyle.body.padding.left, LV_VER_RES - 5); + } + } +} + + +Notifications::NotificationItem::~NotificationItem() { + lv_obj_clean(lv_scr_act()); +} diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h new file mode 100644 index 00000000..fb4e1ef2 --- /dev/null +++ b/src/displayapp/screens/Notifications.h @@ -0,0 +1,61 @@ +#pragma once + +#include <functional> +#include <vector> + +#include "Screen.h" +#include "ScreenList.h" + + +namespace Pinetime { + namespace Applications { + namespace Screens { + class Notifications : public Screen { + public: + enum class Modes {Normal, Preview}; + explicit Notifications(DisplayApp* app, Pinetime::Controllers::NotificationManager& notificationManager, Modes mode); + ~Notifications() override; + + bool Refresh() override; + bool OnButtonPushed() override; + bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; + + private: + bool running = true; + + class NotificationItem { + public: + NotificationItem(const char* title, const char* msg, uint8_t notifNr, uint8_t notifNb, Modes mode); + ~NotificationItem(); + bool Refresh() {return false;} + + private: + uint8_t notifNr = 0; + uint8_t notifNb = 0; + char pageText[4]; + + lv_obj_t* container1; + lv_obj_t* t1; + lv_obj_t* l1; + lv_obj_t* bottomPlaceholder; + Modes mode; + }; + + struct NotificationData { + const char* title; + const char* text; + }; + Pinetime::Controllers::NotificationManager& notificationManager; + Modes mode = Modes::Normal; + std::unique_ptr<NotificationItem> currentItem; + Controllers::NotificationManager::Notification::Id currentId; + bool validDisplay = false; + + lv_point_t timeoutLinePoints[2] { {0, 237}, {239, 237} }; + lv_obj_t* timeoutLine; + uint32_t timeoutTickCountStart; + uint32_t timeoutTickCountEnd; + }; + } + } +} diff --git a/src/DisplayApp/Screens/Screen.cpp b/src/displayapp/screens/Screen.cpp index 1467df33..1467df33 100644 --- a/src/DisplayApp/Screens/Screen.cpp +++ b/src/displayapp/screens/Screen.cpp diff --git a/src/displayapp/screens/Screen.h b/src/displayapp/screens/Screen.h new file mode 100644 index 00000000..6b1d0eec --- /dev/null +++ b/src/displayapp/screens/Screen.h @@ -0,0 +1,42 @@ +#pragma once + +#include <cstdint> +#include "../TouchEvents.h" + +namespace Pinetime { + namespace Applications { + class DisplayApp; + namespace Screens { + class Screen { + public: + explicit Screen(DisplayApp* app) : app{app} {} + virtual ~Screen() = default; + + /** + * Most of the time, apps only react to events (touch events, for example). + * In this case you don't need to do anything in this method. + * + * For example, InfiniPaint does nothing in Refresh(). + * But, if you want to update your display periodically, draw an animation... + * you cannot do it in a touch event handler because these handlers are not + * called if the user does not touch the screen. + * + * That's why Refresh() is there: update the display periodically. + * + * @return false if the app can be closed, true if it must continue to run + **/ + virtual bool Refresh() = 0; + + /** @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; } + virtual bool OnTouchEvent(uint16_t x, uint16_t y) { return false; } + + protected: + DisplayApp* app; + }; + } + } +} diff --git a/src/displayapp/screens/ScreenList.h b/src/displayapp/screens/ScreenList.h new file mode 100644 index 00000000..b198634f --- /dev/null +++ b/src/displayapp/screens/ScreenList.h @@ -0,0 +1,66 @@ +#pragma once + +#include <vector> +#include <functional> +#include "components/ble/NimbleController.h" +#include "Screen.h" +#include "Label.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + template <size_t N> + class ScreenList : public Screen { + public: + ScreenList(DisplayApp* app, std::array<std::function<std::unique_ptr<Screen>()>, N>&& screens) + : Screen(app), screens{std::move(screens)}, current{this->screens[0]()} { + + } + + ~ScreenList() override { + + } + + bool Refresh() override { + running = current->Refresh(); + return running; + } + + bool OnButtonPushed() override { + running = false; + return true; + } + + bool OnTouchEvent(TouchEvents event) override { + switch (event) { + case TouchEvents::SwipeDown: + if (screenIndex > 0) { + current.reset(nullptr); + app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down); + screenIndex--; + current = screens[screenIndex](); + } + return true; + case TouchEvents::SwipeUp: + if (screenIndex < screens.size() - 1) { + current.reset(nullptr); + app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up); + screenIndex++; + current = screens[screenIndex](); + } + return true; + default: + return false; + } + return false; + } + + private: + bool running = true; + uint8_t screenIndex = 0; + std::array<std::function<std::unique_ptr<Screen>()>, N> screens; + std::unique_ptr<Screen> current; + }; + } + } +}
\ No newline at end of file diff --git a/src/displayapp/screens/Symbols.h b/src/displayapp/screens/Symbols.h new file mode 100644 index 00000000..aeea3243 --- /dev/null +++ b/src/displayapp/screens/Symbols.h @@ -0,0 +1,30 @@ +#pragma once + +namespace Pinetime { + namespace Applications { + namespace Screens { + namespace Symbols { + static constexpr const char* none = ""; + static constexpr const char* batteryFull = "\xEF\x89\x80"; + static constexpr const char* batteryEmpty = "\xEF\x89\x84"; + static constexpr const char* batteryThreeQuarter = "\xEF\x89\x81"; + static constexpr const char* batteryHalf = "\xEF\x89\x82"; + static constexpr const char* batteryOneQuarter = "\xEF\x89\x83"; + static constexpr const char* heartBeat = "\xEF\x88\x9E"; + static constexpr const char* bluetoothFull = "\xEF\x8A\x93"; + static constexpr const char* bluetooth = "\xEF\x8A\x94"; + static constexpr const char* plug = "\xEF\x87\xA6"; + static constexpr const char* shoe = "\xEF\x95\x8B"; + static constexpr const char* clock = "\xEF\x80\x97"; + static constexpr const char* info = "\xEF\x84\xA9"; + static constexpr const char* list = "\xEF\x80\xBA"; + static constexpr const char* sun = "\xEF\x86\x85"; + static constexpr const char* check = "\xEF\x95\xA0"; + static constexpr const char* music = "\xEF\x80\x81"; + static constexpr const char* tachometer = "\xEF\x8F\xBD"; + static constexpr const char* asterisk = "\xEF\x81\xA9"; + static constexpr const char* paintbrush = "\xEF\x87\xBC"; + } + } + } +}
\ No newline at end of file diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp new file mode 100644 index 00000000..867fdaeb --- /dev/null +++ b/src/displayapp/screens/SystemInfo.cpp @@ -0,0 +1,116 @@ +#include <libs/lvgl/lvgl.h> +#include <displayapp/DisplayApp.h> +#include <functional> +#include "SystemInfo.h" +#include "../../Version.h" +#include "Tile.h" + +using namespace Pinetime::Applications::Screens; + +SystemInfo::SystemInfo(Pinetime::Applications::DisplayApp *app, + Pinetime::Controllers::DateTime &dateTimeController, + Pinetime::Controllers::Battery& batteryController, + Pinetime::Controllers::BrightnessController& brightnessController, + Pinetime::Controllers::Ble& bleController, + Pinetime::Drivers::WatchdogView& watchdog) : + Screen(app), + dateTimeController{dateTimeController}, batteryController{batteryController}, + brightnessController{brightnessController}, bleController{bleController}, watchdog{watchdog}, + screens{app, { + [this]() -> std::unique_ptr<Screen> { return CreateScreen1(); }, + [this]() -> std::unique_ptr<Screen> { return CreateScreen2(); }, + [this]() -> std::unique_ptr<Screen> { return CreateScreen3(); } + } + } {} + + +SystemInfo::~SystemInfo() { + lv_obj_clean(lv_scr_act()); +} + +bool SystemInfo::Refresh() { + screens.Refresh(); + return running; +} + +bool SystemInfo::OnButtonPushed() { + running = false; + return true; +} + +bool SystemInfo::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return screens.OnTouchEvent(event); +} + +std::unique_ptr<Screen> SystemInfo::CreateScreen1() { + auto batteryPercentF = batteryController.PercentRemaining(); + uint16_t batteryPercent = 0; + if(batteryPercentF > 100.0f) batteryPercent = 100; + else if(batteryPercentF < 0.0f) batteryPercent = 0; + + uint8_t brightness = 0; + switch(brightnessController.Level()) { + case Controllers::BrightnessController::Levels::Off: brightness = 0; break; + 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 = [this]() { + 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 "?"; + } + }(); + + // uptime + static constexpr uint32_t secondsInADay = 60*60*24; + static constexpr uint32_t secondsInAnHour = 60*60; + static constexpr uint32_t secondsInAMinute = 60; + uint32_t uptimeSeconds = dateTimeController.Uptime().count(); + uint32_t uptimeDays = (uptimeSeconds / secondsInADay); + uptimeSeconds = uptimeSeconds % secondsInADay; + uint32_t uptimeHours = uptimeSeconds / secondsInAnHour; + uptimeSeconds = uptimeSeconds % secondsInAnHour; + uint32_t uptimeMinutes = uptimeSeconds / secondsInAMinute; + uptimeSeconds = uptimeSeconds % secondsInAMinute; + // TODO handle more than 100 days of uptime + + sprintf(t1, "Pinetime\n" + "Version:%ld.%ld.%ld\n" + "Build: %s\n" + " %s\n" + "Date: %02d/%02d/%04d\n" + "Time: %02d:%02d:%02d\n" + "Uptime: %02lud %02lu:%02lu:%02lu\n" + "Battery: %d%%\n" + "Backlight: %d/3\n" + "Last reset: %s\n", + Version::Major(), Version::Minor(), Version::Patch(), + __DATE__, __TIME__, + dateTimeController.Day(), static_cast<uint8_t>(dateTimeController.Month()), dateTimeController.Year(), + dateTimeController.Hours(), dateTimeController.Minutes(), dateTimeController.Seconds(), + uptimeDays, uptimeHours, uptimeMinutes, uptimeSeconds, + batteryPercent, brightness, resetReason); + + return std::unique_ptr<Screen>(new Screens::Label(app, t1)); +} + +std::unique_ptr<Screen> SystemInfo::CreateScreen2() { + auto& bleAddr = bleController.Address(); + sprintf(t2, "BLE MAC: \n %02x:%02x:%02x:%02x:%02x:%02x", + bleAddr[5], bleAddr[4], bleAddr[3], bleAddr[2], bleAddr[1], bleAddr[0]); + return std::unique_ptr<Screen>(new Screens::Label(app, t2)); +} + +std::unique_ptr<Screen> SystemInfo::CreateScreen3() { + strncpy(t3, "Hello from\nthe developer!", 27); + return std::unique_ptr<Screen>(new Screens::Label(app, t3)); +} diff --git a/src/DisplayApp/Screens/ScreenList.h b/src/displayapp/screens/SystemInfo.h index b0ee016b..987a584b 100644 --- a/src/DisplayApp/Screens/ScreenList.h +++ b/src/displayapp/screens/SystemInfo.h @@ -1,41 +1,47 @@ #pragma once +#include <functional> #include <vector> -#include <Components/Ble/NimbleController.h> + +#include "components/ble/NimbleController.h" #include "Screen.h" #include "Label.h" +#include "ScreenList.h" +#include "Gauge.h" +#include "Meter.h" namespace Pinetime { namespace Applications { namespace Screens { - class ScreenList : public Screen { + class SystemInfo : public Screen { public: - explicit ScreenList(DisplayApp* app, + explicit SystemInfo(DisplayApp* app, Pinetime::Controllers::DateTime& dateTimeController, Pinetime::Controllers::Battery& batteryController, Pinetime::Controllers::BrightnessController& brightnessController, Pinetime::Controllers::Ble& bleController, Pinetime::Drivers::WatchdogView& watchdog); - ~ScreenList() override; + ~SystemInfo() 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::Controllers::Ble& bleController; Pinetime::Drivers::WatchdogView& watchdog; - char t1[200]; char t2[200]; char t3[30]; + + ScreenList<3> screens; + std::unique_ptr<Screen> CreateScreen1(); + std::unique_ptr<Screen> CreateScreen2(); + std::unique_ptr<Screen> CreateScreen3(); }; } } diff --git a/src/DisplayApp/Screens/Tab.cpp b/src/displayapp/screens/Tab.cpp index adc32578..44b806c0 100644 --- a/src/DisplayApp/Screens/Tab.cpp +++ b/src/displayapp/screens/Tab.cpp @@ -1,13 +1,13 @@ #include <cstdio> #include <libs/date/includes/date/date.h> -#include <Components/DateTime/DateTimeController.h> +#include "components/datetime/DateTimeController.h" #include <Version.h> #include <libs/lvgl/src/lv_core/lv_obj.h> #include <libs/lvgl/src/lv_font/lv_font.h> #include <libs/lvgl/lvgl.h> #include <libraries/log/nrf_log.h> #include "Tab.h" -#include <DisplayApp/DisplayApp.h> +#include "displayapp/DisplayApp.h" using namespace Pinetime::Applications::Screens; diff --git a/src/DisplayApp/Screens/Tab.h b/src/displayapp/screens/Tab.h index e16dbb96..e16dbb96 100644 --- a/src/DisplayApp/Screens/Tab.h +++ b/src/displayapp/screens/Tab.h diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp new file mode 100644 index 00000000..75fa6ef5 --- /dev/null +++ b/src/displayapp/screens/Tile.cpp @@ -0,0 +1,62 @@ +#include <libs/lvgl/src/lv_core/lv_obj.h> +#include <libs/lvgl/src/lv_font/lv_font.h> +#include <libs/lvgl/lvgl.h> + +#include "Tile.h" +#include "displayapp/DisplayApp.h" +#include "Symbols.h" +#include "../../Version.h" + +using namespace Pinetime::Applications::Screens; + +extern lv_font_t jetbrains_mono_bold_20; + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + Tile* screen = static_cast<Tile *>(obj->user_data); + uint32_t* eventDataPtr = (uint32_t*) lv_event_get_data(); + uint32_t eventData = *eventDataPtr; + screen->OnObjectEvent(obj, event, eventData); +} + +Tile::Tile(DisplayApp* app, std::array<Applications, 6>& applications) : Screen(app) { + for(int i = 0, appIndex = 0; i < 8; i++) { + if(i == 3) btnm_map1[i] = "\n"; + else if(i == 7) btnm_map1[i] = ""; + else { + btnm_map1[i] = applications[appIndex].icon; + apps[appIndex] = applications[appIndex].application; + appIndex++; + } + } + modal.reset(new Modal(app)); + + btnm1 = lv_btnm_create(lv_scr_act(), nullptr); + lv_btnm_set_map(btnm1, btnm_map1); + lv_obj_set_size(btnm1, LV_HOR_RES, LV_VER_RES); + + btnm1->user_data = this; + lv_obj_set_event_cb(btnm1, event_handler); +} + +Tile::~Tile() { + lv_obj_clean(lv_scr_act()); +} + +bool Tile::Refresh() { + return running; +} + +void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event, uint32_t buttonId) { + if(event == LV_EVENT_VALUE_CHANGED) { + app->StartApp(apps[buttonId]); + running = false; + } +} + +bool Tile::OnButtonPushed() { + app->StartApp(Apps::Clock); + running = false; + return true; +} + + diff --git a/src/displayapp/screens/Tile.h b/src/displayapp/screens/Tile.h new file mode 100644 index 00000000..cf5fcf15 --- /dev/null +++ b/src/displayapp/screens/Tile.h @@ -0,0 +1,39 @@ +#pragma once + +#include <cstdint> +#include "Screen.h" +#include <bits/unique_ptr.h> +#include "Modal.h" +#include <lvgl/src/lv_core/lv_style.h> +#include <displayapp/Apps.h> + +namespace Pinetime { + namespace Applications { + namespace Screens { + class Tile : public Screen { + public: + struct Applications { + const char* icon; + Pinetime::Applications::Apps application; + }; + + explicit Tile(DisplayApp* app, std::array<Applications, 6>& applications); + ~Tile() override; + + bool Refresh() override; + bool OnButtonPushed() override; + + void OnObjectEvent(lv_obj_t* obj, lv_event_t event, uint32_t buttonId); + + private: + lv_obj_t * btnm1; + bool running = true; + + std::unique_ptr<Modal> modal; + + const char* btnm_map1[8]; + Pinetime::Applications::Apps apps[6]; + }; + } + } +} diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp index 60cd402c..94db3b34 100644 --- a/src/drivers/Cst816s.cpp +++ b/src/drivers/Cst816s.cpp @@ -2,7 +2,6 @@ #include <task.h> #include <nrfx_log.h> #include <legacy/nrf_drv_gpiote.h> - #include "Cst816s.h" using namespace Pinetime::Drivers; @@ -38,7 +37,9 @@ void Cst816S::Init() { Cst816S::TouchInfos Cst816S::GetTouchInfo() { Cst816S::TouchInfos info; - twiMaster.Read(twiAddress, 0, touchData, 63); + auto ret = twiMaster.Read(twiAddress, 0, touchData, 63); + if(ret != TwiMaster::ErrorCodes::NoError) return {}; + auto nbTouchPoints = touchData[2] & 0x0f; // uint8_t i = 0; @@ -60,9 +61,9 @@ Cst816S::TouchInfos Cst816S::GetTouchInfo() { uint16_t y = (yHigh << 8) | yLow; auto action = touchData[touchEventIndex + (touchStep * i)] >> 6; /* 0 = Down, 1 = Up, 2 = contact*/ - auto finger = touchData[touchIdIndex + (touchStep * i)] >> 4; - auto pressure = touchData[touchXYIndex + (touchStep * i)]; - auto area = touchData[touchMiscIndex + (touchStep * i)] >> 4; + //auto finger = touchData[touchIdIndex + (touchStep * i)] >> 4; + //auto pressure = touchData[touchXYIndex + (touchStep * i)]; + //auto area = touchData[touchMiscIndex + (touchStep * i)] >> 4; info.x = x; info.y = y; @@ -89,7 +90,6 @@ Cst816S::TouchInfos Cst816S::GetTouchInfo() { // case Gestures::LongPress: NRF_LOG_INFO("Gesture : Long press"); break; // default : NRF_LOG_INFO("Unknown"); break; // } - } @@ -97,12 +97,16 @@ Cst816S::TouchInfos Cst816S::GetTouchInfo() { } void Cst816S::Sleep() { - // TODO re enable sleep mode - //twiMaster.Sleep(); - nrf_gpio_cfg_default(6); - nrf_gpio_cfg_default(7); + nrf_gpio_pin_clear(pinReset); + vTaskDelay(5); + nrf_gpio_pin_set(pinReset); + vTaskDelay(50); + static constexpr uint8_t sleepValue = 0x03; + twiMaster.Write(twiAddress, 0xA5, &sleepValue, 1); + NRF_LOG_INFO("[TOUCHPANEL] Sleep"); } void Cst816S::Wakeup() { Init(); + NRF_LOG_INFO("[TOUCHPANEL] Wakeup"); }
\ No newline at end of file diff --git a/src/drivers/Cst816s.h b/src/drivers/Cst816s.h index b115a688..4569e82f 100644 --- a/src/drivers/Cst816s.h +++ b/src/drivers/Cst816s.h @@ -18,13 +18,13 @@ namespace Pinetime { LongPress = 0x0C }; struct TouchInfos { - uint16_t x; - uint16_t y; - uint8_t action; - uint8_t finger; - uint8_t pressure; - uint8_t area; - Gestures gesture; + uint16_t x = 0; + uint16_t y = 0; + uint8_t action = 0; + uint8_t finger = 0; + uint8_t pressure = 0; + uint8_t area = 0; + Gestures gesture = Gestures::None; bool isTouch = false; }; diff --git a/src/drivers/Spi.cpp b/src/drivers/Spi.cpp index bf08178d..2d8aa3b8 100644 --- a/src/drivers/Spi.cpp +++ b/src/drivers/Spi.cpp @@ -1,4 +1,5 @@ #include <hal/nrf_gpio.h> +#include <nrfx_log.h> #include "Spi.h" using namespace Pinetime::Drivers; @@ -18,8 +19,12 @@ bool Spi::Read(uint8_t* cmd, size_t cmdSize, uint8_t *data, size_t dataSize) { } void Spi::Sleep() { - // TODO sleep spi nrf_gpio_cfg_default(pinCsn); + NRF_LOG_INFO("[SPI] Sleep") +} + +bool Spi::WriteCmdAndBuffer(const uint8_t *cmd, size_t cmdSize, const uint8_t *data, size_t dataSize) { + return spiMaster.WriteCmdAndBuffer(pinCsn, cmd, cmdSize, data, dataSize); } bool Spi::Init() { @@ -27,8 +32,10 @@ bool Spi::Init() { return true; } -bool Spi::WriteCmdAndBuffer(const uint8_t *cmd, size_t cmdSize, const uint8_t *data, size_t dataSize) { - return spiMaster.WriteCmdAndBuffer(pinCsn, cmd, cmdSize, data, dataSize); +void Spi::Wakeup() { + nrf_gpio_cfg_output(pinCsn); + nrf_gpio_pin_set(pinCsn); + NRF_LOG_INFO("[SPI] Wakeup") } diff --git a/src/drivers/SpiMaster.cpp b/src/drivers/SpiMaster.cpp index 8087d386..2e5852a5 100644 --- a/src/drivers/SpiMaster.cpp +++ b/src/drivers/SpiMaster.cpp @@ -4,6 +4,7 @@ #include "SpiMaster.h" #include <algorithm> #include <task.h> +#include <nrfx_log.h> using namespace Pinetime::Drivers; @@ -117,8 +118,6 @@ void SpiMaster::OnEndEvent() { spiBaseAddress->TASKS_START = 1; } else { - uint8_t* buffer = nullptr; - size_t size = 0; if(taskToNotify != nullptr) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; vTaskNotifyGiveFromISR(taskToNotify, &xHigherPriorityTaskWoken); @@ -233,10 +232,13 @@ void SpiMaster::Sleep() { nrf_gpio_cfg_default(params.pinSCK); nrf_gpio_cfg_default(params.pinMOSI); nrf_gpio_cfg_default(params.pinMISO); + + NRF_LOG_INFO("[SPIMASTER] sleep") } void SpiMaster::Wakeup() { Init(); + NRF_LOG_INFO("[SPIMASTER] Wakeup"); } bool SpiMaster::WriteCmdAndBuffer(uint8_t pinCsn, const uint8_t *cmd, size_t cmdSize, const uint8_t *data, size_t dataSize) { diff --git a/src/drivers/SpiNorFlash.cpp b/src/drivers/SpiNorFlash.cpp index 7e4da1ca..bd24834e 100644 --- a/src/drivers/SpiNorFlash.cpp +++ b/src/drivers/SpiNorFlash.cpp @@ -11,8 +11,8 @@ SpiNorFlash::SpiNorFlash(Spi& spi) : spi{spi} { } void SpiNorFlash::Init() { - auto id = ReadIdentificaion(); - NRF_LOG_INFO("[SPI FLASH] Manufacturer : %d, Memory type : %d, memory density : %d", id.manufacturer, id.type, id.density); + device_id = ReadIdentificaion(); + NRF_LOG_INFO("[SpiNorFlash] Manufacturer : %d, Memory type : %d, memory density : %d", device_id.manufacturer, device_id.type, device_id.density); } void SpiNorFlash::Uninit() { @@ -20,11 +20,25 @@ void SpiNorFlash::Uninit() { } void SpiNorFlash::Sleep() { - + auto cmd = static_cast<uint8_t>(Commands::DeepPowerDown); + spi.Write(&cmd, sizeof(uint8_t)); + NRF_LOG_INFO("[SpiNorFlash] Sleep") } void SpiNorFlash::Wakeup() { - + // send Commands::ReleaseFromDeepPowerDown then 3 dummy bytes before reading Device ID + static constexpr uint8_t cmdSize = 4; + uint8_t cmd[cmdSize] = {static_cast<uint8_t>(Commands::ReleaseFromDeepPowerDown), 0x01, 0x02, 0x03}; + uint8_t id = 0; + spi.Read(reinterpret_cast<uint8_t *>(&cmd), cmdSize, &id, 1); + auto devId = device_id = ReadIdentificaion(); + if(devId.type != device_id.type) { + NRF_LOG_INFO("[SpiNorFlash] ID on Wakeup: Failed"); + } + else { + NRF_LOG_INFO("[SpiNorFlash] ID on Wakeup: %d", id); + } + NRF_LOG_INFO("[SpiNorFlash] Wakeup") } SpiNorFlash::Identification SpiNorFlash::ReadIdentificaion() { diff --git a/src/drivers/SpiNorFlash.h b/src/drivers/SpiNorFlash.h index 98267c09..10c25a01 100644 --- a/src/drivers/SpiNorFlash.h +++ b/src/drivers/SpiNorFlash.h @@ -48,11 +48,13 @@ namespace Pinetime { SectorErase = 0x20, ReadSecurityRegister = 0x2B, ReadIdentification = 0x9F, + ReleaseFromDeepPowerDown = 0xAB, + DeepPowerDown = 0xB9 }; static constexpr uint16_t pageSize = 256; Spi& spi; - + Identification device_id; }; } } diff --git a/src/drivers/St7789.cpp b/src/drivers/St7789.cpp index 09269afd..ed28c82c 100644 --- a/src/drivers/St7789.cpp +++ b/src/drivers/St7789.cpp @@ -1,5 +1,6 @@ #include <hal/nrf_gpio.h> #include <libraries/delay/nrf_delay.h> +#include <nrfx_log.h> #include "St7789.h" #include "Spi.h" @@ -174,12 +175,10 @@ void St7789::HardwareReset() { void St7789::Sleep() { SleepIn(); nrf_gpio_cfg_default(pinDataCommand); -// spi.Sleep(); // TODO sleep SPI + NRF_LOG_INFO("[LCD] Sleep"); } void St7789::Wakeup() { -// spi.Wakeup(); // TODO wake up SPI - nrf_gpio_cfg_output(pinDataCommand); // TODO why do we need to reset the controller? HardwareReset(); @@ -193,4 +192,5 @@ void St7789::Wakeup() { NormalModeOn(); VerticalScrollStartAddress(verticalScrollingStartAddress); DisplayOn(); + NRF_LOG_INFO("[LCD] Wakeup") } diff --git a/src/drivers/TwiMaster.cpp b/src/drivers/TwiMaster.cpp index 4a0c536d..3ff8a952 100644 --- a/src/drivers/TwiMaster.cpp +++ b/src/drivers/TwiMaster.cpp @@ -60,24 +60,53 @@ void TwiMaster::Init() { } -void TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t *data, size_t size) { +TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t *data, size_t size) { xSemaphoreTake(mutex, portMAX_DELAY); - Write(deviceAddress, ®isterAddress, 1, false); - Read(deviceAddress, data, size, true); + auto ret = ReadWithRetry(deviceAddress, registerAddress, data, size); xSemaphoreGive(mutex); + + return ret; } -void TwiMaster::Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t *data, size_t size) { +TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t *data, size_t size) { ASSERT(size <= maxDataSize); xSemaphoreTake(mutex, portMAX_DELAY); + + auto ret = WriteWithRetry(deviceAddress, registerAddress, data, size); + xSemaphoreGive(mutex); + return ret; +} + +/* Execute a read transaction (composed of a write and a read operation). If one of these opeartion fails, + * it's retried once. If it fails again, an error is returned */ +TwiMaster::ErrorCodes TwiMaster::ReadWithRetry(uint8_t deviceAddress, uint8_t registerAddress, uint8_t *data, size_t size) { + TwiMaster::ErrorCodes ret; + ret = Write(deviceAddress, ®isterAddress, 1, false); + if(ret != ErrorCodes::NoError) + ret = Write(deviceAddress, ®isterAddress, 1, false); + + if(ret != ErrorCodes::NoError) return ret; + + ret = Read(deviceAddress, data, size, true); + if(ret != ErrorCodes::NoError) + ret = Read(deviceAddress, data, size, true); + + return ret; +} + +/* Execute a write transaction. If it fails, it is retried once. If it fails again, an error is returned. */ +TwiMaster::ErrorCodes TwiMaster::WriteWithRetry(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t *data, size_t size) { internalBuffer[0] = registerAddress; std::memcpy(internalBuffer+1, data, size); - Write(deviceAddress, internalBuffer, size+1, true); - xSemaphoreGive(mutex); + auto ret = Write(deviceAddress, internalBuffer, size+1, true); + if(ret != ErrorCodes::NoError) + ret = Write(deviceAddress, internalBuffer, size+1, true); + + return ret; } -void TwiMaster::Read(uint8_t deviceAddress, uint8_t *buffer, size_t size, bool stop) { +TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t *buffer, size_t size, bool stop) { twiBaseAddress->ADDRESS = deviceAddress; twiBaseAddress->TASKS_RESUME = 0x1UL; twiBaseAddress->RXD.PTR = (uint32_t)buffer; @@ -88,7 +117,15 @@ void TwiMaster::Read(uint8_t deviceAddress, uint8_t *buffer, size_t size, bool s while(!twiBaseAddress->EVENTS_RXSTARTED && !twiBaseAddress->EVENTS_ERROR); twiBaseAddress->EVENTS_RXSTARTED = 0x0UL; - while(!twiBaseAddress->EVENTS_LASTRX && !twiBaseAddress->EVENTS_ERROR); + txStartedCycleCount = DWT->CYCCNT; + uint32_t currentCycleCount; + while(!twiBaseAddress->EVENTS_LASTRX && !twiBaseAddress->EVENTS_ERROR) { + currentCycleCount = DWT->CYCCNT; + if ((currentCycleCount-txStartedCycleCount) > HwFreezedDelay) { + FixHwFreezed(); + return ErrorCodes::TransactionFailed; + } + } twiBaseAddress->EVENTS_LASTRX = 0x0UL; if (stop || twiBaseAddress->EVENTS_ERROR) { @@ -105,9 +142,10 @@ void TwiMaster::Read(uint8_t deviceAddress, uint8_t *buffer, size_t size, bool s if (twiBaseAddress->EVENTS_ERROR) { twiBaseAddress->EVENTS_ERROR = 0x0UL; } + return ErrorCodes::NoError; } -void TwiMaster::Write(uint8_t deviceAddress, const uint8_t *data, size_t size, bool stop) { +TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, const uint8_t *data, size_t size, bool stop) { twiBaseAddress->ADDRESS = deviceAddress; twiBaseAddress->TASKS_RESUME = 0x1UL; twiBaseAddress->TXD.PTR = (uint32_t)data; @@ -118,7 +156,15 @@ void TwiMaster::Write(uint8_t deviceAddress, const uint8_t *data, size_t size, b while(!twiBaseAddress->EVENTS_TXSTARTED && !twiBaseAddress->EVENTS_ERROR); twiBaseAddress->EVENTS_TXSTARTED = 0x0UL; - while(!twiBaseAddress->EVENTS_LASTTX && !twiBaseAddress->EVENTS_ERROR); + txStartedCycleCount = DWT->CYCCNT; + uint32_t currentCycleCount; + while(!twiBaseAddress->EVENTS_LASTTX && !twiBaseAddress->EVENTS_ERROR) { + currentCycleCount = DWT->CYCCNT; + if ((currentCycleCount-txStartedCycleCount) > HwFreezedDelay) { + FixHwFreezed(); + return ErrorCodes::TransactionFailed; + } + } twiBaseAddress->EVENTS_LASTTX = 0x0UL; if (stop || twiBaseAddress->EVENTS_ERROR) { @@ -137,4 +183,47 @@ void TwiMaster::Write(uint8_t deviceAddress, const uint8_t *data, size_t size, b uint32_t error = twiBaseAddress->ERRORSRC; twiBaseAddress->ERRORSRC = error; } -}
\ No newline at end of file + + return ErrorCodes::NoError; +} + +void TwiMaster::Sleep() { + while(twiBaseAddress->ENABLE != 0) { + twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos); + } + nrf_gpio_cfg_default(6); + nrf_gpio_cfg_default(7); + NRF_LOG_INFO("[TWIMASTER] Sleep"); +} + +void TwiMaster::Wakeup() { + Init(); + NRF_LOG_INFO("[TWIMASTER] Wakeup"); +} + +/* Sometimes, the TWIM device just freeze and never set the event EVENTS_LASTTX. + * This method disable and re-enable the peripheral so that it works again. + * This is just a workaround, and it would be better if we could find a way to prevent + * this issue from happening. + * */ +void TwiMaster::FixHwFreezed() { + NRF_LOG_INFO("I2C device frozen, reinitializing it!"); + // Disable I²C + uint32_t twi_state = NRF_TWI1->ENABLE; + twiBaseAddress->ENABLE = TWIM_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; + + NRF_GPIO->PIN_CNF[params.pinScl] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) + | ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) + | ((uint32_t)GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) + | ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) + | ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + + NRF_GPIO->PIN_CNF[params.pinSda] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) + | ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) + | ((uint32_t)GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) + | ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) + | ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + + // Re-enable I²C + twiBaseAddress->ENABLE = twi_state; +} diff --git a/src/drivers/TwiMaster.h b/src/drivers/TwiMaster.h index 3b7555f5..52e39098 100644 --- a/src/drivers/TwiMaster.h +++ b/src/drivers/TwiMaster.h @@ -10,6 +10,7 @@ namespace Pinetime { public: enum class Modules { TWIM1 }; enum class Frequencies {Khz100, Khz250, Khz400}; + enum class ErrorCodes {NoError, TransactionFailed}; struct Parameters { uint32_t frequency; uint8_t pinSda; @@ -19,12 +20,19 @@ namespace Pinetime { TwiMaster(const Modules module, const Parameters& params); void Init(); - void Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* buffer, size_t size); - void Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size); + ErrorCodes Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* buffer, size_t size); + ErrorCodes Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size); + + void Sleep(); + void Wakeup(); private: - void Read(uint8_t deviceAddress, uint8_t* buffer, size_t size, bool stop); - void Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop); + ErrorCodes ReadWithRetry(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* buffer, size_t size); + ErrorCodes WriteWithRetry(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size); + + ErrorCodes Read(uint8_t deviceAddress, uint8_t* buffer, size_t size, bool stop); + ErrorCodes Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop); + void FixHwFreezed(); NRF_TWIM_Type* twiBaseAddress; SemaphoreHandle_t mutex; const Modules module; @@ -32,7 +40,8 @@ namespace Pinetime { static constexpr uint8_t maxDataSize{8}; static constexpr uint8_t registerSize{1}; uint8_t internalBuffer[maxDataSize + registerSize]; - + uint32_t txStartedCycleCount = 0; + static constexpr uint32_t HwFreezedDelay{161000}; }; } }
\ No newline at end of file diff --git a/src/graphics.cpp b/src/graphics.cpp index 3b53703c..288b5e9a 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -11,15 +11,15 @@ #include <libraries/gpiote/app_gpiote.h> #include <hal/nrf_wdt.h> #include <cstring> -#include <Components/Gfx/Gfx.h> +#include <components/gfx/Gfx.h> #include <drivers/St7789.h> -#include <Components/Brightness/BrightnessController.h> +#include <components/brightness/BrightnessController.h> #if NRF_LOG_ENABLED -#include "Logging/NrfLogger.h" +#include "logging/NrfLogger.h" Pinetime::Logging::NrfLogger logger; #else -#include "Logging/DummyLogger.h" +#include "logging/DummyLogger.h" Pinetime::Logging::DummyLogger logger; #endif @@ -79,6 +79,7 @@ void Process(void* instance) { NRF_LOG_INFO("Init..."); spi.Init(); spiNorFlash.Init(); + spiNorFlash.Wakeup(); brightnessController.Init(); lcd.Init(); gfx.Init(); @@ -103,10 +104,10 @@ void Process(void* instance) { 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(int line = 0; line < screenWidth; line++) { + 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(int col = 0; col < screenWidth; col++) { + for(uint32_t col = 0; col < screenWidth; col++) { gfx.pixel_draw(col, line, displayLineBuffer[col]); } } diff --git a/src/libs/lvgl/src/lv_core/lv_obj.c b/src/libs/lvgl/src/lv_core/lv_obj.c index 510a8706..511e72db 100644 --- a/src/libs/lvgl/src/lv_core/lv_obj.c +++ b/src/libs/lvgl/src/lv_core/lv_obj.c @@ -163,7 +163,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) LV_ASSERT_MEM(new_obj); if(new_obj == NULL) return NULL; - new_obj->par = NULL; /*Screens has no a parent*/ + new_obj->par = NULL; /*screens has no a parent*/ lv_ll_init(&(new_obj->child_ll), sizeof(lv_obj_t)); /*Set the callbacks*/ diff --git a/src/libs/mynewt-nimble/nimble/host/src/ble_gap.c b/src/libs/mynewt-nimble/nimble/host/src/ble_gap.c index be4a1cb3..e32482e6 100644 --- a/src/libs/mynewt-nimble/nimble/host/src/ble_gap.c +++ b/src/libs/mynewt-nimble/nimble/host/src/ble_gap.c @@ -310,12 +310,14 @@ ble_gap_log_conn(uint8_t own_addr_type, const ble_addr_t *peer_addr, BLE_HS_LOG_ADDR(INFO, peer_addr->val); } + /* // NRF LOG support max 6 params in log BLE_HS_LOG(INFO, " scan_itvl=%d scan_window=%d itvl_min=%d itvl_max=%d " "latency=%d supervision_timeout=%d min_ce_len=%d " "max_ce_len=%d own_addr_type=%d", params->scan_itvl, params->scan_window, params->itvl_min, params->itvl_max, params->latency, params->supervision_timeout, params->min_ce_len, params->max_ce_len, own_addr_type); + */ } #endif diff --git a/src/Logging/DummyLogger.h b/src/logging/DummyLogger.h index 0aa72882..0aa72882 100644 --- a/src/Logging/DummyLogger.h +++ b/src/logging/DummyLogger.h diff --git a/src/Logging/Logger.h b/src/logging/Logger.h index 95d21dc4..95d21dc4 100644 --- a/src/Logging/Logger.h +++ b/src/logging/Logger.h diff --git a/src/Logging/NrfLogger.cpp b/src/logging/NrfLogger.cpp index 7ccacc82..0d95c06a 100644 --- a/src/Logging/NrfLogger.cpp +++ b/src/logging/NrfLogger.cpp @@ -19,10 +19,15 @@ void NrfLogger::Init() { void NrfLogger::Process(void*) { NRF_LOG_INFO("Logger task started!"); + // Suppress endless loop diagnostic + #pragma clang diagnostic push + #pragma ide diagnostic ignored "EndlessLoop" while (1) { NRF_LOG_FLUSH(); vTaskDelay(100); // Not good for power consumption, it will wake up every 100ms... } + // Clear diagnostic suppression + #pragma clang diagnostic pop } void NrfLogger::Resume() { diff --git a/src/Logging/NrfLogger.h b/src/logging/NrfLogger.h index cb7089f2..cb7089f2 100644 --- a/src/Logging/NrfLogger.h +++ b/src/logging/NrfLogger.h diff --git a/src/main.cpp b/src/main.cpp index fe413585..45aac6de 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,38 +1,38 @@ #include <FreeRTOS.h> #include <task.h> +#include <timers.h> #include <legacy/nrf_drv_clock.h> +#include <hal/nrf_rtc.h> +#include <hal/nrf_wdt.h> +#include <os/os_cputime.h> #include <libraries/timer/app_timer.h> #include <libraries/gpiote/app_gpiote.h> -#include <DisplayApp/DisplayApp.h> +#include "displayapp/DisplayApp.h" #include <softdevice/common/nrf_sdh.h> -#include <hal/nrf_rtc.h> -#include <timers.h> -#include <Components/DateTime/DateTimeController.h> -#include "Components/Battery/BatteryController.h" -#include "Components/Ble/BleController.h" +#include "components/datetime/DateTimeController.h" +#include "components/battery/BatteryController.h" +#include "components/ble/BleController.h" +#include "components/ble/NotificationManager.h" #include <drivers/St7789.h> #include <drivers/SpiMaster.h> #include <drivers/Spi.h> -#include <DisplayApp/LittleVgl.h> -#include <SystemTask/SystemTask.h> -#include <Components/Ble/NotificationManager.h> +#include "displayapp/LittleVgl.h" +#include <systemtask/SystemTask.h> #include <nimble/nimble_port_freertos.h> #include <nimble/npl_freertos.h> #include <nimble/nimble_port.h> #include <host/ble_hs.h> #include <controller/ble_ll.h> -#include <os/os_cputime.h> #include <transport/ram/ble_hci_ram.h> -#include <hal/nrf_wdt.h> #include <host/util/util.h> #include <services/gap/ble_svc_gap.h> #if NRF_LOG_ENABLED -#include "Logging/NrfLogger.h" +#include "logging/NrfLogger.h" Pinetime::Logging::NrfLogger logger; #else -#include "Logging/DummyLogger.h" +#include "logging/DummyLogger.h" Pinetime::Logging::DummyLogger logger; #endif diff --git a/src/SystemTask/SystemMonitor.h b/src/systemtask/SystemMonitor.h index 8fcfafb2..029a1364 100644 --- a/src/SystemTask/SystemMonitor.h +++ b/src/systemtask/SystemMonitor.h @@ -27,8 +27,8 @@ namespace Pinetime { void Process() const { if(xTaskGetTickCount() - lastTick > 10000) { NRF_LOG_INFO("---------------------------------------\nFree heap : %d", xPortGetFreeHeapSize()); - auto nb = uxTaskGetSystemState(tasksStatus, 10, NULL); - for (int i = 0; i < nb; i++) { + auto nb = uxTaskGetSystemState(tasksStatus, 10, nullptr); + for (uint32_t i = 0; i < nb; i++) { NRF_LOG_INFO("Task [%s] - %d", tasksStatus[i].pcTaskName, tasksStatus[i].usStackHighWaterMark); if (tasksStatus[i].usStackHighWaterMark < 20) NRF_LOG_INFO("WARNING!!! Task %s task is nearly full, only %dB available", tasksStatus[i].pcTaskName, diff --git a/src/SystemTask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 9f57f6f6..dac4ce29 100644 --- a/src/SystemTask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -1,9 +1,9 @@ #include <libraries/log/nrf_log.h> #include <libraries/gpiote/app_gpiote.h> #include <drivers/Cst816s.h> -#include <DisplayApp/LittleVgl.h> +#include "displayapp/LittleVgl.h" #include <hal/nrf_rtc.h> -#include <Components/Ble/NotificationManager.h> +#include "components/ble/NotificationManager.h" #include <host/ble_gatt.h> #include <host/ble_hs_adv.h> #include "SystemTask.h" @@ -11,8 +11,9 @@ #include <host/ble_gap.h> #include <host/util/util.h> #include <drivers/InternalFlash.h> -#include "../main.h" -#include "Components/Ble/NimbleController.h" +#include "main.h" +#include "components/ble/NimbleController.h" +#include "../BootloaderVersion.h" using namespace Pinetime::System; @@ -35,8 +36,8 @@ SystemTask::SystemTask(Drivers::SpiMaster &spi, Drivers::St7789 &lcd, twiMaster{twiMaster}, touchPanel{touchPanel}, lvgl{lvgl}, batteryController{batteryController}, bleController{bleController}, dateTimeController{dateTimeController}, watchdog{}, watchdogView{watchdog}, notificationManager{notificationManager}, - nimbleController(*this, bleController,dateTimeController, notificationManager, spiNorFlash) { - systemTaksMsgQueue = xQueueCreate(10, 1); + nimbleController(*this, bleController,dateTimeController, notificationManager, batteryController, spiNorFlash) { + systemTasksMsgQueue = xQueueCreate(10, 1); } void SystemTask::Start() { @@ -46,7 +47,7 @@ void SystemTask::Start() { void SystemTask::Process(void *instance) { auto *app = static_cast<SystemTask *>(instance); - NRF_LOG_INFO("SystemTask task started!"); + NRF_LOG_INFO("systemtask task started!"); app->Work(); } @@ -58,14 +59,7 @@ void SystemTask::Work() { spi.Init(); spiNorFlash.Init(); - - // Write the 'image OK' flag if it's not already done - // TODO implement a better verification mecanism for the image (ask for user confirmation via UI/BLE ?) - uint32_t* imageOkPtr = reinterpret_cast<uint32_t *>(0x7BFE8); - uint32_t imageOk = *imageOkPtr; - if(imageOk != 1) - Pinetime::Drivers::InternalFlash::WriteWord(0x7BFE8, 1); - + spiNorFlash.Wakeup(); nimbleController.Init(); nimbleController.StartAdvertising(); lcd.Init(); @@ -107,28 +101,42 @@ void SystemTask::Work() { idleTimer = xTimerCreate ("idleTimer", idleTime, pdFALSE, this, IdleTimerCallback); xTimerStart(idleTimer, 0); + // Suppress endless loop diagnostic + #pragma clang diagnostic push + #pragma ide diagnostic ignored "EndlessLoop" while(true) { uint8_t msg; - if (xQueueReceive(systemTaksMsgQueue, &msg, isSleeping?2500 : 1000)) { + if (xQueueReceive(systemTasksMsgQueue, &msg, isSleeping ? 2500 : 1000)) { Messages message = static_cast<Messages >(msg); switch(message) { case Messages::GoToRunning: - isSleeping = false; + spi.Wakeup(); + twiMaster.Wakeup(); + + spiNorFlash.Wakeup(); + lcd.Wakeup(); + touchPanel.Wakeup(); + + displayApp->PushMessage(Applications::DisplayApp::Messages::GoToRunning); + displayApp->PushMessage(Applications::DisplayApp::Messages::UpdateBatteryLevel); + xTimerStart(idleTimer, 0); nimbleController.StartAdvertising(); + isSleeping = false; + isWakingUp = false; break; case Messages::GoToSleep: - NRF_LOG_INFO("[SystemTask] Going to sleep"); + isGoingToSleep = true; + NRF_LOG_INFO("[systemtask] Going to sleep"); xTimerStop(idleTimer, 0); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep); - isSleeping = true; break; case Messages::OnNewTime: ReloadIdleTimer(); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateDateTime); break; case Messages::OnNewNotification: - if(isSleeping) GoToRunning(); + if(isSleeping && !isWakingUp) GoToRunning(); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::NewNotification); break; case Messages::BleConnected: @@ -138,13 +146,12 @@ void SystemTask::Work() { break; case Messages::BleFirmwareUpdateStarted: doNotGoToSleep = true; - if(isSleeping) GoToRunning(); + if(isSleeping && !isWakingUp) GoToRunning(); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::BleFirmwareUpdateStarted); break; case Messages::BleFirmwareUpdateFinished: doNotGoToSleep = false; xTimerStart(idleTimer, 0); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::BleFirmwareUpdateFinished); if(bleController.State() == Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated) NVIC_SystemReset(); break; @@ -154,6 +161,20 @@ void SystemTask::Work() { case Messages::OnButtonEvent: ReloadIdleTimer(); break; + case Messages::OnDisplayTaskSleeping: + if(BootloaderVersion::IsValid()) { + // First versions of the bootloader do not expose their version and cannot initialize the SPI NOR FLASH + // if it's in sleep mode. Avoid bricked device by disabling sleep mode on these versions. + spiNorFlash.Sleep(); + } + lcd.Sleep(); + touchPanel.Sleep(); + + spi.Sleep(); + twiMaster.Sleep(); + isSleeping = true; + isGoingToSleep = false; + break; default: break; } } @@ -178,28 +199,33 @@ void SystemTask::Work() { if(!nrf_gpio_pin_read(pinButton)) watchdog.Kick(); } + // Clear diagnostic suppression + #pragma clang diagnostic pop } void SystemTask::OnButtonPushed() { + if(isGoingToSleep) return; if(!isSleeping) { - NRF_LOG_INFO("[SystemTask] Button pushed"); + NRF_LOG_INFO("[systemtask] Button pushed"); PushMessage(Messages::OnButtonEvent); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::ButtonPushed); } else { - NRF_LOG_INFO("[SystemTask] Button pushed, waking up"); - GoToRunning(); + if(!isWakingUp) { + NRF_LOG_INFO("[systemtask] Button pushed, waking up"); + GoToRunning(); + } } } void SystemTask::GoToRunning() { + isWakingUp = true; PushMessage(Messages::GoToRunning); - displayApp->PushMessage(Applications::DisplayApp::Messages::GoToRunning); - displayApp->PushMessage(Applications::DisplayApp::Messages::UpdateBatteryLevel); } void SystemTask::OnTouchEvent() { - NRF_LOG_INFO("[SystemTask] Touch event"); + if(isGoingToSleep) return ; + NRF_LOG_INFO("[systemtask] Touch event"); if(!isSleeping) { PushMessage(Messages::OnTouchEvent); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::TouchEvent); @@ -207,12 +233,15 @@ void SystemTask::OnTouchEvent() { } void SystemTask::PushMessage(SystemTask::Messages msg) { + if(msg == Messages::GoToSleep) { + isGoingToSleep = true; + } BaseType_t xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; - xQueueSendFromISR(systemTaksMsgQueue, &msg, &xHigherPriorityTaskWoken); + xQueueSendFromISR(systemTasksMsgQueue, &msg, &xHigherPriorityTaskWoken); if (xHigherPriorityTaskWoken) { /* Actual macro used here is port specific. */ - // TODO : should I do something here? + // TODO: should I do something here? } } @@ -223,6 +252,6 @@ void SystemTask::OnIdle() { } void SystemTask::ReloadIdleTimer() const { - if(isSleeping) return; + if(isSleeping || isGoingToSleep) return; xTimerReset(idleTimer, 0); } diff --git a/src/SystemTask/SystemTask.h b/src/systemtask/SystemTask.h index 3e53baed..6ef0cfbf 100644 --- a/src/SystemTask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -1,16 +1,17 @@ #pragma once +#include <memory> + #include <FreeRTOS.h> #include <task.h> -#include <memory> #include <drivers/SpiMaster.h> #include <drivers/St7789.h> -#include <Components/Battery/BatteryController.h> -#include <DisplayApp/DisplayApp.h> +#include "components/battery/BatteryController.h" +#include "displayapp/DisplayApp.h" #include <drivers/Watchdog.h> #include <drivers/SpiNorFlash.h> #include "SystemMonitor.h" -#include "Components/Ble/NimbleController.h" +#include "components/ble/NimbleController.h" #include "timers.h" namespace Pinetime { @@ -18,7 +19,7 @@ namespace Pinetime { class SystemTask { public: enum class Messages {GoToSleep, GoToRunning, OnNewTime, OnNewNotification, BleConnected, - BleFirmwareUpdateStarted, BleFirmwareUpdateFinished, OnTouchEvent, OnButtonEvent + BleFirmwareUpdateStarted, BleFirmwareUpdateFinished, OnTouchEvent, OnButtonEvent, OnDisplayTaskSleeping }; SystemTask(Drivers::SpiMaster &spi, Drivers::St7789 &lcd, @@ -53,8 +54,10 @@ namespace Pinetime { std::unique_ptr<Pinetime::Applications::DisplayApp> displayApp; Pinetime::Controllers::Ble& bleController; Pinetime::Controllers::DateTime& dateTimeController; - QueueHandle_t systemTaksMsgQueue; - bool isSleeping = false; + QueueHandle_t systemTasksMsgQueue; + std::atomic<bool> isSleeping{false}; + std::atomic<bool> isGoingToSleep{false}; + std::atomic<bool> isWakingUp{false}; Pinetime::Drivers::Watchdog watchdog; Pinetime::Drivers::WatchdogView watchdogView; Pinetime::Controllers::NotificationManager& notificationManager; |
