├── .gitignore ├── .gitmodules ├── .vscode ├── c_cpp_properties.json ├── launch.json └── tasks.json ├── CMakeLists.txt ├── Makefile ├── README.md ├── dependencies.lock ├── main ├── CMakeLists.txt ├── WatchBma │ ├── WatchBma.cpp │ └── WatchBma.h ├── WatchGps │ ├── WatchGps.cpp │ ├── WatchGps.h │ └── home_gps_example.h ├── WatchNvs │ ├── WatchNvs.cpp │ └── WatchNvs.h ├── WatchPower │ ├── WatchPower.cpp │ └── WatchPower.h ├── WatchSd │ ├── WatchSd.cpp │ └── WatchSd.h ├── WatchTft │ ├── Bma_Sceen.cpp │ ├── Gps_Screen.cpp │ ├── Power_Screen.cpp │ ├── Settings_Screen.cpp │ ├── WatchTft.cpp │ ├── WatchTft.h │ ├── ampoule.cpp │ ├── arrow.cpp │ ├── circle.cpp │ ├── download.cpp │ ├── gradient_count.cpp │ ├── lune.cpp │ ├── main_bg.cpp │ ├── rotate.cpp │ └── run.cpp ├── WatchWiFi │ ├── WatchWiFi.cpp │ ├── WatchWiFi.h │ └── wifi_credentials_example.h ├── component.mk ├── main.cpp └── main.h ├── partitions.csv ├── sdkconfig ├── sdkconfig.ci └── sdkconfig.old /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | .vscode/settings.json 3 | main/WatchWiFi/wifi_credentials.h 4 | main/WatchGps/home_gps.h -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "components/lvgl"] 2 | path = components/lvgl 3 | url = https://github.com/lvgl/lvgl.git 4 | [submodule "components/C_AXP202X_Library"] 5 | path = components/C_AXP202X_Library 6 | url = https://github.com/MathieuDeprez/C_AXP202X_Library.git 7 | [submodule "components/lvgl_esp32_drivers"] 8 | path = components/lvgl_esp32_drivers 9 | url = https://github.com/MathieuDeprez/lvgl_esp32_drivers.git 10 | [submodule "components/BMA423-Sensor-API"] 11 | path = components/BMA423-Sensor-API 12 | url = https://github.com/MathieuDeprez/BMA423-Sensor-API.git 13 | -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "ESP-IDF", 5 | "compilerPath": "/home/mathieu/.espressif/tools/xtensa-esp32-elf/esp-2021r2-patch3-8.4.0/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc", 6 | "cStandard": "c11", 7 | "cppStandard": "c++17", 8 | "includePath": [ 9 | "${config:idf.espIdfPath}/components/**", 10 | "${config:idf.espIdfPathWin}/components/**", 11 | "${config:idf.espAdfPath}/components/**", 12 | "${config:idf.espAdfPathWin}/components/**", 13 | "${workspaceFolder}/**", 14 | "${workspaceFolder}/build/config/" 15 | ], 16 | "browse": { 17 | "path": [ 18 | "${config:idf.espIdfPath}/components", 19 | "${config:idf.espIdfPathWin}/components", 20 | "${config:idf.espAdfPath}/components/**", 21 | "${config:idf.espAdfPathWin}/components/**", 22 | "${workspaceFolder}", 23 | "${workspaceFolder}/build/config" 24 | ], 25 | "limitSymbolsToIncludedHeaders": false 26 | }, 27 | "compileCommands": "${workspaceFolder}/build/compile_commands.json" 28 | } 29 | ], 30 | "version": 4 31 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "espidf", 6 | "name": "Launch", 7 | "request": "launch" 8 | } 9 | ] 10 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "Build - Build project", 6 | "type": "shell", 7 | "command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py build", 8 | "windows": { 9 | "command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py build", 10 | "options": { 11 | "env": { 12 | "PATH": "${env:PATH};${config:idf.customExtraPaths}" 13 | } 14 | } 15 | }, 16 | "options": { 17 | "env": { 18 | "PATH": "${env:PATH}:${config:idf.customExtraPaths}" 19 | } 20 | }, 21 | "problemMatcher": [ 22 | { 23 | "owner": "cpp", 24 | "fileLocation": [ 25 | "relative", 26 | "${workspaceFolder}" 27 | ], 28 | "pattern": { 29 | "regexp": "^\\.\\.(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", 30 | "file": 1, 31 | "line": 2, 32 | "column": 3, 33 | "severity": 4, 34 | "message": 5 35 | } 36 | }, 37 | { 38 | "owner": "cpp", 39 | "fileLocation": "absolute", 40 | "pattern": { 41 | "regexp": "^[^\\.](.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", 42 | "file": 1, 43 | "line": 2, 44 | "column": 3, 45 | "severity": 4, 46 | "message": 5 47 | } 48 | } 49 | ], 50 | "group": { 51 | "kind": "build", 52 | "isDefault": true 53 | } 54 | }, 55 | { 56 | "label": "Set ESP-IDF Target", 57 | "type": "shell", 58 | "command": "${command:espIdf.setTarget}", 59 | "problemMatcher": { 60 | "owner": "cpp", 61 | "fileLocation": "absolute", 62 | "pattern": { 63 | "regexp": "^(.*):(//d+):(//d+)://s+(warning|error)://s+(.*)$", 64 | "file": 1, 65 | "line": 2, 66 | "column": 3, 67 | "severity": 4, 68 | "message": 5 69 | } 70 | } 71 | }, 72 | { 73 | "label": "Clean - Clean the project", 74 | "type": "shell", 75 | "command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py fullclean", 76 | "windows": { 77 | "command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py fullclean", 78 | "options": { 79 | "env": { 80 | "PATH": "${env:PATH};${config:idf.customExtraPaths}" 81 | } 82 | } 83 | }, 84 | "options": { 85 | "env": { 86 | "PATH": "${env:PATH}:${config:idf.customExtraPaths}" 87 | } 88 | }, 89 | "problemMatcher": [ 90 | { 91 | "owner": "cpp", 92 | "fileLocation": [ 93 | "relative", 94 | "${workspaceFolder}" 95 | ], 96 | "pattern": { 97 | "regexp": "^\\.\\.(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", 98 | "file": 1, 99 | "line": 2, 100 | "column": 3, 101 | "severity": 4, 102 | "message": 5 103 | } 104 | }, 105 | { 106 | "owner": "cpp", 107 | "fileLocation": "absolute", 108 | "pattern": { 109 | "regexp": "^[^\\.](.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", 110 | "file": 1, 111 | "line": 2, 112 | "column": 3, 113 | "severity": 4, 114 | "message": 5 115 | } 116 | } 117 | ] 118 | }, 119 | { 120 | "label": "Flash - Flash the device", 121 | "type": "shell", 122 | "command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py -p ${config:idf.port} -b ${config:idf.flashBaudRate} flash", 123 | "windows": { 124 | "command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py flash -p ${config:idf.portWin} -b ${config:idf.flashBaudRate}", 125 | "options": { 126 | "env": { 127 | "PATH": "${env:PATH};${config:idf.customExtraPaths}" 128 | } 129 | } 130 | }, 131 | "options": { 132 | "env": { 133 | "PATH": "${env:PATH}:${config:idf.customExtraPaths}" 134 | } 135 | }, 136 | "problemMatcher": [ 137 | { 138 | "owner": "cpp", 139 | "fileLocation": [ 140 | "relative", 141 | "${workspaceFolder}" 142 | ], 143 | "pattern": { 144 | "regexp": "^\\.\\.(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", 145 | "file": 1, 146 | "line": 2, 147 | "column": 3, 148 | "severity": 4, 149 | "message": 5 150 | } 151 | }, 152 | { 153 | "owner": "cpp", 154 | "fileLocation": "absolute", 155 | "pattern": { 156 | "regexp": "^[^\\.](.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", 157 | "file": 1, 158 | "line": 2, 159 | "column": 3, 160 | "severity": 4, 161 | "message": 5 162 | } 163 | } 164 | ] 165 | }, 166 | { 167 | "label": "Monitor: Start the monitor", 168 | "type": "shell", 169 | "command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py -p ${config:idf.port} monitor", 170 | "windows": { 171 | "command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py -p ${config:idf.portWin} monitor", 172 | "options": { 173 | "env": { 174 | "PATH": "${env:PATH};${config:idf.customExtraPaths}" 175 | } 176 | } 177 | }, 178 | "options": { 179 | "env": { 180 | "PATH": "${env:PATH}:${config:idf.customExtraPaths}" 181 | } 182 | }, 183 | "problemMatcher": [ 184 | { 185 | "owner": "cpp", 186 | "fileLocation": [ 187 | "relative", 188 | "${workspaceFolder}" 189 | ], 190 | "pattern": { 191 | "regexp": "^\\.\\.(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", 192 | "file": 1, 193 | "line": 2, 194 | "column": 3, 195 | "severity": 4, 196 | "message": 5 197 | } 198 | }, 199 | { 200 | "owner": "cpp", 201 | "fileLocation": "absolute", 202 | "pattern": { 203 | "regexp": "^[^\\.](.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", 204 | "file": 1, 205 | "line": 2, 206 | "column": 3, 207 | "severity": 4, 208 | "message": 5 209 | } 210 | } 211 | ], 212 | "dependsOn": "Flash - Flash the device" 213 | }, 214 | { 215 | "label": "OpenOCD: Start openOCD", 216 | "type": "shell", 217 | "presentation": { 218 | "echo": true, 219 | "reveal": "never", 220 | "focus": false, 221 | "panel": "new" 222 | }, 223 | "command": "openocd -s ${command:espIdf.getOpenOcdScriptValue} ${command:espIdf.getOpenOcdConfigs}", 224 | "windows": { 225 | "command": "openocd.exe -s ${command:espIdf.getOpenOcdScriptValue} ${command:espIdf.getOpenOcdConfigs}", 226 | "options": { 227 | "env": { 228 | "PATH": "${env:PATH};${config:idf.customExtraPaths}" 229 | } 230 | } 231 | }, 232 | "options": { 233 | "env": { 234 | "PATH": "${env:PATH}:${config:idf.customExtraPaths}" 235 | } 236 | }, 237 | "problemMatcher": { 238 | "owner": "cpp", 239 | "fileLocation": "absolute", 240 | "pattern": { 241 | "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", 242 | "file": 1, 243 | "line": 2, 244 | "column": 3, 245 | "severity": 4, 246 | "message": 5 247 | } 248 | } 249 | }, 250 | { 251 | "label": "adapter", 252 | "type": "shell", 253 | "command": "${config:idf.pythonBinPath}", 254 | "isBackground": true, 255 | "options": { 256 | "env": { 257 | "PATH": "${env:PATH}:${config:idf.customExtraPaths}", 258 | "PYTHONPATH": "${command:espIdf.getExtensionPath}/esp_debug_adapter/debug_adapter" 259 | } 260 | }, 261 | "problemMatcher": { 262 | "background": { 263 | "beginsPattern": "\bDEBUG_ADAPTER_STARTED\b", 264 | "endsPattern": "DEBUG_ADAPTER_READY2CONNECT", 265 | "activeOnStart": true 266 | }, 267 | "pattern": { 268 | "regexp": "(\\d+)-(\\d+)-(\\d+)\\s(\\d+):(\\d+):(\\d+),(\\d+)\\s-(.+)\\s(ERROR)", 269 | "file": 8, 270 | "line": 2, 271 | "column": 3, 272 | "severity": 4, 273 | "message": 9 274 | } 275 | }, 276 | "args": [ 277 | "${command:espIdf.getExtensionPath}/esp_debug_adapter/debug_adapter_main.py", 278 | "-e", 279 | "${workspaceFolder}/build/${command:espIdf.getProjectName}.elf", 280 | "-s", 281 | "${command:espIdf.getOpenOcdScriptValue}", 282 | "-ip", 283 | "localhost", 284 | "-dn", 285 | "${config:idf.adapterTargetName}", 286 | "-om", 287 | "connect_to_instance" 288 | ], 289 | "windows": { 290 | "command": "${config:idf.pythonBinPathWin}", 291 | "options": { 292 | "env": { 293 | "PATH": "${env:PATH};${config:idf.customExtraPaths}", 294 | "PYTHONPATH": "${command:espIdf.getExtensionPath}/esp_debug_adapter/debug_adapter" 295 | } 296 | } 297 | } 298 | } 299 | ] 300 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The following lines of boilerplate have to be in your project's 2 | # CMakeLists in this exact order for cmake to work correctly 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | add_compile_definitions(SPI_HOST_MAX=3) 6 | add_compile_definitions(LV_HOR_RES_MAX=240) 7 | add_compile_definitions(LV_VER_RES_MAX=240) 8 | 9 | # x_out = x_in*TOUCH_CAL_X_MUL+TOUCH_CAL_X_OFF 10 | add_compile_definitions(TOUCH_CAL_X_OFF=25) 11 | add_compile_definitions(TOUCH_CAL_X_MUL=0.75) 12 | # y_out = y_in*TOUCH_CAL_Y_MUL+TOUCH_CAL_Y_OFF 13 | add_compile_definitions(TOUCH_CAL_Y_OFF=0) 14 | add_compile_definitions(TOUCH_CAL_Y_MUL=1) 15 | 16 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 17 | project(watch_display_01) 18 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This is a project Makefile. It is assumed the directory this Makefile resides in is a 3 | # project subdirectory. 4 | # 5 | 6 | PROJECT_NAME := hello_world 7 | 8 | include $(IDF_PATH)/make/project.mk 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # my_esp32_watch_base 2 | 3 | to clone the project : 4 | 5 | ```bash 6 | git clone --recurse-submodules https://github.com/MathieuDeprez/my_esp32_watch_base.git 7 | ``` -------------------------------------------------------------------------------- /dependencies.lock: -------------------------------------------------------------------------------- 1 | manifest_hash: e0cfd1319bfb46d732ec9d319e9dc49e36898e504018c81401232151605e3547 2 | target: esp32 3 | version: 1.0.0 4 | -------------------------------------------------------------------------------- /main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB_RECURSE SOURCES "*.cpp") 2 | set(LVGL_INCLUDE_DIRS . WatchTft) 3 | list(APPEND LVGL_INCLUDE_DIRS WatchPower) 4 | list(APPEND LVGL_INCLUDE_DIRS WatchBma) 5 | list(APPEND LVGL_INCLUDE_DIRS WatchNvs) 6 | list(APPEND LVGL_INCLUDE_DIRS WatchGps) 7 | list(APPEND LVGL_INCLUDE_DIRS WatchSd) 8 | list(APPEND LVGL_INCLUDE_DIRS WatchWiFi) 9 | 10 | idf_component_register(SRCS "main.cpp" ${SOURCES} "WatchTft/Power_Screen.cpp" "WatchTft/Settings_Screen.cpp" "WatchTft/Gps_Screen.cpp" "WatchTft/download.cpp" 11 | INCLUDE_DIRS ${LVGL_INCLUDE_DIRS} 12 | REQUIRES lvgl lvgl_esp32_drivers C_AXP202X_Library BMA423-Sensor-API nvs_flash fatfs esp_http_client) 13 | 14 | 15 | target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-missing-field-initializers) 16 | -------------------------------------------------------------------------------- /main/WatchBma/WatchBma.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchBma.h" 2 | struct bma4_dev WatchBma::bma; 3 | uint32_t WatchBma::steps_count_save = 0; 4 | volatile bool WatchBma::_irq = 0; 5 | uint16_t WatchBma::s_int_status = 0; 6 | bool WatchBma::wakeup_on_double_tap = true; 7 | bool WatchBma::wakeup_on_tilt = false; 8 | uint32_t WatchBma::step_counter_goal = 1000; 9 | 10 | void WatchBma::init() 11 | { 12 | xSemaphoreTake(i2c_0_semaphore, portMAX_DELAY); 13 | 14 | uint16_t rslt = BMA4_OK; 15 | 16 | struct bma4_accel_config accel_conf; 17 | uint8_t dev_addr = BMA4_I2C_ADDR_PRIMARY; 18 | 19 | bma.chip_id = BMA423_CHIP_ID; 20 | bma.intf = BMA4_I2C_INTF; 21 | bma.bus_read = user_i2c_read; 22 | bma.bus_write = user_i2c_write; 23 | bma.variant = BMA42X_VARIANT; 24 | bma.intf_ptr = &dev_addr; 25 | bma.delay_us = user_delay; 26 | bma.read_write_len = 8; 27 | bma.resolution = 12; 28 | bma.feature_len = 64; 29 | bma.dummy_byte = 0; 30 | 31 | bma4_soft_reset(&bma); 32 | vTaskDelay(20); 33 | 34 | /* Sensor initialization */ 35 | rslt = bma423_init(&bma); 36 | bma4_error_codes_print_result("bma423_init", rslt); 37 | if (rslt != 0) 38 | { 39 | printf("error bma423_init: %d\n", rslt); 40 | vTaskDelay(portMAX_DELAY); 41 | } 42 | 43 | /* Upload the configuration file to enable the features of the sensor. */ 44 | rslt = bma423_write_config_file(&bma); 45 | bma4_error_codes_print_result("bma423_write_config", rslt); 46 | if (rslt != 0) 47 | { 48 | printf("error write config: %d\n", rslt); 49 | vTaskDelay(portMAX_DELAY); 50 | } 51 | 52 | struct bma4_int_pin_config config; 53 | config.edge_ctrl = BMA4_LEVEL_TRIGGER; 54 | config.lvl = BMA4_ACTIVE_HIGH; 55 | config.od = BMA4_PUSH_PULL; 56 | config.output_en = BMA4_OUTPUT_ENABLE; 57 | config.input_en = BMA4_INPUT_DISABLE; 58 | rslt = bma4_set_int_pin_config(&config, BMA4_INTR1_MAP, &bma); 59 | if (rslt != 0) 60 | { 61 | printf("error bma4_set_int_pin_config: %d\n", rslt); 62 | vTaskDelay(portMAX_DELAY); 63 | } 64 | 65 | /* Enable the accelerometer */ 66 | rslt = bma4_set_accel_enable(1, &bma); 67 | bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); 68 | 69 | /* Accelerometer Configuration Setting */ 70 | /* Output data Rate */ 71 | accel_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; 72 | 73 | /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ 74 | accel_conf.range = BMA4_ACCEL_RANGE_2G; 75 | 76 | /* Bandwidth configure number of sensor samples required to average 77 | * if value = 2, then 4 samples are averaged 78 | * averaged samples = 2^(val(accel bandwidth)) 79 | * Note1 : More info refer datasheets 80 | * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but since the 81 | * performance power mode phase is increased, the power consumption will also rise. 82 | */ 83 | accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; 84 | 85 | /* Enable the filter performance mode where averaging of samples 86 | * will be done based on above set bandwidth and ODR. 87 | * There are two modes 88 | * 0 -> Averaging samples (Default) 89 | * 1 -> No averaging 90 | * For more info on No Averaging mode refer datasheets. 91 | */ 92 | accel_conf.perf_mode = BMA4_CIC_AVG_MODE; 93 | 94 | /* Set the accel configurations */ 95 | rslt = bma4_set_accel_config(&accel_conf, &bma); 96 | bma4_error_codes_print_result("bma4_set_accel_config status", rslt); 97 | 98 | rslt |= bma423_reset_step_counter(&bma); 99 | 100 | rslt = bma423_step_detector_enable(1, &bma); 101 | bma4_error_codes_print_result("bma423_step_detector_enable status", rslt); 102 | 103 | /* Enable step counter */ 104 | rslt = bma423_feature_enable(BMA423_STEP_CNTR, 1, &bma); 105 | bma4_error_codes_print_result("bma423_feature_enable step status", rslt); 106 | 107 | /* Enable activity counter */ 108 | rslt = bma423_feature_enable(BMA423_STEP_ACT, 1, &bma); 109 | bma4_error_codes_print_result("bma423_feature_enable activity status", rslt); 110 | 111 | /* Enable wrist counter */ 112 | rslt = bma423_feature_enable(BMA423_WRIST_WEAR, 1, &bma); 113 | bma4_error_codes_print_result("bma423_feature_enable wrist status", rslt); 114 | 115 | rslt |= bma423_feature_enable(0x20, BMA4_ENABLE, &bma); 116 | rslt |= bma423_feature_enable(0x10, BMA4_ENABLE, &bma); 117 | 118 | /* Set water-mark level 1 to get interrupt after 20 steps. 119 | * Range of step counter interrupt is 0 to 20460(resolution of 20 steps). 120 | */ 121 | rslt = bma423_step_counter_set_watermark(1, &bma); 122 | bma4_error_codes_print_result("bma423_step_counter status", rslt); 123 | 124 | /* Map the interrupt pin with that of step counter interrupts 125 | * Interrupt will be generated when step activity is generated. 126 | */ 127 | rslt = bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_STEP_CNTR_INT | BMA423_ACTIVITY_INT | BMA423_WRIST_WEAR_INT | BMA423_DOUBLE_TAP_INT, 1, &bma); 128 | bma4_error_codes_print_result("bma423_map_interrupt status", rslt); 129 | 130 | bma423_double_tap_set_sensitivity(0, &bma); 131 | 132 | struct bma423_axes_remap remap_data; 133 | remap_data.x_axis = 1; 134 | remap_data.x_axis_sign = 0; 135 | remap_data.y_axis = 0; 136 | remap_data.y_axis_sign = 0; 137 | remap_data.z_axis = 2; 138 | remap_data.z_axis_sign = 1; 139 | bma423_set_remap_axes(&remap_data, &bma); 140 | 141 | register_int_isr(); 142 | 143 | xSemaphoreGive(i2c_0_semaphore); 144 | 145 | TaskHandle_t bma_int_task_hanlde = NULL; 146 | xTaskCreatePinnedToCore(check_int_task, "int_bma", 4096 * 2, NULL, 0, &bma_int_task_hanlde, 1); 147 | } 148 | 149 | void WatchBma::check_int_task(void *pvParameter) 150 | { 151 | while (1) 152 | { 153 | if (check_irq()) 154 | { 155 | s_int_status |= check_int_status(); 156 | if ((s_int_status & BMA423_WRIST_WEAR_INT) && wakeup_on_tilt) 157 | { 158 | if (!WatchTft::screen_en) 159 | { 160 | WatchTft::toggle_button_menu_view(); 161 | WatchTft::turn_screen_on(); 162 | } 163 | } 164 | else if ((s_int_status & BMA423_DOUBLE_TAP_INT) && wakeup_on_double_tap) 165 | { 166 | if (!WatchTft::screen_en) 167 | { 168 | WatchTft::toggle_button_menu_view(); 169 | WatchTft::turn_screen_on(); 170 | } 171 | } 172 | } 173 | vTaskDelay(1000); 174 | } 175 | } 176 | 177 | void WatchBma::register_int_isr() 178 | { 179 | gpio_config_t io_conf = {}; 180 | io_conf.intr_type = GPIO_INTR_POSEDGE; 181 | io_conf.mode = GPIO_MODE_INPUT; 182 | io_conf.pin_bit_mask = (1ULL << BMA423_INT); 183 | io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; 184 | io_conf.pull_up_en = GPIO_PULLUP_ENABLE; 185 | gpio_config(&io_conf); 186 | gpio_isr_handler_add(BMA423_INT, gpio_isr_handler, NULL); 187 | } 188 | 189 | void IRAM_ATTR WatchBma::gpio_isr_handler(void *arg) 190 | { 191 | _irq = true; 192 | } 193 | 194 | bool WatchBma::check_irq() 195 | { 196 | bool irq = _irq; 197 | _irq = false; 198 | return irq; 199 | } 200 | 201 | uint32_t WatchBma::get_steps() 202 | { 203 | BaseType_t err = xSemaphoreTake(i2c_0_semaphore, 500); 204 | if (err != pdTRUE) 205 | { 206 | return 0; 207 | } 208 | uint32_t step_out = 0; 209 | int8_t rslt = bma423_step_counter_output(&step_out, &bma); 210 | printf("Step counter: %u\n", step_out); 211 | bma4_error_codes_print_result("bma423_step_counter_output status", rslt); 212 | xSemaphoreGive(i2c_0_semaphore); 213 | return step_out; 214 | } 215 | 216 | uint16_t WatchBma::check_int_status() 217 | { 218 | BaseType_t err = xSemaphoreTake(i2c_0_semaphore, 500); 219 | if (err != pdTRUE) 220 | { 221 | return 0; 222 | } 223 | uint16_t int_status = 0; 224 | int8_t rslt = bma423_read_int_status(&int_status, &bma); 225 | if (int_status != 0) 226 | { 227 | if (int_status & BMA423_WRIST_WEAR_INT) 228 | { 229 | printf("BMA: Wrist int\n"); 230 | } 231 | else if (int_status & BMA423_DOUBLE_TAP_INT) 232 | { 233 | printf("BMA: Double tap int\n"); 234 | } 235 | else if (int_status & BMA423_ACTIVITY_INT) 236 | { 237 | uint8_t activity_output = 0; 238 | bma423_activity_output(&activity_output, &bma); 239 | 240 | char activity_desc[11] = "Stationary"; 241 | if (activity_output & BMA423_USER_WALKING) 242 | { 243 | strcpy(activity_desc, "Walking"); 244 | } 245 | else if (activity_output & BMA423_USER_RUNNING) 246 | { 247 | strcpy(activity_desc, "Running"); 248 | } 249 | else if (activity_output & BMA423_STATE_INVALID) 250 | { 251 | strcpy(activity_desc, "Invalid"); 252 | } 253 | 254 | printf("BMA: Activity int: %s\n", activity_desc); 255 | } 256 | } 257 | bma4_error_codes_print_result("bma423_read_int_status status", rslt); 258 | xSemaphoreGive(i2c_0_semaphore); 259 | return int_status; 260 | } -------------------------------------------------------------------------------- /main/WatchBma/WatchBma.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | #ifndef WATCH_BMA 4 | #define WATCH_BMA 5 | 6 | #define BMA423_ANY_NO_MOTION_AXIS_EN_MSK 0xE0 7 | #define BMA423_ANY_NO_MOTION_AXIS_EN_POS UINT8_C(5) 8 | #define BMA423_ANYMOTION_EN_LEN 2 9 | #define BMA423_INT GPIO_NUM_39 10 | 11 | class WatchBma 12 | { 13 | public: 14 | static struct bma4_dev bma; 15 | static uint32_t steps_count_save; 16 | static uint16_t s_int_status; 17 | static bool wakeup_on_double_tap; 18 | static bool wakeup_on_tilt; 19 | static uint32_t step_counter_goal; 20 | 21 | static void init(); 22 | static uint32_t get_steps(); 23 | static uint16_t check_int_status(); 24 | static bool check_irq(); 25 | 26 | private: 27 | static volatile bool _irq; 28 | 29 | static void register_int_isr(); 30 | static void IRAM_ATTR gpio_isr_handler(void *arg); 31 | static void check_int_task(void *pvParameter); 32 | }; 33 | 34 | #endif -------------------------------------------------------------------------------- /main/WatchGps/WatchGps.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchGps.h" 2 | 3 | WatchGps::gps_fix_mode_t WatchGps::gps_status = gps_fix_mode_t::GPS_MODE_INVALID; 4 | bool WatchGps::gps_tracking_stop = true; 5 | WatchGps::esp_gps_t WatchGps::global_gps = {}; 6 | 7 | WatchGps::gps_t WatchGps::gps_saved = {}; 8 | uint32_t WatchGps::gps_point_saved = 0; 9 | 10 | bool WatchGps::gps_enabled = false; 11 | bool WatchGps::gps_fixed = false; 12 | 13 | double WatchGps::gps_lat = HOME_LAT; 14 | double WatchGps::gps_lon = HOME_LON; 15 | 16 | WatchGps::esp_gps_t *WatchGps::esp_gps = NULL; 17 | 18 | void WatchGps::set_state_gps(bool state) 19 | { 20 | static bool old_state = false; 21 | if (state == old_state) 22 | { 23 | return; 24 | } 25 | 26 | if (state) 27 | { 28 | axpxx_setPowerOutPut(AXP202_LDO4, AXP202_ON); 29 | 30 | nmea_parser_config_t config = NMEA_PARSER_CONFIG_DEFAULT(); 31 | nmea_parser_handle_t nmea_hdl = nmea_parser_init(&config); 32 | 33 | // Create NMEA Parser task 34 | BaseType_t err = xTaskCreate( 35 | nmea_parser_task_entry, 36 | "nmea_parser", 37 | CONFIG_NMEA_PARSER_TASK_STACK_SIZE, 38 | esp_gps, 39 | CONFIG_NMEA_PARSER_TASK_PRIORITY, 40 | &esp_gps->tsk_hdl); 41 | if (err != pdTRUE) 42 | { 43 | printf("create NMEA Parser task failed\n"); 44 | uart_driver_delete(esp_gps->uart_port); 45 | free(esp_gps->buffer); 46 | free(esp_gps); 47 | } 48 | } 49 | else 50 | { 51 | axpxx_setPowerOutPut(AXP202_LDO4, AXP202_OFF); 52 | vTaskDelete(esp_gps->tsk_hdl); 53 | uart_driver_delete(esp_gps->uart_port); 54 | free(esp_gps->buffer); 55 | free(esp_gps); 56 | } 57 | 58 | old_state = state; 59 | } 60 | 61 | WatchGps::nmea_parser_handle_t WatchGps::nmea_parser_init(const nmea_parser_config_t *config) 62 | { 63 | esp_gps = (esp_gps_t *)calloc(1, sizeof(esp_gps_t)); 64 | if (!esp_gps) 65 | { 66 | printf("calloc memory for esp_fps failed\n"); 67 | free(esp_gps); 68 | return NULL; 69 | } 70 | esp_gps->buffer = (uint8_t *)calloc(1, NMEA_PARSER_RUNTIME_BUFFER_SIZE); 71 | if (!esp_gps->buffer) 72 | { 73 | printf("calloc memory for runtime buffer failed\n"); 74 | free(esp_gps->buffer); 75 | free(esp_gps); 76 | return NULL; 77 | } 78 | #if CONFIG_NMEA_STATEMENT_GSA 79 | esp_gps->all_statements |= (1 << STATEMENT_GSA); 80 | #endif 81 | #if CONFIG_NMEA_STATEMENT_GSV 82 | esp_gps->all_statements |= (1 << STATEMENT_GSV); 83 | #endif 84 | #if CONFIG_NMEA_STATEMENT_GGA 85 | esp_gps->all_statements |= (1 << STATEMENT_GGA); 86 | #endif 87 | #if CONFIG_NMEA_STATEMENT_RMC 88 | esp_gps->all_statements |= (1 << STATEMENT_RMC); 89 | #endif 90 | #if CONFIG_NMEA_STATEMENT_GLL 91 | esp_gps->all_statements |= (1 << STATEMENT_GLL); 92 | #endif 93 | #if CONFIG_NMEA_STATEMENT_VTG 94 | esp_gps->all_statements |= (1 << STATEMENT_VTG); 95 | #endif 96 | esp_gps->all_statements |= (1 << STATEMENT_GPTXT); 97 | esp_gps->all_statements |= (1 << STATEMENT_GNZDA); 98 | // Set attributes 99 | esp_gps->uart_port = config->uart.uart_port; 100 | esp_gps->all_statements &= 0xFE; 101 | // Install UART friver 102 | uart_config_t uart_config = { 103 | .baud_rate = (int)config->uart.baud_rate, 104 | .data_bits = config->uart.data_bits, 105 | .parity = config->uart.parity, 106 | .stop_bits = config->uart.stop_bits, 107 | .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, 108 | .source_clk = UART_SCLK_APB, 109 | }; 110 | if (uart_driver_install(esp_gps->uart_port, CONFIG_NMEA_PARSER_RING_BUFFER_SIZE, 0, 111 | 0, NULL, 0) != ESP_OK) 112 | { 113 | printf("install uart driver failed\n"); 114 | uart_driver_delete(esp_gps->uart_port); 115 | free(esp_gps->buffer); 116 | free(esp_gps); 117 | return NULL; 118 | } 119 | if (uart_param_config(esp_gps->uart_port, &uart_config) != ESP_OK) 120 | { 121 | printf("config uart parameter failed\n"); 122 | free(esp_gps->buffer); 123 | free(esp_gps); 124 | return NULL; 125 | } 126 | if (uart_set_pin(esp_gps->uart_port, GPIO_NUM_26, config->uart.rx_pin, // TX to GPIO_NUM_26 127 | UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE) != ESP_OK) 128 | { 129 | printf("config uart gpio failed\n"); 130 | free(esp_gps->buffer); 131 | free(esp_gps); 132 | return NULL; 133 | } 134 | 135 | uart_flush(esp_gps->uart_port); 136 | 137 | printf("NMEA Parser init OK\n"); 138 | return esp_gps; 139 | } 140 | 141 | void WatchGps::nmea_parser_task_entry(void *arg) 142 | { 143 | esp_gps_t *esp_gps = (esp_gps_t *)arg; 144 | uart_event_t event; 145 | while (1) 146 | { 147 | uint8_t data[1024] = {}; 148 | int len = uart_read_bytes(UART_NUM_1, data, 1023, 20 / portTICK_RATE_MS); 149 | 150 | if (len) 151 | { 152 | if (gps_decode(data, len) != ESP_OK) 153 | { 154 | printf("GPS decode line failed\n"); 155 | } 156 | vTaskDelay(20); 157 | } 158 | 159 | static uint32_t timer_stage = esp_timer_get_time() / 1000U; 160 | static uint8_t get_done_stage = 0; 161 | const uint32_t timer_btw_stage = 1000; 162 | 163 | if ((esp_timer_get_time() / 500U) - timer_stage > timer_btw_stage && get_done_stage == 0) 164 | { 165 | 166 | printf("Enabling GALILEO L76L!\n"); 167 | 168 | char cmd_qt_02[] = "$PMTK353,1,1,1,0,0*2A\r\n"; // set protocol galileo enable 169 | uart_write_bytes(UART_NUM_1, cmd_qt_02, sizeof(cmd_qt_02)); 170 | uart_wait_tx_done(UART_NUM_1, 10000 / portTICK_PERIOD_MS); 171 | 172 | timer_stage = esp_timer_get_time() / 1000U; 173 | get_done_stage++; 174 | } 175 | else if ((esp_timer_get_time() / 500U) - timer_stage > timer_btw_stage && get_done_stage == 1) 176 | { 177 | printf("Setting pedestrian mode L76L!\n"); 178 | char cmd_qt_04[] = "$PMTK886,1*29\r\n"; 179 | uart_write_bytes(UART_NUM_1, cmd_qt_04, sizeof(cmd_qt_04)); 180 | uart_wait_tx_done(UART_NUM_1, 10000 / portTICK_PERIOD_MS); 181 | 182 | timer_stage = esp_timer_get_time() / 1000U; 183 | get_done_stage++; 184 | } 185 | 186 | static uint32_t timer_print = esp_timer_get_time() / 1000U; 187 | if ((esp_timer_get_time() / 1000U) - timer_print > 1000) 188 | { 189 | 190 | gps_t *gps = &global_gps.parent; 191 | 192 | WatchGps::gps_status = gps->fix_mode; 193 | 194 | if (!gps->fix_mode || gps->fix_mode == gps_fix_mode_t::GPS_MODE_INVALID) 195 | { 196 | WatchTft::set_gps_info(false, gps->sats_in_view, gps->dop_p, gps->latitude, gps->longitude); 197 | } 198 | else 199 | { 200 | WatchTft::set_gps_info(true, gps->sats_in_use, gps->dop_p, gps->latitude, gps->longitude); 201 | 202 | memcpy(&WatchGps::gps_saved, gps, sizeof(WatchGps::gps_saved)); 203 | } 204 | 205 | printf("%d/%d/%d %d:%d:%d => fixed %d view %d, use %d, lat %.05f, lon %.05f, alt: %.02f, dop %.2f\r\n", 206 | gps->date.year + YEAR_BASE, gps->date.month, gps->date.day, 207 | gps->tim.hour + TIME_ZONE, gps->tim.minute, gps->tim.second, 208 | gps->fix_mode > 1, 209 | gps->sats_in_view, gps->sats_in_use, gps->latitude, gps->longitude, gps->altitude, 210 | gps->dop_p); 211 | 212 | timer_print = esp_timer_get_time() / 1000U; 213 | } 214 | } 215 | vTaskDelete(NULL); 216 | } 217 | 218 | esp_err_t WatchGps::gps_decode(uint8_t *buff_uart, size_t len) 219 | { 220 | const uint8_t *d = buff_uart; 221 | 222 | static bool is_nmea = false; 223 | static bool is_ubx = false; 224 | static bool ga_printed = false; 225 | 226 | /*for (size_t i = 0; i < len; i++) 227 | { 228 | if (i && i % 32 == 0) 229 | { 230 | printf("\n"); 231 | } 232 | printf("%02x ", buff_uart[i]); 233 | } 234 | printf("\n");*/ 235 | 236 | for (size_t i = 0; i < len; i++, buff_uart++) 237 | { 238 | // Start of a statement 239 | if (*d == '$') 240 | { 241 | if (is_ubx && !is_nmea) 242 | { 243 | printf("\n"); 244 | } 245 | is_nmea = true; 246 | is_ubx = false; 247 | 248 | ga_printed = false; 249 | // Reset runtime information 250 | global_gps.asterisk = 0; 251 | global_gps.item_num = 0; 252 | global_gps.item_pos = 0; 253 | global_gps.cur_statement = 0; 254 | global_gps.crc = 0; 255 | global_gps.sat_count = 0; 256 | global_gps.sat_num = 0; 257 | // Add character to item 258 | global_gps.item_str[global_gps.item_pos++] = *d; 259 | global_gps.item_str[global_gps.item_pos] = '\0'; 260 | } 261 | else if (!is_nmea) 262 | { 263 | printf("%02x ", *d); 264 | is_ubx = true; 265 | 266 | if (len > 30 && !ga_printed) 267 | { 268 | if (*d == 0xb5 && 269 | *(d + 1) == 0x62 && 270 | *(d + 2) == 0x06 && 271 | *(d + 3) == 0x3e && 272 | *(d + 4) == 0x3c && 273 | *(d + 5) == 0x00) 274 | { 275 | bool galileo_en = d[30]; 276 | printf("galileo_en: %d\n", galileo_en); 277 | ga_printed = true; 278 | } 279 | } 280 | } 281 | // Detect item separator character 282 | else if (*d == ',') 283 | { 284 | // Parse current item 285 | parse_item(&global_gps); 286 | // Add character to CRC computation 287 | global_gps.crc ^= (uint8_t)(*d); 288 | // Start with next item 289 | global_gps.item_pos = 0; 290 | global_gps.item_str[0] = '\0'; 291 | global_gps.item_num++; 292 | } 293 | // End of CRC computation 294 | else if (*d == '*') 295 | { 296 | // Parse current item 297 | parse_item(&global_gps); 298 | // Asterisk detected 299 | global_gps.asterisk = 1; 300 | // Start with next item 301 | global_gps.item_pos = 0; 302 | global_gps.item_str[0] = '\0'; 303 | global_gps.item_num++; 304 | } 305 | // End of statement 306 | else if (*d == '\r') 307 | { 308 | // Convert received CRC from string (hex) to number 309 | uint8_t crc = (uint8_t)strtol(global_gps.item_str, NULL, 16); 310 | // CRC passed 311 | if (global_gps.crc == crc) 312 | { 313 | switch (global_gps.cur_statement) 314 | { 315 | #if CONFIG_NMEA_STATEMENT_GGA 316 | case STATEMENT_GGA: 317 | global_gps.parsed_statement |= 1 << STATEMENT_GGA; 318 | break; 319 | #endif 320 | #if CONFIG_NMEA_STATEMENT_GSA 321 | case STATEMENT_GSA: 322 | global_gps.parsed_statement |= 1 << STATEMENT_GSA; 323 | break; 324 | #endif 325 | #if CONFIG_NMEA_STATEMENT_RMC 326 | case STATEMENT_RMC: 327 | global_gps.parsed_statement |= 1 << STATEMENT_RMC; 328 | break; 329 | #endif 330 | #if CONFIG_NMEA_STATEMENT_GSV 331 | case STATEMENT_GSV: 332 | if (global_gps.sat_num == global_gps.sat_count) 333 | { 334 | global_gps.parsed_statement |= 1 << STATEMENT_GSV; 335 | } 336 | break; 337 | #endif 338 | #if CONFIG_NMEA_STATEMENT_GLL 339 | case STATEMENT_GLL: 340 | global_gps.parsed_statement |= 1 << STATEMENT_GLL; 341 | break; 342 | #endif 343 | #if CONFIG_NMEA_STATEMENT_VTG 344 | case STATEMENT_VTG: 345 | global_gps.parsed_statement |= 1 << STATEMENT_VTG; 346 | break; 347 | #endif 348 | case STATEMENT_GPTXT: 349 | global_gps.parsed_statement |= 1 << STATEMENT_GPTXT; 350 | break; 351 | case STATEMENT_GNZDA: 352 | global_gps.parsed_statement |= 1 << STATEMENT_GNZDA; 353 | break; 354 | default: 355 | break; 356 | } 357 | // Check if all statements have been parsed 358 | if (((global_gps.parsed_statement) & global_gps.all_statements) == global_gps.all_statements) 359 | { 360 | global_gps.parsed_statement = 0; 361 | } 362 | if (*(d + 1) == '\n') 363 | { 364 | d++; 365 | i++; 366 | } 367 | } 368 | else 369 | { 370 | printf("CRC Error for statement:%s\n", global_gps.buffer); 371 | } 372 | if (global_gps.cur_statement == STATEMENT_UNKNOWN) 373 | { 374 | // Send signal to notify that one unknown statement has been met 375 | } 376 | } 377 | // Other non-space character 378 | else 379 | { 380 | if (!(global_gps.asterisk)) 381 | { 382 | // Add to CRC 383 | global_gps.crc ^= (uint8_t)(*d); 384 | } 385 | // Add character to item 386 | global_gps.item_str[global_gps.item_pos++] = *d; 387 | global_gps.item_str[global_gps.item_pos] = '\0'; 388 | } 389 | // Process next character 390 | d++; 391 | } 392 | return ESP_OK; 393 | } 394 | 395 | esp_err_t WatchGps::parse_item(esp_gps_t *esp_gps) 396 | { 397 | esp_err_t err = ESP_OK; 398 | /* start of a statement */ 399 | if (esp_gps->item_num == 0 && esp_gps->item_str[0] == '$') 400 | { 401 | if (0) 402 | { 403 | } 404 | #if CONFIG_NMEA_STATEMENT_GGA 405 | else if (strstr(esp_gps->item_str, "GGA")) 406 | { 407 | esp_gps->cur_statement = STATEMENT_GGA; 408 | } 409 | #endif 410 | #if CONFIG_NMEA_STATEMENT_GSA 411 | else if (strstr(esp_gps->item_str, "GSA")) 412 | { 413 | esp_gps->cur_statement = STATEMENT_GSA; 414 | } 415 | #endif 416 | #if CONFIG_NMEA_STATEMENT_RMC 417 | else if (strstr(esp_gps->item_str, "RMC")) 418 | { 419 | esp_gps->cur_statement = STATEMENT_RMC; 420 | } 421 | #endif 422 | #if CONFIG_NMEA_STATEMENT_GSV 423 | else if (strstr(esp_gps->item_str, "GSV")) 424 | { 425 | esp_gps->cur_statement = STATEMENT_GSV; 426 | } 427 | #endif 428 | #if CONFIG_NMEA_STATEMENT_GLL 429 | else if (strstr(esp_gps->item_str, "GLL")) 430 | { 431 | esp_gps->cur_statement = STATEMENT_GLL; 432 | } 433 | #endif 434 | #if CONFIG_NMEA_STATEMENT_VTG 435 | else if (strstr(esp_gps->item_str, "VTG")) 436 | { 437 | esp_gps->cur_statement = STATEMENT_VTG; 438 | } 439 | #endif 440 | else if (strstr(esp_gps->item_str, "GPTXT")) 441 | { 442 | esp_gps->cur_statement = STATEMENT_GPTXT; 443 | } 444 | else if (strstr(esp_gps->item_str, "GNZDA")) 445 | { 446 | esp_gps->cur_statement = STATEMENT_GNZDA; 447 | } 448 | else 449 | { 450 | esp_gps->cur_statement = STATEMENT_UNKNOWN; 451 | } 452 | goto out; 453 | } 454 | // Parse each item, depend on the type of the statement 455 | if (esp_gps->cur_statement == STATEMENT_UNKNOWN) 456 | { 457 | goto out; 458 | } 459 | #if CONFIG_NMEA_STATEMENT_GGA 460 | else if (esp_gps->cur_statement == STATEMENT_GGA) 461 | { 462 | parse_gga(esp_gps); 463 | } 464 | #endif 465 | #if CONFIG_NMEA_STATEMENT_GSA 466 | else if (esp_gps->cur_statement == STATEMENT_GSA) 467 | { 468 | parse_gsa(esp_gps); 469 | } 470 | #endif 471 | #if CONFIG_NMEA_STATEMENT_GSV 472 | else if (esp_gps->cur_statement == STATEMENT_GSV) 473 | { 474 | parse_gsv(esp_gps); 475 | } 476 | #endif 477 | #if CONFIG_NMEA_STATEMENT_RMC 478 | else if (esp_gps->cur_statement == STATEMENT_RMC) 479 | { 480 | parse_rmc(esp_gps); 481 | } 482 | #endif 483 | #if CONFIG_NMEA_STATEMENT_GLL 484 | else if (esp_gps->cur_statement == STATEMENT_GLL) 485 | { 486 | parse_gll(esp_gps); 487 | } 488 | #endif 489 | #if CONFIG_NMEA_STATEMENT_VTG 490 | else if (esp_gps->cur_statement == STATEMENT_VTG) 491 | { 492 | parse_vtg(esp_gps); 493 | } 494 | #endif 495 | else if (esp_gps->cur_statement == STATEMENT_GPTXT) 496 | { 497 | parse_gptxt(esp_gps); 498 | } 499 | else if (esp_gps->cur_statement == STATEMENT_GNZDA) 500 | { 501 | parse_gnzda(esp_gps); 502 | } 503 | else 504 | { 505 | err = ESP_FAIL; 506 | } 507 | out: 508 | return err; 509 | } 510 | 511 | float WatchGps::parse_lat_long(esp_gps_t *esp_gps) 512 | { 513 | float ll = strtof(esp_gps->item_str, NULL); 514 | int deg = ((int)ll) / 100; 515 | float min = ll - (deg * 100); 516 | ll = deg + min / 60.0f; 517 | // printf("lat_long %.6f\n", ll); 518 | return ll; 519 | } 520 | 521 | #if CONFIG_NMEA_STATEMENT_GGA 522 | /** 523 | * @brief Parse GGA statements 524 | * 525 | * @param esp_gps esp_gps_t type object 526 | */ 527 | void WatchGps::parse_gga(esp_gps_t *esp_gps) 528 | { 529 | // Process GGA statement 530 | switch (esp_gps->item_num) 531 | { 532 | case 1: // Process UTC time 533 | parse_utc_time(esp_gps); 534 | break; 535 | case 2: // Latitude 536 | esp_gps->parent.latitude = parse_lat_long(esp_gps); 537 | break; 538 | case 3: // Latitude north(1)/south(-1) information 539 | if (esp_gps->item_str[0] == 'S' || esp_gps->item_str[0] == 's') 540 | { 541 | esp_gps->parent.latitude *= -1; 542 | } 543 | break; 544 | case 4: // Longitude 545 | esp_gps->parent.longitude = parse_lat_long(esp_gps); 546 | break; 547 | case 5: // Longitude east(1)/west(-1) information 548 | if (esp_gps->item_str[0] == 'W' || esp_gps->item_str[0] == 'w') 549 | { 550 | esp_gps->parent.longitude *= -1; 551 | } 552 | break; 553 | case 6: // Fix status 554 | esp_gps->parent.fix = (gps_fix_t)strtol(esp_gps->item_str, NULL, 10); 555 | break; 556 | case 7: // Satellites in use 557 | esp_gps->parent.sats_in_use = (uint8_t)strtol(esp_gps->item_str, NULL, 10); 558 | break; 559 | case 8: // HDOP 560 | esp_gps->parent.dop_h = strtof(esp_gps->item_str, NULL); 561 | break; 562 | case 9: // Altitude 563 | esp_gps->parent.altitude = strtof(esp_gps->item_str, NULL); 564 | break; 565 | case 11: // Altitude above ellipsoid 566 | esp_gps->parent.altitude += strtof(esp_gps->item_str, NULL); 567 | break; 568 | default: 569 | break; 570 | } 571 | } 572 | #endif 573 | 574 | uint8_t WatchGps::convert_two_digit2number(const char *digit_char) 575 | { 576 | return 10 * (digit_char[0] - '0') + (digit_char[1] - '0'); 577 | } 578 | 579 | void WatchGps::parse_utc_time(esp_gps_t *esp_gps) 580 | { 581 | esp_gps->parent.tim.hour = convert_two_digit2number(esp_gps->item_str + 0); 582 | esp_gps->parent.tim.minute = convert_two_digit2number(esp_gps->item_str + 2); 583 | esp_gps->parent.tim.second = convert_two_digit2number(esp_gps->item_str + 4); 584 | if (esp_gps->item_str[6] == '.') 585 | { 586 | uint16_t tmp = 0; 587 | uint8_t i = 7; 588 | while (esp_gps->item_str[i]) 589 | { 590 | tmp = 10 * tmp + esp_gps->item_str[i] - '0'; 591 | i++; 592 | } 593 | esp_gps->parent.tim.thousand = tmp; 594 | } 595 | } 596 | 597 | #if CONFIG_NMEA_STATEMENT_GSA 598 | /** 599 | * @brief Parse GSA statements 600 | * 601 | * @param esp_gps esp_gps_t type object 602 | */ 603 | void WatchGps::parse_gsa(esp_gps_t *esp_gps) 604 | { 605 | // Process GSA statement 606 | switch (esp_gps->item_num) 607 | { 608 | case 2: // Process fix mode 609 | esp_gps->parent.fix_mode = (gps_fix_mode_t)strtol(esp_gps->item_str, NULL, 10); 610 | break; 611 | case 15: // Process PDOP 612 | esp_gps->parent.dop_p = strtof(esp_gps->item_str, NULL); 613 | break; 614 | case 16: // Process HDOP 615 | esp_gps->parent.dop_h = strtof(esp_gps->item_str, NULL); 616 | break; 617 | case 17: // Process VDOP 618 | esp_gps->parent.dop_v = strtof(esp_gps->item_str, NULL); 619 | break; 620 | default: 621 | // Parse satellite IDs 622 | if (esp_gps->item_num >= 3 && esp_gps->item_num <= 14) 623 | { 624 | esp_gps->parent.sats_id_in_use[esp_gps->item_num - 3] = (uint8_t)strtol(esp_gps->item_str, NULL, 10); 625 | } 626 | break; 627 | } 628 | } 629 | #endif 630 | 631 | #if CONFIG_NMEA_STATEMENT_GSV 632 | /** 633 | * @brief Parse GSV statements 634 | * 635 | * @param esp_gps esp_gps_t type object 636 | */ 637 | void WatchGps::parse_gsv(esp_gps_t *esp_gps) 638 | { 639 | // Process GSV statement 640 | switch (esp_gps->item_num) 641 | { 642 | case 1: // total GSV numbers 643 | esp_gps->sat_count = (uint8_t)strtol(esp_gps->item_str, NULL, 10); 644 | break; 645 | case 2: // Current GSV statement number 646 | esp_gps->sat_num = (uint8_t)strtol(esp_gps->item_str, NULL, 10); 647 | break; 648 | case 3: // Process satellites in view 649 | esp_gps->parent.sats_in_view = (uint8_t)strtol(esp_gps->item_str, NULL, 10); 650 | break; 651 | default: 652 | if (esp_gps->item_num >= 4 && esp_gps->item_num <= 19) 653 | { 654 | uint8_t item_num = esp_gps->item_num - 4; // Normalize item number from 4-19 to 0-15 655 | uint8_t index; 656 | uint32_t value; 657 | index = 4 * (esp_gps->sat_num - 1) + item_num / 4; // Get array index 658 | if (index < GPS_MAX_SATELLITES_IN_VIEW) 659 | { 660 | value = strtol(esp_gps->item_str, NULL, 10); 661 | switch (item_num % 4) 662 | { 663 | case 0: 664 | esp_gps->parent.sats_desc_in_view[index].num = (uint8_t)value; 665 | break; 666 | case 1: 667 | esp_gps->parent.sats_desc_in_view[index].elevation = (uint8_t)value; 668 | break; 669 | case 2: 670 | esp_gps->parent.sats_desc_in_view[index].azimuth = (uint16_t)value; 671 | break; 672 | case 3: 673 | esp_gps->parent.sats_desc_in_view[index].snr = (uint8_t)value; 674 | break; 675 | default: 676 | break; 677 | } 678 | } 679 | } 680 | break; 681 | } 682 | } 683 | #endif 684 | 685 | #if CONFIG_NMEA_STATEMENT_RMC 686 | /** 687 | * @brief Parse RMC statements 688 | * 689 | * @param esp_gps esp_gps_t type object 690 | */ 691 | void WatchGps::parse_rmc(esp_gps_t *esp_gps) 692 | { 693 | // Process GPRMC statement 694 | switch (esp_gps->item_num) 695 | { 696 | case 1: // Process UTC time 697 | parse_utc_time(esp_gps); 698 | break; 699 | case 2: // Process valid status 700 | esp_gps->parent.valid = (esp_gps->item_str[0] == 'A'); 701 | break; 702 | case 3: // Latitude 703 | esp_gps->parent.latitude = parse_lat_long(esp_gps); 704 | break; 705 | case 4: // Latitude north(1)/south(-1) information 706 | if (esp_gps->item_str[0] == 'S' || esp_gps->item_str[0] == 's') 707 | { 708 | esp_gps->parent.latitude *= -1; 709 | } 710 | break; 711 | case 5: // Longitude 712 | esp_gps->parent.longitude = parse_lat_long(esp_gps); 713 | break; 714 | case 6: // Longitude east(1)/west(-1) information 715 | if (esp_gps->item_str[0] == 'W' || esp_gps->item_str[0] == 'w') 716 | { 717 | esp_gps->parent.longitude *= -1; 718 | } 719 | break; 720 | case 7: // Process ground speed in unit m/s 721 | esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) * 1.852; 722 | break; 723 | case 8: // Process true course over ground 724 | esp_gps->parent.cog = strtof(esp_gps->item_str, NULL); 725 | break; 726 | case 9: // Process date 727 | esp_gps->parent.date.day = convert_two_digit2number(esp_gps->item_str + 0); 728 | esp_gps->parent.date.month = convert_two_digit2number(esp_gps->item_str + 2); 729 | esp_gps->parent.date.year = convert_two_digit2number(esp_gps->item_str + 4); 730 | break; 731 | case 10: // Process magnetic variation 732 | esp_gps->parent.variation = strtof(esp_gps->item_str, NULL); 733 | break; 734 | default: 735 | break; 736 | } 737 | } 738 | #endif 739 | 740 | void WatchGps::parse_gnzda(esp_gps_t *esp_gps) 741 | { 742 | // Process GPRMC statement 743 | switch (esp_gps->item_num) 744 | { 745 | case 1: // Process UTC time 746 | parse_utc_time(esp_gps); 747 | break; 748 | case 2: 749 | esp_gps->parent.date.day = convert_two_digit2number(esp_gps->item_str); 750 | case 3: 751 | esp_gps->parent.date.month = convert_two_digit2number(esp_gps->item_str); 752 | case 4: 753 | esp_gps->parent.date.year = convert_two_digit2number(esp_gps->item_str); 754 | default: 755 | break; 756 | } 757 | } 758 | 759 | #if CONFIG_NMEA_STATEMENT_GLL 760 | /** 761 | * @brief Parse GLL statements 762 | * 763 | * @param esp_gps esp_gps_t type object 764 | */ 765 | void WatchGps::parse_gll(esp_gps_t *esp_gps) 766 | { 767 | // Process GPGLL statement 768 | switch (esp_gps->item_num) 769 | { 770 | case 1: // Latitude 771 | esp_gps->parent.latitude = parse_lat_long(esp_gps); 772 | break; 773 | case 2: // Latitude north(1)/south(-1) information 774 | if (esp_gps->item_str[0] == 'S' || esp_gps->item_str[0] == 's') 775 | { 776 | esp_gps->parent.latitude *= -1; 777 | } 778 | break; 779 | case 3: // Longitude 780 | esp_gps->parent.longitude = parse_lat_long(esp_gps); 781 | break; 782 | case 4: // Longitude east(1)/west(-1) information 783 | if (esp_gps->item_str[0] == 'W' || esp_gps->item_str[0] == 'w') 784 | { 785 | esp_gps->parent.longitude *= -1; 786 | } 787 | break; 788 | case 5: // Process UTC time 789 | parse_utc_time(esp_gps); 790 | break; 791 | case 6: // Process valid status 792 | esp_gps->parent.valid = (esp_gps->item_str[0] == 'A'); 793 | break; 794 | default: 795 | break; 796 | } 797 | } 798 | #endif 799 | 800 | #if CONFIG_NMEA_STATEMENT_VTG 801 | /** 802 | * @brief Parse VTG statements 803 | * 804 | * @param esp_gps esp_gps_t type object 805 | */ 806 | void WatchGps::parse_vtg(esp_gps_t *esp_gps) 807 | { 808 | // Process GPVGT statement 809 | switch (esp_gps->item_num) 810 | { 811 | case 1: // Process true course over ground 812 | esp_gps->parent.cog = strtof(esp_gps->item_str, NULL); 813 | break; 814 | case 3: // Process magnetic variation 815 | esp_gps->parent.variation = strtof(esp_gps->item_str, NULL); 816 | break; 817 | case 5: // Process ground speed in unit m/s 818 | esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) * 1.852; // knots to m/s 819 | break; 820 | case 7: // Process ground speed in unit m/s 821 | esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) / 3.6; // km/h to m/s 822 | break; 823 | default: 824 | break; 825 | } 826 | } 827 | #endif 828 | 829 | void WatchGps::parse_gptxt(esp_gps_t *esp_gps) 830 | { 831 | // Process GPVGT statement 832 | switch (esp_gps->item_num) 833 | { 834 | case 1: 835 | case 2: 836 | case 3: 837 | printf("%s ", esp_gps->item_str); 838 | break; 839 | case 4: // Process magnetic variation 840 | printf("%s\n", esp_gps->item_str); 841 | break; 842 | default: 843 | break; 844 | } 845 | } 846 | 847 | void WatchGps::tracking_task(void *pvParameter) 848 | { 849 | gps_tracking_stop = false; 850 | 851 | char gps_file_name[32] = {}; 852 | // "/sdcard/2016-07-17-08:30:28.gpx"; 853 | 854 | gps_point_saved = 0; 855 | 856 | while (1) 857 | { 858 | 859 | static uint32_t timer_gps_task = (uint32_t)esp_timer_get_time() / 1000U; 860 | 861 | if ((uint32_t)esp_timer_get_time() / 1000U - timer_gps_task > 3000) 862 | { 863 | printf("tracking task\n"); 864 | timer_gps_task = (uint32_t)esp_timer_get_time() / 1000U; 865 | 866 | if (gps_status != gps_fix_mode_t::GPS_MODE_INVALID) 867 | { 868 | printf("Saving pos to SD\n"); 869 | 870 | if (strlen(gps_file_name) == 0) 871 | { 872 | 873 | char gps_date[11] = "2016-07-17"; 874 | char gps_time[9] = "08-30-28"; 875 | 876 | sprintf(gps_date, "%hu-%02hhu-%02hhu", 877 | gps_saved.date.year + YEAR_BASE, 878 | gps_saved.date.month, 879 | gps_saved.date.day); 880 | sprintf(gps_time, "%02hhu-%02hhu-%02hhu", 881 | gps_saved.tim.hour + TIME_ZONE, 882 | gps_saved.tim.minute, 883 | gps_saved.tim.second); 884 | 885 | sprintf(gps_file_name, "/sdcard/%s-%s.gpx", 886 | gps_date, 887 | gps_time); 888 | 889 | printf("new gps_file_name: %s\n", gps_file_name); 890 | 891 | char start_file[] = "\n" 892 | "\n" 893 | "\n" 894 | "esp_gpx\n" 895 | "Running\n" 896 | "\n"; 897 | 898 | FILE *f = fopen(gps_file_name, "w"); 899 | if (f == NULL) 900 | { 901 | printf("Failed to open gps_file for writing\n"); 902 | 903 | gps_tracking_stop = true; 904 | WatchTft::current_task_hanlde = NULL; 905 | vTaskDelete(NULL); 906 | } 907 | fwrite(start_file, strlen(start_file), 1, f); 908 | fclose(f); 909 | printf("Gps_file start written\n"); 910 | } 911 | 912 | if (gps_status == gps_fix_mode_t::GPS_MODE_INVALID) 913 | { 914 | gps_saved.latitude = (float)(rand() % 100000) / (float)50000; 915 | gps_saved.longitude = (float)(rand() % 100000) / (float)50000; 916 | gps_saved.altitude = (float)(rand() % 100000) / (float)50000; 917 | } 918 | 919 | char gps_datetime[21] = "2016-07-17T08:30:28Z"; 920 | sprintf(gps_datetime, "%hu-%02hhu-%02hhuT%02hhu:%02hhu:%02hhuZ", 921 | gps_saved.date.year + YEAR_BASE, 922 | gps_saved.date.month, 923 | gps_saved.date.day, 924 | gps_saved.tim.hour + TIME_ZONE, 925 | gps_saved.tim.minute, 926 | gps_saved.tim.second); 927 | 928 | char gps_pos_line[200] = {}; 929 | sprintf(gps_pos_line, "\n" 930 | "%.05f\n" 931 | "\n" 932 | "%.05f\n" 933 | "%hhu\n" 934 | "%.02f\n" 935 | "%.02f\n" 936 | "%.02f\n" 937 | "\n", 938 | gps_saved.latitude, 939 | gps_saved.longitude, 940 | gps_saved.altitude, 941 | gps_datetime, 942 | gps_saved.speed, 943 | gps_saved.sats_in_use, 944 | gps_saved.dop_h, 945 | gps_saved.dop_v, 946 | gps_saved.dop_p); 947 | printf("line: %s\n", gps_pos_line); 948 | 949 | FILE *f = fopen(gps_file_name, "a"); 950 | if (f == NULL) 951 | { 952 | printf("Failed to open gps_file for appending\n"); 953 | continue; 954 | } 955 | fwrite(gps_pos_line, strlen(gps_pos_line), 1, f); 956 | fclose(f); 957 | printf("Gps_file written\n"); 958 | 959 | gps_point_saved++; 960 | } 961 | } 962 | 963 | if (gps_tracking_stop) 964 | { 965 | printf("STOP gps tracking task: %s\n", gps_file_name); 966 | 967 | char end_file[] = "\n" 968 | "\n" 969 | "\n"; 970 | 971 | FILE *f = fopen(gps_file_name, "a"); 972 | if (f == NULL) 973 | { 974 | printf("Failed to open gps_file for end appending\n"); 975 | } 976 | else 977 | { 978 | fwrite(end_file, strlen(end_file), 1, f); 979 | fclose(f); 980 | printf("Gps_file written\n"); 981 | } 982 | 983 | f = fopen(gps_file_name, "r"); 984 | if (f == NULL) 985 | { 986 | printf("Failed to open gps_file for end reading\n"); 987 | } 988 | else 989 | { 990 | char currentline[100]; 991 | while (fgets(currentline, sizeof(currentline), f) != NULL) 992 | { 993 | printf("%s", currentline); 994 | } 995 | printf("\n"); 996 | 997 | fclose(f); 998 | } 999 | WatchTft::current_task_hanlde = NULL; 1000 | vTaskDelete(NULL); 1001 | } 1002 | 1003 | vTaskDelay(200); 1004 | } 1005 | } 1006 | 1007 | uint32_t WatchGps::lon_to_tile_x(double lon) 1008 | { 1009 | uint32_t z = 15; 1010 | return (int)(floor((lon + 180.0) / 360.0 * (1 << z))); 1011 | } 1012 | 1013 | uint32_t WatchGps::lat_lon_to_tile_y(double lat, double lon) 1014 | { 1015 | double latrad = lat * M_PI / 180.0; 1016 | 1017 | uint32_t z = 15; 1018 | return (int)(floor((1.0 - asinh(tan(latrad)) / M_PI) / 2.0 * (1 << z))); 1019 | } 1020 | 1021 | uint32_t WatchGps::lon_to_x(double lon) 1022 | { 1023 | uint32_t z = 15; 1024 | double xtile_d = (lon + 180.0) / 360.0 * (1 << z); 1025 | return xtile_d * 256; 1026 | } 1027 | 1028 | uint32_t WatchGps::lat_lon_to_y(double lat, double lon) 1029 | { 1030 | uint32_t z = 15; 1031 | 1032 | double latrad = lat * M_PI / 180.0; 1033 | 1034 | double ytile_d = (1.0 - asinh(tan(latrad)) / M_PI) / 2.0 * (1 << z); 1035 | return ytile_d * 256; 1036 | } -------------------------------------------------------------------------------- /main/WatchGps/WatchGps.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | #ifndef WATCH_GPS 4 | #define WATCH_GPS 5 | 6 | #define TIME_ZONE (+1) // Paris Time 7 | #define YEAR_BASE (2000) // date in GPS starts from 2000 8 | 9 | #define GPS_MAX_SATELLITES_IN_USE (12) 10 | #define GPS_MAX_SATELLITES_IN_VIEW (16) 11 | 12 | #define CONFIG_NMEA_PARSER_RING_BUFFER_SIZE 4096 13 | #define CONFIG_NMEA_PARSER_TASK_STACK_SIZE 4096 14 | #define CONFIG_NMEA_PARSER_TASK_PRIORITY 2 15 | 16 | #define CONFIG_NMEA_STATEMENT_GGA 1 17 | #define CONFIG_NMEA_STATEMENT_GSA 1 18 | #define CONFIG_NMEA_STATEMENT_RMC 1 19 | #define CONFIG_NMEA_STATEMENT_GSV 1 20 | #define CONFIG_NMEA_STATEMENT_GLL 1 21 | #define CONFIG_NMEA_STATEMENT_VTG 1 22 | 23 | #define NMEA_PARSER_RUNTIME_BUFFER_SIZE (CONFIG_NMEA_PARSER_RING_BUFFER_SIZE / 2) 24 | #define NMEA_EVENT_LOOP_QUEUE_SIZE (16) 25 | 26 | #define NMEA_MAX_STATEMENT_ITEM_LENGTH (16) 27 | 28 | #define NMEA_PARSER_CONFIG_DEFAULT() \ 29 | { \ 30 | .uart = { \ 31 | .uart_port = UART_NUM_1, \ 32 | .rx_pin = GPIO_NUM_36, \ 33 | .baud_rate = 9600, \ 34 | .data_bits = UART_DATA_8_BITS, \ 35 | .parity = UART_PARITY_DISABLE, \ 36 | .stop_bits = UART_STOP_BITS_1, \ 37 | .event_queue_size = 16 \ 38 | } \ 39 | } 40 | 41 | class WatchGps 42 | { 43 | public: 44 | typedef enum 45 | { 46 | GPS_FIX_INVALID, /*!< Not fixed */ 47 | GPS_FIX_GPS, /*!< GPS */ 48 | GPS_FIX_DGPS, /*!< Differential GPS */ 49 | } gps_fix_t; 50 | 51 | typedef enum 52 | { 53 | GPS_MODE_INVALID = 1, /*!< Not fixed */ 54 | GPS_MODE_2D, /*!< 2D GPS */ 55 | GPS_MODE_3D /*!< 3D GPS */ 56 | } gps_fix_mode_t; 57 | 58 | typedef struct 59 | { 60 | uint8_t num; /*!< Satellite number */ 61 | uint8_t elevation; /*!< Satellite elevation */ 62 | uint16_t azimuth; /*!< Satellite azimuth */ 63 | uint8_t snr; /*!< Satellite signal noise ratio */ 64 | } gps_satellite_t; 65 | 66 | typedef struct 67 | { 68 | uint8_t hour; /*!< Hour */ 69 | uint8_t minute; /*!< Minute */ 70 | uint8_t second; /*!< Second */ 71 | uint16_t thousand; /*!< Thousand */ 72 | } gps_time_t; 73 | 74 | typedef struct 75 | { 76 | uint8_t day; /*!< Day (start from 1) */ 77 | uint8_t month; /*!< Month (start from 1) */ 78 | uint16_t year; /*!< Year (start from 2000) */ 79 | } gps_date_t; 80 | 81 | typedef enum 82 | { 83 | STATEMENT_UNKNOWN = 0, /*!< Unknown statement */ 84 | STATEMENT_GGA, /*!< GGA */ 85 | STATEMENT_GSA, /*!< GSA */ 86 | STATEMENT_RMC, /*!< RMC */ 87 | STATEMENT_GSV, /*!< GSV */ 88 | STATEMENT_GLL, /*!< GLL */ 89 | STATEMENT_VTG, /*!< VTG */ 90 | STATEMENT_GPTXT, /*!< GPTXT */ 91 | STATEMENT_GNZDA /*!< GNZDA */ 92 | } nmea_statement_t; 93 | 94 | typedef struct 95 | { 96 | float latitude; /*!< Latitude (degrees) */ 97 | float longitude; /*!< Longitude (degrees) */ 98 | float altitude; /*!< Altitude (meters) */ 99 | gps_fix_t fix; /*!< Fix status */ 100 | uint8_t sats_in_use; /*!< Number of satellites in use */ 101 | gps_time_t tim; /*!< time in UTC */ 102 | gps_fix_mode_t fix_mode; /*!< Fix mode */ 103 | uint8_t sats_id_in_use[GPS_MAX_SATELLITES_IN_USE]; /*!< ID list of satellite in use */ 104 | float dop_h; /*!< Horizontal dilution of precision */ 105 | float dop_p; /*!< Position dilution of precision */ 106 | float dop_v; /*!< Vertical dilution of precision */ 107 | uint8_t sats_in_view; /*!< Number of satellites in view */ 108 | gps_satellite_t sats_desc_in_view[GPS_MAX_SATELLITES_IN_VIEW]; /*!< Information of satellites in view */ 109 | gps_date_t date; /*!< Fix date */ 110 | bool valid; /*!< GPS validity */ 111 | float speed; /*!< Ground speed, unit: m/s */ 112 | float cog; /*!< Course over ground */ 113 | float variation; /*!< Magnetic variation */ 114 | } gps_t; 115 | 116 | typedef struct esp_gps_t 117 | { 118 | uint8_t item_pos; /*!< Current position in item */ 119 | uint8_t item_num; /*!< Current item number */ 120 | uint8_t asterisk; /*!< Asterisk detected flag */ 121 | uint8_t crc; /*!< Calculated CRC value */ 122 | uint8_t parsed_statement; /*!< OR'd of statements that have been parsed */ 123 | uint8_t sat_num; /*!< Satellite number */ 124 | uint8_t sat_count; /*!< Satellite count */ 125 | uint8_t cur_statement; /*!< Current statement ID */ 126 | uint32_t all_statements; /*!< All statements mask */ 127 | char item_str[NMEA_MAX_STATEMENT_ITEM_LENGTH]; /*!< Current item */ 128 | gps_t parent; /*!< Parent class */ 129 | uart_port_t uart_port; /*!< Uart port number */ 130 | uint8_t *buffer; /*!< Runtime buffer */ 131 | TaskHandle_t tsk_hdl; /*!< NMEA Parser task handle */ 132 | QueueHandle_t event_queue; /*!< UART event queue handle */ 133 | } esp_gps_t; 134 | 135 | typedef struct 136 | { 137 | struct 138 | { 139 | uart_port_t uart_port; /*!< UART port number */ 140 | uint32_t rx_pin; /*!< UART Rx Pin number */ 141 | uint32_t baud_rate; /*!< UART baud rate */ 142 | uart_word_length_t data_bits; /*!< UART data bits length */ 143 | uart_parity_t parity; /*!< UART parity */ 144 | uart_stop_bits_t stop_bits; /*!< UART stop bits length */ 145 | uint32_t event_queue_size; /*!< UART event queue size */ 146 | } uart; /*!< UART specific configuration */ 147 | } nmea_parser_config_t; 148 | 149 | typedef void *nmea_parser_handle_t; 150 | 151 | typedef enum 152 | { 153 | GPS_UPDATE, /*!< GPS information has been updated */ 154 | GPS_UNKNOWN /*!< Unknown statements detected */ 155 | } nmea_event_id_t; 156 | 157 | static bool gps_enabled; 158 | static bool gps_fixed; 159 | 160 | static bool gps_tracking_stop; 161 | static uint32_t gps_point_saved; 162 | static gps_t gps_saved; 163 | static gps_fix_mode_t gps_status; 164 | static esp_gps_t global_gps; 165 | // static float gps_latitude; 166 | // static float gps_longitude; 167 | // static float gps_altitude; 168 | // static float gps_speed; 169 | // static char gps_datetime[21]; 170 | // static char gps_date[11]; 171 | // static char gps_time[9]; 172 | 173 | static void tracking_task(void *pvParameter); 174 | 175 | static nmea_parser_handle_t nmea_parser_init(const nmea_parser_config_t *config); 176 | 177 | static double gps_lat; 178 | static double gps_lon; 179 | static uint32_t lon_to_tile_x(double lon); 180 | static uint32_t lat_lon_to_tile_y(double lat, double lon); 181 | static uint32_t lon_to_x(double lon); 182 | static uint32_t lat_lon_to_y(double lat, double lon); 183 | 184 | static void set_state_gps(bool state); 185 | 186 | private: 187 | static esp_gps_t *esp_gps; 188 | // static void gps_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data); 189 | static void nmea_parser_task_entry(void *arg); 190 | static esp_err_t gps_decode(uint8_t *buff_uart, size_t len); 191 | static esp_err_t parse_item(esp_gps_t *esp_gps); 192 | static void parse_gptxt(esp_gps_t *esp_gps); 193 | static void parse_vtg(esp_gps_t *esp_gps); 194 | static void parse_gll(esp_gps_t *esp_gps); 195 | static void parse_gnzda(esp_gps_t *esp_gps); 196 | static void parse_rmc(esp_gps_t *esp_gps); 197 | static void parse_gsv(esp_gps_t *esp_gps); 198 | static void parse_gsa(esp_gps_t *esp_gps); 199 | static void parse_gga(esp_gps_t *esp_gps); 200 | static void parse_utc_time(esp_gps_t *esp_gps); 201 | static float parse_lat_long(esp_gps_t *esp_gps); 202 | static inline uint8_t convert_two_digit2number(const char *digit_char); 203 | }; 204 | 205 | #endif -------------------------------------------------------------------------------- /main/WatchGps/home_gps_example.h: -------------------------------------------------------------------------------- 1 | // Rename this file to "home_gps_example.h" 2 | // Paris location as default GPS lat/lon 3 | #define HOME_LAT 48.858307 4 | #define HOME_LON 2.294498 -------------------------------------------------------------------------------- /main/WatchNvs/WatchNvs.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchNvs.h" 2 | 3 | char WatchNvs::main_storage_name[7] = "stg_01"; 4 | 5 | void WatchNvs::init() 6 | { 7 | esp_err_t err = nvs_flash_init(); 8 | if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) 9 | { 10 | // NVS partition was truncated and needs to be erased 11 | // Retry nvs_flash_init 12 | ESP_ERROR_CHECK(nvs_flash_erase()); 13 | err = nvs_flash_init(); 14 | } 15 | ESP_ERROR_CHECK(err); 16 | 17 | // Open 18 | printf("Opening Non-Volatile Storage (NVS) handle... "); 19 | nvs_handle_t my_handle; 20 | err = nvs_open(main_storage_name, NVS_READONLY, &my_handle); 21 | if (err != ESP_OK) 22 | { 23 | printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err)); 24 | vTaskDelay(1000); 25 | esp_restart(); 26 | } 27 | printf("Done\n"); 28 | 29 | // Read tmo_screen 30 | printf("Reading tmo screen from NVS ... "); 31 | uint32_t tmo_screen = 60000; // value will default to 0, if not set yet in NVS 32 | err = nvs_get_u32(my_handle, NVS_KEY_TIMEOUT_SCREEN, &tmo_screen); 33 | switch (err) 34 | { 35 | case ESP_OK: 36 | printf("Done\n"); 37 | printf("tmo_screen = %d\n", tmo_screen); 38 | timer_turn_off_screen = tmo_screen; 39 | break; 40 | case ESP_ERR_NVS_NOT_FOUND: 41 | printf("The value is not initialized yet!\n"); 42 | break; 43 | default: 44 | printf("Error (%s) reading!\n", esp_err_to_name(err)); 45 | } 46 | 47 | // Read wakeup double tap 48 | printf("Reading wakeup double tap from NVS ... "); 49 | uint8_t wakeup_double_tap = 1; // value will default to 0, if not set yet in NVS 50 | err = nvs_get_u8(my_handle, NVS_KEY_WAKEUP_DOUBLE_TAP, &wakeup_double_tap); 51 | switch (err) 52 | { 53 | case ESP_OK: 54 | printf("Done\n"); 55 | printf("wakeup_double_tap = %d\n", wakeup_double_tap); 56 | WatchBma::wakeup_on_double_tap = wakeup_double_tap; 57 | break; 58 | case ESP_ERR_NVS_NOT_FOUND: 59 | printf("The value is not initialized yet!\n"); 60 | break; 61 | default: 62 | printf("Error (%s) reading!\n", esp_err_to_name(err)); 63 | } 64 | 65 | // Read wakeup tilt 66 | printf("Reading wakeup tilt from NVS ... "); 67 | uint8_t wakeup_tilt = 0; // value will default to 0, if not set yet in NVS 68 | err = nvs_get_u8(my_handle, NVS_KEY_WAKEUP_TILT, &wakeup_tilt); 69 | switch (err) 70 | { 71 | case ESP_OK: 72 | printf("Done\n"); 73 | printf("wakeup_tilt = %d\n", wakeup_tilt); 74 | WatchBma::wakeup_on_tilt = wakeup_tilt; 75 | break; 76 | case ESP_ERR_NVS_NOT_FOUND: 77 | printf("The value is not initialized yet!\n"); 78 | break; 79 | default: 80 | printf("Error (%s) reading!\n", esp_err_to_name(err)); 81 | } 82 | 83 | // Read step goal 84 | printf("Reading step goal from NVS ... "); 85 | uint32_t step_goal = 1000; // value will default to 0, if not set yet in NVS 86 | err = nvs_get_u32(my_handle, NVS_KEY_STEP_GOAL, &step_goal); 87 | switch (err) 88 | { 89 | case ESP_OK: 90 | printf("Done\n"); 91 | printf("step_goal = %d\n", step_goal); 92 | WatchBma::step_counter_goal = step_goal; 93 | break; 94 | case ESP_ERR_NVS_NOT_FOUND: 95 | printf("The value is not initialized yet!\n"); 96 | break; 97 | default: 98 | printf("Error (%s) reading!\n", esp_err_to_name(err)); 99 | } 100 | 101 | nvs_close(my_handle); 102 | } 103 | 104 | void WatchNvs::set_tmo_screen(uint32_t value) 105 | { 106 | nvs_handle_t my_handle; 107 | esp_err_t err = nvs_open(main_storage_name, NVS_READWRITE, &my_handle); 108 | if (err != ESP_OK) 109 | { 110 | printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err)); 111 | vTaskDelay(1000); 112 | esp_restart(); 113 | } 114 | 115 | err |= nvs_set_u32(my_handle, NVS_KEY_TIMEOUT_SCREEN, value); 116 | err |= nvs_commit(my_handle); 117 | 118 | if (err != ESP_OK) 119 | { 120 | printf("set_tmo_screen failed (%s)!\n", esp_err_to_name(err)); 121 | vTaskDelay(1000); 122 | esp_restart(); 123 | } 124 | 125 | nvs_close(my_handle); 126 | } 127 | 128 | void WatchNvs::set_wakeup_double_tap(uint8_t value) 129 | { 130 | nvs_handle_t my_handle; 131 | esp_err_t err = nvs_open(main_storage_name, NVS_READWRITE, &my_handle); 132 | if (err != ESP_OK) 133 | { 134 | printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err)); 135 | vTaskDelay(1000); 136 | esp_restart(); 137 | } 138 | 139 | err |= nvs_set_u8(my_handle, NVS_KEY_WAKEUP_DOUBLE_TAP, value); 140 | err |= nvs_commit(my_handle); 141 | 142 | if (err != ESP_OK) 143 | { 144 | printf("set_wakeup_double_tap failed (%s)!\n", esp_err_to_name(err)); 145 | vTaskDelay(1000); 146 | esp_restart(); 147 | } 148 | 149 | nvs_close(my_handle); 150 | } 151 | 152 | void WatchNvs::set_wakeup_tilt(uint8_t value) 153 | { 154 | nvs_handle_t my_handle; 155 | esp_err_t err = nvs_open(main_storage_name, NVS_READWRITE, &my_handle); 156 | if (err != ESP_OK) 157 | { 158 | printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err)); 159 | vTaskDelay(1000); 160 | esp_restart(); 161 | } 162 | 163 | err |= nvs_set_u8(my_handle, NVS_KEY_WAKEUP_TILT, value); 164 | err |= nvs_commit(my_handle); 165 | 166 | if (err != ESP_OK) 167 | { 168 | printf("set_wakeup_tilt failed (%s)!\n", esp_err_to_name(err)); 169 | vTaskDelay(1000); 170 | esp_restart(); 171 | } 172 | 173 | nvs_close(my_handle); 174 | } 175 | 176 | void WatchNvs::set_step_goal(uint32_t value) 177 | { 178 | nvs_handle_t my_handle; 179 | esp_err_t err = nvs_open(main_storage_name, NVS_READWRITE, &my_handle); 180 | if (err != ESP_OK) 181 | { 182 | printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err)); 183 | vTaskDelay(1000); 184 | esp_restart(); 185 | } 186 | 187 | err |= nvs_set_u32(my_handle, NVS_KEY_STEP_GOAL, value); 188 | err |= nvs_commit(my_handle); 189 | 190 | if (err != ESP_OK) 191 | { 192 | printf("set_step_goal failed (%s)!\n", esp_err_to_name(err)); 193 | vTaskDelay(1000); 194 | esp_restart(); 195 | } 196 | 197 | nvs_close(my_handle); 198 | } -------------------------------------------------------------------------------- /main/WatchNvs/WatchNvs.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | #ifndef WATCH_NVS 4 | #define WATCH_NVS 5 | 6 | #define NVS_KEY_TIMEOUT_SCREEN "tmo_screen" 7 | #define NVS_KEY_WAKEUP_DOUBLE_TAP "wakeup_db_tap" 8 | #define NVS_KEY_WAKEUP_TILT "wakeup_tilt" 9 | #define NVS_KEY_STEP_GOAL "step_goal" 10 | 11 | class WatchNvs 12 | { 13 | public: 14 | static void init(); 15 | static void set_tmo_screen(uint32_t value); 16 | static void set_wakeup_double_tap(uint8_t value); 17 | static void set_wakeup_tilt(uint8_t value); 18 | static void set_step_goal(uint32_t value); 19 | 20 | private: 21 | static char main_storage_name[7]; 22 | }; 23 | 24 | #endif -------------------------------------------------------------------------------- /main/WatchPower/WatchPower.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchPower.h" 2 | 3 | volatile bool WatchPower::_irq = false; 4 | bool WatchPower::is_charging = false; 5 | 6 | void WatchPower::init() 7 | { 8 | axpxx_i2c_init(); 9 | 10 | axp202_init(); 11 | 12 | register_int_isr(); 13 | is_charging = axpxx_isVBUSPlug(); 14 | 15 | xTaskCreatePinnedToCore(power_task, "power", 4096 * 2, NULL, 0, NULL, 1); 16 | } 17 | 18 | void WatchPower::register_int_isr() 19 | { 20 | gpio_config_t io_conf = {}; 21 | io_conf.intr_type = GPIO_INTR_NEGEDGE; 22 | io_conf.mode = GPIO_MODE_INPUT; 23 | io_conf.pin_bit_mask = (1ULL << AXP202_INT); 24 | io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; 25 | io_conf.pull_up_en = GPIO_PULLUP_ENABLE; 26 | gpio_config(&io_conf); 27 | gpio_isr_handler_add(AXP202_INT, gpio_isr_handler, NULL); 28 | axpxx_clearIRQ(); 29 | } 30 | 31 | void IRAM_ATTR WatchPower::gpio_isr_handler(void *arg) 32 | { 33 | _irq = true; 34 | } 35 | 36 | void WatchPower::enter_light_sleep() 37 | { 38 | printf("enter_light_sleep()\n"); 39 | static bool is_sleeping = false; 40 | if (is_sleeping) 41 | return; 42 | 43 | is_sleeping = true; 44 | 45 | esp_pm_config_esp32_t pm_config = { 46 | .max_freq_mhz = 160, 47 | .min_freq_mhz = 80}; 48 | esp_pm_configure(&pm_config); 49 | 50 | gpio_config_t config = { 51 | .pin_bit_mask = BIT64(AXP202_INT), 52 | .mode = GPIO_MODE_INPUT}; 53 | ESP_ERROR_CHECK(gpio_config(&config)); 54 | 55 | gpio_wakeup_enable(AXP202_INT, GPIO_INTR_LOW_LEVEL); 56 | 57 | esp_sleep_enable_gpio_wakeup(); 58 | 59 | WatchTft::turn_screen_off(); 60 | 61 | int64_t t_before_us = esp_timer_get_time(); 62 | printf("\nSleeping...\n\n"); 63 | uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM); 64 | 65 | esp_light_sleep_start(); 66 | 67 | int64_t t_after_us = esp_timer_get_time(); 68 | 69 | WatchTft::main_screen_from_sleep(); 70 | 71 | const char *wakeup_reason; 72 | switch (esp_sleep_get_wakeup_cause()) 73 | { 74 | case ESP_SLEEP_WAKEUP_TIMER: 75 | wakeup_reason = "timer"; 76 | break; 77 | case ESP_SLEEP_WAKEUP_GPIO: 78 | wakeup_reason = "pin"; 79 | break; 80 | default: 81 | wakeup_reason = "other"; 82 | break; 83 | } 84 | 85 | printf("Returned from light sleep, reason: %s, t=%lld ms, slept for %lld ms\n", 86 | wakeup_reason, t_after_us / 1000, (t_after_us - t_before_us) / 1000); 87 | 88 | pm_config = { 89 | .max_freq_mhz = 240, 90 | .min_freq_mhz = 80}; 91 | esp_pm_configure(&pm_config); 92 | 93 | register_int_isr(); 94 | 95 | is_sleeping = false; 96 | } 97 | 98 | void WatchPower::power_task(void *pvParameter) 99 | { 100 | while (1) 101 | { 102 | if (_irq) 103 | { 104 | axpxx_readIRQ(); 105 | _irq = false; 106 | if (axpxx_isPEKShortPressIRQ()) 107 | { 108 | WatchTft::toggle_button_menu_view(); 109 | WatchTft::turn_screen_on(); 110 | } 111 | if (axpxx_isVbusPlugInIRQ()) 112 | { 113 | printf("axpxx_isVBUSPlug()\n"); 114 | is_charging = true; 115 | WatchTft::set_charge_state(is_charging); 116 | } 117 | if (axpxx_isVbusRemoveIRQ()) 118 | { 119 | printf("axpxx_isVbusRemoveIRQ()\n"); 120 | is_charging = false; 121 | WatchTft::set_charge_state(is_charging); 122 | } 123 | if (axpxx_isPEKLongtPressIRQ()) 124 | { 125 | printf("axpxx_isPEKLongtPressIRQ()\n"); 126 | } 127 | 128 | axpxx_clearIRQ(); 129 | } 130 | vTaskDelay(200); 131 | 132 | static int64_t timer_battery_voltage = esp_timer_get_time() - 9 * 1000 * 1000; 133 | if ((esp_timer_get_time()) - timer_battery_voltage > 10 * 1000 * 1000) 134 | { 135 | timer_battery_voltage = esp_timer_get_time(); 136 | BaseType_t err = xSemaphoreTake(i2c_0_semaphore, 500); 137 | if (err == pdTRUE) 138 | { 139 | WatchTft::set_battery_text(axpxx_getBattPercentage()); 140 | xSemaphoreGive(i2c_0_semaphore); 141 | } 142 | } 143 | } 144 | } -------------------------------------------------------------------------------- /main/WatchPower/WatchPower.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | #ifndef WATCH_POWER 4 | #define WATCH_POWER 5 | 6 | #define AXP202_INT GPIO_NUM_35 7 | 8 | class WatchPower 9 | { 10 | public: 11 | 12 | static bool is_charging; 13 | 14 | static void init(); 15 | static void register_int_isr(); 16 | static void enter_light_sleep(); 17 | static void turn_off_tft(); 18 | 19 | private: 20 | static volatile bool _irq; 21 | static void IRAM_ATTR gpio_isr_handler(void *arg); 22 | static void power_task(void *pvParameter); 23 | }; 24 | #endif -------------------------------------------------------------------------------- /main/WatchSd/WatchSd.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchSd.h" 2 | 3 | void WatchSd::init() 4 | { 5 | esp_err_t ret; 6 | 7 | esp_vfs_fat_sdmmc_mount_config_t mount_config = { 8 | .format_if_mount_failed = false, 9 | .max_files = 5, 10 | .allocation_unit_size = 16 * 1024}; 11 | sdmmc_card_t *card; 12 | const char mount_point[] = MOUNT_POINT; 13 | printf("Initializing SD card\n"); 14 | 15 | sdmmc_host_t host = SDSPI_HOST_DEFAULT(); 16 | host.max_freq_khz = SDMMC_FREQ_DEFAULT; 17 | 18 | spi_bus_config_t bus_cfg = { 19 | .mosi_io_num = PIN_NUM_MOSI, 20 | .miso_io_num = PIN_NUM_MISO, 21 | .sclk_io_num = PIN_NUM_CLK, 22 | .quadwp_io_num = -1, 23 | .quadhd_io_num = -1, 24 | .max_transfer_sz = 4000, 25 | }; 26 | ret = spi_bus_initialize(spi_host_device_t::SPI3_HOST, &bus_cfg, SPI_DMA_CH2); 27 | if (ret != ESP_OK) 28 | { 29 | printf("Failed to initialize bus.\n"); 30 | return; 31 | } 32 | 33 | // This initializes the slot without card detect (CD) and write protect (WP) signals. 34 | // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals. 35 | sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT(); 36 | slot_config.gpio_cs = PIN_NUM_CS; 37 | slot_config.host_id = spi_host_device_t::SPI3_HOST; 38 | 39 | printf("Mounting filesystem\n"); 40 | ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card); 41 | 42 | if (ret != ESP_OK) 43 | { 44 | if (ret == ESP_FAIL) 45 | { 46 | printf("Failed to mount filesystem. " 47 | "If you want the card to be formatted, set the CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.\n"); 48 | } 49 | else 50 | { 51 | printf("Failed to initialize the card (%s). " 52 | "Make sure SD card lines have pull-up resistors in place.\n", 53 | esp_err_to_name(ret)); 54 | } 55 | vTaskDelay(3000); 56 | esp_restart(); 57 | return; 58 | } 59 | printf("Filesystem mounted\n"); 60 | 61 | // Card has been initialized, print its properties 62 | sdmmc_card_print_info(stdout, card); 63 | } -------------------------------------------------------------------------------- /main/WatchSd/WatchSd.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | #ifndef WATCH_SD 4 | #define WATCH_SD 5 | 6 | #define MOUNT_POINT "/sdcard" 7 | 8 | // Pin assignments can be set in menuconfig, see "SD SPI Example Configuration" menu. 9 | // You can also change the pin assignments here by changing the following 4 lines. 10 | #define PIN_NUM_MISO GPIO_NUM_4 11 | #define PIN_NUM_MOSI GPIO_NUM_15 12 | #define PIN_NUM_CLK GPIO_NUM_14 13 | #define PIN_NUM_CS GPIO_NUM_13 14 | 15 | class WatchSd 16 | { 17 | public: 18 | static void init(); 19 | 20 | private: 21 | }; 22 | 23 | #endif -------------------------------------------------------------------------------- /main/WatchTft/Bma_Sceen.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchTft.h" 2 | 3 | lv_obj_t *WatchTft::label_step_count = NULL; 4 | lv_obj_t *WatchTft::arc_counter = NULL; 5 | 6 | void WatchTft::run_screen() 7 | { 8 | printf("run_screen()\n"); 9 | lv_obj_t *run_bg = NULL; 10 | 11 | static bool init_style_done = false; 12 | static lv_style_t run_bg_style; 13 | if (!init_style_done) 14 | { 15 | lv_style_init(&run_bg_style); 16 | lv_style_set_bg_color(&run_bg_style, lv_color_black()); 17 | lv_style_set_radius(&run_bg_style, 0); 18 | lv_style_set_border_width(&run_bg_style, 0); 19 | lv_style_set_pad_all(&run_bg_style, 0); 20 | init_style_done = true; 21 | } 22 | 23 | if (pdTRUE == xSemaphoreTake(xGuiSemaphore, 1000)) 24 | { 25 | 26 | run_bg = lv_obj_create(current_screen); 27 | lv_obj_set_size(run_bg, 240, 210); 28 | lv_obj_align(run_bg, LV_ALIGN_TOP_LEFT, 0, 30); 29 | lv_obj_clear_flag(run_bg, LV_OBJ_FLAG_SCROLLABLE); 30 | lv_obj_add_style(run_bg, &run_bg_style, LV_PART_MAIN); 31 | 32 | lv_obj_t *btn_home = lv_btn_create(run_bg); 33 | lv_obj_align(btn_home, LV_ALIGN_BOTTOM_LEFT, 5, -5); 34 | lv_obj_set_size(btn_home, 48, 35); 35 | lv_obj_set_style_bg_opa(btn_home, 0, LV_PART_MAIN); 36 | static LCD_BTN_EVENT cmd_home = LCD_BTN_EVENT::RETURN_HOME; 37 | lv_obj_add_event_cb(btn_home, event_handler_main, LV_EVENT_CLICKED, &cmd_home); 38 | 39 | lv_obj_t *img_arrow_left = lv_img_create(btn_home); 40 | lv_img_set_src(img_arrow_left, &arrow); 41 | lv_obj_align(img_arrow_left, LV_ALIGN_CENTER, 0, 0); 42 | lv_obj_set_size(img_arrow_left, 24, 24); 43 | lv_img_set_angle(img_arrow_left, 1800); 44 | lv_obj_add_style(img_arrow_left, &img_recolor_white_style, LV_PART_MAIN); 45 | 46 | lv_obj_t *label_title_run = lv_label_create(run_bg); 47 | lv_obj_align(label_title_run, LV_ALIGN_CENTER, 0, -32); 48 | lv_obj_set_style_text_align(label_title_run, LV_TEXT_ALIGN_CENTER, 0); 49 | lv_obj_set_style_text_color(label_title_run, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN); 50 | lv_label_set_text(label_title_run, "Steps"); 51 | 52 | label_step_count = lv_label_create(run_bg); 53 | lv_obj_align(label_step_count, LV_ALIGN_CENTER, 0, 0); 54 | lv_obj_set_style_text_align(label_step_count, LV_TEXT_ALIGN_CENTER, 0); 55 | lv_obj_set_style_text_color(label_step_count, lv_color_white(), LV_PART_MAIN); 56 | lv_obj_set_style_text_font(label_step_count, &lv_font_montserrat_48, 0); 57 | std::string start_steps = std::to_string(WatchBma::steps_count_save); 58 | lv_label_set_text(label_step_count, start_steps.c_str()); 59 | 60 | arc_counter = lv_arc_create(run_bg); 61 | lv_obj_align(arc_counter, LV_ALIGN_CENTER, 0, 0); 62 | lv_arc_set_rotation(arc_counter, 270); 63 | uint16_t start_angle = (WatchBma::steps_count_save % WatchBma::step_counter_goal) * 360 / WatchBma::step_counter_goal; 64 | lv_arc_set_angles(arc_counter, 0, start_angle); 65 | lv_arc_set_bg_angles(arc_counter, 0, 360); 66 | lv_obj_set_size(arc_counter, 160, 160); 67 | lv_obj_set_style_arc_img_src(arc_counter, &gradient_count, LV_PART_INDICATOR); 68 | lv_obj_remove_style(arc_counter, NULL, LV_PART_KNOB); /*Be sure the knob is not displayed*/ 69 | lv_obj_clear_flag(arc_counter, LV_OBJ_FLAG_CLICKABLE); /*To not allow adjusting by click*/ 70 | lv_obj_center(arc_counter); 71 | lv_obj_set_style_arc_rounded(arc_counter, 0, LV_PART_INDICATOR); 72 | 73 | lv_obj_t *label_goal_step = lv_label_create(run_bg); 74 | lv_obj_align(label_goal_step, LV_ALIGN_CENTER, 0, 32); 75 | lv_obj_set_style_text_align(label_goal_step, LV_TEXT_ALIGN_CENTER, 0); 76 | lv_obj_set_style_text_color(label_goal_step, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN); 77 | std::string goal_text = LV_SYMBOL_EYE_OPEN + std::to_string(WatchBma::step_counter_goal); 78 | lv_label_set_text(label_goal_step, goal_text.c_str()); 79 | 80 | xSemaphoreGive(xGuiSemaphore); 81 | } 82 | TaskHandle_t count_step_task_hanlde = NULL; 83 | xTaskCreatePinnedToCore(count_step_task, "count_step", 4096 * 2, NULL, 0, &count_step_task_hanlde, 1); 84 | current_task_hanlde = count_step_task_hanlde; 85 | } 86 | 87 | void WatchTft::set_step_counter_value(uint32_t steps) 88 | { 89 | if (pdTRUE != xSemaphoreTake(xGuiSemaphore, 50)) 90 | { 91 | return; 92 | } 93 | uint16_t angle = (steps % WatchBma::step_counter_goal) * 360 / WatchBma::step_counter_goal; 94 | lv_arc_set_angles(arc_counter, 0, angle); 95 | std::string step_str = std::to_string(steps); 96 | lv_label_set_text(label_step_count, step_str.c_str()); 97 | xSemaphoreGive(xGuiSemaphore); 98 | } 99 | 100 | void WatchTft::count_step_task(void *pvParameter) 101 | { 102 | printf("Move/perform the walk/step action with the sensor\n"); 103 | while (1) 104 | { 105 | uint16_t int_status = WatchBma::s_int_status; 106 | WatchBma::s_int_status = 0; 107 | if (int_status & BMA423_STEP_CNTR_INT) 108 | { 109 | WatchBma::steps_count_save = WatchBma::get_steps(); 110 | set_step_counter_value(WatchBma::steps_count_save); 111 | } 112 | 113 | vTaskDelay(1000); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /main/WatchTft/Gps_Screen.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchTft.h" 2 | 3 | lv_obj_t *WatchTft::label_title_gps = NULL; 4 | lv_obj_t *WatchTft::label_gps_info = NULL; 5 | lv_obj_t *WatchTft::gps_recording_indicator = NULL; 6 | 7 | lv_point_t drag_view(int32_t x, int32_t y); 8 | 9 | lv_style_t arc_gps_style; 10 | lv_obj_t *arc_gps_status = NULL; 11 | lv_obj_t *label_gps_status = NULL; 12 | 13 | lv_obj_t *WatchTft::btn_start_tracking = NULL; 14 | lv_obj_t *btn_center_gps = NULL; 15 | lv_obj_t *btn_pos_gps = NULL; 16 | lv_point_t btn_pos_gps_point = {}; 17 | 18 | lv_obj_t *map_bg_p[4] = {}; 19 | lv_point_t map_bg_p_points[4] = {}; 20 | 21 | uint32_t glob_x = 0; 22 | uint32_t glob_y = 0; 23 | 24 | int32_t tile_x = 0; 25 | int32_t tile_y = 0; 26 | 27 | uint32_t gps_x = 0; 28 | uint32_t gps_y = 0; 29 | 30 | int32_t gps_screen_x = 0; 31 | int32_t gps_screen_y = 0; 32 | 33 | int32_t square_x[2] = {tile_x, tile_x + 1}; 34 | int32_t square_y[2] = {tile_y, tile_y + 1}; 35 | 36 | uint8_t user_map_square[4] = {0, 1, 2, 3}; // M R B BR 37 | 38 | bool centered_to_gps = false; 39 | 40 | lv_obj_t *main_bg_img_M = NULL; 41 | lv_obj_t *main_bg_img_R = NULL; 42 | lv_obj_t *main_bg_img_BR = NULL; 43 | lv_obj_t *main_bg_img_B = NULL; 44 | 45 | void WatchTft::refresh_tile(int32_t x, int32_t y) 46 | { 47 | 48 | lv_obj_t *main_bg_img = NULL; 49 | if (x == square_x[0] && y == square_y[0]) 50 | { 51 | main_bg_img = main_bg_img_M; 52 | } 53 | else if (x == square_x[1] && y == square_y[0]) 54 | { 55 | main_bg_img = main_bg_img_R; 56 | } 57 | else if (x == square_x[0] && y == square_y[1]) 58 | { 59 | main_bg_img = main_bg_img_B; 60 | } 61 | else if (x == square_x[1] && y == square_y[1]) 62 | { 63 | main_bg_img = main_bg_img_BR; 64 | } 65 | 66 | if (main_bg_img == NULL) 67 | { 68 | return; 69 | } 70 | 71 | char filename[60] = {}; 72 | sprintf(filename, MOUNT_POINT "/map_15_%u_%u.png", x, y); 73 | printf("M: %s\n", filename); 74 | if (access(filename, F_OK) == 0) 75 | { 76 | char filename_lv[60] = {}; 77 | sprintf(filename_lv, "S:/map_15_%u_%u.png", x, y); 78 | lv_img_set_src(main_bg_img, filename_lv); 79 | } 80 | else 81 | { 82 | printf("file don't exist...\n"); 83 | lv_img_set_src(main_bg_img, &download); 84 | } 85 | } 86 | 87 | void WatchTft::add_xy_to_gps_point(int32_t x, int32_t y, bool sem_taken) 88 | { 89 | 90 | gps_screen_x -= x; 91 | gps_screen_y -= y; 92 | 93 | // printf("add_xy_to_gps_point: %d %d\n", x, y); 94 | 95 | btn_pos_gps_point.x -= x; 96 | btn_pos_gps_point.y -= y; 97 | 98 | // printf("gps_screen_x: %d, gps_screen_y: %d\n", gps_screen_x, gps_screen_y); 99 | 100 | if (sem_taken) 101 | { 102 | 103 | lv_obj_set_pos(btn_pos_gps, gps_screen_x, gps_screen_y); 104 | } 105 | else if (xSemaphoreTake(xGuiSemaphore, 0) == pdTRUE) 106 | { 107 | lv_obj_set_pos(btn_pos_gps, gps_screen_x, gps_screen_y); 108 | xSemaphoreGive(xGuiSemaphore); 109 | } 110 | /*static lv_point_t line_points[] = {{5, 5}, {70, 70}}; 111 | line_points[0].x = gps_screen_x += x; 112 | line_points[0].y = gps_screen_y += y; 113 | 114 | line_points[1].x = gps_screen_x; 115 | line_points[1].y = gps_screen_y; 116 | 117 | static lv_style_t style_line; 118 | lv_style_init(&style_line); 119 | lv_style_set_line_width(&style_line, 8); 120 | lv_style_set_line_color(&style_line, lv_palette_main(LV_PALETTE_BLUE)); 121 | lv_style_set_line_rounded(&style_line, true); 122 | 123 | static lv_obj_t *line1; 124 | line1 = lv_line_create(lv_scr_act()); 125 | lv_line_set_points(line1, line_points, 2); //Set the points 126 | lv_obj_add_style(line1, &style_line, 0); 127 | lv_obj_center(line1);*/ 128 | } 129 | 130 | void WatchTft::drag_event_handler(lv_event_t *e) 131 | { 132 | 133 | if (centered_to_gps) 134 | { 135 | printf("quit centered to gps\n"); 136 | centered_to_gps = false; 137 | lv_obj_set_style_bg_color(btn_center_gps, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN); 138 | } 139 | 140 | lv_indev_t *indev = lv_indev_get_act(); 141 | if (indev == NULL) 142 | return; 143 | 144 | lv_point_t vect; 145 | lv_indev_get_vect(indev, &vect); 146 | 147 | if (vect.x == 0 && vect.y == 0) 148 | { 149 | return; 150 | } 151 | 152 | lv_point_t lv_point = drag_view(vect.x, vect.y, true); 153 | 154 | add_xy_to_gps_point(-lv_point.x, -lv_point.y, true); 155 | } 156 | 157 | lv_point_t WatchTft::drag_view(int32_t x, int32_t y, bool sem_taken) 158 | { 159 | lv_coord_t x_M = map_bg_p_points[0].x; 160 | lv_coord_t y_M = map_bg_p_points[0].y; 161 | 162 | lv_coord_t x_R = map_bg_p_points[1].x; 163 | lv_coord_t y_R = map_bg_p_points[1].y; 164 | 165 | lv_coord_t x_B = map_bg_p_points[2].x; 166 | lv_coord_t y_B = map_bg_p_points[2].y; 167 | 168 | lv_coord_t x_BR = map_bg_p_points[3].x; 169 | lv_coord_t y_BR = map_bg_p_points[3].y; 170 | 171 | glob_x -= x; 172 | glob_y -= y; 173 | // printf("glob_xy: %u:%u\n", glob_x, glob_y); 174 | 175 | // printf("drag_view: %d %d\n", x, y); 176 | 177 | int32_t new_tile_x = glob_x / 256; 178 | int32_t new_tile_y = glob_y / 256; 179 | if (new_tile_x != tile_x || new_tile_y != tile_y) 180 | { 181 | tile_x = new_tile_x; 182 | tile_y = new_tile_y; 183 | printf("change tile: %d:%d\n", tile_x, tile_y); 184 | } 185 | 186 | int32_t new_square_x = (glob_x + 128) / 256 - 1; 187 | int32_t new_square_y = (glob_y + 128) / 256 - 1; 188 | 189 | int32_t offset_x_map = 0; 190 | int32_t offset_y_map = 0; 191 | if (new_square_x != square_x[0] || new_square_y != square_y[0]) 192 | { 193 | 194 | offset_x_map = -(square_x[0] - new_square_x) * 256; 195 | offset_y_map = -(square_y[0] - new_square_y) * 256; 196 | 197 | square_x[0] = new_square_x; 198 | square_x[1] = new_square_x + 1; 199 | square_y[0] = new_square_y; 200 | square_y[1] = new_square_y + 1; 201 | printf("change square: %d:%d->%d:%d\n", 202 | square_x[0], square_x[1], square_y[0], square_y[1]); 203 | 204 | printf("off_x_y: %d %d\n", offset_x_map, offset_y_map); 205 | 206 | char filename[60] = {}; 207 | sprintf(filename, MOUNT_POINT "/map_15_%u_%u.png", new_square_x, new_square_y); 208 | printf("M: %s\n", filename); 209 | if (access(filename, F_OK) == 0) 210 | { 211 | char filename_lv[60] = {}; 212 | sprintf(filename_lv, "S:/map_15_%u_%u.png", new_square_x, new_square_y); 213 | if (sem_taken) 214 | { 215 | lv_img_set_src(main_bg_img_M, filename_lv); 216 | } 217 | else if (xSemaphoreTake(xGuiSemaphore, 0) == pdTRUE) 218 | { 219 | lv_img_set_src(main_bg_img_M, filename_lv); 220 | xSemaphoreGive(xGuiSemaphore); 221 | } 222 | } 223 | else 224 | { 225 | if (sem_taken) 226 | { 227 | lv_img_set_src(main_bg_img_M, &download); 228 | } 229 | else if (xSemaphoreTake(xGuiSemaphore, 0) == pdTRUE) 230 | { 231 | lv_img_set_src(main_bg_img_M, &download); 232 | xSemaphoreGive(xGuiSemaphore); 233 | } 234 | } 235 | 236 | sprintf(filename, MOUNT_POINT "/map_15_%u_%u.png", new_square_x + 1, new_square_y); 237 | printf("R: %s\n", filename); 238 | if (access(filename, F_OK) == 0) 239 | { 240 | char filename_lv[60] = {}; 241 | sprintf(filename_lv, "S:/map_15_%u_%u.png", new_square_x + 1, new_square_y); 242 | 243 | if (sem_taken) 244 | { 245 | lv_img_set_src(main_bg_img_R, filename_lv); 246 | } 247 | else if (xSemaphoreTake(xGuiSemaphore, 0) == pdTRUE) 248 | { 249 | lv_img_set_src(main_bg_img_R, filename_lv); 250 | xSemaphoreGive(xGuiSemaphore); 251 | } 252 | } 253 | else 254 | { 255 | if (sem_taken) 256 | { 257 | lv_img_set_src(main_bg_img_R, &download); 258 | } 259 | else if (xSemaphoreTake(xGuiSemaphore, 0) == pdTRUE) 260 | { 261 | lv_img_set_src(main_bg_img_R, &download); 262 | xSemaphoreGive(xGuiSemaphore); 263 | } 264 | } 265 | 266 | sprintf(filename, MOUNT_POINT "/map_15_%u_%u.png", new_square_x, new_square_y + 1); 267 | printf("B: %s\n", filename); 268 | if (access(filename, F_OK) == 0) 269 | { 270 | char filename_lv[60] = {}; 271 | sprintf(filename_lv, "S:/map_15_%u_%u.png", new_square_x, new_square_y + 1); 272 | 273 | if (sem_taken) 274 | { 275 | lv_img_set_src(main_bg_img_B, filename_lv); 276 | } 277 | else if (xSemaphoreTake(xGuiSemaphore, 0) == pdTRUE) 278 | { 279 | lv_img_set_src(main_bg_img_B, filename_lv); 280 | xSemaphoreGive(xGuiSemaphore); 281 | } 282 | } 283 | else 284 | { 285 | if (sem_taken) 286 | { 287 | lv_img_set_src(main_bg_img_B, &download); 288 | } 289 | else if (xSemaphoreTake(xGuiSemaphore, 0) == pdTRUE) 290 | { 291 | lv_img_set_src(main_bg_img_B, &download); 292 | xSemaphoreGive(xGuiSemaphore); 293 | } 294 | } 295 | 296 | sprintf(filename, MOUNT_POINT "/map_15_%u_%u.png", new_square_x + 1, new_square_y + 1); 297 | printf("BR: %s\n", filename); 298 | if (access(filename, F_OK) == 0) 299 | { 300 | char filename_lv[60] = {}; 301 | sprintf(filename_lv, "S:/map_15_%u_%u.png", new_square_x + 1, new_square_y + 1); 302 | if (sem_taken) 303 | { 304 | lv_img_set_src(main_bg_img_BR, filename_lv); 305 | } 306 | else if (xSemaphoreTake(xGuiSemaphore, 0) == pdTRUE) 307 | { 308 | lv_img_set_src(main_bg_img_BR, filename_lv); 309 | xSemaphoreGive(xGuiSemaphore); 310 | } 311 | } 312 | else 313 | { 314 | if (sem_taken) 315 | { 316 | lv_img_set_src(main_bg_img_BR, &download); 317 | } 318 | else if (xSemaphoreTake(xGuiSemaphore, 0) == pdTRUE) 319 | { 320 | lv_img_set_src(main_bg_img_BR, &download); 321 | xSemaphoreGive(xGuiSemaphore); 322 | } 323 | } 324 | } 325 | 326 | for (uint8_t i = 0; i < 4; i++) 327 | { 328 | map_bg_p_points[i].x += x + offset_x_map; 329 | map_bg_p_points[i].y += y + offset_y_map; 330 | } 331 | 332 | if (sem_taken) 333 | { 334 | lv_obj_set_pos(map_bg_p[0], map_bg_p_points[0].x, map_bg_p_points[0].y); 335 | lv_obj_set_pos(map_bg_p[1], map_bg_p_points[1].x, map_bg_p_points[1].y); 336 | lv_obj_set_pos(map_bg_p[2], map_bg_p_points[2].x, map_bg_p_points[2].y); 337 | lv_obj_set_pos(map_bg_p[3], map_bg_p_points[3].x, map_bg_p_points[3].y); 338 | } 339 | else if (xSemaphoreTake(xGuiSemaphore, 0) == pdTRUE) 340 | { 341 | lv_obj_set_pos(map_bg_p[0], map_bg_p_points[0].x, map_bg_p_points[0].y); 342 | lv_obj_set_pos(map_bg_p[1], map_bg_p_points[1].x, map_bg_p_points[1].y); 343 | lv_obj_set_pos(map_bg_p[2], map_bg_p_points[2].x, map_bg_p_points[2].y); 344 | lv_obj_set_pos(map_bg_p[3], map_bg_p_points[3].x, map_bg_p_points[3].y); 345 | 346 | xSemaphoreGive(xGuiSemaphore); 347 | } 348 | 349 | lv_point_t lv_point = {}; 350 | lv_point.x = x; 351 | lv_point.y = y; 352 | 353 | return lv_point; 354 | } 355 | 356 | static void pressed_event_handler(lv_event_t *e) 357 | { 358 | 359 | static struct timeval timer_start; 360 | if (e->code == 1) 361 | { 362 | gettimeofday(&timer_start, NULL); 363 | return; 364 | } 365 | 366 | struct timeval timer_end; 367 | gettimeofday(&timer_end, NULL); 368 | uint32_t ms_btw = (timer_end.tv_sec - timer_start.tv_sec) * 1000 + timer_end.tv_usec / 1000 - timer_start.tv_usec / 1000; 369 | 370 | printf("took %u us\n", ms_btw); 371 | 372 | if (ms_btw > 250) 373 | { 374 | return; 375 | } 376 | 377 | uint8_t index = *((uint8_t *)e->user_data); 378 | int32_t tile_index_x = square_x[index % 2]; 379 | int32_t tile_index_y = square_y[index > 1]; 380 | 381 | char filename[60] = {}; 382 | sprintf(filename, MOUNT_POINT "/map_15_%u_%u.png", tile_index_x, tile_index_y); 383 | 384 | bool file_exist = false; 385 | FILE *f = fopen(filename, "r"); 386 | if (f == NULL) 387 | { 388 | file_exist = false; 389 | } 390 | else 391 | { 392 | file_exist = true; 393 | fclose(f); 394 | } 395 | 396 | printf("CLICKED %d %d:%d, exist: %d, event: %d\n", index, tile_index_x, tile_index_y, file_exist, e->code); 397 | 398 | if (!file_exist) 399 | { 400 | WatchWiFi::download_tile(tile_index_x, tile_index_y); 401 | } 402 | } 403 | 404 | void WatchTft::center_gps() 405 | { 406 | 407 | centered_to_gps = !centered_to_gps; 408 | if (centered_to_gps) 409 | { 410 | 411 | int32_t diff_x = glob_x - gps_x; 412 | int32_t diff_y = glob_y - gps_y; 413 | printf("diff: %d %d %u:%u\n", diff_x, diff_y, glob_x, gps_x); 414 | drag_view(diff_x, diff_y, true); 415 | add_xy_to_gps_point(-diff_x, -diff_y, true); 416 | 417 | lv_obj_set_style_bg_color(btn_center_gps, lv_palette_main(LV_PALETTE_GREEN), LV_PART_MAIN); 418 | } 419 | else 420 | { 421 | lv_obj_set_style_bg_color(btn_center_gps, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN); 422 | } 423 | } 424 | 425 | void WatchTft::gps_screen() 426 | { 427 | 428 | static bool init_style_done = false; 429 | static lv_style_t gps_bg_style; 430 | if (!init_style_done) 431 | { 432 | lv_style_init(&gps_bg_style); 433 | lv_style_set_bg_color(&gps_bg_style, lv_color_black()); 434 | lv_style_set_radius(&gps_bg_style, 0); 435 | lv_style_set_border_width(&gps_bg_style, 0); 436 | lv_style_set_pad_all(&gps_bg_style, 0); 437 | 438 | lv_style_init(&arc_gps_style); 439 | lv_style_set_arc_color(&arc_gps_style, lv_palette_main(LV_PALETTE_RED)); 440 | lv_style_set_arc_width(&arc_gps_style, 5); 441 | init_style_done = true; 442 | } 443 | 444 | tile_x = WatchGps::lon_to_tile_x(WatchGps::gps_lon); 445 | tile_y = WatchGps::lat_lon_to_tile_y(WatchGps::gps_lat, WatchGps::gps_lon); 446 | printf("tile_x: %u, tile_y: %u\n", tile_x, tile_y); 447 | 448 | glob_x = tile_x * 256 + 128; 449 | glob_y = tile_y * 256 + 128; 450 | printf("glob_x: %u, glob_y: %u\n", glob_x, glob_y); 451 | 452 | square_x[0] = tile_x; 453 | square_x[1] = tile_x + 1; 454 | square_y[0] = tile_y; 455 | square_y[1] = tile_y + 1; 456 | 457 | gps_x = WatchGps::lon_to_x(WatchGps::gps_lon); 458 | gps_y = WatchGps::lat_lon_to_y(WatchGps::gps_lat, WatchGps::gps_lon); 459 | printf("gps_x: %u, gps_y: %u\n", gps_x, gps_y); 460 | 461 | lv_obj_t *gps_bg = NULL; 462 | 463 | size_t free_block = heap_caps_get_largest_free_block(MALLOC_CAP_32BIT); 464 | printf("free_block: %u\n", free_block); 465 | 466 | if (pdTRUE == xSemaphoreTake(xGuiSemaphore, 1000)) 467 | { 468 | 469 | gps_bg = lv_obj_create(current_screen); 470 | lv_obj_set_size(gps_bg, 240, 210); 471 | lv_obj_align(gps_bg, LV_ALIGN_TOP_LEFT, 0, 30); 472 | lv_obj_clear_flag(gps_bg, LV_OBJ_FLAG_SCROLLABLE); 473 | lv_obj_add_style(gps_bg, &gps_bg_style, LV_PART_MAIN); 474 | 475 | main_bg_img_M = lv_img_create(gps_bg); 476 | char filename[50] = {}; 477 | sprintf(filename, MOUNT_POINT "/map_15_%u_%u.png", square_x[0], square_y[0]); 478 | if (access(filename, F_OK) == 0) 479 | { 480 | char filename_lv[50] = {}; 481 | sprintf(filename_lv, "S:/map_15_%u_%u.png", square_x[0], square_y[0]); 482 | lv_img_set_src(main_bg_img_M, filename_lv); 483 | } 484 | else 485 | { 486 | lv_img_set_src(main_bg_img_M, &download); 487 | } 488 | 489 | lv_obj_align(main_bg_img_M, LV_ALIGN_TOP_LEFT, -8, -23); 490 | lv_obj_set_size(main_bg_img_M, 256, 256); 491 | lv_obj_add_flag(main_bg_img_M, LV_OBJ_FLAG_CLICKABLE); 492 | lv_obj_add_event_cb(main_bg_img_M, drag_event_handler, LV_EVENT_PRESSING, NULL); 493 | lv_obj_add_event_cb(main_bg_img_M, pressed_event_handler, LV_EVENT_PRESSED, &user_map_square[0]); 494 | lv_obj_add_event_cb(main_bg_img_M, pressed_event_handler, LV_EVENT_RELEASED, &user_map_square[0]); 495 | map_bg_p[0] = main_bg_img_M; 496 | 497 | main_bg_img_R = lv_img_create(gps_bg); 498 | sprintf(filename, MOUNT_POINT "/map_15_%u_%u.png", square_x[1], square_y[0]); 499 | if (access(filename, F_OK) == 0) 500 | { 501 | char filename_lv[50] = {}; 502 | sprintf(filename_lv, "S:/map_15_%u_%u.png", square_x[1], square_y[0]); 503 | lv_img_set_src(main_bg_img_R, filename_lv); 504 | } 505 | else 506 | { 507 | lv_img_set_src(main_bg_img_R, &download); 508 | } 509 | lv_obj_align(main_bg_img_R, LV_ALIGN_TOP_LEFT, 248, -23); 510 | lv_obj_set_size(main_bg_img_R, 256, 256); 511 | lv_obj_add_flag(main_bg_img_R, LV_OBJ_FLAG_CLICKABLE); 512 | lv_obj_add_event_cb(main_bg_img_R, drag_event_handler, LV_EVENT_PRESSING, NULL); 513 | lv_obj_add_event_cb(main_bg_img_R, pressed_event_handler, LV_EVENT_PRESSED, &user_map_square[1]); 514 | lv_obj_add_event_cb(main_bg_img_R, pressed_event_handler, LV_EVENT_RELEASED, &user_map_square[1]); 515 | map_bg_p[1] = main_bg_img_R; 516 | 517 | main_bg_img_B = lv_img_create(gps_bg); 518 | sprintf(filename, MOUNT_POINT "/map_15_%u_%u.png", square_x[0], square_y[1]); 519 | if (access(filename, F_OK) == 0) 520 | { 521 | char filename_lv[50] = {}; 522 | sprintf(filename_lv, "S:/map_15_%u_%u.png", square_x[0], square_y[1]); 523 | lv_img_set_src(main_bg_img_B, filename_lv); 524 | } 525 | else 526 | { 527 | lv_img_set_src(main_bg_img_B, &download); 528 | } 529 | lv_obj_align(main_bg_img_B, LV_ALIGN_TOP_LEFT, -8, 233); 530 | lv_obj_set_size(main_bg_img_B, 256, 256); 531 | lv_obj_add_flag(main_bg_img_B, LV_OBJ_FLAG_CLICKABLE); 532 | lv_obj_add_event_cb(main_bg_img_B, drag_event_handler, LV_EVENT_PRESSING, NULL); 533 | lv_obj_add_event_cb(main_bg_img_B, pressed_event_handler, LV_EVENT_PRESSED, &user_map_square[2]); 534 | lv_obj_add_event_cb(main_bg_img_B, pressed_event_handler, LV_EVENT_RELEASED, &user_map_square[2]); 535 | map_bg_p[2] = main_bg_img_B; 536 | 537 | main_bg_img_BR = lv_img_create(gps_bg); 538 | sprintf(filename, MOUNT_POINT "/map_15_%u_%u.png", square_x[1], square_y[1]); 539 | if (access(filename, F_OK) == 0) 540 | { 541 | char filename_lv[50] = {}; 542 | sprintf(filename_lv, "S:/map_15_%u_%u.png", square_x[1], square_y[1]); 543 | lv_img_set_src(main_bg_img_BR, filename_lv); 544 | } 545 | else 546 | { 547 | lv_img_set_src(main_bg_img_BR, &download); 548 | } 549 | lv_obj_align(main_bg_img_BR, LV_ALIGN_TOP_LEFT, 248, 233); 550 | lv_obj_set_size(main_bg_img_BR, 256, 256); 551 | lv_obj_add_flag(main_bg_img_BR, LV_OBJ_FLAG_CLICKABLE); 552 | lv_obj_add_event_cb(main_bg_img_BR, drag_event_handler, LV_EVENT_PRESSING, NULL); 553 | lv_obj_add_event_cb(main_bg_img_BR, pressed_event_handler, LV_EVENT_PRESSED, &user_map_square[3]); 554 | lv_obj_add_event_cb(main_bg_img_BR, pressed_event_handler, LV_EVENT_RELEASED, &user_map_square[3]); 555 | map_bg_p[3] = main_bg_img_BR; 556 | 557 | lv_obj_t *label_container_gps_status = lv_obj_create(gps_bg); 558 | lv_obj_set_size(label_container_gps_status, 50, 50); 559 | lv_obj_set_style_radius(label_container_gps_status, 50, LV_PART_MAIN); 560 | lv_obj_align(label_container_gps_status, LV_ALIGN_TOP_LEFT, -10, 10); 561 | lv_obj_clear_flag(label_container_gps_status, LV_OBJ_FLAG_SCROLLABLE); 562 | 563 | arc_gps_status = lv_arc_create(label_container_gps_status); 564 | lv_arc_set_bg_angles(arc_gps_status, 0, 0); 565 | lv_arc_set_angles(arc_gps_status, 0, 260); 566 | lv_obj_set_size(arc_gps_status, 40, 40); 567 | lv_arc_set_rotation(arc_gps_status, -135); 568 | lv_obj_add_style(arc_gps_status, &arc_gps_style, LV_PART_INDICATOR); 569 | lv_obj_remove_style(arc_gps_status, NULL, LV_PART_KNOB); 570 | lv_obj_clear_flag(arc_gps_status, LV_OBJ_FLAG_CLICKABLE); 571 | lv_obj_center(arc_gps_status); 572 | 573 | label_gps_status = lv_label_create(label_container_gps_status); 574 | lv_obj_align(label_gps_status, LV_ALIGN_CENTER, 0, 0); 575 | lv_obj_set_style_text_align(label_gps_status, LV_TEXT_ALIGN_LEFT, 0); 576 | lv_obj_set_style_text_color(label_gps_status, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN); 577 | lv_obj_set_style_text_font(label_gps_status, &lv_font_montserrat_16, 0); 578 | lv_label_set_text(label_gps_status, "0"); 579 | 580 | btn_start_tracking = lv_btn_create(gps_bg); 581 | lv_obj_align(btn_start_tracking, LV_ALIGN_BOTTOM_MID, 0, -5); 582 | lv_obj_set_style_radius(btn_start_tracking, 50, LV_PART_MAIN); 583 | lv_obj_set_size(btn_start_tracking, 50, 50); 584 | lv_obj_set_style_bg_color(btn_start_tracking, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN); 585 | static LCD_BTN_EVENT cmd_gps_tracking = LCD_BTN_EVENT::GPS_TRACKING; 586 | lv_obj_add_event_cb(btn_start_tracking, event_handler_main, LV_EVENT_CLICKED, &cmd_gps_tracking); 587 | 588 | lv_obj_t *img_run = lv_img_create(btn_start_tracking); 589 | lv_img_set_src(img_run, &run); 590 | lv_obj_align(img_run, LV_ALIGN_CENTER, 0, 0); 591 | lv_obj_set_size(img_run, 24, 24); 592 | lv_obj_add_style(img_run, &img_recolor_white_style, LV_PART_MAIN); 593 | 594 | btn_center_gps = lv_btn_create(gps_bg); 595 | lv_obj_align(btn_center_gps, LV_ALIGN_BOTTOM_RIGHT, -5, -5); 596 | lv_obj_set_size(btn_center_gps, 48, 35); 597 | lv_obj_set_style_bg_color(btn_center_gps, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN); 598 | static LCD_BTN_EVENT cmd_center_gps = LCD_BTN_EVENT::CENTER_GPS; 599 | lv_obj_add_event_cb(btn_center_gps, event_handler_main, LV_EVENT_CLICKED, &cmd_center_gps); 600 | 601 | lv_obj_t *img_gps = lv_label_create(btn_center_gps); 602 | lv_obj_set_size(img_gps, 24, 24); 603 | lv_label_set_text(img_gps, LV_SYMBOL_GPS); 604 | lv_obj_set_style_text_align(img_gps, LV_TEXT_ALIGN_CENTER, 0); 605 | lv_obj_align(img_gps, LV_ALIGN_CENTER, 0, 3); 606 | lv_img_set_angle(img_gps, 1800); 607 | lv_obj_add_style(img_gps, &img_recolor_white_style, LV_PART_MAIN); 608 | 609 | lv_obj_t *btn_clean_file = lv_btn_create(gps_bg); 610 | lv_obj_align(btn_clean_file, LV_ALIGN_BOTTOM_RIGHT, -5, -45); 611 | lv_obj_set_size(btn_clean_file, 48, 35); 612 | lv_obj_set_style_bg_color(btn_clean_file, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN); 613 | static LCD_BTN_EVENT cmd_clean_file = LCD_BTN_EVENT::CLEAN_FILE; 614 | lv_obj_add_event_cb(btn_clean_file, event_handler_main, LV_EVENT_CLICKED, &cmd_clean_file); 615 | 616 | lv_obj_t *img_clean_file = lv_label_create(btn_clean_file); 617 | lv_obj_set_size(img_clean_file, 24, 24); 618 | lv_label_set_text(img_clean_file, LV_SYMBOL_DRIVE); 619 | lv_obj_set_style_text_align(img_clean_file, LV_TEXT_ALIGN_CENTER, 0); 620 | lv_obj_align(img_clean_file, LV_ALIGN_CENTER, 0, 3); 621 | lv_img_set_angle(img_clean_file, 1800); 622 | lv_obj_add_style(img_clean_file, &img_recolor_white_style, LV_PART_MAIN); 623 | 624 | lv_obj_t *btn_home = lv_btn_create(gps_bg); 625 | lv_obj_align(btn_home, LV_ALIGN_BOTTOM_LEFT, 5, -5); 626 | lv_obj_set_size(btn_home, 48, 35); 627 | lv_obj_set_style_bg_color(btn_home, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN); 628 | static LCD_BTN_EVENT cmd_home = LCD_BTN_EVENT::RETURN_HOME; 629 | lv_obj_add_event_cb(btn_home, event_handler_main, LV_EVENT_CLICKED, &cmd_home); 630 | 631 | gps_screen_x = gps_x - glob_x + 120; 632 | gps_screen_y = gps_y - glob_y + 105; 633 | printf("gps_screen_x: %u, gps_screen_y: %u\n", gps_screen_x, gps_screen_y); 634 | btn_pos_gps = lv_btn_create(gps_bg); 635 | lv_obj_align(btn_pos_gps, LV_ALIGN_TOP_LEFT, gps_screen_x, gps_screen_y); 636 | lv_obj_set_style_radius(btn_pos_gps, 50, LV_PART_MAIN); 637 | lv_obj_set_style_shadow_opa(btn_pos_gps, 0, LV_PART_MAIN); 638 | lv_obj_set_size(btn_pos_gps, 10, 10); 639 | lv_obj_set_style_bg_color(btn_pos_gps, lv_palette_main(LV_PALETTE_BLUE), LV_PART_MAIN); 640 | 641 | lv_obj_t *center_point = lv_btn_create(gps_bg); 642 | lv_obj_align(center_point, LV_ALIGN_TOP_LEFT, 120, 105); 643 | lv_obj_set_style_radius(center_point, 50, LV_PART_MAIN); 644 | lv_obj_set_style_shadow_opa(center_point, 0, LV_PART_MAIN); 645 | lv_obj_set_size(center_point, 10, 10); 646 | lv_obj_set_style_bg_color(center_point, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN); 647 | 648 | lv_obj_t *img_home = lv_label_create(btn_home); 649 | lv_obj_set_size(img_home, 24, 24); 650 | lv_label_set_text(img_home, LV_SYMBOL_HOME); 651 | lv_obj_set_style_text_align(img_home, LV_TEXT_ALIGN_CENTER, 0); 652 | lv_obj_align(img_home, LV_ALIGN_CENTER, 0, 3); 653 | lv_img_set_angle(img_home, 1800); 654 | lv_obj_add_style(img_home, &img_recolor_white_style, LV_PART_MAIN); 655 | 656 | btn_pos_gps_point.x = gps_screen_x; 657 | btn_pos_gps_point.y = gps_screen_y; 658 | 659 | printf("**btn_pos_gps_point.x: %d, btn_pos_gps_point.y: %d\n", btn_pos_gps_point.x, btn_pos_gps_point.y); 660 | 661 | map_bg_p_points[0].x = lv_obj_get_x(map_bg_p[0]); 662 | map_bg_p_points[0].y = lv_obj_get_y(map_bg_p[0]); 663 | 664 | map_bg_p_points[1].x = lv_obj_get_x(map_bg_p[1]); 665 | map_bg_p_points[1].y = lv_obj_get_y(map_bg_p[1]); 666 | 667 | map_bg_p_points[2].x = lv_obj_get_x(map_bg_p[2]); 668 | map_bg_p_points[2].y = lv_obj_get_y(map_bg_p[2]); 669 | 670 | map_bg_p_points[3].x = lv_obj_get_x(map_bg_p[3]); 671 | map_bg_p_points[3].y = lv_obj_get_y(map_bg_p[3]); 672 | 673 | printf("**map_bg_p_points[0].x: %d, map_bg_p_points[0].y: %d\n", map_bg_p_points[0].x, map_bg_p_points[0].y); 674 | 675 | xSemaphoreGive(xGuiSemaphore); 676 | } 677 | else 678 | { 679 | printf("Sem not takn !!!\n"); 680 | } 681 | } 682 | 683 | void WatchTft::set_gps_info(bool fixed, uint8_t in_use, float dop, double lat, double lon) 684 | { 685 | 686 | static bool last_fixed = false; 687 | static uint8_t last_in_use = 0; 688 | static float last_dop = 0; 689 | static double last_lat = WatchGps::gps_lat; 690 | static double last_lon = WatchGps::gps_lon; 691 | 692 | if (fixed != WatchGps::gps_fixed) 693 | { 694 | WatchGps::gps_fixed = fixed; 695 | WatchTft::set_gps_state(WatchGps::gps_enabled, WatchGps::gps_fixed); 696 | } 697 | 698 | if (current_screen_index != screen_index_t::gps) 699 | { 700 | return; 701 | } 702 | 703 | if (fixed && in_use == 0) 704 | { 705 | fixed = false; 706 | } 707 | 708 | bool fixed_changed = false; 709 | if (last_fixed != fixed) 710 | { 711 | last_fixed = fixed; 712 | fixed_changed = true; 713 | } 714 | 715 | bool in_use_changed = false; 716 | if (last_in_use != in_use) 717 | { 718 | last_in_use = in_use; 719 | in_use_changed = true; 720 | } 721 | 722 | bool dop_changed = false; 723 | if (last_dop != dop) 724 | { 725 | last_dop = dop; 726 | dop_changed = true; 727 | } 728 | 729 | bool latlon_changed = false; 730 | if ((lat != last_lat || lon != last_lon) && 731 | (lat != 0 || lon != 0)) 732 | { 733 | last_lat = lat; 734 | last_lon = lon; 735 | latlon_changed = true; 736 | } 737 | 738 | if (!fixed_changed && !in_use_changed && !dop_changed) 739 | { 740 | return; 741 | } 742 | 743 | if (pdTRUE != xSemaphoreTake(xGuiSemaphore, 0)) 744 | { 745 | return; 746 | } 747 | 748 | if (dop_changed) 749 | { 750 | if (dop < 1) 751 | { 752 | lv_arc_set_angles(arc_gps_status, 0, 260); 753 | } 754 | else if (dop < 2) 755 | { 756 | lv_arc_set_angles(arc_gps_status, 20, 240); 757 | } 758 | else if (dop < 5) 759 | { 760 | lv_arc_set_angles(arc_gps_status, 60, 200); 761 | } 762 | else 763 | { 764 | lv_arc_set_angles(arc_gps_status, 100, 160); 765 | } 766 | } 767 | 768 | if (fixed_changed) 769 | { 770 | if (fixed) 771 | { 772 | lv_style_set_arc_color(&arc_gps_style, lv_palette_main(LV_PALETTE_GREEN)); 773 | lv_obj_set_style_text_color(label_gps_status, lv_palette_main(LV_PALETTE_GREEN), LV_PART_MAIN); 774 | } 775 | else 776 | { 777 | lv_style_set_arc_color(&arc_gps_style, lv_palette_main(LV_PALETTE_RED)); 778 | lv_obj_set_style_text_color(label_gps_status, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN); 779 | } 780 | 781 | lv_obj_add_style(arc_gps_status, &arc_gps_style, LV_PART_INDICATOR); 782 | } 783 | 784 | if (in_use_changed) 785 | { 786 | char sat_in_use[5] = {}; 787 | sprintf(sat_in_use, "%d", in_use); 788 | lv_label_set_text(label_gps_status, sat_in_use); 789 | } 790 | 791 | xSemaphoreGive(xGuiSemaphore); 792 | 793 | if (latlon_changed) 794 | { 795 | WatchGps::gps_lat = lat; 796 | WatchGps::gps_lon = lon; 797 | 798 | uint32_t new_gps_x = WatchGps::lon_to_x(WatchGps::gps_lon); 799 | uint32_t new_gps_y = WatchGps::lat_lon_to_y(WatchGps::gps_lat, WatchGps::gps_lon); 800 | 801 | int32_t diff_x = gps_x - new_gps_x; 802 | int32_t diff_y = gps_y - new_gps_y; 803 | 804 | printf("gps move: %u->%u, %u->%u\n", gps_x, new_gps_x, gps_y, new_gps_y); 805 | 806 | add_gps_pos(diff_x, diff_y); 807 | } 808 | } 809 | 810 | void WatchTft::add_gps_pos(int32_t x, int32_t y) 811 | { 812 | gps_x -= x; 813 | gps_y -= y; 814 | 815 | printf("gps_xy: %u:%u\n", gps_x, gps_y); 816 | 817 | lv_point_t lv_point = {}; 818 | lv_point.x = 0; 819 | lv_point.y = 0; 820 | 821 | if (centered_to_gps) 822 | { 823 | lv_point = drag_view(x, y); 824 | } 825 | else 826 | { 827 | add_xy_to_gps_point(x, y); 828 | } 829 | } 830 | -------------------------------------------------------------------------------- /main/WatchTft/Power_Screen.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchTft.h" 2 | 3 | // chart power 4 | lv_obj_t *WatchTft::chart_power = NULL; 5 | lv_obj_t *WatchTft::label_chart_usb; 6 | lv_obj_t *WatchTft::label_chart_bat; 7 | lv_chart_series_t *WatchTft::power_chart_ser_bat = NULL; 8 | lv_chart_series_t *WatchTft::power_chart_ser_usb = NULL; 9 | 10 | void WatchTft::power_screen() 11 | { 12 | lv_obj_t *power_bg = NULL; 13 | 14 | static bool init_style_done = false; 15 | static lv_style_t power_bg_style; 16 | if (!init_style_done) 17 | { 18 | lv_style_init(&power_bg_style); 19 | lv_style_set_bg_color(&power_bg_style, lv_color_black()); 20 | lv_style_set_radius(&power_bg_style, 0); 21 | lv_style_set_border_width(&power_bg_style, 0); 22 | lv_style_set_pad_all(&power_bg_style, 0); 23 | init_style_done = true; 24 | } 25 | 26 | if (pdTRUE == xSemaphoreTake(xGuiSemaphore, 1000)) 27 | { 28 | 29 | power_bg = lv_obj_create(current_screen); 30 | lv_obj_set_size(power_bg, 240, 210); 31 | lv_obj_align(power_bg, LV_ALIGN_TOP_LEFT, 0, 30); 32 | lv_obj_clear_flag(power_bg, LV_OBJ_FLAG_SCROLLABLE); 33 | lv_obj_add_style(power_bg, &power_bg_style, LV_PART_MAIN); 34 | 35 | lv_obj_t *btn_home = lv_btn_create(power_bg); 36 | lv_obj_align(btn_home, LV_ALIGN_BOTTOM_LEFT, 5, -5); 37 | lv_obj_set_size(btn_home, 48, 35); 38 | lv_obj_set_style_bg_opa(btn_home, 0, LV_PART_MAIN); 39 | static LCD_BTN_EVENT cmd_home = LCD_BTN_EVENT::RETURN_HOME; 40 | lv_obj_add_event_cb(btn_home, event_handler_main, LV_EVENT_CLICKED, &cmd_home); 41 | 42 | lv_obj_t *img_arrow_left = lv_img_create(btn_home); 43 | lv_img_set_src(img_arrow_left, &arrow); 44 | lv_obj_align(img_arrow_left, LV_ALIGN_CENTER, 0, 0); 45 | lv_obj_set_size(img_arrow_left, 24, 24); 46 | lv_img_set_angle(img_arrow_left, 1800); 47 | lv_obj_add_style(img_arrow_left, &img_recolor_white_style, LV_PART_MAIN); 48 | 49 | lv_obj_t *label_chart_unit = lv_label_create(power_bg); 50 | lv_obj_align(label_chart_unit, LV_ALIGN_TOP_LEFT, 5, 5); 51 | lv_obj_set_style_text_align(label_chart_unit, LV_TEXT_ALIGN_LEFT, 0); 52 | lv_obj_set_style_text_color(label_chart_unit, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN); 53 | lv_label_set_text(label_chart_unit, "(mA)"); 54 | 55 | label_chart_usb = lv_label_create(power_bg); 56 | lv_obj_align(label_chart_usb, LV_ALIGN_BOTTOM_RIGHT, -10, -30); 57 | lv_obj_set_style_text_align(label_chart_usb, LV_TEXT_ALIGN_RIGHT, 0); 58 | lv_obj_set_style_text_color(label_chart_usb, lv_palette_main(LV_PALETTE_GREEN), LV_PART_MAIN); 59 | lv_label_set_text(label_chart_usb, "USB 417ma"); 60 | 61 | label_chart_bat = lv_label_create(power_bg); 62 | lv_obj_align(label_chart_bat, LV_ALIGN_BOTTOM_RIGHT, -10, -15); 63 | lv_obj_set_style_text_align(label_chart_bat, LV_TEXT_ALIGN_RIGHT, 0); 64 | lv_obj_set_style_text_color(label_chart_bat, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN); 65 | lv_label_set_text(label_chart_bat, "BATT 536ma"); 66 | 67 | chart_power = lv_chart_create(power_bg); 68 | lv_obj_set_size(chart_power, 185, 130); 69 | lv_obj_align(chart_power, LV_ALIGN_TOP_LEFT, 45, 25); 70 | lv_chart_set_type(chart_power, LV_CHART_TYPE_LINE); 71 | lv_chart_set_range(chart_power, LV_CHART_AXIS_PRIMARY_Y, 0, 500); 72 | lv_chart_set_range(chart_power, LV_CHART_AXIS_SECONDARY_Y, 0, 500); 73 | lv_chart_set_axis_tick(chart_power, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 6, 2, true, 50); 74 | power_chart_ser_bat = lv_chart_add_series(chart_power, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y); 75 | power_chart_ser_usb = lv_chart_add_series(chart_power, lv_palette_main(LV_PALETTE_GREEN), LV_CHART_AXIS_SECONDARY_Y); 76 | for (uint8_t i = 0; i < 10; i++) 77 | { 78 | power_chart_ser_bat->y_points[i] = 0; 79 | power_chart_ser_usb->y_points[i] = 0; 80 | } 81 | 82 | lv_chart_refresh(chart_power); 83 | 84 | xSemaphoreGive(xGuiSemaphore); 85 | } 86 | } 87 | 88 | void WatchTft::add_chart_power_value(lv_coord_t batt, lv_coord_t vbus) 89 | { 90 | if (power_chart_ser_bat == NULL || power_chart_ser_usb == NULL) 91 | { 92 | return; 93 | } 94 | for (uint8_t i = 0; i < 9; i++) 95 | { 96 | power_chart_ser_bat->y_points[i] = power_chart_ser_bat->y_points[i + 1]; 97 | power_chart_ser_usb->y_points[i] = power_chart_ser_usb->y_points[i + 1]; 98 | } 99 | power_chart_ser_bat->y_points[9] = batt; 100 | power_chart_ser_usb->y_points[9] = vbus; 101 | 102 | char usb_str[15] = {}; 103 | sprintf(usb_str, "USB %dma", vbus); 104 | 105 | char batt_str[15] = {}; 106 | sprintf(batt_str, "BATT %dma", batt); 107 | 108 | lv_label_set_text(label_chart_usb, usb_str); 109 | lv_label_set_text(label_chart_bat, batt_str); 110 | 111 | if (pdTRUE == xSemaphoreTake(xGuiSemaphore, 50)) 112 | { 113 | lv_chart_refresh(chart_power); 114 | xSemaphoreGive(xGuiSemaphore); 115 | } 116 | } -------------------------------------------------------------------------------- /main/WatchTft/Settings_Screen.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchTft.h" 2 | 3 | lv_obj_t *WatchTft::label_desc_tmo_off = NULL; 4 | lv_obj_t *WatchTft::label_desc_step_goal = NULL; 5 | 6 | void WatchTft::settings_screen() 7 | { 8 | lv_obj_t *settings_bg = NULL; 9 | 10 | static bool init_style_done = false; 11 | static lv_style_t settings_bg_style; 12 | if (!init_style_done) 13 | { 14 | lv_style_init(&settings_bg_style); 15 | lv_style_set_bg_color(&settings_bg_style, lv_color_black()); 16 | lv_style_set_radius(&settings_bg_style, 0); 17 | lv_style_set_border_width(&settings_bg_style, 0); 18 | lv_style_set_pad_all(&settings_bg_style, 0); 19 | init_style_done = true; 20 | } 21 | 22 | if (pdTRUE == xSemaphoreTake(xGuiSemaphore, 1000)) 23 | { 24 | 25 | settings_bg = lv_obj_create(current_screen); 26 | lv_obj_set_size(settings_bg, 240, 210); 27 | lv_obj_align(settings_bg, LV_ALIGN_TOP_LEFT, 0, 30); 28 | lv_obj_clear_flag(settings_bg, LV_OBJ_FLAG_SCROLLABLE); 29 | lv_obj_add_style(settings_bg, &settings_bg_style, LV_PART_MAIN); 30 | 31 | lv_obj_t *settings_scroll = lv_obj_create(settings_bg); 32 | lv_obj_set_size(settings_scroll, 240, 165); 33 | lv_obj_align(settings_scroll, LV_ALIGN_TOP_LEFT, 0, 0); 34 | lv_obj_add_style(settings_scroll, &settings_bg_style, LV_PART_MAIN); 35 | 36 | lv_obj_t *btn_home = lv_btn_create(settings_bg); 37 | lv_obj_align(btn_home, LV_ALIGN_BOTTOM_LEFT, 5, -5); 38 | lv_obj_set_size(btn_home, 48, 35); 39 | lv_obj_set_style_bg_opa(btn_home, 0, LV_PART_MAIN); 40 | static LCD_BTN_EVENT cmd_home = LCD_BTN_EVENT::RETURN_HOME; 41 | lv_obj_add_event_cb(btn_home, event_handler_main, LV_EVENT_CLICKED, &cmd_home); 42 | 43 | lv_obj_t *img_arrow_left = lv_img_create(btn_home); 44 | lv_img_set_src(img_arrow_left, &arrow); 45 | lv_obj_align(img_arrow_left, LV_ALIGN_CENTER, 0, 0); 46 | lv_obj_set_size(img_arrow_left, 24, 24); 47 | lv_img_set_angle(img_arrow_left, 1800); 48 | lv_obj_add_style(img_arrow_left, &img_recolor_white_style, LV_PART_MAIN); 49 | 50 | // Timeout Screen 51 | 52 | lv_obj_t *label_title_tmo_off = lv_label_create(settings_scroll); 53 | lv_obj_align(label_title_tmo_off, LV_ALIGN_TOP_LEFT, 5, 10); 54 | lv_obj_set_style_text_align(label_title_tmo_off, LV_TEXT_ALIGN_CENTER, 0); 55 | lv_obj_set_style_text_color(label_title_tmo_off, lv_color_white(), LV_PART_MAIN); 56 | lv_label_set_text(label_title_tmo_off, "Timeout screen"); 57 | 58 | label_desc_tmo_off = lv_label_create(settings_scroll); 59 | lv_obj_align(label_desc_tmo_off, LV_ALIGN_TOP_RIGHT, -15, 10); 60 | lv_obj_set_style_text_align(label_desc_tmo_off, LV_TEXT_ALIGN_RIGHT, 0); 61 | lv_obj_set_style_text_color(label_desc_tmo_off, lv_color_white(), LV_PART_MAIN); 62 | std::string delay_tmo = std::to_string(timer_turn_off_screen / 1000) + "s"; 63 | lv_label_set_text(label_desc_tmo_off, delay_tmo.c_str()); 64 | 65 | lv_obj_t *slider_tmo_off = lv_slider_create(settings_scroll); 66 | lv_obj_align(slider_tmo_off, LV_ALIGN_TOP_MID, 0, 40); 67 | lv_obj_set_size(slider_tmo_off, 160, 20); 68 | lv_slider_set_range(slider_tmo_off, 5, 120); 69 | lv_slider_set_value(slider_tmo_off, timer_turn_off_screen / 1000, LV_ANIM_ON); 70 | lv_obj_set_style_bg_color(slider_tmo_off, lv_color_hex(0xed1590), LV_PART_KNOB); 71 | lv_obj_set_style_bg_color(slider_tmo_off, lv_palette_main(LV_PALETTE_DEEP_PURPLE), LV_PART_INDICATOR); 72 | lv_obj_add_event_cb(slider_tmo_off, slider_tmo_off_event_cb, LV_EVENT_ALL, NULL); 73 | 74 | lv_obj_t *hor_bar_01 = lv_obj_create(settings_scroll); 75 | lv_obj_align(hor_bar_01, LV_ALIGN_TOP_MID, 0, 70); 76 | lv_obj_set_size(hor_bar_01, 200, 2); 77 | lv_obj_set_style_bg_color(hor_bar_01, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN); 78 | lv_obj_set_style_border_width(hor_bar_01, 0, LV_PART_MAIN); 79 | 80 | // Wakeup action 81 | 82 | lv_obj_t *label_title_wakeup = lv_label_create(settings_scroll); 83 | lv_obj_align(label_title_wakeup, LV_ALIGN_TOP_MID, 0, 80); 84 | lv_obj_set_style_text_align(label_title_wakeup, LV_TEXT_ALIGN_CENTER, 0); 85 | lv_obj_set_style_text_color(label_title_wakeup, lv_color_white(), LV_PART_MAIN); 86 | lv_label_set_text(label_title_wakeup, "Wake up action"); 87 | 88 | lv_obj_t *label_desc_wakeup_01 = lv_label_create(settings_scroll); 89 | lv_obj_align(label_desc_wakeup_01, LV_ALIGN_TOP_LEFT, 20, 100); 90 | lv_obj_set_style_text_align(label_desc_wakeup_01, LV_TEXT_ALIGN_LEFT, 0); 91 | lv_obj_set_style_text_color(label_desc_wakeup_01, lv_color_white(), LV_PART_MAIN); 92 | lv_label_set_text(label_desc_wakeup_01, "Double Tap"); 93 | 94 | lv_obj_t *cb_wakeup_double_tap = lv_checkbox_create(settings_scroll); 95 | lv_obj_align(cb_wakeup_double_tap, LV_ALIGN_TOP_LEFT, 55, 120); 96 | lv_checkbox_set_text(cb_wakeup_double_tap, ""); 97 | lv_obj_set_style_border_color(cb_wakeup_double_tap, lv_palette_main(LV_PALETTE_DEEP_PURPLE), LV_PART_INDICATOR | LV_STATE_DEFAULT); 98 | lv_obj_set_style_bg_color(cb_wakeup_double_tap, lv_color_hex(0xed1590), LV_PART_INDICATOR | LV_STATE_CHECKED); 99 | if (WatchBma::wakeup_on_double_tap) 100 | { 101 | lv_obj_add_state(cb_wakeup_double_tap, LV_STATE_CHECKED); 102 | } 103 | lv_obj_add_event_cb(cb_wakeup_double_tap, wakeup_double_tap_event_cb, LV_EVENT_ALL, NULL); 104 | 105 | lv_obj_t *label_desc_wakeup_02 = lv_label_create(settings_scroll); 106 | lv_obj_align(label_desc_wakeup_02, LV_ALIGN_TOP_RIGHT, -65, 100); 107 | lv_obj_set_style_text_align(label_desc_wakeup_02, LV_TEXT_ALIGN_RIGHT, 0); 108 | lv_obj_set_style_text_color(label_desc_wakeup_02, lv_color_white(), LV_PART_MAIN); 109 | lv_label_set_text(label_desc_wakeup_02, "Tilt"); 110 | 111 | lv_obj_t *cb_wakeup_tilt = lv_checkbox_create(settings_scroll); 112 | lv_obj_align(cb_wakeup_tilt, LV_ALIGN_TOP_RIGHT, -55, 120); 113 | lv_checkbox_set_text(cb_wakeup_tilt, ""); 114 | lv_obj_set_style_border_color(cb_wakeup_tilt, lv_palette_main(LV_PALETTE_DEEP_PURPLE), LV_PART_INDICATOR | LV_STATE_DEFAULT); 115 | lv_obj_set_style_bg_color(cb_wakeup_tilt, lv_color_hex(0xed1590), LV_PART_INDICATOR | LV_STATE_CHECKED); 116 | if (WatchBma::wakeup_on_tilt) 117 | { 118 | lv_obj_add_state(cb_wakeup_tilt, LV_STATE_CHECKED); 119 | } 120 | lv_obj_add_event_cb(cb_wakeup_tilt, wakeup_tilt_event_cb, LV_EVENT_ALL, NULL); 121 | 122 | lv_obj_t *hor_bar_02 = lv_obj_create(settings_scroll); 123 | lv_obj_align(hor_bar_02, LV_ALIGN_TOP_MID, 0, 150); 124 | lv_obj_set_size(hor_bar_02, 200, 2); 125 | lv_obj_set_style_bg_color(hor_bar_02, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN); 126 | lv_obj_set_style_border_width(hor_bar_02, 0, LV_PART_MAIN); 127 | 128 | // Step Goal 129 | 130 | lv_obj_t *label_title_step_goal = lv_label_create(settings_scroll); 131 | lv_obj_align(label_title_step_goal, LV_ALIGN_TOP_LEFT, 5, 160); 132 | lv_obj_set_style_text_align(label_title_step_goal, LV_TEXT_ALIGN_CENTER, 0); 133 | lv_obj_set_style_text_color(label_title_step_goal, lv_color_white(), LV_PART_MAIN); 134 | lv_label_set_text(label_title_step_goal, "Steps goal"); 135 | 136 | label_desc_step_goal = lv_label_create(settings_scroll); 137 | lv_obj_align(label_desc_step_goal, LV_ALIGN_TOP_RIGHT, -15, 160); 138 | lv_obj_set_style_text_align(label_desc_step_goal, LV_TEXT_ALIGN_RIGHT, 0); 139 | lv_obj_set_style_text_color(label_desc_step_goal, lv_color_white(), LV_PART_MAIN); 140 | std::string step_goal = std::to_string(WatchBma::step_counter_goal) + " steps"; 141 | lv_label_set_text(label_desc_step_goal, step_goal.c_str()); 142 | 143 | lv_obj_t *slider_step_goal = lv_slider_create(settings_scroll); 144 | lv_obj_align(slider_step_goal, LV_ALIGN_TOP_MID, 0, 190); 145 | lv_obj_set_size(slider_step_goal, 160, 20); 146 | lv_slider_set_range(slider_step_goal, 5, 30); 147 | lv_slider_set_value(slider_step_goal, WatchBma::step_counter_goal / 1000, LV_ANIM_ON); 148 | lv_obj_set_style_bg_color(slider_step_goal, lv_color_hex(0xed1590), LV_PART_KNOB); 149 | lv_obj_set_style_bg_color(slider_step_goal, lv_palette_main(LV_PALETTE_DEEP_PURPLE), LV_PART_INDICATOR); 150 | lv_obj_add_event_cb(slider_step_goal, slider_step_goal_event_cb, LV_EVENT_ALL, NULL); 151 | 152 | lv_obj_t *hor_bar_03 = lv_obj_create(settings_scroll); 153 | lv_obj_align(hor_bar_03, LV_ALIGN_TOP_MID, 0, 220); 154 | lv_obj_set_size(hor_bar_03, 200, 2); 155 | lv_obj_set_style_bg_color(hor_bar_03, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN); 156 | lv_obj_set_style_border_width(hor_bar_03, 0, LV_PART_MAIN); 157 | 158 | xSemaphoreGive(xGuiSemaphore); 159 | } 160 | } 161 | 162 | void WatchTft::slider_tmo_off_event_cb(lv_event_t *e) 163 | { 164 | lv_event_code_t code = lv_event_get_code(e); 165 | lv_obj_t *slider = lv_event_get_target(e); 166 | timer_turn_off_screen = lv_slider_get_value(slider) * 1000; 167 | if (code == LV_EVENT_VALUE_CHANGED) 168 | { 169 | std::string delay_tmo = std::to_string(timer_turn_off_screen / 1000) + "s"; 170 | lv_label_set_text(label_desc_tmo_off, delay_tmo.c_str()); 171 | } 172 | 173 | if (code == LV_EVENT_RELEASED) 174 | { 175 | WatchNvs::set_tmo_screen(timer_turn_off_screen); 176 | } 177 | } 178 | 179 | void WatchTft::wakeup_double_tap_event_cb(lv_event_t *e) 180 | { 181 | lv_event_code_t code = lv_event_get_code(e); 182 | lv_obj_t *obj = lv_event_get_target(e); 183 | if (code != LV_EVENT_VALUE_CHANGED) 184 | { 185 | return; 186 | } 187 | lv_state_t state = lv_obj_get_state(obj); 188 | WatchBma::wakeup_on_double_tap = state & LV_STATE_CHECKED; 189 | WatchNvs::set_wakeup_double_tap(WatchBma::wakeup_on_double_tap); 190 | printf("lv_State dt: %d\n", state); 191 | } 192 | 193 | void WatchTft::wakeup_tilt_event_cb(lv_event_t *e) 194 | { 195 | lv_event_code_t code = lv_event_get_code(e); 196 | lv_obj_t *obj = lv_event_get_target(e); 197 | if (code != LV_EVENT_VALUE_CHANGED) 198 | { 199 | return; 200 | } 201 | lv_state_t state = lv_obj_get_state(obj); 202 | WatchBma::wakeup_on_tilt = state & LV_STATE_CHECKED; 203 | WatchNvs::set_wakeup_tilt(WatchBma::wakeup_on_tilt); 204 | printf("lv_State ti: %d\n", state); 205 | } 206 | 207 | void WatchTft::slider_step_goal_event_cb(lv_event_t *e) 208 | { 209 | lv_event_code_t code = lv_event_get_code(e); 210 | lv_obj_t *slider = lv_event_get_target(e); 211 | WatchBma::step_counter_goal = lv_slider_get_value(slider) * 1000; 212 | if (code == LV_EVENT_VALUE_CHANGED) 213 | { 214 | std::string step_goal = std::to_string(WatchBma::step_counter_goal) + " steps"; 215 | lv_label_set_text(label_desc_step_goal, step_goal.c_str()); 216 | } 217 | 218 | if (code == LV_EVENT_RELEASED) 219 | { 220 | WatchNvs::set_step_goal(WatchBma::step_counter_goal); 221 | } 222 | } -------------------------------------------------------------------------------- /main/WatchTft/WatchTft.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "lvgl/lvgl.h" 3 | #include "lvgl_helpers.h" 4 | 5 | #ifndef WATCH_TFT 6 | #define WATCH_TFT 7 | 8 | #define LV_TICK_PERIOD_MS 2 9 | 10 | #define DELAY_BETWEEN_LV(X) \ 11 | xSemaphoreGive(xGuiSemaphore); \ 12 | } \ 13 | vTaskDelay(X); \ 14 | if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY)) \ 15 | { 16 | 17 | // #define DISPLAY_TOUCH_LIMIT 18 | 19 | class WatchTft 20 | { 21 | 22 | public: 23 | enum class screen_index_t 24 | { 25 | main = 1, 26 | power = 2, 27 | run = 3, 28 | settings = 4, 29 | gps = 5, 30 | }; 31 | static bool screen_en; 32 | static TaskHandle_t current_task_hanlde; 33 | 34 | static const lv_img_dsc_t download; 35 | 36 | static void init(); 37 | 38 | static void turn_screen_on(); 39 | static void turn_screen_off(); 40 | static void turn_off_screen(); 41 | static void set_battery_text(uint8_t percent); 42 | static void toggle_button_menu_view(); 43 | 44 | static void main_screen_from_sleep(); 45 | static void add_chart_power_value(lv_coord_t batt, lv_coord_t vbus); 46 | 47 | static void set_gps_info(bool fixed, uint8_t in_use, float dop, double lat, double lon); 48 | 49 | static void refresh_tile(int32_t x, int32_t y); 50 | static void add_gps_pos(int32_t x, int32_t y); 51 | 52 | static void set_wifi_state(bool enable, bool connected); 53 | static void set_gps_state(bool enable, bool fixed); 54 | 55 | static void set_charge_state(bool state); 56 | 57 | private: 58 | enum class LCD_CMD : uint32_t 59 | { 60 | TURN_OFF_SCREEN, 61 | SLEEP_SCREEN, 62 | RESET_ESP, 63 | RETURN_HOME, 64 | POWER_SCREEN, 65 | RUN_SCREEN, 66 | SETTINGS_SCREEN, 67 | GPS_SCREEN, 68 | }; 69 | 70 | enum class LCD_BTN_EVENT : uint32_t 71 | { 72 | TURN_OFF_SCREEN, 73 | SLEEP_SCREEN, 74 | MAIN_PAGE, 75 | NEXT_PAGE, 76 | PREVIOUS_PAGE, 77 | RESET_ESP, 78 | TOP_BAR_TOGGLE, 79 | RETURN_HOME, 80 | POWER_SCREEN, 81 | RUN_SCREEN, 82 | SETTINGS_SCREEN, 83 | GPS_SCREEN, 84 | GPS_TRACKING, 85 | CENTER_GPS, 86 | CLEAN_FILE, 87 | }; 88 | 89 | static lv_obj_t *current_screen; 90 | static lv_obj_t *top_menu; 91 | static lv_obj_t *button_menu; 92 | 93 | // images 94 | static const lv_img_dsc_t lune; 95 | static const lv_img_dsc_t ampoule; 96 | static const lv_img_dsc_t main_bg; 97 | static const lv_img_dsc_t gradient_count; 98 | static const lv_img_dsc_t rotate; 99 | static const lv_img_dsc_t arrow; 100 | static const lv_img_dsc_t circle; 101 | static const lv_img_dsc_t run; 102 | 103 | // top menu 104 | static lv_obj_t *label_battery; 105 | static lv_obj_t *slider_top_bl; 106 | static uint8_t s_battery_percent; 107 | 108 | // power screen 109 | static lv_obj_t *chart_power; 110 | static lv_obj_t *label_chart_usb; 111 | static lv_obj_t *label_chart_bat; 112 | static lv_chart_series_t *power_chart_ser_bat; 113 | static lv_chart_series_t *power_chart_ser_usb; 114 | 115 | // run screen 116 | static lv_obj_t *label_step_count; 117 | static lv_obj_t *arc_counter; 118 | 119 | // settings screen 120 | static lv_obj_t *label_desc_tmo_off; 121 | static lv_obj_t *label_desc_step_goal; 122 | 123 | // gps screen 124 | static lv_obj_t *label_title_gps; 125 | static lv_obj_t *label_gps_info; 126 | static lv_obj_t *gps_recording_indicator; 127 | static lv_obj_t *btn_start_tracking; 128 | 129 | // physical button menu 130 | static lv_obj_t *lcd_turn_off_screen; 131 | static lv_obj_t *lcd_reset_screen; 132 | static lv_obj_t *lcd_sleep_screen; 133 | 134 | static uint8_t bl_value; 135 | static disp_backlight_h bckl_handle; 136 | static lv_style_t img_recolor_white_style; 137 | 138 | static SemaphoreHandle_t xGuiSemaphore; 139 | static QueueHandle_t xQueueLcdCmd; 140 | 141 | static lv_obj_t *img_wifi; 142 | static lv_obj_t *line_wifi; 143 | static lv_obj_t *img_gps; 144 | static lv_obj_t *line_gps; 145 | 146 | static lv_point_t wifi_line_points[2]; 147 | static lv_point_t gps_line_points[2]; 148 | 149 | static screen_index_t current_screen_index; 150 | 151 | static void lv_tick_task(void *arg); 152 | static void gui_task(void *pvParameter); 153 | static void queue_cmd_task(void *pvParameter); 154 | static void init_home_screen(void); 155 | static void slider_event_cb(lv_event_t *e); 156 | static void set_bl(uint8_t value); 157 | static void toggle_top_bar_view(); 158 | static void event_handler_main(lv_event_t *e); 159 | static void sleep_screen(); 160 | static void reset_screen(); 161 | static void power_screen(); 162 | static void load_screen(screen_index_t screen_index); 163 | static void load_main_screen(); 164 | static void load_top_bar(const char *title); 165 | static void load_button_menu(); 166 | 167 | static void run_screen(); 168 | static void count_step_task(void *pvParameter); 169 | static void set_step_counter_value(uint32_t steps); 170 | 171 | static void settings_screen(); 172 | static void slider_tmo_off_event_cb(lv_event_t *e); 173 | static void wakeup_double_tap_event_cb(lv_event_t *e); 174 | static void wakeup_tilt_event_cb(lv_event_t *e); 175 | static void slider_step_goal_event_cb(lv_event_t *e); 176 | 177 | static void gps_screen(); 178 | static void center_gps(); 179 | static lv_point_t drag_view(int32_t x, int32_t y, bool sem_taken = false); 180 | static void drag_event_handler(lv_event_t *e); 181 | static void add_xy_to_gps_point(int32_t x, int32_t y, bool sem_taken = false); 182 | 183 | static void top_menu_event_handler(lv_event_t *e); 184 | }; 185 | 186 | #endif -------------------------------------------------------------------------------- /main/WatchTft/ampoule.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchTft.h" 2 | 3 | 4 | const uint8_t ampoule_map[1728] = { 5 | /*Pixel format: Alpha 8 bit, Red: 5 bit, Green: 6 bit, Blue: 5 bit BUT the 2 color bytes are swapped*/ 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x9c, 0x00, 0x00, 0xd8, 0x00, 0x00, 0xee, 0x00, 0x00, 0xf1, 0x00, 0x00, 0xd5, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0xba, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0xeb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xed, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xeb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x96, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x36, 0x00, 0x00, 0x93, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0xea, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x8c, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xec, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0xde, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0xfd, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0xb0, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x37, 0x00, 0x00, 0x80, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x80, 0x00, 0x00, 0x4c, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0xeb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0xa9, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 30 | }; 31 | 32 | const lv_img_header_t ampoule_header = { 33 | .cf = LV_IMG_CF_TRUE_COLOR_ALPHA, 34 | .always_zero = 0, 35 | .reserved = 0, 36 | .w = 24, 37 | .h = 24, 38 | }; 39 | 40 | const lv_img_dsc_t WatchTft::ampoule = { 41 | .header = ampoule_header, 42 | .data_size = 576 * LV_COLOR_SIZE / 8, 43 | .data = ampoule_map, 44 | }; -------------------------------------------------------------------------------- /main/WatchTft/arrow.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchTft.h" 2 | 3 | 4 | const uint8_t arrow_map[1728] = { 5 | /*Pixel format: Alpha 8 bit, Red: 5 bit, Green: 6 bit, Blue: 5 bit BUT the 2 color bytes are swapped*/ 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0xef, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0xed, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf4, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf4, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x77, 0x00, 0x00, 0x77, 0x00, 0x00, 0x77, 0x00, 0x00, 0x77, 0x00, 0x00, 0x77, 0x00, 0x00, 0x77, 0x00, 0x00, 0x77, 0x00, 0x00, 0x77, 0x00, 0x00, 0xb3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x88, 0x00, 0x00, 0x88, 0x00, 0x00, 0x88, 0x00, 0x00, 0x88, 0x00, 0x00, 0x88, 0x00, 0x00, 0x88, 0x00, 0x00, 0x88, 0x00, 0x00, 0x88, 0x00, 0x00, 0xc0, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf4, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf4, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0xed, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0xee, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x79, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 30 | }; 31 | 32 | const lv_img_header_t arrow_header = { 33 | .cf = LV_IMG_CF_TRUE_COLOR_ALPHA, 34 | .always_zero = 0, 35 | .reserved = 0, 36 | .w = 24, 37 | .h = 24, 38 | }; 39 | 40 | const lv_img_dsc_t WatchTft::arrow = { 41 | .header = arrow_header, 42 | .data_size = 576 * LV_COLOR_SIZE / 8, 43 | .data = arrow_map, 44 | }; -------------------------------------------------------------------------------- /main/WatchTft/circle.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchTft.h" 2 | 3 | 4 | const uint8_t circle_map[1728] = { 5 | /*Pixel format: Alpha 8 bit, Red: 5 bit, Green: 6 bit, Blue: 5 bit BUT the 2 color bytes are swapped*/ 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x54, 0x00, 0x00, 0x76, 0x00, 0x00, 0x71, 0x00, 0x00, 0x54, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x9d, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x98, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0xe5, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0xe6, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x8f, 0x00, 0x00, 0xcb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0xf2, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0xf1, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0xe3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xca, 0x00, 0x00, 0x94, 0x00, 0x00, 0x8f, 0x00, 0x00, 0xcb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0xe3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x9b, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x53, 0x00, 0x00, 0x74, 0x00, 0x00, 0x75, 0x00, 0x00, 0x52, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 30 | }; 31 | 32 | const lv_img_header_t circle_header = { 33 | .cf = LV_IMG_CF_TRUE_COLOR_ALPHA, 34 | .always_zero = 0, 35 | .reserved = 0, 36 | .w = 24, 37 | .h = 24, 38 | }; 39 | 40 | const lv_img_dsc_t WatchTft::circle = { 41 | .header = circle_header, 42 | .data_size = 576 * LV_COLOR_SIZE / 8, 43 | .data = circle_map, 44 | }; -------------------------------------------------------------------------------- /main/WatchTft/lune.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchTft.h" 2 | 3 | const uint8_t lune_map[1728] = { 4 | /*Pixel format: Red: 5 bit, Green: 6 bit, Blue: 5 bit*/ 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x73, 0x00, 0x00, 0xab, 0x00, 0x00, 0xde, 0x00, 0x00, 0xee, 0x00, 0x00, 0xee, 0x00, 0x00, 0xe3, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x9c, 0x00, 0x00, 0xf7, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0xec, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x64, 0x00, 0x00, 0x29, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x28, 0x00, 0x00, 0x8f, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0xfd, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0xee, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0xf3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0xf5, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xef, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0xe3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0xfd, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0xfd, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0xe2, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0xeb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0xf4, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xef, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xde, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0xee, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x64, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x92, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0xee, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x9d, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x69, 0x00, 0x00, 0xb4, 0x00, 0x00, 0xd5, 0x00, 0x00, 0xf1, 0x00, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29 | }; 30 | 31 | const lv_img_header_t lune_header = { 32 | .cf = LV_IMG_CF_TRUE_COLOR_ALPHA, 33 | .always_zero = 0, 34 | .reserved = 0, 35 | .w = 24, 36 | .h = 24, 37 | }; 38 | 39 | const lv_img_dsc_t WatchTft::lune = { 40 | .header = lune_header, 41 | .data_size = 576 * LV_COLOR_SIZE / 8, 42 | .data = lune_map, 43 | }; 44 | -------------------------------------------------------------------------------- /main/WatchTft/rotate.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchTft.h" 2 | 3 | const uint8_t rotate_map[1728] = { 4 | /*Pixel format: Red: 5 bit, Green: 6 bit, Blue: 5 bit*/ 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x6d, 0x00, 0x00, 0xb1, 0x00, 0x00, 0xda, 0x00, 0x00, 0xf7, 0x00, 0x00, 0xee, 0x00, 0x00, 0xe7, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x77, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x9b, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfb, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0xec, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x59, 0x00, 0x00, 0x78, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0a, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xba, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x26, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x59, 0x00, 0x00, 0xb3, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0e, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0xfd, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0xd3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0e, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0xe6, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0e, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0e, 12 | 0x00, 0x00, 0x12, 0x00, 0x00, 0xf4, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0xf7, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xca, 0x00, 0x00, 0x02, 13 | 0x00, 0x00, 0x66, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0xa3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0xd5, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0xe3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0xe8, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x79, 18 | 0x00, 0x00, 0xcd, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe6, 19 | 0x00, 0x00, 0xa5, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xc0, 20 | 0x00, 0x00, 0x62, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x81, 21 | 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf6, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x25, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0xd6, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xe8, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xbb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0xd1, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0xfd, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x61, 0x00, 0x00, 0x23, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x04, 0x00, 0x00, 0x25, 0x00, 0x00, 0x5b, 0x00, 0x00, 0xb7, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0xe7, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x97, 0x00, 0x00, 0xf6, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x6d, 0x00, 0x00, 0xaa, 0x00, 0x00, 0xde, 0x00, 0x00, 0xee, 0x00, 0x00, 0xf2, 0x00, 0x00, 0xdb, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x72, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29 | 30 | }; 31 | 32 | const lv_img_header_t rotate_header = { 33 | .cf = LV_IMG_CF_TRUE_COLOR_ALPHA, 34 | .always_zero = 0, 35 | .reserved = 0, 36 | .w = 24, 37 | .h = 24, 38 | }; 39 | 40 | const lv_img_dsc_t WatchTft::rotate = { 41 | .header = rotate_header, 42 | .data_size = 576 * LV_COLOR_SIZE / 8, 43 | .data = rotate_map, 44 | }; 45 | -------------------------------------------------------------------------------- /main/WatchTft/run.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchTft.h" 2 | 3 | 4 | const uint8_t run_map[1728] = { 5 | /*Pixel format: Alpha 8 bit, Red: 5 bit, Green: 6 bit, Blue: 5 bit BUT the 2 color bytes are swapped*/ 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0xc1, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xba, 0x00, 0x00, 0xf4, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0xbd, 0x00, 0x00, 0xf7, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0xf3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xf7, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x08, 0x00, 0x00, 0xd4, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xc5, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0x00, 0x00, 0x43, 0x00, 0x00, 0xdb, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xac, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xc0, 0x00, 0x00, 0xff, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x73, 0x00, 0x00, 0xef, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x9e, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfd, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 30 | }; 31 | 32 | const lv_img_header_t run_header = { 33 | .cf = LV_IMG_CF_TRUE_COLOR_ALPHA, 34 | .always_zero = 0, 35 | .reserved = 0, 36 | .w = 24, 37 | .h = 24, 38 | }; 39 | 40 | const lv_img_dsc_t WatchTft::run = { 41 | .header = run_header, 42 | .data_size = 576 * LV_COLOR_SIZE / 8, 43 | .data = run_map, 44 | }; -------------------------------------------------------------------------------- /main/WatchWiFi/WatchWiFi.cpp: -------------------------------------------------------------------------------- 1 | #include "WatchWiFi.h" 2 | 3 | EventGroupHandle_t WatchWiFi::s_wifi_event_group = NULL; 4 | bool WatchWiFi::connected = false; 5 | bool WatchWiFi::enable = false; 6 | 7 | void WatchWiFi::init() 8 | { 9 | printf("WatchWiFi::init()\n"); 10 | 11 | s_wifi_event_group = xEventGroupCreate(); 12 | 13 | ESP_ERROR_CHECK(esp_netif_init()); 14 | 15 | ESP_ERROR_CHECK(esp_event_loop_create_default()); 16 | esp_netif_create_default_wifi_sta(); 17 | 18 | wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); 19 | ESP_ERROR_CHECK(esp_wifi_init(&cfg)); 20 | 21 | esp_event_handler_instance_t instance_any_id; 22 | esp_event_handler_instance_t instance_got_ip; 23 | ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, 24 | ESP_EVENT_ANY_ID, 25 | &event_handler, 26 | NULL, 27 | &instance_any_id)); 28 | ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, 29 | IP_EVENT_STA_GOT_IP, 30 | &event_handler, 31 | NULL, 32 | &instance_got_ip)); 33 | 34 | wifi_sta_config_t wifi_sta_config = {}; 35 | strcpy((char *)wifi_sta_config.ssid, WIFI_SSID); 36 | strcpy((char *)wifi_sta_config.password, WIFI_PASSWORD); 37 | 38 | wifi_config_t wifi_config = { 39 | .sta = wifi_sta_config, 40 | }; 41 | ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); 42 | ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); 43 | 44 | printf("wifi_init_sta finished.\n"); 45 | } 46 | 47 | void WatchWiFi::connect() 48 | { 49 | printf("WatchWiFi::connect\n"); 50 | ESP_ERROR_CHECK(esp_wifi_start()); 51 | } 52 | 53 | void WatchWiFi::disconnect() 54 | { 55 | printf("WatchWiFi::disconnect\n"); 56 | ESP_ERROR_CHECK(esp_wifi_stop()); 57 | } 58 | 59 | void WatchWiFi::event_handler(void *arg, esp_event_base_t event_base, 60 | int32_t event_id, void *event_data) 61 | { 62 | if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) 63 | { 64 | if (enable) 65 | { 66 | esp_wifi_connect(); 67 | } 68 | } 69 | else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) 70 | { 71 | 72 | printf("connect to the AP fail\n"); 73 | 74 | connected = false; 75 | WatchTft::set_wifi_state(enable, connected); 76 | if (enable) 77 | { 78 | esp_wifi_connect(); 79 | printf("retry to connect to the AP\n"); 80 | } 81 | } 82 | else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) 83 | { 84 | ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; 85 | printf("got ip:" IPSTR "\n", IP2STR(&event->ip_info.ip)); 86 | xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); 87 | connected = true; 88 | WatchTft::set_wifi_state(enable, connected); 89 | } 90 | } 91 | 92 | esp_err_t WatchWiFi::_http_event_handler(esp_http_client_event_t *evt) 93 | { 94 | static char *output_buffer; // Buffer to store response of http request from event handler 95 | static int output_len; // Stores number of bytes read 96 | switch (evt->event_id) 97 | { 98 | case HTTP_EVENT_ERROR: 99 | printf("HTTP_EVENT_ERROR\n"); 100 | break; 101 | case HTTP_EVENT_ON_CONNECTED: 102 | printf("HTTP_EVENT_ON_CONNECTED\n"); 103 | break; 104 | case HTTP_EVENT_HEADER_SENT: 105 | printf("HTTP_EVENT_HEADER_SENT\n"); 106 | break; 107 | case HTTP_EVENT_ON_HEADER: 108 | printf("HTTP_EVENT_ON_HEADER, key=%s, value=%s\n", evt->header_key, evt->header_value); 109 | break; 110 | case HTTP_EVENT_ON_DATA: 111 | printf("HTTP_EVENT_ON_DATA, len=%d\n", evt->data_len); 112 | /* 113 | * Check for chunked encoding is added as the URL for chunked encoding used in this example returns binary data. 114 | * However, event handler can also be used in case chunked encoding is used. 115 | */ 116 | if (!esp_http_client_is_chunked_response(evt->client)) 117 | { 118 | // If user_data buffer is configured, copy the response into the buffer 119 | if (evt->user_data) 120 | { 121 | memcpy(evt->user_data + output_len, evt->data, evt->data_len); 122 | } 123 | else 124 | { 125 | if (output_buffer == NULL) 126 | { 127 | output_buffer = (char *)malloc(esp_http_client_get_content_length(evt->client)); 128 | output_len = 0; 129 | if (output_buffer == NULL) 130 | { 131 | printf("Failed to allocate memory for output buffer\n"); 132 | return ESP_FAIL; 133 | } 134 | } 135 | memcpy(output_buffer + output_len, evt->data, evt->data_len); 136 | } 137 | output_len += evt->data_len; 138 | } 139 | 140 | break; 141 | case HTTP_EVENT_ON_FINISH: 142 | printf("HTTP_EVENT_ON_FINISH\n"); 143 | if (output_buffer != NULL) 144 | { 145 | // Response is accumulated in output_buffer. Uncomment the below line to print the accumulated response 146 | // ESP_LOG_BUFFER_HEX(TAG, output_buffer, output_len); 147 | free(output_buffer); 148 | output_buffer = NULL; 149 | } 150 | output_len = 0; 151 | break; 152 | case HTTP_EVENT_DISCONNECTED: 153 | printf("HTTP_EVENT_DISCONNECTED\n"); 154 | int mbedtls_err = 0; 155 | if (output_buffer != NULL) 156 | { 157 | free(output_buffer); 158 | output_buffer = NULL; 159 | } 160 | output_len = 0; 161 | break; 162 | } 163 | return ESP_OK; 164 | } 165 | 166 | void WatchWiFi::download_tile(int32_t x, int32_t y) 167 | { 168 | printf("download_tile: %d:%d\n", x, y); 169 | 170 | if (!connected) 171 | { 172 | printf("Can't download tile, not connected\n"); 173 | return; 174 | } 175 | char tile_url[60] = {}; 176 | sprintf(tile_url, "http://a.tile.openstreetmap.org/15/%u/%u.png", x, y); 177 | 178 | char tile_filename[60] = {}; 179 | sprintf(tile_filename, MOUNT_POINT "/map_15_%u_%u.png", x, y); 180 | 181 | FILE *f_tile = NULL; 182 | f_tile = fopen(tile_filename, "w"); 183 | 184 | char output_buffer[50] = {0}; // Buffer to store response of http request 185 | int content_length = 0; 186 | esp_http_client_config_t config = { 187 | .url = tile_url, 188 | }; 189 | esp_http_client_handle_t client = esp_http_client_init(&config); 190 | 191 | // GET Request 192 | esp_http_client_set_method(client, HTTP_METHOD_GET); 193 | esp_err_t err = esp_http_client_open(client, 0); 194 | if (err != ESP_OK) 195 | { 196 | printf("Failed to open HTTP connection: %s\n", esp_err_to_name(err)); 197 | } 198 | else 199 | { 200 | content_length = esp_http_client_fetch_headers(client); 201 | if (content_length < 0) 202 | { 203 | printf("HTTP client fetch headers failed\n"); 204 | } 205 | else 206 | { 207 | uint8_t body_data[1024] = {}; 208 | uint32_t size_writen = 0; 209 | int data_read = esp_http_client_read_response(client, (char *)body_data, sizeof(body_data)); 210 | if (data_read >= 0) 211 | { 212 | printf("HTTP GET Status = %d, content_length = %d, data_read = %d\n", 213 | esp_http_client_get_status_code(client), 214 | esp_http_client_get_content_length(client), 215 | data_read); 216 | if (f_tile != NULL) 217 | { 218 | fwrite(body_data, data_read, 1, f_tile); 219 | size_writen += data_read; 220 | while (data_read > 0) 221 | { 222 | data_read = esp_http_client_read_response(client, (char *)body_data, sizeof(body_data)); 223 | if (data_read > 0) 224 | { 225 | fwrite(body_data, data_read, 1, f_tile); 226 | size_writen += data_read; 227 | } 228 | } 229 | printf("Write tile file DONE: %u !!!\n", size_writen); 230 | } 231 | else 232 | { 233 | printf("f_tile NULL\n"); 234 | } 235 | } 236 | else 237 | { 238 | printf("Failed to read response\n"); 239 | } 240 | } 241 | } 242 | esp_http_client_close(client); 243 | 244 | esp_http_client_cleanup(client); 245 | 246 | fclose(f_tile); 247 | WatchTft::refresh_tile(x, y); 248 | } 249 | -------------------------------------------------------------------------------- /main/WatchWiFi/WatchWiFi.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "wifi_credentials.h" 3 | 4 | #ifndef WATCH_WIFI 5 | #define WATCH_WIFI 6 | 7 | #define WIFI_CONNECTED_BIT BIT0 8 | #define WIFI_FAIL_BIT BIT1 9 | 10 | class WatchWiFi 11 | { 12 | 13 | public: 14 | static EventGroupHandle_t s_wifi_event_group; 15 | static bool connected; 16 | static bool enable; 17 | 18 | static void init(); 19 | static void connect(); 20 | static void disconnect(); 21 | static void download_tile(int32_t x, int32_t y); 22 | 23 | private: 24 | static void event_handler(void *arg, esp_event_base_t event_base, 25 | int32_t event_id, void *event_data); 26 | 27 | static esp_err_t _http_event_handler(esp_http_client_event_t *evt); 28 | }; 29 | #endif -------------------------------------------------------------------------------- /main/WatchWiFi/wifi_credentials_example.h: -------------------------------------------------------------------------------- 1 | // Rename this file to "wifi_credentials.h" 2 | #define WIFI_SSID "ssid" 3 | #define WIFI_PASSWORD "password" -------------------------------------------------------------------------------- /main/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # "main" pseudo-component makefile. 3 | # 4 | # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) 5 | -------------------------------------------------------------------------------- /main/main.cpp: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #define TAG "main" 3 | 4 | SemaphoreHandle_t i2c_0_semaphore; 5 | uint32_t timer_last_touch = esp_timer_get_time() / 1000; 6 | uint32_t timer_turn_off_screen = 60000; 7 | extern "C" 8 | { 9 | void app_main(); 10 | } 11 | 12 | void app_main() 13 | { 14 | printf("begin !\n"); 15 | 16 | i2c_0_semaphore = xSemaphoreCreateMutex(); 17 | 18 | gpio_install_isr_service(0); 19 | 20 | WatchNvs::init(); 21 | WatchPower::init(); 22 | WatchSd::init(); 23 | WatchWiFi::init(); 24 | WatchTft::init(); 25 | WatchBma::init(); 26 | printf("*** INIT DONE ***\n"); 27 | vTaskDelay(4000); 28 | 29 | while (1) 30 | { 31 | if ((esp_timer_get_time() / 1000) - timer_last_touch > timer_turn_off_screen && WatchTft::screen_en) 32 | { 33 | WatchTft::turn_off_screen(); 34 | } 35 | BaseType_t err = xSemaphoreTake(i2c_0_semaphore, 500); 36 | if (err != pdTRUE) 37 | { 38 | printf("can't take i2c_sem from main\n"); 39 | continue; 40 | } 41 | 42 | float current_Batt = axpxx_getBattDischargeCurrent(); 43 | float current_Vbus = axpxx_getVbusCurrent(); 44 | xSemaphoreGive(i2c_0_semaphore); 45 | 46 | WatchTft::add_chart_power_value((lv_coord_t)current_Batt, (lv_coord_t)current_Vbus); 47 | vTaskDelay(1000); 48 | } 49 | } -------------------------------------------------------------------------------- /main/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "freertos/FreeRTOS.h" 12 | #include "freertos/task.h" 13 | #include "esp_freertos_hooks.h" 14 | #include "freertos/semphr.h" 15 | #include "esp_system.h" 16 | #include "driver/gpio.h" 17 | #include "esp_pm.h" 18 | #include "esp_sleep.h" 19 | #include "driver/uart.h" 20 | #include "freertos/queue.h" 21 | #include "freertos/event_groups.h" 22 | #include "nvs_flash.h" 23 | #include "nvs.h" 24 | #include "esp_vfs_fat.h" 25 | #include "sdmmc_cmd.h" 26 | #include "esp_wifi.h" 27 | #include "esp_event.h" 28 | #include "esp_http_client.h" 29 | #include 30 | 31 | // my classes 32 | #include "WatchTft.h" 33 | #include "WatchPower.h" 34 | #include "WatchBma.h" 35 | #include "WatchNvs.h" 36 | #include "WatchGps.h" 37 | #include "WatchSd.h" 38 | #include "home_gps.h" 39 | #include "WatchWiFi.h" 40 | 41 | // my cpp 42 | #include "C_AXP202X_Library/axp20x.h" 43 | 44 | #include "BMA423-Sensor-API/bma423.h" 45 | #include "BMA423-Sensor-API/examples/generic/common/bma4_common.h" 46 | 47 | extern SemaphoreHandle_t i2c_0_semaphore; 48 | extern uint32_t timer_turn_off_screen; 49 | 50 | #endif -------------------------------------------------------------------------------- /partitions.csv: -------------------------------------------------------------------------------- 1 | # Name, Type, SubType, Offset, Size, Flags 2 | # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap 3 | nvs, data, nvs, , 0x6000, 4 | phy_init, data, phy, , 0x1000, 5 | factory, app, factory, , 3M, -------------------------------------------------------------------------------- /sdkconfig.ci: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuDeprez/my_esp32_watch_base/a58f63192d21e1f8e1f0ea21eca9297de15efa18/sdkconfig.ci --------------------------------------------------------------------------------