├── .github └── workflows │ └── lv_sim.yml ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── README.md ├── cmake ├── FindFilesystem.cmake └── FindSDL2.cmake ├── external ├── miniz │ ├── CMakeLists.txt │ ├── ChangeLog.md │ ├── LICENSE │ ├── download-url.txt │ ├── examples │ │ ├── example1.c │ │ ├── example2.c │ │ ├── example3.c │ │ ├── example4.c │ │ ├── example5.c │ │ └── example6.c │ ├── miniz.c │ ├── miniz.h │ └── readme.md └── nlohmann_json │ ├── CMakeLists.txt │ └── include │ └── nlohmann │ └── json.hpp ├── gif-h ├── LICENSE ├── README.md ├── gif-h-demo.cpp └── gif.h ├── img ├── CMakeLists.txt ├── convert_bmp_to_header.py ├── sim_background.bmp └── sim_background.xcf ├── littlefs-do-main.cpp ├── lv_drv_conf.h ├── main.cpp └── sim ├── FreeRTOS.cpp ├── FreeRTOS.h ├── components ├── battery │ ├── BatteryController.cpp │ └── BatteryController.h ├── ble │ ├── NimbleController.cpp │ └── NimbleController.h ├── brightness │ ├── BrightnessController.cpp │ └── BrightnessController.h ├── firmwarevalidator │ ├── FirmwareValidator.cpp │ └── FirmwareValidator.h └── heartrate │ ├── HeartRateController.cpp │ └── HeartRateController.h ├── displayapp ├── LittleVgl.cpp └── LittleVgl.h ├── drivers ├── Bma421.cpp ├── Bma421.h ├── Cst816s.cpp ├── Cst816s.h ├── SpiMaster.cpp ├── SpiMaster.h ├── SpiNorFlash.cpp ├── SpiNorFlash.h ├── TwiMaster.cpp └── TwiMaster.h ├── heartratetask ├── HeartRateTask.cpp └── HeartRateTask.h ├── host ├── ble_att.h ├── ble_gap.h ├── ble_gatt.cpp ├── ble_gatt.h ├── ble_hs_mbuf.cpp ├── ble_hs_mbuf.h ├── ble_uuid.cpp ├── ble_uuid.h ├── os_mbuf.cpp └── os_mbuf.h ├── libraries ├── delay │ ├── nrf_delay.cpp │ └── nrf_delay.h ├── gpiote │ └── app_gpiote.h └── log │ └── nrf_log.h ├── nrf_assert.h ├── nrfx ├── drivers │ └── include │ │ └── nrfx_twi.h ├── hal │ ├── nrf_gpio.cpp │ ├── nrf_gpio.h │ ├── nrf_rtc.cpp │ ├── nrf_rtc.h │ └── nrfx_gpiote.h ├── mdk │ ├── nrf.h │ ├── nrf52.cpp │ ├── nrf52.h │ └── nrf52_bitfields.h └── nrfx_log.h ├── portmacro_cmsis.cpp ├── portmacro_cmsis.h ├── projdefs.h ├── queue.cpp ├── queue.h ├── semphr.cpp ├── semphr.h ├── task.cpp ├── task.h ├── timers.cpp └── timers.h /.github/workflows/lv_sim.yml: -------------------------------------------------------------------------------- 1 | # GitHub Actions Workflow to build Simulator for PineTime Smart Watch LVGL Interface 2 | 3 | # Name of this Workflow 4 | name: Build InfiniSim LVGL Simulator 5 | 6 | # When to run this Workflow... 7 | on: 8 | 9 | # Run on all branches 10 | push: 11 | branches: [] 12 | 13 | # Also run this Workflow when a Pull Request is created or updated in the "main" and "develop" Branch 14 | pull_request: 15 | branches: [ main, develop ] 16 | 17 | # Steps to run for the Workflow 18 | jobs: 19 | build: 20 | 21 | # Run these steps on Ubuntu 22 | runs-on: ubuntu-latest 23 | 24 | steps: 25 | 26 | ######################################################################################### 27 | # Download and Install Dependencies 28 | 29 | - name: Install cmake 30 | uses: lukka/get-cmake@v3.18.3 31 | 32 | - name: Install SDL2 and libpng development package 33 | run: | 34 | sudo apt-get update 35 | sudo apt-get -y install libsdl2-dev libpng-dev 36 | 37 | - name: Install resource build dependencies 38 | run: | 39 | sudo apt-get -y install --no-install-recommends python3-pil 40 | 41 | - name: Install lv_font_conv 42 | run: 43 | npm i -g lv_font_conv@1.5.2 44 | 45 | ######################################################################################### 46 | # Checkout 47 | 48 | - name: Checkout source files 49 | uses: actions/checkout@v4 50 | with: 51 | submodules: recursive 52 | 53 | ######################################################################################### 54 | # CMake 55 | 56 | - name: CMake 57 | run: | 58 | cmake -G Ninja -S . -B build_lv_sim 59 | 60 | ######################################################################################### 61 | # Build and Upload simulator 62 | 63 | # For Debugging Builds: Remove "make" option "-j" for clearer output. Add "--trace" to see details. 64 | # For Faster Builds: Add "make" option "-j" 65 | 66 | - name: Build simulator executable 67 | run: | 68 | cmake --build build_lv_sim 69 | 70 | - name: Upload simulator executable 71 | uses: actions/upload-artifact@v4 72 | with: 73 | name: infinisim 74 | path: build_lv_sim/infinisim 75 | 76 | - name: Upload littlefs-do executable 77 | uses: actions/upload-artifact@v4 78 | with: 79 | name: littlefs-do 80 | path: build_lv_sim/littlefs-do 81 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | # Python virtual environment for DFU images 3 | .venv/ 4 | 5 | # CMake 6 | cmake-build-* 7 | cmake-*/ 8 | CMakeFiles 9 | **/CMakeCache.txt 10 | cmake_install.cmake 11 | Makefile 12 | build 13 | _build*/ 14 | tools 15 | 16 | # Resulting binary files 17 | *.a 18 | *.so 19 | *.s 20 | *.hex 21 | *.bin 22 | !bootloader/bootloader-5.0.4.bin 23 | *.map 24 | *.out 25 | pinetime*.cbp 26 | 27 | # InfiniTime's files 28 | core 29 | sdk 30 | src/Version.h 31 | docker/post_build.sh 32 | Testing/Temporary/ 33 | 34 | # Linux 35 | **/.directory 36 | **/*.swp 37 | 38 | # OSX/MacOS 39 | **/.DS_Store 40 | 41 | # Windows 42 | **/thumbs.db 43 | 44 | #VSCODE 45 | .vscode/.cortex-debug.registers.state.json 46 | .vscode/.cortex-debug.peripherals.state.json 47 | 48 | #build files 49 | src/nRF5_SDK_15.3.0_59ac345 50 | src/arm-none-eabi 51 | 52 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "InfiniTime"] 2 | path = InfiniTime 3 | url = ../../InfiniTimeOrg/InfiniTime.git 4 | [submodule "lv_drivers"] 5 | path = lv_drivers 6 | url = ../../lvgl/lv_drivers.git 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [InfiniSim](https://github.com/InfiniTimeOrg/InfiniSim) 2 | 3 | [![Build InfiniSim LVGL Simulator](https://github.com/InfiniTimeOrg/InfiniSim/actions/workflows/lv_sim.yml/badge.svg)](https://github.com/InfiniTimeOrg/InfiniSim/actions/workflows/lv_sim.yml) 4 | 5 | Simulator for [InfiniTime](https://github.com/InfiniTimeOrg/InfiniTime) project. 6 | 7 | Experience the `InfiniTime` user interface directly on your PC, to shorten the time until you get your hands on a real [PineTime smartwatch](https://www.pine64.org/pinetime/). 8 | Or use it to develop new Watchfaces, new Screens, or quickly iterate on the user interface. 9 | 10 | For a history on how this simulator started and the challenges on its way visit the [original PR](https://github.com/InfiniTimeOrg/InfiniTime/pull/743). 11 | 12 | ## Get the Sources 13 | 14 | Clone this repository and tell `git` to recursively download the submodules as well 15 | 16 | ```sh 17 | git clone --recursive https://github.com/InfiniTimeOrg/InfiniSim.git 18 | ``` 19 | 20 | If you've already cloned the repository without the submodules (or you want to update them to the latest checked in version) run the following command: 21 | 22 | ```sh 23 | git submodule update --init --recursive 24 | ``` 25 | 26 | ## Build dependencies 27 | 28 | - CMake 29 | - SDL2 (provides the simulator window, handles mouse and keyboard input) 30 | - Compiler (g++ or clang++) 31 | - [lv_font_conv](https://github.com/lvgl/lv_font_conv#install-the-script) (for `font.c` generation since [InfiniTime#1097](https://github.com/InfiniTimeOrg/InfiniTime/pull/1097)) 32 | - Note: requires Node.js v14.0.0 or later 33 | - [Pillow](https://python-pillow.org/) (for `resource.zip` generation when `BUILD_RESOURCES=ON`, which is the default) 34 | - optional: `libpng`, see `-DWITH_PNG=ON` cmake setting below for more info 35 | 36 | On Ubuntu/Debian install the following packages: 37 | 38 | ```sh 39 | sudo apt install -y cmake libsdl2-dev g++ npm libpng-dev 40 | ``` 41 | 42 | On Arch Linux the following packages are needed: 43 | 44 | ```sh 45 | sudo pacman -S cmake sdl2 gcc npm libpng 46 | ``` 47 | 48 | On Fedora the following packages are needed: 49 | 50 | ```sh 51 | sudo dnf install cmake SDL2-devel g++ npm patch perl libpng-devel 52 | ``` 53 | 54 | On OpenSUSE (Tumbleweed) the following packages are needed: 55 | 56 | ```sh 57 | sudo zypper install cmake libSDL2-devel gcc-c++ gcc npm libpng16-devel patch 58 | ``` 59 | 60 | Then install the `lv_font_conv` executable to the InfiniSim source directory (will be installed at `node_modules/.bin/lv_font_conv`) 61 | 62 | ```sh 63 | npm install lv_font_conv@1.5.2 64 | ``` 65 | 66 | When you want to create a `resource.zip` file then install the `pillow` Python library to the InfiniSim source directory (will be installed in `.venv/`) 67 | 68 | ```sh 69 | python3 -m venv .venv 70 | source .venv/bin/activate 71 | pip install wheel Pillow 72 | ``` 73 | 74 | Optionally, depending on your distro, it may also serve the Pip package as official native installation packages: 75 | 76 | On Ubuntu/Debian 77 | 78 | ```sh 79 | sudo apt install python3-pil 80 | ``` 81 | 82 | On OpenSUSE (Tumbleweed) 83 | 84 | ```sh 85 | sudo zypper install python311-Pillow 86 | ``` 87 | 88 | ## Configure and Build 89 | 90 | In the most basic configuration tell cmake to configure the project and build it with the following two commands: 91 | 92 | ```sh 93 | cmake -S . -B build 94 | cmake --build build -j4 95 | ``` 96 | 97 | The following configuration settings can be added to the first `cmake -S . -B build` call 98 | 99 | - `-DInfiniTime_DIR=InfiniTime`: a full path to an existing InfiniTime repository checked out. 100 | Inside that directory the `src/libs/lvgl` submodule must be checked out as well. 101 | The default value points to the InfiniTime submodule in this repository. 102 | - `-DMONITOR_ZOOM=1`: scale simulator window by this factor 103 | - `-DBUILD_RESOURCES=ON`: enable/disable `resource.zip` creation, will be created in the `/resources` folder 104 | - `-DWITH_PNG=ON`: enable/disable the screenshot to `PNG` support. 105 | Per default InfiniSim tries to use `libpng` to create screenshots in PNG format. 106 | This requires `libpng` development libraries as build and runtime dependency. 107 | Can be disabled with cmake config setting `-DWITH_PNG=OFF`. 108 | - `-DENABLE_USERAPPS`: ordered list of user applications to build into InfiniTime. 109 | Values must be fields from the enumeration `Pinetime::Applications::Apps` and must be separated by a comma. 110 | Ex: `-DENABLE_USERAPPS="Apps::Timer, Apps::Alarm"`. 111 | The default list of user applications will be selected if this variable is not set. 112 | 113 | ## Run Simulator 114 | 115 | When the build was successful the simulator binary can be started with 116 | 117 | ```sh 118 | ./build/infinisim 119 | ``` 120 | 121 | ![Running Simulator](https://user-images.githubusercontent.com/9076163/151057090-66fa6b10-eb4f-4b62-88e6-f9f307a57e40.gif) 122 | 123 | To hide the second simulator-status-window start the binary with the `--hide-status` option 124 | 125 | ```sh 126 | ./build/infinisim --hide-status 127 | ``` 128 | 129 | - Left mouse button: simulates your finger, just click to tap, click and drag to swipe 130 | - Right mouse button: simulates the hardware button (for example turn the screen off or on again) 131 | 132 | Using the keyboard the following events can be triggered: 133 | 134 | - `r` ... enable ringing 135 | - `R` ... disable ringing 136 | - `m` ... let motor run for 100 ms 137 | - `M` ... let motor run for 255 ms 138 | - `n` ... send notification 139 | - `N` ... clear new notification flag 140 | - `b` ... connect Bluetooth 141 | - `B` ... disconnect Bluetooth 142 | - `v` ... increase battery voltage and percentage 143 | - `V` ... decrease battery voltage and percentage 144 | - `c` ... charging, 145 | - `C` ... not charging 146 | - `l` ... increase brightness level 147 | - `L` ... lower brightness level 148 | - `p` ... enable print lvgl memory usage to terminal 149 | - `P` ... disable print memory usage 150 | - `s` ... increase step count by 500 steps 151 | - `S` ... decrease step count by 500 steps 152 | - `h` ... set heartrate running, and on further presses increase by 10 bpm 153 | - `H` ... stop heartrate 154 | - `i` ... take screenshot 155 | - `I` ... start/stop Gif screen capture 156 | - `w` ... generate weather data 157 | - `W` ... clear weather data 158 | 159 | Additionally using the arrow keys the respective swipe gesture can be triggered. 160 | For example pressing the UP key triggers a `SwipeUp` gesture. 161 | 162 | ## Littlefs-do helper 163 | 164 | To help working with the SPI-raw file the tool `littlefs-do` is provided (in the build directory). 165 | The SPI-raw file emulates the persistent 4MB storage available over the SPI bus on the PineTime. 166 | 167 | ```sh 168 | $ ./littlefs-do --help 169 | Usage: ./littlefs-do [options] 170 | Commands: 171 | -h, --help show this help message for the selected command and exit 172 | -v, --verbose print status messages to the console 173 | stat show information of specified file or directory 174 | ls list available files in 'spiNorFlash.raw' file 175 | mkdir create directory 176 | rmdir remove directory 177 | rm remove directory or file 178 | cp copy files into or out of flash file 179 | settings list settings from 'settings.h' 180 | res resource.zip handling 181 | ``` 182 | 183 | ### Resource loading 184 | 185 | To load resource zip files into the SPI raw file for the simulator to use the `res load` command can be used. 186 | 187 | ```sh 188 | $ ./littlefs-do res --help 189 | Usage: ./littlefs-do res [options] 190 | actions: 191 | load res.zip load zip file into SPI memory 192 | Options: 193 | -h, --help show this help message for the selected command and exit 194 | ``` 195 | 196 | ## Licenses 197 | 198 | This project is released under the GNU General Public License version 3 or, at your option, any later version. 199 | The same license as [InfiniTime](https://github.com/InfiniTimeOrg/InfiniTime). 200 | 201 | The simulator is based on [lv_sim_eclipse_sdl](https://github.com/lvgl/lv_sim_eclipse_sdl) project under the MIT license. 202 | -------------------------------------------------------------------------------- /cmake/FindFilesystem.cmake: -------------------------------------------------------------------------------- 1 | # Verbatim copy of https://github.com/lethal-guitar/RigelEngine/blob/011976b3feb35a7f038e9fe10c622e818b417e45/cmake/Modules/FindFilesystem.cmake 2 | 3 | # START OF FILE 4 | 5 | # Distributed under the OSI-approved BSD 3-Clause License. See accompanying 6 | # file Copyright.txt or https://cmake.org/licensing for details. 7 | 8 | # This is copied from: 9 | # https://github.com/vector-of-bool/CMakeCM/blob/master/modules/FindFilesystem.cmake 10 | 11 | #[=======================================================================[.rst: 12 | 13 | FindFilesystem 14 | ############## 15 | 16 | This module supports the C++17 standard library's filesystem utilities. Use the 17 | :imp-target:`std::filesystem` imported target to 18 | 19 | Options 20 | ******* 21 | 22 | The ``COMPONENTS`` argument to this module supports the following values: 23 | 24 | .. find-component:: Experimental 25 | :name: fs.Experimental 26 | 27 | Allows the module to find the "experimental" Filesystem TS version of the 28 | Filesystem library. This is the library that should be used with the 29 | ``std::experimental::filesystem`` namespace. 30 | 31 | .. find-component:: Final 32 | :name: fs.Final 33 | 34 | Finds the final C++17 standard version of the filesystem library. 35 | 36 | If no components are provided, behaves as if the 37 | :find-component:`fs.Final` component was specified. 38 | 39 | If both :find-component:`fs.Experimental` and :find-component:`fs.Final` are 40 | provided, first looks for ``Final``, and falls back to ``Experimental`` in case 41 | of failure. If ``Final`` is found, :imp-target:`std::filesystem` and all 42 | :ref:`variables ` will refer to the ``Final`` version. 43 | 44 | 45 | Imported Targets 46 | **************** 47 | 48 | .. imp-target:: std::filesystem 49 | 50 | The ``std::filesystem`` imported target is defined when any requested 51 | version of the C++ filesystem library has been found, whether it is 52 | *Experimental* or *Final*. 53 | 54 | If no version of the filesystem library is available, this target will not 55 | be defined. 56 | 57 | .. note:: 58 | This target has ``cxx_std_17`` as an ``INTERFACE`` 59 | :ref:`compile language standard feature `. Linking 60 | to this target will automatically enable C++17 if no later standard 61 | version is already required on the linking target. 62 | 63 | 64 | .. _fs.variables: 65 | 66 | Variables 67 | ********* 68 | 69 | .. variable:: CXX_FILESYSTEM_IS_EXPERIMENTAL 70 | 71 | Set to ``TRUE`` when the :find-component:`fs.Experimental` version of C++ 72 | filesystem library was found, otherwise ``FALSE``. 73 | 74 | .. variable:: CXX_FILESYSTEM_HAVE_FS 75 | 76 | Set to ``TRUE`` when a filesystem header was found. 77 | 78 | .. variable:: CXX_FILESYSTEM_HEADER 79 | 80 | Set to either ``filesystem`` or ``experimental/filesystem`` depending on 81 | whether :find-component:`fs.Final` or :find-component:`fs.Experimental` was 82 | found. 83 | 84 | .. variable:: CXX_FILESYSTEM_NAMESPACE 85 | 86 | Set to either ``std::filesystem`` or ``std::experimental::filesystem`` 87 | depending on whether :find-component:`fs.Final` or 88 | :find-component:`fs.Experimental` was found. 89 | 90 | 91 | Examples 92 | ******** 93 | 94 | Using `find_package(Filesystem)` with no component arguments: 95 | 96 | .. code-block:: cmake 97 | 98 | find_package(Filesystem REQUIRED) 99 | 100 | add_executable(my-program main.cpp) 101 | target_link_libraries(my-program PRIVATE std::filesystem) 102 | 103 | 104 | #]=======================================================================] 105 | 106 | 107 | if(TARGET std::filesystem) 108 | # This module has already been processed. Don't do it again. 109 | return() 110 | endif() 111 | 112 | cmake_policy(PUSH) 113 | if(POLICY CMP0067) 114 | # pass CMAKE_CXX_STANDARD to check_cxx_source_compiles() 115 | # has to appear before including CheckCXXSourceCompiles module 116 | cmake_policy(SET CMP0067 NEW) 117 | endif() 118 | 119 | include(CMakePushCheckState) 120 | include(CheckIncludeFileCXX) 121 | include(CheckCXXSourceCompiles) 122 | 123 | cmake_push_check_state() 124 | 125 | set(CMAKE_REQUIRED_QUIET ${Filesystem_FIND_QUIETLY}) 126 | 127 | # All of our tests required C++17 or later 128 | set(CMAKE_CXX_STANDARD 17) 129 | 130 | # Normalize and check the component list we were given 131 | set(want_components ${Filesystem_FIND_COMPONENTS}) 132 | if(Filesystem_FIND_COMPONENTS STREQUAL "") 133 | set(want_components Final) 134 | endif() 135 | 136 | # Warn on any unrecognized components 137 | set(extra_components ${want_components}) 138 | list(REMOVE_ITEM extra_components Final Experimental) 139 | foreach(component IN LISTS extra_components) 140 | message(WARNING "Extraneous find_package component for Filesystem: ${component}") 141 | endforeach() 142 | 143 | # Detect which of Experimental and Final we should look for 144 | set(find_experimental TRUE) 145 | set(find_final TRUE) 146 | if(NOT "Final" IN_LIST want_components) 147 | set(find_final FALSE) 148 | endif() 149 | if(NOT "Experimental" IN_LIST want_components) 150 | set(find_experimental FALSE) 151 | endif() 152 | 153 | if(find_final) 154 | check_include_file_cxx("filesystem" _CXX_FILESYSTEM_HAVE_HEADER) 155 | mark_as_advanced(_CXX_FILESYSTEM_HAVE_HEADER) 156 | if(_CXX_FILESYSTEM_HAVE_HEADER) 157 | # We found the non-experimental header. Don't bother looking for the 158 | # experimental one. 159 | set(find_experimental FALSE) 160 | endif() 161 | else() 162 | set(_CXX_FILESYSTEM_HAVE_HEADER FALSE) 163 | endif() 164 | 165 | if(find_experimental) 166 | check_include_file_cxx("experimental/filesystem" _CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER) 167 | mark_as_advanced(_CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER) 168 | else() 169 | set(_CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER FALSE) 170 | endif() 171 | 172 | if(_CXX_FILESYSTEM_HAVE_HEADER) 173 | set(_have_fs TRUE) 174 | set(_fs_header filesystem) 175 | set(_fs_namespace std::filesystem) 176 | elseif(_CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER) 177 | set(_have_fs TRUE) 178 | set(_fs_header experimental/filesystem) 179 | set(_fs_namespace std::experimental::filesystem) 180 | else() 181 | set(_have_fs FALSE) 182 | endif() 183 | 184 | set(CXX_FILESYSTEM_HAVE_FS ${_have_fs} CACHE BOOL "TRUE if we have the C++ filesystem headers") 185 | set(CXX_FILESYSTEM_HEADER ${_fs_header} CACHE STRING "The header that should be included to obtain the filesystem APIs") 186 | set(CXX_FILESYSTEM_NAMESPACE ${_fs_namespace} CACHE STRING "The C++ namespace that contains the filesystem APIs") 187 | 188 | set(_found FALSE) 189 | 190 | if(CXX_FILESYSTEM_HAVE_FS) 191 | # We have some filesystem library available. Do link checks 192 | string(CONFIGURE [[ 193 | #include <@CXX_FILESYSTEM_HEADER@> 194 | 195 | int main() { 196 | auto cwd = @CXX_FILESYSTEM_NAMESPACE@::current_path(); 197 | return static_cast(cwd.string().size()); 198 | } 199 | ]] code @ONLY) 200 | 201 | # Try to compile a simple filesystem program without any linker flags 202 | check_cxx_source_compiles("${code}" CXX_FILESYSTEM_NO_LINK_NEEDED) 203 | 204 | set(can_link ${CXX_FILESYSTEM_NO_LINK_NEEDED}) 205 | 206 | if(NOT CXX_FILESYSTEM_NO_LINK_NEEDED) 207 | set(prev_libraries ${CMAKE_REQUIRED_LIBRARIES}) 208 | # Add the libstdc++ flag 209 | set(CMAKE_REQUIRED_LIBRARIES ${prev_libraries} -lstdc++fs) 210 | check_cxx_source_compiles("${code}" CXX_FILESYSTEM_STDCPPFS_NEEDED) 211 | set(can_link ${CXX_FILESYSTEM_STDCPPFS_NEEDED}) 212 | if(NOT CXX_FILESYSTEM_STDCPPFS_NEEDED) 213 | # Try the libc++ flag 214 | set(CMAKE_REQUIRED_LIBRARIES ${prev_libraries} -lc++fs) 215 | check_cxx_source_compiles("${code}" CXX_FILESYSTEM_CPPFS_NEEDED) 216 | set(can_link ${CXX_FILESYSTEM_CPPFS_NEEDED}) 217 | endif() 218 | endif() 219 | 220 | if(can_link) 221 | add_library(std::filesystem INTERFACE IMPORTED) 222 | target_compile_features(std::filesystem INTERFACE cxx_std_17) 223 | set(_found TRUE) 224 | if(CXX_FILESYSTEM_NO_LINK_NEEDED) 225 | # on certain linux distros we have a version of libstdc++ which has the final code for c++17 fs in the 226 | # libstdc++.so.*. BUT when compiling with g++ < 9, we MUST still link with libstdc++fs.a 227 | # libc++ should not suffer from this issue, so, in theory we should be fine with only checking for 228 | # GCC's libstdc++ 229 | if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0.0")) 230 | target_link_libraries(std::filesystem INTERFACE -lstdc++fs) 231 | endif() 232 | elseif(CXX_FILESYSTEM_STDCPPFS_NEEDED) 233 | target_link_libraries(std::filesystem INTERFACE -lstdc++fs) 234 | elseif(CXX_FILESYSTEM_CPPFS_NEEDED) 235 | target_link_libraries(std::filesystem INTERFACE -lc++fs) 236 | endif() 237 | endif() 238 | endif() 239 | 240 | cmake_pop_check_state() 241 | 242 | set(Filesystem_FOUND ${_found} CACHE BOOL "TRUE if we can compile and link a program using std::filesystem" FORCE) 243 | 244 | if(Filesystem_FIND_REQUIRED AND NOT Filesystem_FOUND) 245 | message(FATAL_ERROR "Cannot Compile simple program using std::filesystem") 246 | endif() 247 | 248 | cmake_policy(POP) 249 | -------------------------------------------------------------------------------- /cmake/FindSDL2.cmake: -------------------------------------------------------------------------------- 1 | # Module: FindSDL2.cmake 2 | # Based on: https://github.com/mosra/magnum/blob/master/modules/FindSDL2.cmake 3 | # 4 | # Exports: 5 | # SDL2::SDL2 - Imported target 6 | # SDL2_FOUND - True if SDL2 was found. 7 | # 8 | # Additionally these variables are defined for internal usage: 9 | # 10 | # SDL2_LIBRARY_DEBUG - SDL2 debug library, if found 11 | # SDL2_LIBRARY_RELEASE - SDL2 release library, if found 12 | # SDL2_DLL_DEBUG - SDL2 debug DLL on Windows, if found 13 | # SDL2_DLL_RELEASE - SDL2 release DLL on Windows, if found 14 | # SDL2_INCLUDE_DIR - Root include dir 15 | 16 | set(_SDL2_PATH_SUFFIXES SDL2) 17 | if(WIN32) 18 | # Precompiled libraries for MSVC are in x86/x64 subdirectories 19 | if(MSVC) 20 | if(CMAKE_SIZEOF_VOID_P EQUAL 8) 21 | set(_SDL2_LIBRARY_PATH_SUFFIX lib/x64) 22 | elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) 23 | set(_SDL2_LIBRARY_PATH_SUFFIX lib/x86) 24 | endif() 25 | 26 | # Both includes and libraries for MinGW are in some directory deep 27 | # inside. There's also a CMake config file but it has HARDCODED path 28 | # to /opt/local/i686-w64-mingw32, which doesn't make ANY SENSE, 29 | # especially on Windows. 30 | elseif(MINGW) 31 | if(CMAKE_SIZEOF_VOID_P EQUAL 8) 32 | set(_SDL2_LIBRARY_PATH_SUFFIX x86_64-w64-mingw32/lib) 33 | set(_SDL2_RUNTIME_PATH_SUFFIX x86_64-w64-mingw32/bin) 34 | list(APPEND _SDL2_PATH_SUFFIXES x86_64-w64-mingw32/include/SDL2) 35 | elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) 36 | set(_SDL2_LIBRARY_PATH_SUFFIX i686-w64-mingw32/lib) 37 | set(_SDL2_RUNTIME_PATH_SUFFIX i686-w64-mingw32/lib) 38 | list(APPEND _SDL2_PATH_SUFFIXES i686-w64-mingw32/include/SDL2) 39 | endif() 40 | else() 41 | message(FATAL_ERROR "Unsupported compiler") 42 | endif() 43 | endif() 44 | 45 | find_library(SDL2_LIBRARY_RELEASE 46 | NAMES SDL2-2.0 SDL2 47 | PATH_SUFFIXES ${_SDL2_LIBRARY_PATH_SUFFIX}) 48 | find_library(SDL2_LIBRARY_DEBUG 49 | NAMES SDL2d 50 | PATH_SUFFIXES ${_SDL2_LIBRARY_PATH_SUFFIX}) 51 | 52 | set(SDL2_LIBRARY_NEEDED SDL2_LIBRARY) 53 | 54 | include(SelectLibraryConfigurations) 55 | select_library_configurations(SDL2) 56 | 57 | # Include dir 58 | find_path(SDL2_INCLUDE_DIR 59 | # We must search file which is present only in SDL2 and not in SDL1. 60 | # Apparently when both SDL.h and SDL_scancode.h are specified, CMake is 61 | # happy enough that it found SDL.h and doesn't bother about the other. 62 | # 63 | # On macOS, where the includes are not in SDL2/SDL.h form (which would 64 | # solve this issue), but rather SDL2.framework/Headers/SDL.h, CMake might 65 | # find SDL.framework/Headers/SDL.h if SDL1 is installed, which is wrong. 66 | NAMES SDL_scancode.h 67 | PATH_SUFFIXES ${_SDL2_PATH_SUFFIXES}) 68 | 69 | if(WIN32) 70 | find_file(SDL2_DLL_RELEASE 71 | NAMES SDL2.dll 72 | PATH_SUFFIXES ${_SDL2_RUNTIME_PATH_SUFFIX} ${_SDL2_LIBRARY_PATH_SUFFIX}) 73 | find_file(SDL2_DLL_DEBUG 74 | NAMES SDL2d.dll 75 | PATH_SUFFIXES ${_SDL2_RUNTIME_PATH_SUFFIX} ${_SDL2_LIBRARY_PATH_SUFFIX}) 76 | endif() 77 | 78 | include(FindPackageHandleStandardArgs) 79 | find_package_handle_standard_args("SDL2" DEFAULT_MSG 80 | ${SDL2_LIBRARY_NEEDED} 81 | ${_SDL2_FRAMEWORK_LIBRARY_NAMES} 82 | SDL2_INCLUDE_DIR) 83 | 84 | if(NOT TARGET SDL2::SDL2) 85 | if(SDL2_LIBRARY_NEEDED) 86 | add_library(SDL2::SDL2 UNKNOWN IMPORTED) 87 | 88 | # Work around BUGGY framework support on macOS 89 | # https://cmake.org/Bug/view.php?id=14105 90 | if(APPLE AND SDL2_LIBRARY_RELEASE MATCHES "\\.framework$") 91 | set_property(TARGET SDL2::SDL2 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) 92 | set_property(TARGET SDL2::SDL2 PROPERTY IMPORTED_LOCATION_RELEASE ${SDL2_LIBRARY_RELEASE}/SDL2) 93 | else() 94 | if(SDL2_LIBRARY_RELEASE) 95 | set_property(TARGET SDL2::SDL2 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) 96 | set_property(TARGET SDL2::SDL2 PROPERTY IMPORTED_LOCATION_RELEASE ${SDL2_LIBRARY_RELEASE}) 97 | endif() 98 | 99 | if(SDL2_LIBRARY_DEBUG) 100 | set_property(TARGET SDL2::SDL2 APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) 101 | set_property(TARGET SDL2::SDL2 PROPERTY IMPORTED_LOCATION_DEBUG ${SDL2_LIBRARY_DEBUG}) 102 | endif() 103 | endif() 104 | 105 | # Link additional `dl` and `pthread` libraries required by a static 106 | # build of SDL on Unixy platforms (except Apple, where it is most 107 | # probably some frameworks instead) 108 | if(UNIX AND NOT APPLE AND (SDL2_LIBRARY_DEBUG MATCHES "${CMAKE_STATIC_LIBRARY_SUFFIX}$" OR SDL2_LIBRARY_RELEASE MATCHES "${CMAKE_STATIC_LIBRARY_SUFFIX}$")) 109 | find_package(Threads REQUIRED) 110 | set_property(TARGET SDL2::SDL2 APPEND PROPERTY 111 | INTERFACE_LINK_LIBRARIES Threads::Threads ${CMAKE_DL_LIBS}) 112 | endif() 113 | 114 | # Windows dependencies for a static library. Unfortunately there's no 115 | # easy way to figure out if a *.lib is static or dynamic, so we're 116 | # adding only if a DLL is not found. 117 | if(WIN32 AND NOT SDL2_DLL_RELEASE AND NOT SDL2_DLL_DEBUG) 118 | set_property(TARGET SDL2::SDL2 APPEND PROPERTY INTERFACE_LINK_LIBRARIES 119 | # https://github.com/SDL-mirror/SDL/blob/release-2.0.10/CMakeLists.txt#L1338 120 | user32 gdi32 winmm imm32 ole32 oleaut32 version uuid advapi32 setupapi shell32 121 | # https://github.com/SDL-mirror/SDL/blob/release-2.0.10/CMakeLists.txt#L1384 122 | dinput8) 123 | # https://github.com/SDL-mirror/SDL/blob/release-2.0.10/CMakeLists.txt#L1422 124 | # additionally has dxerr for MSVC if DirectX SDK is not used, but 125 | # according to https://walbourn.github.io/wheres-dxerr-lib/ this 126 | # thing is long deprecated. 127 | if(MINGW) 128 | set_property(TARGET SDL2::SDL2 APPEND PROPERTY INTERFACE_LINK_LIBRARIES 129 | # https://github.com/SDL-mirror/SDL/blob/release-2.0.10/CMakeLists.txt#L1386 130 | dxerr8 131 | # https://github.com/SDL-mirror/SDL/blob/release-2.0.10/CMakeLists.txt#L1388 132 | mingw32) 133 | endif() 134 | endif() 135 | 136 | else() 137 | add_library(SDL2::SDL2 INTERFACE IMPORTED) 138 | endif() 139 | 140 | set_property(TARGET SDL2::SDL2 PROPERTY 141 | INTERFACE_INCLUDE_DIRECTORIES ${SDL2_INCLUDE_DIR}) 142 | endif() 143 | 144 | mark_as_advanced(SDL2_INCLUDE_DIR) -------------------------------------------------------------------------------- /external/miniz/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_library(miniz STATIC 3 | miniz.h 4 | miniz.c 5 | ) 6 | target_include_directories(miniz PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") 7 | -------------------------------------------------------------------------------- /external/miniz/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013-2014 RAD Game Tools and Valve Software 2 | Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC 3 | 4 | All Rights Reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /external/miniz/download-url.txt: -------------------------------------------------------------------------------- 1 | https://github.com/richgel999/miniz/releases/tag/2.2.0 2 | -------------------------------------------------------------------------------- /external/miniz/examples/example1.c: -------------------------------------------------------------------------------- 1 | // example1.c - Demonstrates miniz.c's compress() and uncompress() functions (same as zlib's). 2 | // Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. 3 | #include 4 | #include "miniz.h" 5 | typedef unsigned char uint8; 6 | typedef unsigned short uint16; 7 | typedef unsigned int uint; 8 | 9 | // The string to compress. 10 | static const char *s_pStr = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 11 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 12 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 13 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 14 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 15 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 16 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."; 17 | 18 | int main(int argc, char *argv[]) 19 | { 20 | uint step = 0; 21 | int cmp_status; 22 | uLong src_len = (uLong)strlen(s_pStr); 23 | uLong cmp_len = compressBound(src_len); 24 | uLong uncomp_len = src_len; 25 | uint8 *pCmp, *pUncomp; 26 | uint total_succeeded = 0; 27 | (void)argc, (void)argv; 28 | 29 | printf("miniz.c version: %s\n", MZ_VERSION); 30 | 31 | do 32 | { 33 | // Allocate buffers to hold compressed and uncompressed data. 34 | pCmp = (mz_uint8 *)malloc((size_t)cmp_len); 35 | pUncomp = (mz_uint8 *)malloc((size_t)src_len); 36 | if ((!pCmp) || (!pUncomp)) 37 | { 38 | printf("Out of memory!\n"); 39 | return EXIT_FAILURE; 40 | } 41 | 42 | // Compress the string. 43 | cmp_status = compress(pCmp, &cmp_len, (const unsigned char *)s_pStr, src_len); 44 | if (cmp_status != Z_OK) 45 | { 46 | printf("compress() failed!\n"); 47 | free(pCmp); 48 | free(pUncomp); 49 | return EXIT_FAILURE; 50 | } 51 | 52 | printf("Compressed from %u to %u bytes\n", (mz_uint32)src_len, (mz_uint32)cmp_len); 53 | 54 | if (step) 55 | { 56 | // Purposely corrupt the compressed data if fuzzy testing (this is a very crude fuzzy test). 57 | uint n = 1 + (rand() % 3); 58 | while (n--) 59 | { 60 | uint i = rand() % cmp_len; 61 | pCmp[i] ^= (rand() & 0xFF); 62 | } 63 | } 64 | 65 | // Decompress. 66 | cmp_status = uncompress(pUncomp, &uncomp_len, pCmp, cmp_len); 67 | total_succeeded += (cmp_status == Z_OK); 68 | 69 | if (step) 70 | { 71 | printf("Simple fuzzy test: step %u total_succeeded: %u\n", step, total_succeeded); 72 | } 73 | else 74 | { 75 | if (cmp_status != Z_OK) 76 | { 77 | printf("uncompress failed!\n"); 78 | free(pCmp); 79 | free(pUncomp); 80 | return EXIT_FAILURE; 81 | } 82 | 83 | printf("Decompressed from %u to %u bytes\n", (mz_uint32)cmp_len, (mz_uint32)uncomp_len); 84 | 85 | // Ensure uncompress() returned the expected data. 86 | if ((uncomp_len != src_len) || (memcmp(pUncomp, s_pStr, (size_t)src_len))) 87 | { 88 | printf("Decompression failed!\n"); 89 | free(pCmp); 90 | free(pUncomp); 91 | return EXIT_FAILURE; 92 | } 93 | } 94 | 95 | free(pCmp); 96 | free(pUncomp); 97 | 98 | step++; 99 | 100 | // Keep on fuzzy testing if there's a non-empty command line. 101 | } while (argc >= 2); 102 | 103 | printf("Success.\n"); 104 | return EXIT_SUCCESS; 105 | } 106 | -------------------------------------------------------------------------------- /external/miniz/examples/example2.c: -------------------------------------------------------------------------------- 1 | // example2.c - Simple demonstration of miniz.c's ZIP archive API's. 2 | // Note this test deletes the test archive file "__mz_example2_test__.zip" in the current directory, then creates a new one with test data. 3 | // Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. 4 | 5 | #if defined(__GNUC__) 6 | // Ensure we get the 64-bit variants of the CRT's file I/O calls 7 | #ifndef _FILE_OFFSET_BITS 8 | #define _FILE_OFFSET_BITS 64 9 | #endif 10 | #ifndef _LARGEFILE64_SOURCE 11 | #define _LARGEFILE64_SOURCE 1 12 | #endif 13 | #endif 14 | 15 | #include 16 | #include "miniz.h" 17 | 18 | typedef unsigned char uint8; 19 | typedef unsigned short uint16; 20 | typedef unsigned int uint; 21 | 22 | // The string to compress. 23 | static const char *s_pTest_str = 24 | "MISSION CONTROL I wouldn't worry too much about the computer. First of all, there is still a chance that he is right, despite your tests, and" \ 25 | "if it should happen again, we suggest eliminating this possibility by allowing the unit to remain in place and seeing whether or not it" \ 26 | "actually fails. If the computer should turn out to be wrong, the situation is still not alarming. The type of obsessional error he may be" \ 27 | "guilty of is not unknown among the latest generation of HAL 9000 computers. It has almost always revolved around a single detail, such as" \ 28 | "the one you have described, and it has never interfered with the integrity or reliability of the computer's performance in other areas." \ 29 | "No one is certain of the cause of this kind of malfunctioning. It may be over-programming, but it could also be any number of reasons. In any" \ 30 | "event, it is somewhat analogous to human neurotic behavior. Does this answer your query? Zero-five-three-Zero, MC, transmission concluded."; 31 | 32 | static const char *s_pComment = "This is a comment"; 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | int i, sort_iter; 37 | mz_bool status; 38 | size_t uncomp_size; 39 | mz_zip_archive zip_archive; 40 | void *p; 41 | const int N = 50; 42 | char data[2048]; 43 | char archive_filename[64]; 44 | static const char *s_Test_archive_filename = "__mz_example2_test__.zip"; 45 | 46 | assert((strlen(s_pTest_str) + 64) < sizeof(data)); 47 | 48 | printf("miniz.c version: %s\n", MZ_VERSION); 49 | 50 | (void)argc, (void)argv; 51 | 52 | // Delete the test archive, so it doesn't keep growing as we run this test 53 | remove(s_Test_archive_filename); 54 | 55 | // Append a bunch of text files to the test archive 56 | for (i = (N - 1); i >= 0; --i) 57 | { 58 | sprintf(archive_filename, "%u.txt", i); 59 | sprintf(data, "%u %s %u", (N - 1) - i, s_pTest_str, i); 60 | 61 | // Add a new file to the archive. Note this is an IN-PLACE operation, so if it fails your archive is probably hosed (its central directory may not be complete) but it should be recoverable using zip -F or -FF. So use caution with this guy. 62 | // A more robust way to add a file to an archive would be to read it into memory, perform the operation, then write a new archive out to a temp file and then delete/rename the files. 63 | // Or, write a new archive to disk to a temp file, then delete/rename the files. For this test this API is fine. 64 | status = mz_zip_add_mem_to_archive_file_in_place(s_Test_archive_filename, archive_filename, data, strlen(data) + 1, s_pComment, (uint16)strlen(s_pComment), MZ_BEST_COMPRESSION); 65 | if (!status) 66 | { 67 | printf("mz_zip_add_mem_to_archive_file_in_place failed!\n"); 68 | return EXIT_FAILURE; 69 | } 70 | } 71 | 72 | // Add a directory entry for testing 73 | status = mz_zip_add_mem_to_archive_file_in_place(s_Test_archive_filename, "directory/", NULL, 0, "no comment", (uint16)strlen("no comment"), MZ_BEST_COMPRESSION); 74 | if (!status) 75 | { 76 | printf("mz_zip_add_mem_to_archive_file_in_place failed!\n"); 77 | return EXIT_FAILURE; 78 | } 79 | 80 | // Now try to open the archive. 81 | memset(&zip_archive, 0, sizeof(zip_archive)); 82 | 83 | status = mz_zip_reader_init_file(&zip_archive, s_Test_archive_filename, 0); 84 | if (!status) 85 | { 86 | printf("mz_zip_reader_init_file() failed!\n"); 87 | return EXIT_FAILURE; 88 | } 89 | 90 | // Get and print information about each file in the archive. 91 | for (i = 0; i < (int)mz_zip_reader_get_num_files(&zip_archive); i++) 92 | { 93 | mz_zip_archive_file_stat file_stat; 94 | if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) 95 | { 96 | printf("mz_zip_reader_file_stat() failed!\n"); 97 | mz_zip_reader_end(&zip_archive); 98 | return EXIT_FAILURE; 99 | } 100 | 101 | printf("Filename: \"%s\", Comment: \"%s\", Uncompressed size: %u, Compressed size: %u, Is Dir: %u\n", file_stat.m_filename, file_stat.m_comment, (uint)file_stat.m_uncomp_size, (uint)file_stat.m_comp_size, mz_zip_reader_is_file_a_directory(&zip_archive, i)); 102 | 103 | if (!strcmp(file_stat.m_filename, "directory/")) 104 | { 105 | if (!mz_zip_reader_is_file_a_directory(&zip_archive, i)) 106 | { 107 | printf("mz_zip_reader_is_file_a_directory() didn't return the expected results!\n"); 108 | mz_zip_reader_end(&zip_archive); 109 | return EXIT_FAILURE; 110 | } 111 | } 112 | } 113 | 114 | // Close the archive, freeing any resources it was using 115 | mz_zip_reader_end(&zip_archive); 116 | 117 | // Now verify the compressed data 118 | for (sort_iter = 0; sort_iter < 2; sort_iter++) 119 | { 120 | memset(&zip_archive, 0, sizeof(zip_archive)); 121 | status = mz_zip_reader_init_file(&zip_archive, s_Test_archive_filename, sort_iter ? MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY : 0); 122 | if (!status) 123 | { 124 | printf("mz_zip_reader_init_file() failed!\n"); 125 | return EXIT_FAILURE; 126 | } 127 | 128 | for (i = 0; i < N; i++) 129 | { 130 | sprintf(archive_filename, "%u.txt", i); 131 | sprintf(data, "%u %s %u", (N - 1) - i, s_pTest_str, i); 132 | 133 | // Try to extract all the files to the heap. 134 | p = mz_zip_reader_extract_file_to_heap(&zip_archive, archive_filename, &uncomp_size, 0); 135 | if (!p) 136 | { 137 | printf("mz_zip_reader_extract_file_to_heap() failed!\n"); 138 | mz_zip_reader_end(&zip_archive); 139 | return EXIT_FAILURE; 140 | } 141 | 142 | // Make sure the extraction really succeeded. 143 | if ((uncomp_size != (strlen(data) + 1)) || (memcmp(p, data, strlen(data)))) 144 | { 145 | printf("mz_zip_reader_extract_file_to_heap() failed to extract the proper data\n"); 146 | mz_free(p); 147 | mz_zip_reader_end(&zip_archive); 148 | return EXIT_FAILURE; 149 | } 150 | 151 | printf("Successfully extracted file \"%s\", size %u\n", archive_filename, (uint)uncomp_size); 152 | printf("File data: \"%s\"\n", (const char *)p); 153 | 154 | // We're done. 155 | mz_free(p); 156 | } 157 | 158 | // Close the archive, freeing any resources it was using 159 | mz_zip_reader_end(&zip_archive); 160 | } 161 | 162 | printf("Success.\n"); 163 | return EXIT_SUCCESS; 164 | } 165 | -------------------------------------------------------------------------------- /external/miniz/examples/example3.c: -------------------------------------------------------------------------------- 1 | // example3.c - Demonstrates how to use miniz.c's deflate() and inflate() functions for simple file compression. 2 | // Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. 3 | // For simplicity, this example is limited to files smaller than 4GB, but this is not a limitation of miniz.c. 4 | #include 5 | #include 6 | #include "miniz.h" 7 | 8 | typedef unsigned char uint8; 9 | typedef unsigned short uint16; 10 | typedef unsigned int uint; 11 | 12 | #define my_max(a,b) (((a) > (b)) ? (a) : (b)) 13 | #define my_min(a,b) (((a) < (b)) ? (a) : (b)) 14 | 15 | #define BUF_SIZE (1024 * 1024) 16 | static uint8 s_inbuf[BUF_SIZE]; 17 | static uint8 s_outbuf[BUF_SIZE]; 18 | 19 | int main(int argc, char *argv[]) 20 | { 21 | const char *pMode; 22 | FILE *pInfile, *pOutfile; 23 | uint infile_size; 24 | int level = Z_BEST_COMPRESSION; 25 | z_stream stream; 26 | int p = 1; 27 | const char *pSrc_filename; 28 | const char *pDst_filename; 29 | long file_loc; 30 | 31 | printf("miniz.c version: %s\n", MZ_VERSION); 32 | 33 | if (argc < 4) 34 | { 35 | printf("Usage: example3 [options] [mode:c or d] infile outfile\n"); 36 | printf("\nModes:\n"); 37 | printf("c - Compresses file infile to a zlib stream in file outfile\n"); 38 | printf("d - Decompress zlib stream in file infile to file outfile\n"); 39 | printf("\nOptions:\n"); 40 | printf("-l[0-10] - Compression level, higher values are slower.\n"); 41 | return EXIT_FAILURE; 42 | } 43 | 44 | while ((p < argc) && (argv[p][0] == '-')) 45 | { 46 | switch (argv[p][1]) 47 | { 48 | case 'l': 49 | { 50 | level = atoi(&argv[1][2]); 51 | if ((level < 0) || (level > 10)) 52 | { 53 | printf("Invalid level!\n"); 54 | return EXIT_FAILURE; 55 | } 56 | break; 57 | } 58 | default: 59 | { 60 | printf("Invalid option: %s\n", argv[p]); 61 | return EXIT_FAILURE; 62 | } 63 | } 64 | p++; 65 | } 66 | 67 | if ((argc - p) < 3) 68 | { 69 | printf("Must specify mode, input filename, and output filename after options!\n"); 70 | return EXIT_FAILURE; 71 | } 72 | else if ((argc - p) > 3) 73 | { 74 | printf("Too many filenames!\n"); 75 | return EXIT_FAILURE; 76 | } 77 | 78 | pMode = argv[p++]; 79 | if (!strchr("cCdD", pMode[0])) 80 | { 81 | printf("Invalid mode!\n"); 82 | return EXIT_FAILURE; 83 | } 84 | 85 | pSrc_filename = argv[p++]; 86 | pDst_filename = argv[p++]; 87 | 88 | printf("Mode: %c, Level: %u\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename); 89 | 90 | // Open input file. 91 | pInfile = fopen(pSrc_filename, "rb"); 92 | if (!pInfile) 93 | { 94 | printf("Failed opening input file!\n"); 95 | return EXIT_FAILURE; 96 | } 97 | 98 | // Determine input file's size. 99 | fseek(pInfile, 0, SEEK_END); 100 | file_loc = ftell(pInfile); 101 | fseek(pInfile, 0, SEEK_SET); 102 | 103 | if ((file_loc < 0) || (file_loc > INT_MAX)) 104 | { 105 | // This is not a limitation of miniz or tinfl, but this example. 106 | printf("File is too large to be processed by this example.\n"); 107 | return EXIT_FAILURE; 108 | } 109 | 110 | infile_size = (uint)file_loc; 111 | 112 | // Open output file. 113 | pOutfile = fopen(pDst_filename, "wb"); 114 | if (!pOutfile) 115 | { 116 | printf("Failed opening output file!\n"); 117 | return EXIT_FAILURE; 118 | } 119 | 120 | printf("Input file size: %u\n", infile_size); 121 | 122 | // Init the z_stream 123 | memset(&stream, 0, sizeof(stream)); 124 | stream.next_in = s_inbuf; 125 | stream.avail_in = 0; 126 | stream.next_out = s_outbuf; 127 | stream.avail_out = BUF_SIZE; 128 | 129 | if ((pMode[0] == 'c') || (pMode[0] == 'C')) 130 | { 131 | // Compression. 132 | uint infile_remaining = infile_size; 133 | 134 | if (deflateInit(&stream, level) != Z_OK) 135 | { 136 | printf("deflateInit() failed!\n"); 137 | return EXIT_FAILURE; 138 | } 139 | 140 | for ( ; ; ) 141 | { 142 | int status; 143 | if (!stream.avail_in) 144 | { 145 | // Input buffer is empty, so read more bytes from input file. 146 | uint n = my_min(BUF_SIZE, infile_remaining); 147 | 148 | if (fread(s_inbuf, 1, n, pInfile) != n) 149 | { 150 | printf("Failed reading from input file!\n"); 151 | return EXIT_FAILURE; 152 | } 153 | 154 | stream.next_in = s_inbuf; 155 | stream.avail_in = n; 156 | 157 | infile_remaining -= n; 158 | //printf("Input bytes remaining: %u\n", infile_remaining); 159 | } 160 | 161 | status = deflate(&stream, infile_remaining ? Z_NO_FLUSH : Z_FINISH); 162 | 163 | if ((status == Z_STREAM_END) || (!stream.avail_out)) 164 | { 165 | // Output buffer is full, or compression is done, so write buffer to output file. 166 | uint n = BUF_SIZE - stream.avail_out; 167 | if (fwrite(s_outbuf, 1, n, pOutfile) != n) 168 | { 169 | printf("Failed writing to output file!\n"); 170 | return EXIT_FAILURE; 171 | } 172 | stream.next_out = s_outbuf; 173 | stream.avail_out = BUF_SIZE; 174 | } 175 | 176 | if (status == Z_STREAM_END) 177 | break; 178 | else if (status != Z_OK) 179 | { 180 | printf("deflate() failed with status %i!\n", status); 181 | return EXIT_FAILURE; 182 | } 183 | } 184 | 185 | if (deflateEnd(&stream) != Z_OK) 186 | { 187 | printf("deflateEnd() failed!\n"); 188 | return EXIT_FAILURE; 189 | } 190 | } 191 | else if ((pMode[0] == 'd') || (pMode[0] == 'D')) 192 | { 193 | // Decompression. 194 | uint infile_remaining = infile_size; 195 | 196 | if (inflateInit(&stream)) 197 | { 198 | printf("inflateInit() failed!\n"); 199 | return EXIT_FAILURE; 200 | } 201 | 202 | for ( ; ; ) 203 | { 204 | int status; 205 | if (!stream.avail_in) 206 | { 207 | // Input buffer is empty, so read more bytes from input file. 208 | uint n = my_min(BUF_SIZE, infile_remaining); 209 | 210 | if (fread(s_inbuf, 1, n, pInfile) != n) 211 | { 212 | printf("Failed reading from input file!\n"); 213 | return EXIT_FAILURE; 214 | } 215 | 216 | stream.next_in = s_inbuf; 217 | stream.avail_in = n; 218 | 219 | infile_remaining -= n; 220 | } 221 | 222 | status = inflate(&stream, Z_SYNC_FLUSH); 223 | 224 | if ((status == Z_STREAM_END) || (!stream.avail_out)) 225 | { 226 | // Output buffer is full, or decompression is done, so write buffer to output file. 227 | uint n = BUF_SIZE - stream.avail_out; 228 | if (fwrite(s_outbuf, 1, n, pOutfile) != n) 229 | { 230 | printf("Failed writing to output file!\n"); 231 | return EXIT_FAILURE; 232 | } 233 | stream.next_out = s_outbuf; 234 | stream.avail_out = BUF_SIZE; 235 | } 236 | 237 | if (status == Z_STREAM_END) 238 | break; 239 | else if (status != Z_OK) 240 | { 241 | printf("inflate() failed with status %i!\n", status); 242 | return EXIT_FAILURE; 243 | } 244 | } 245 | 246 | if (inflateEnd(&stream) != Z_OK) 247 | { 248 | printf("inflateEnd() failed!\n"); 249 | return EXIT_FAILURE; 250 | } 251 | } 252 | else 253 | { 254 | printf("Invalid mode!\n"); 255 | return EXIT_FAILURE; 256 | } 257 | 258 | fclose(pInfile); 259 | if (EOF == fclose(pOutfile)) 260 | { 261 | printf("Failed writing to output file!\n"); 262 | return EXIT_FAILURE; 263 | } 264 | 265 | printf("Total input bytes: %u\n", (mz_uint32)stream.total_in); 266 | printf("Total output bytes: %u\n", (mz_uint32)stream.total_out); 267 | printf("Success.\n"); 268 | return EXIT_SUCCESS; 269 | } 270 | -------------------------------------------------------------------------------- /external/miniz/examples/example4.c: -------------------------------------------------------------------------------- 1 | // example4.c - Uses tinfl.c to decompress a zlib stream in memory to an output file 2 | // Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. 3 | #include "miniz.h" 4 | #include 5 | #include 6 | 7 | typedef unsigned char uint8; 8 | typedef unsigned short uint16; 9 | typedef unsigned int uint; 10 | 11 | #define my_max(a,b) (((a) > (b)) ? (a) : (b)) 12 | #define my_min(a,b) (((a) < (b)) ? (a) : (b)) 13 | 14 | static int tinfl_put_buf_func(const void* pBuf, int len, void *pUser) 15 | { 16 | return len == (int)fwrite(pBuf, 1, len, (FILE*)pUser); 17 | } 18 | 19 | int main(int argc, char *argv[]) 20 | { 21 | int status; 22 | FILE *pInfile, *pOutfile; 23 | uint infile_size, outfile_size; 24 | size_t in_buf_size; 25 | uint8 *pCmp_data; 26 | long file_loc; 27 | 28 | if (argc != 3) 29 | { 30 | printf("Usage: example4 infile outfile\n"); 31 | printf("Decompresses zlib stream in file infile to file outfile.\n"); 32 | printf("Input file must be able to fit entirely in memory.\n"); 33 | printf("example3 can be used to create compressed zlib streams.\n"); 34 | return EXIT_FAILURE; 35 | } 36 | 37 | // Open input file. 38 | pInfile = fopen(argv[1], "rb"); 39 | if (!pInfile) 40 | { 41 | printf("Failed opening input file!\n"); 42 | return EXIT_FAILURE; 43 | } 44 | 45 | // Determine input file's size. 46 | fseek(pInfile, 0, SEEK_END); 47 | file_loc = ftell(pInfile); 48 | fseek(pInfile, 0, SEEK_SET); 49 | 50 | if ((file_loc < 0) || (file_loc > INT_MAX)) 51 | { 52 | // This is not a limitation of miniz or tinfl, but this example. 53 | printf("File is too large to be processed by this example.\n"); 54 | return EXIT_FAILURE; 55 | } 56 | 57 | infile_size = (uint)file_loc; 58 | 59 | pCmp_data = (uint8 *)malloc(infile_size); 60 | if (!pCmp_data) 61 | { 62 | printf("Out of memory!\n"); 63 | return EXIT_FAILURE; 64 | } 65 | if (fread(pCmp_data, 1, infile_size, pInfile) != infile_size) 66 | { 67 | printf("Failed reading input file!\n"); 68 | return EXIT_FAILURE; 69 | } 70 | 71 | // Open output file. 72 | pOutfile = fopen(argv[2], "wb"); 73 | if (!pOutfile) 74 | { 75 | printf("Failed opening output file!\n"); 76 | return EXIT_FAILURE; 77 | } 78 | 79 | printf("Input file size: %u\n", infile_size); 80 | 81 | in_buf_size = infile_size; 82 | status = tinfl_decompress_mem_to_callback(pCmp_data, &in_buf_size, tinfl_put_buf_func, pOutfile, TINFL_FLAG_PARSE_ZLIB_HEADER); 83 | if (!status) 84 | { 85 | printf("tinfl_decompress_mem_to_callback() failed with status %i!\n", status); 86 | return EXIT_FAILURE; 87 | } 88 | 89 | outfile_size = ftell(pOutfile); 90 | 91 | fclose(pInfile); 92 | if (EOF == fclose(pOutfile)) 93 | { 94 | printf("Failed writing to output file!\n"); 95 | return EXIT_FAILURE; 96 | } 97 | 98 | printf("Total input bytes: %u\n", (uint)in_buf_size); 99 | printf("Total output bytes: %u\n", outfile_size); 100 | printf("Success.\n"); 101 | return EXIT_SUCCESS; 102 | } 103 | -------------------------------------------------------------------------------- /external/miniz/examples/example6.c: -------------------------------------------------------------------------------- 1 | // example6.c - Demonstrates how to miniz's PNG writer func 2 | // Public domain, April 11 2012, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. 3 | // Mandlebrot set code from http://rosettacode.org/wiki/Mandelbrot_set#C 4 | // Must link this example against libm on Linux. 5 | 6 | // Purposely disable a whole bunch of stuff this low-level example doesn't use. 7 | #define MINIZ_NO_STDIO 8 | #define MINIZ_NO_TIME 9 | #define MINIZ_NO_ZLIB_APIS 10 | #include "miniz.h" 11 | 12 | // Now include stdio.h because this test uses fopen(), etc. (but we still don't want miniz.c's stdio stuff, for testing). 13 | #include 14 | #include 15 | #include 16 | 17 | typedef unsigned char uint8; 18 | typedef unsigned short uint16; 19 | typedef unsigned int uint; 20 | 21 | typedef struct 22 | { 23 | uint8 r, g, b; 24 | } rgb_t; 25 | 26 | static void hsv_to_rgb(int hue, int min, int max, rgb_t *p) 27 | { 28 | const int invert = 0; 29 | const int saturation = 1; 30 | const int color_rotate = 0; 31 | 32 | if (min == max) max = min + 1; 33 | if (invert) hue = max - (hue - min); 34 | if (!saturation) { 35 | p->r = p->g = p->b = 255 * (max - hue) / (max - min); 36 | return; 37 | } 38 | double h = fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6); 39 | double c = 255.0f * saturation; 40 | double X = c * (1 - fabs(fmod(h, 2) - 1)); 41 | 42 | p->r = p->g = p->b = 0; 43 | 44 | switch((int)h) { 45 | case 0: p->r = c; p->g = X; return; 46 | case 1: p->r = X; p->g = c; return; 47 | case 2: p->g = c; p->b = X; return; 48 | case 3: p->g = X; p->b = c; return; 49 | case 4: p->r = X; p->b = c; return; 50 | default:p->r = c; p->b = X; 51 | } 52 | } 53 | 54 | int main(int argc, char *argv[]) 55 | { 56 | (void)argc, (void)argv; 57 | 58 | // Image resolution 59 | const int iXmax = 4096; 60 | const int iYmax = 4096; 61 | 62 | // Output filename 63 | static const char *pFilename = "mandelbrot.png"; 64 | 65 | int iX, iY; 66 | const double CxMin = -2.5; 67 | const double CxMax = 1.5; 68 | const double CyMin = -2.0; 69 | const double CyMax = 2.0; 70 | 71 | double PixelWidth = (CxMax - CxMin) / iXmax; 72 | double PixelHeight = (CyMax - CyMin) / iYmax; 73 | 74 | // Z=Zx+Zy*i ; Z0 = 0 75 | double Zx, Zy; 76 | double Zx2, Zy2; // Zx2=Zx*Zx; Zy2=Zy*Zy 77 | 78 | int Iteration; 79 | const int IterationMax = 200; 80 | 81 | // bail-out value , radius of circle 82 | const double EscapeRadius = 2; 83 | double ER2=EscapeRadius * EscapeRadius; 84 | 85 | uint8 *pImage = (uint8 *)malloc(iXmax * 3 * iYmax); 86 | 87 | // world ( double) coordinate = parameter plane 88 | double Cx,Cy; 89 | 90 | int MinIter = 9999, MaxIter = 0; 91 | 92 | for(iY = 0; iY < iYmax; iY++) 93 | { 94 | Cy = CyMin + iY * PixelHeight; 95 | if (fabs(Cy) < PixelHeight/2) 96 | Cy = 0.0; // Main antenna 97 | 98 | for(iX = 0; iX < iXmax; iX++) 99 | { 100 | uint8 *color = pImage + (iX * 3) + (iY * iXmax * 3); 101 | 102 | Cx = CxMin + iX * PixelWidth; 103 | 104 | // initial value of orbit = critical point Z= 0 105 | Zx = 0.0; 106 | Zy = 0.0; 107 | Zx2 = Zx * Zx; 108 | Zy2 = Zy * Zy; 109 | 110 | for (Iteration=0;Iteration> 8; 120 | color[2] = 0; 121 | 122 | if (Iteration < MinIter) 123 | MinIter = Iteration; 124 | if (Iteration > MaxIter) 125 | MaxIter = Iteration; 126 | } 127 | } 128 | 129 | for(iY = 0; iY < iYmax; iY++) 130 | { 131 | for(iX = 0; iX < iXmax; iX++) 132 | { 133 | uint8 *color = (uint8 *)(pImage + (iX * 3) + (iY * iXmax * 3)); 134 | 135 | uint Iterations = color[0] | (color[1] << 8U); 136 | 137 | hsv_to_rgb(Iterations, MinIter, MaxIter, (rgb_t *)color); 138 | } 139 | } 140 | 141 | // Now write the PNG image. 142 | { 143 | size_t png_data_size = 0; 144 | void *pPNG_data = tdefl_write_image_to_png_file_in_memory_ex(pImage, iXmax, iYmax, 3, &png_data_size, 6, MZ_FALSE); 145 | if (!pPNG_data) 146 | fprintf(stderr, "tdefl_write_image_to_png_file_in_memory_ex() failed!\n"); 147 | else 148 | { 149 | FILE *pFile = fopen(pFilename, "wb"); 150 | fwrite(pPNG_data, 1, png_data_size, pFile); 151 | fclose(pFile); 152 | printf("Wrote %s\n", pFilename); 153 | } 154 | 155 | // mz_free() is by default just an alias to free() internally, but if you've overridden miniz's allocation funcs you'll probably need to call mz_free(). 156 | mz_free(pPNG_data); 157 | } 158 | 159 | free(pImage); 160 | 161 | return EXIT_SUCCESS; 162 | } 163 | -------------------------------------------------------------------------------- /external/miniz/readme.md: -------------------------------------------------------------------------------- 1 | ## Miniz 2 | 3 | Miniz is a lossless, high performance data compression library in a single source file that implements the zlib (RFC 1950) and Deflate (RFC 1951) compressed data format specification standards. It supports the most commonly used functions exported by the zlib library, but is a completely independent implementation so zlib's licensing requirements do not apply. Miniz also contains simple to use functions for writing .PNG format image files and reading/writing/appending .ZIP format archives. Miniz's compression speed has been tuned to be comparable to zlib's, and it also has a specialized real-time compressor function designed to compare well against fastlz/minilzo. 4 | 5 | ## Usage 6 | 7 | Please use the files from the [releases page](https://github.com/richgel999/miniz/releases) in your projects. Do not use the git checkout directly! The different source and header files are [amalgamated](https://www.sqlite.org/amalgamation.html) into one `miniz.c`/`miniz.h` pair in a build step (`amalgamate.sh`). Include `miniz.c` and `miniz.h` in your project to use Miniz. 8 | 9 | ## Features 10 | 11 | * MIT licensed 12 | * A portable, single source and header file library written in plain C. Tested with GCC, clang and Visual Studio. 13 | * Easily tuned and trimmed down by defines 14 | * A drop-in replacement for zlib's most used API's (tested in several open source projects that use zlib, such as libpng and libzip). 15 | * Fills a single threaded performance vs. compression ratio gap between several popular real-time compressors and zlib. For example, at level 1, miniz.c compresses around 5-9% better than minilzo, but is approx. 35% slower. At levels 2-9, miniz.c is designed to compare favorably against zlib's ratio and speed. See the miniz performance comparison page for example timings. 16 | * Not a block based compressor: miniz.c fully supports stream based processing using a coroutine-style implementation. The zlib-style API functions can be called a single byte at a time if that's all you've got. 17 | * Easy to use. The low-level compressor (tdefl) and decompressor (tinfl) have simple state structs which can be saved/restored as needed with simple memcpy's. The low-level codec API's don't use the heap in any way. 18 | * Entire inflater (including optional zlib header parsing and Adler-32 checking) is implemented in a single function as a coroutine, which is separately available in a small (~550 line) source file: miniz_tinfl.c 19 | * A fairly complete (but totally optional) set of .ZIP archive manipulation and extraction API's. The archive functionality is intended to solve common problems encountered in embedded, mobile, or game development situations. (The archive API's are purposely just powerful enough to write an entire archiver given a bit of additional higher-level logic.) 20 | 21 | ## Known Problems 22 | 23 | * No support for encrypted archives. Not sure how useful this stuff is in practice. 24 | * Minimal documentation. The assumption is that the user is already familiar with the basic zlib API. I need to write an API wiki - for now I've tried to place key comments before each enum/API, and I've included 6 examples that demonstrate how to use the module's major features. 25 | 26 | ## Special Thanks 27 | 28 | Thanks to Alex Evans for the PNG writer function. Also, thanks to Paul Holden and Thorsten Scheuermann for feedback and testing, Matt Pritchard for all his encouragement, and Sean Barrett's various public domain libraries for inspiration (and encouraging me to write miniz.c in C, which was much more enjoyable and less painful than I thought it would be considering I've been programming in C++ for so long). 29 | 30 | Thanks to Bruce Dawson for reporting a problem with the level_and_flags archive API parameter (which is fixed in v1.12) and general feedback, and Janez Zemva for indirectly encouraging me into writing more examples. 31 | 32 | ## Patents 33 | 34 | I was recently asked if miniz avoids patent issues. miniz purposely uses the same core algorithms as the ones used by zlib. The compressor uses vanilla hash chaining as described [here](https://datatracker.ietf.org/doc/html/rfc1951#section-4). Also see the [gzip FAQ](https://web.archive.org/web/20160308045258/http://www.gzip.org/#faq11). In my opinion, if miniz falls prey to a patent attack then zlib/gzip are likely to be at serious risk too. 35 | -------------------------------------------------------------------------------- /external/nlohmann_json/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(nlohmann_json LANGUAGES CXX VERSION 3.11.2) 2 | 3 | add_library(nlohmann_json INTERFACE) 4 | 5 | target_include_directories(nlohmann_json 6 | SYSTEM INTERFACE 7 | $ 8 | ) 9 | # Enable extended diagnostics information 10 | # https://github.com/nlohmann/json/releases/tag/v3.10.0 11 | target_compile_definitions(nlohmann_json INTERFACE JSON_DIAGNOSTICS=1) 12 | 13 | # provide a namespaced alias for clients to 'link' against if nlohman_json is included as a sub-project 14 | add_library(nlohmann_json::nlohmann_json ALIAS nlohmann_json) 15 | -------------------------------------------------------------------------------- /gif-h/LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /gif-h/README.md: -------------------------------------------------------------------------------- 1 | gif-h 2 | ===== 3 | 4 | This one-header library offers a simple, very limited way to create animated GIFs directly in code. 5 | Those looking for particular cleverness are likely to be disappointed; it's pretty much a straight-ahead 6 | implementation of the GIF format with optional Floyd-Steinberg dithering. (It does at least use delta 7 | encoding - only the changed portions of each frame are saved.) 8 | 9 | So resulting files are often quite large. The hope is that it will be handy nonetheless as a quick and easily-integrated way for programs to spit out animations. 10 | 11 | Only RGBA8 is currently supported as an input format. (The alpha is ignored.) 12 | 13 | Email me : ctangora -at- gmail -dot- com 14 | 15 | Usage: 16 | ------------------- 17 | Create a GifWriter struct. 18 | 19 | Pass the struct to GifBegin() to initialize values and write the file header. 20 | 21 | Pass frames of the animation to GifWriteFrame(). 22 | 23 | Finally, call GifEnd() to close the file handle and free memory. 24 | 25 | #include 26 | #include 27 | #include 28 | int main() 29 | { 30 | int width = 100; 31 | int height = 200; 32 | std::vector black(width * height * 4, 0); 33 | std::vector white(width * height * 4, 255); 34 | 35 | auto fileName = "bwgif.gif"; 36 | int delay = 100; 37 | GifWriter g; 38 | GifBegin(&g, fileName, width, height, delay); 39 | GifWriteFrame(&g, black.data(), width, height, delay); 40 | GifWriteFrame(&g, white.data(), width, height, delay); 41 | GifEnd(&g); 42 | 43 | return 0; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /gif-h/gif-h-demo.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // gif-h-demo.cpp 3 | // by Charlie Tangora 4 | // Public domain. 5 | // Email me : ctangora -at- gmail -dot- com 6 | // 7 | // Shows an example usage of gif.h 8 | // 9 | 10 | #include "gif.h" 11 | 12 | #include 13 | 14 | const int width = 256; 15 | const int height = 256; 16 | uint8_t image[ width * height * 4 ]; 17 | 18 | void SetPixel( int xx, int yy, uint8_t red, uint8_t grn, uint8_t blu ) 19 | { 20 | uint8_t* pixel = &image[(yy*width+xx)*4]; 21 | pixel[0] = red; 22 | pixel[1] = blu; 23 | pixel[2] = grn; 24 | pixel[3] = 255; // no alpha for this demo 25 | } 26 | 27 | void SetPixelFloat( int xx, int yy, float fred, float fgrn, float fblu ) 28 | { 29 | // convert float to unorm 30 | uint8_t red = (uint8_t)roundf( 255.0f * fred ); 31 | uint8_t grn = (uint8_t)roundf( 255.0f * fgrn ); 32 | uint8_t blu = (uint8_t)roundf( 255.0f * fblu ); 33 | 34 | SetPixel( xx, yy, red, grn, blu ); 35 | } 36 | 37 | int main(int argc, const char * argv[]) 38 | { 39 | const char* filename = "./MyGif.gif"; 40 | if( argc > 1 ) 41 | { 42 | filename = argv[1]; 43 | } 44 | 45 | // Create a gif 46 | GifWriter writer = {}; 47 | GifBegin( &writer, filename, width, height, 2, 8, true ); 48 | 49 | for( int frame=0; frame<256; ++frame ) 50 | { 51 | 52 | // Make an image, somehow 53 | // this is the default shadertoy - credit to shadertoy.com 54 | float tt = frame * 3.14159f * 2 / 255.0f; 55 | for( int yy=0; yy 3 | #include 4 | #include 5 | #include 6 | 7 | void NVIC_SystemReset(void) {} 8 | 9 | void APP_ERROR_HANDLER(int err) { 10 | fprintf(stderr, "APP_ERROR_HANDLER: %d", err); 11 | } 12 | 13 | namespace { 14 | std::unordered_map allocatedMemory; 15 | size_t currentFreeHeap = configTOTAL_HEAP_SIZE; 16 | size_t minimumEverFreeHeap = configTOTAL_HEAP_SIZE; 17 | } 18 | 19 | void *pvPortMalloc( size_t xWantedSize ) { 20 | void* ptr = malloc(xWantedSize); 21 | allocatedMemory[ptr] = xWantedSize; 22 | 23 | const size_t currentSize = std::accumulate( 24 | allocatedMemory.begin(), allocatedMemory.end(), 0, 25 | [](const size_t lhs, const std::pair& item){ 26 | return lhs + item.second; 27 | }); 28 | 29 | currentFreeHeap = configTOTAL_HEAP_SIZE - currentSize; 30 | minimumEverFreeHeap = std::min(currentFreeHeap, minimumEverFreeHeap); 31 | 32 | return ptr; 33 | } 34 | void vPortFree( void *pv ) { 35 | allocatedMemory.erase(pv); 36 | return free(pv); 37 | } 38 | 39 | size_t xPortGetHeapSize(void) { 40 | return configTOTAL_HEAP_SIZE; 41 | } 42 | 43 | size_t xPortGetFreeHeapSize(void) { 44 | return currentFreeHeap; 45 | } 46 | 47 | size_t xPortGetMinimumEverFreeHeapSize(void) { 48 | return minimumEverFreeHeap; 49 | } 50 | -------------------------------------------------------------------------------- /sim/FreeRTOS.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.0 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. If you wish to use our Amazon 14 | * FreeRTOS name, please do so in a fair use way that does not cause confusion. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | * http://www.FreeRTOS.org 24 | * http://aws.amazon.com/freertos 25 | * 26 | * 1 tab == 4 spaces! 27 | */ 28 | 29 | #ifndef INC_FREERTOS_H 30 | #define INC_FREERTOS_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include "portmacro_cmsis.h" 37 | //#include "app_error.h" 38 | #include "projdefs.h" 39 | #include 40 | 41 | // from nrf_error.h 42 | /** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions 43 | * @{ */ 44 | #define NRF_ERROR_BASE_NUM (0x0) ///< Global error base 45 | #define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base 46 | #define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base 47 | #define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base 48 | /** @} */ 49 | 50 | #define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command 51 | #define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing 52 | #define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled 53 | #define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error 54 | #define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation 55 | #define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found 56 | #define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported 57 | #define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter 58 | #define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state 59 | #define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length 60 | #define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags 61 | #define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data 62 | #define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Data size exceeds limit 63 | #define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out 64 | #define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer 65 | #define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation 66 | #define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address 67 | #define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy 68 | 69 | void APP_ERROR_HANDLER(int err); 70 | 71 | typedef struct SCB_t { 72 | unsigned ICSR; 73 | } SCB_t; 74 | static SCB_t SCB_member; 75 | static SCB_t *SCB = &SCB_member; 76 | 77 | //#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ 78 | const unsigned SCB_ICSR_VECTACTIVE_Msk = 0x01; 79 | 80 | /** 81 | \brief System Reset 82 | \details Initiates a system reset request to reset the MCU. 83 | */ 84 | // copied from nRF5_SDK_15.3.0_59ac345/components/toolchain/cmsis/include/core_cm4.h 85 | void NVIC_SystemReset(void); 86 | 87 | #define configTOTAL_HEAP_SIZE (1024 * 40) 88 | 89 | size_t xPortGetHeapSize(void); 90 | size_t xPortGetFreeHeapSize(void); 91 | size_t xPortGetMinimumEverFreeHeapSize(void); 92 | 93 | void *pvPortMalloc(size_t xWantedSize); 94 | void vPortFree(void *pv); 95 | 96 | #ifdef __cplusplus 97 | } 98 | #endif 99 | 100 | #endif /* INC_FREERTOS_H */ 101 | -------------------------------------------------------------------------------- /sim/components/battery/BatteryController.cpp: -------------------------------------------------------------------------------- 1 | #include "components/battery/BatteryController.h" 2 | //#include "drivers/PinMap.h" 3 | //#include 4 | //#include 5 | #include 6 | 7 | using namespace Pinetime::Controllers; 8 | 9 | Battery* Battery::instance = nullptr; 10 | 11 | Battery::Battery() { 12 | instance = this; 13 | //nrf_gpio_cfg_input(PinMap::Charging, static_cast GPIO_PIN_CNF_PULL_Disabled); 14 | } 15 | 16 | void Battery::ReadPowerState() { 17 | if (isPowerPresent && !isCharging) { 18 | isFull = true; 19 | } else if (!isPowerPresent) { 20 | isFull = false; 21 | } 22 | } 23 | 24 | void Battery::MeasureVoltage() { 25 | ReadPowerState(); 26 | 27 | if (isReading) { 28 | return; 29 | } 30 | // Non blocking read 31 | isReading = true; 32 | //SaadcInit(); 33 | 34 | //nrfx_saadc_sample(); 35 | } 36 | 37 | //void Battery::AdcCallbackStatic(nrfx_saadc_evt_t const* event) { 38 | // instance->SaadcEventHandler(event); 39 | //} 40 | 41 | //void Battery::SaadcInit() { 42 | // nrfx_saadc_config_t adcConfig = NRFX_SAADC_DEFAULT_CONFIG; 43 | // APP_ERROR_CHECK(nrfx_saadc_init(&adcConfig, AdcCallbackStatic)); 44 | // 45 | // nrf_saadc_channel_config_t adcChannelConfig = {.resistor_p = NRF_SAADC_RESISTOR_DISABLED, 46 | // .resistor_n = NRF_SAADC_RESISTOR_DISABLED, 47 | // .gain = NRF_SAADC_GAIN1_4, 48 | // .reference = NRF_SAADC_REFERENCE_INTERNAL, 49 | // .acq_time = NRF_SAADC_ACQTIME_40US, 50 | // .mode = NRF_SAADC_MODE_SINGLE_ENDED, 51 | // .burst = NRF_SAADC_BURST_ENABLED, 52 | // .pin_p = batteryVoltageAdcInput, 53 | // .pin_n = NRF_SAADC_INPUT_DISABLED}; 54 | // APP_ERROR_CHECK(nrfx_saadc_channel_init(0, &adcChannelConfig)); 55 | // APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1)); 56 | //} 57 | // 58 | //void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { 59 | // const uint16_t battery_max = 4180; // maximum voltage of battery ( max charging voltage is 4.21 ) 60 | // const uint16_t battery_min = 3200; // minimum voltage of battery before shutdown ( depends on the battery ) 61 | // 62 | // if (p_event->type == NRFX_SAADC_EVT_DONE) { 63 | // 64 | // APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1)); 65 | // 66 | // // A hardware voltage divider divides the battery voltage by 2 67 | // // ADC gain is 1/4 68 | // // thus adc_voltage = battery_voltage / 2 * gain = battery_voltage / 8 69 | // // reference_voltage is 600mV 70 | // // p_event->data.done.p_buffer[0] = (adc_voltage / reference_voltage) * 1024 71 | // voltage = p_event->data.done.p_buffer[0] * (8 * 600) / 1024; 72 | // 73 | // uint8_t newPercent; 74 | // if (isFull) { 75 | // newPercent = 100; 76 | // } else if (voltage < battery_min) { 77 | // newPercent = 0; 78 | // } else { 79 | // newPercent = std::min((voltage - battery_min) * 100 / (battery_max - battery_min), isCharging ? 99 : 100); 80 | // } 81 | // 82 | // if ((isPowerPresent && newPercent > percentRemaining) || (!isPowerPresent && newPercent < percentRemaining) || firstMeasurement) { 83 | // firstMeasurement = false; 84 | // percentRemaining = newPercent; 85 | // systemTask->PushMessage(System::Messages::BatteryPercentageUpdated); 86 | // } 87 | // 88 | // nrfx_saadc_uninit(); 89 | // isReading = false; 90 | // } 91 | //} 92 | 93 | void Battery::Register(Pinetime::System::SystemTask* systemTask) { 94 | this->systemTask = systemTask; 95 | } 96 | -------------------------------------------------------------------------------- /sim/components/battery/BatteryController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "systemtask/SystemTask.h" 4 | 5 | namespace Pinetime { 6 | namespace Controllers { 7 | 8 | class Battery { 9 | public: 10 | Battery(); 11 | 12 | void ReadPowerState(); 13 | void MeasureVoltage(); 14 | void Register(System::SystemTask* systemTask); 15 | 16 | uint8_t PercentRemaining() const { 17 | return percentRemaining; 18 | } 19 | 20 | uint16_t Voltage() const { 21 | return voltage; 22 | } 23 | 24 | bool BatteryIsLow() const { 25 | return percentRemaining <= lowBatteryThreshold; 26 | } 27 | 28 | bool IsCharging() const { 29 | // isCharging will go up and down when fully charged 30 | // isFull makes sure this returns false while fully charged. 31 | return isCharging && !isFull; 32 | } 33 | 34 | bool IsPowerPresent() const { 35 | return isPowerPresent; 36 | } 37 | 38 | private: 39 | static Battery* instance; 40 | 41 | //static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7; 42 | public: 43 | uint16_t voltage = 0; 44 | uint8_t percentRemaining = 0; 45 | 46 | bool isFull = false; 47 | bool isCharging = false; 48 | bool isPowerPresent = false; 49 | bool firstMeasurement = true; 50 | 51 | //void SaadcInit(); 52 | 53 | //void SaadcEventHandler(nrfx_saadc_evt_t const* p_event); 54 | //static void AdcCallbackStatic(nrfx_saadc_evt_t const* event); 55 | 56 | static constexpr uint8_t lowBatteryThreshold {20}; 57 | 58 | bool isReading = false; 59 | 60 | Pinetime::System::SystemTask* systemTask = nullptr; 61 | }; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /sim/components/ble/NimbleController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define min // workaround: nimble's min/max macros conflict with libstdc++ 6 | #define max 7 | #include 8 | #undef max 9 | #undef min 10 | //#include "components/ble/AlertNotificationClient.h" 11 | #include "components/ble/AlertNotificationService.h" 12 | //#include "components/ble/BatteryInformationService.h" 13 | //#include "components/ble/CurrentTimeClient.h" 14 | //#include "components/ble/CurrentTimeService.h" 15 | //#include "components/ble/DeviceInformationService.h" 16 | //#include "components/ble/DfuService.h" 17 | //#include "components/ble/HeartRateService.h" 18 | //#include "components/ble/ImmediateAlertService.h" 19 | #include "components/ble/MusicService.h" 20 | #include "components/ble/NavigationService.h" 21 | //#include "components/ble/ServiceDiscovery.h" 22 | #include "components/ble/MotionService.h" 23 | #include "components/ble/SimpleWeatherService.h" 24 | #include "components/fs/FS.h" 25 | //#include "components/ble/FSService.h" 26 | 27 | namespace Pinetime { 28 | namespace Drivers { 29 | class SpiNorFlash; 30 | } 31 | 32 | namespace System { 33 | class SystemTask; 34 | } 35 | 36 | namespace Controllers { 37 | class Battery; 38 | class Ble; 39 | class DateTime; 40 | class FS; 41 | class HeartRateController; 42 | class MotionController; 43 | class NotificationManager; 44 | 45 | class NimbleController { 46 | 47 | public: 48 | NimbleController(Pinetime::System::SystemTask& systemTask, 49 | Pinetime::Controllers::Ble& bleController, 50 | DateTime& dateTimeController, 51 | Pinetime::Controllers::NotificationManager& notificationManager, 52 | Controllers::Battery& batteryController, 53 | Pinetime::Drivers::SpiNorFlash& spiNorFlash, 54 | Controllers::HeartRateController& heartRateController, 55 | Controllers::MotionController& motionController, 56 | Pinetime::Controllers::FS& fs); 57 | void Init(); 58 | void StartAdvertising(); 59 | // int OnGAPEvent(ble_gap_event* event); 60 | 61 | // int OnDiscoveryEvent(uint16_t i, const ble_gatt_error* pError, const ble_gatt_svc* pSvc); 62 | // int OnCTSCharacteristicDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_chr* characteristic); 63 | // int OnANSCharacteristicDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_chr* characteristic); 64 | // int OnCurrentTimeReadResult(uint16_t connectionHandle, const ble_gatt_error* error, ble_gatt_attr* attribute); 65 | // int OnANSDescriptorDiscoveryEventCallback(uint16_t connectionHandle, 66 | // const ble_gatt_error* error, 67 | // uint16_t characteristicValueHandle, 68 | // const ble_gatt_dsc* descriptor); 69 | 70 | void StartDiscovery(); 71 | 72 | Pinetime::Controllers::MusicService& music() { 73 | return musicService; 74 | }; 75 | Pinetime::Controllers::NavigationService& navigation() { 76 | return navService; 77 | }; 78 | Pinetime::Controllers::AlertNotificationService& alertService() { 79 | return anService; 80 | }; 81 | Pinetime::Controllers::SimpleWeatherService& weather() { 82 | return weatherService; 83 | }; 84 | 85 | uint16_t connHandle(); 86 | void NotifyBatteryLevel(uint8_t level); 87 | 88 | void RestartFastAdv() { 89 | fastAdvCount = 0; 90 | } 91 | 92 | void EnableRadio(); 93 | void DisableRadio(); 94 | 95 | private: 96 | // void PersistBond(struct ble_gap_conn_desc& desc); 97 | // void RestoreBond(); 98 | 99 | static constexpr const char* deviceName = "InfiniTime"; 100 | Pinetime::System::SystemTask& systemTask; 101 | Pinetime::Controllers::Ble& bleController; 102 | DateTime& dateTimeController; 103 | Pinetime::Controllers::NotificationManager& notificationManager; 104 | Pinetime::Drivers::SpiNorFlash& spiNorFlash; 105 | Pinetime::Controllers::FS& fs; 106 | // Pinetime::Controllers::DfuService dfuService; 107 | 108 | // DeviceInformationService deviceInformationService; 109 | // CurrentTimeClient currentTimeClient; 110 | AlertNotificationService anService; 111 | // AlertNotificationClient alertNotificationClient; 112 | // CurrentTimeService currentTimeService; 113 | MusicService musicService; 114 | SimpleWeatherService weatherService; 115 | NavigationService navService; 116 | // BatteryInformationService batteryInformationService; 117 | // ImmediateAlertService immediateAlertService; 118 | // HeartRateService heartRateService; 119 | MotionService motionService; 120 | // FSService fsService; 121 | // ServiceDiscovery serviceDiscovery; 122 | 123 | uint8_t addrType; 124 | uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; 125 | uint8_t fastAdvCount = 0; 126 | uint8_t bondId[16] = {0}; 127 | 128 | // ble_uuid128_t dfuServiceUuid { 129 | // .u {.type = BLE_UUID_TYPE_128}, 130 | // .value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, 0xDE, 0xEF, 0x12, 0x12, 0x30, 0x15, 0x00, 0x00}}; 131 | }; 132 | 133 | // static NimbleController* nptr; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /sim/components/brightness/BrightnessController.cpp: -------------------------------------------------------------------------------- 1 | #include "BrightnessController.h" 2 | //#include 3 | #include "displayapp/screens/Symbols.h" 4 | #include "drivers/PinMap.h" 5 | using namespace Pinetime::Controllers; 6 | 7 | void BrightnessController::Init() { 8 | //nrf_gpio_cfg_output(PinMap::LcdBacklightLow); 9 | //nrf_gpio_cfg_output(PinMap::LcdBacklightMedium); 10 | //nrf_gpio_cfg_output(PinMap::LcdBacklightHigh); 11 | Set(level); 12 | } 13 | 14 | void BrightnessController::Set(BrightnessController::Levels level) { 15 | this->level = level; 16 | //switch (level) { 17 | // default: 18 | // case Levels::High: 19 | // nrf_gpio_pin_clear(PinMap::LcdBacklightLow); 20 | // nrf_gpio_pin_clear(PinMap::LcdBacklightMedium); 21 | // nrf_gpio_pin_clear(PinMap::LcdBacklightHigh); 22 | // break; 23 | // case Levels::Medium: 24 | // nrf_gpio_pin_clear(PinMap::LcdBacklightLow); 25 | // nrf_gpio_pin_clear(PinMap::LcdBacklightMedium); 26 | // nrf_gpio_pin_set(PinMap::LcdBacklightHigh); 27 | // break; 28 | // case Levels::Low: 29 | // nrf_gpio_pin_clear(PinMap::LcdBacklightLow); 30 | // nrf_gpio_pin_set(PinMap::LcdBacklightMedium); 31 | // nrf_gpio_pin_set(PinMap::LcdBacklightHigh); 32 | // break; 33 | // case Levels::Off: 34 | // nrf_gpio_pin_set(PinMap::LcdBacklightLow); 35 | // nrf_gpio_pin_set(PinMap::LcdBacklightMedium); 36 | // nrf_gpio_pin_set(PinMap::LcdBacklightHigh); 37 | // break; 38 | //} 39 | } 40 | 41 | void BrightnessController::Lower() { 42 | switch (level) { 43 | case Levels::High: 44 | Set(Levels::Medium); 45 | break; 46 | case Levels::Medium: 47 | Set(Levels::Low); 48 | break; 49 | case Levels::Low: 50 | Set(Levels::Off); 51 | break; 52 | default: 53 | break; 54 | } 55 | } 56 | 57 | void BrightnessController::Higher() { 58 | switch (level) { 59 | case Levels::Off: 60 | Set(Levels::Low); 61 | break; 62 | case Levels::Low: 63 | Set(Levels::Medium); 64 | break; 65 | case Levels::Medium: 66 | Set(Levels::High); 67 | break; 68 | default: 69 | break; 70 | } 71 | } 72 | 73 | BrightnessController::Levels BrightnessController::Level() const { 74 | return level; 75 | } 76 | 77 | void BrightnessController::Backup() { 78 | backupLevel = level; 79 | } 80 | 81 | void BrightnessController::Restore() { 82 | Set(backupLevel); 83 | } 84 | 85 | void BrightnessController::Step() { 86 | switch (level) { 87 | case Levels::Low: 88 | Set(Levels::Medium); 89 | break; 90 | case Levels::Medium: 91 | Set(Levels::High); 92 | break; 93 | case Levels::High: 94 | Set(Levels::Low); 95 | break; 96 | default: 97 | break; 98 | } 99 | } 100 | 101 | const char* BrightnessController::GetIcon() { 102 | switch (level) { 103 | case Levels::Medium: 104 | return Applications::Screens::Symbols::brightnessMedium; 105 | case Levels::High: 106 | return Applications::Screens::Symbols::brightnessHigh; 107 | default: 108 | break; 109 | } 110 | return Applications::Screens::Symbols::brightnessLow; 111 | } 112 | 113 | const char* BrightnessController::ToString() { 114 | switch (level) { 115 | case Levels::Off: 116 | return "Off"; 117 | case Levels::Low: 118 | return "Low"; 119 | case Levels::Medium: 120 | return "Medium"; 121 | case Levels::High: 122 | return "High"; 123 | default: 124 | return "???"; 125 | } 126 | } -------------------------------------------------------------------------------- /sim/components/brightness/BrightnessController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Pinetime { 6 | namespace Controllers { 7 | class BrightnessController { 8 | public: 9 | enum class Levels { Off, AlwaysOn, Low, Medium, High }; 10 | void Init(); 11 | 12 | void Set(Levels level); 13 | Levels Level() const; 14 | void Lower(); 15 | void Higher(); 16 | void Step(); 17 | 18 | void Backup(); 19 | void Restore(); 20 | 21 | const char* GetIcon(); 22 | const char* ToString(); 23 | 24 | private: 25 | Levels level = Levels::High; 26 | Levels backupLevel = Levels::High; 27 | }; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /sim/components/firmwarevalidator/FirmwareValidator.cpp: -------------------------------------------------------------------------------- 1 | #include "components/firmwarevalidator/FirmwareValidator.h" 2 | 3 | //#include 4 | //#include "drivers/InternalFlash.h" 5 | 6 | using namespace Pinetime::Controllers; 7 | 8 | bool FirmwareValidator::IsValidated() const { 9 | return true; // lv_sim 10 | // auto* imageOkPtr = reinterpret_cast(validBitAdress); 11 | // return (*imageOkPtr) == validBitValue; 12 | } 13 | 14 | void FirmwareValidator::Validate() { 15 | // if (!IsValidated()) 16 | // Pinetime::Drivers::InternalFlash::WriteWord(validBitAdress, validBitValue); 17 | } 18 | 19 | void FirmwareValidator::Reset() { 20 | // NVIC_SystemReset(); 21 | } 22 | -------------------------------------------------------------------------------- /sim/components/firmwarevalidator/FirmwareValidator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Pinetime { 6 | namespace Controllers { 7 | class FirmwareValidator { 8 | public: 9 | void Validate(); 10 | bool IsValidated() const; 11 | 12 | void Reset(); 13 | 14 | private: 15 | static constexpr uint32_t validBitAdress {0x7BFE8}; 16 | static constexpr uint32_t validBitValue {1}; 17 | }; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /sim/components/heartrate/HeartRateController.cpp: -------------------------------------------------------------------------------- 1 | #include "components/heartrate/HeartRateController.h" 2 | #include 3 | #include "systemtask/SystemTask.h" 4 | 5 | using namespace Pinetime::Controllers; 6 | 7 | void HeartRateController::Update(HeartRateController::States newState, uint8_t heartRate) { 8 | this->state = newState; 9 | if (this->heartRate != heartRate) { 10 | this->heartRate = heartRate; 11 | //service->OnNewHeartRateValue(heartRate); 12 | } 13 | } 14 | 15 | void HeartRateController::Start() { 16 | if (task != nullptr) { 17 | state = States::NotEnoughData; 18 | task->PushMessage(Pinetime::Applications::HeartRateTask::Messages::StartMeasurement); 19 | } 20 | } 21 | 22 | void HeartRateController::Stop() { 23 | if (task != nullptr) { 24 | state = States::Stopped; 25 | task->PushMessage(Pinetime::Applications::HeartRateTask::Messages::StopMeasurement); 26 | } 27 | } 28 | 29 | void HeartRateController::SetHeartRateTask(Pinetime::Applications::HeartRateTask* task) { 30 | this->task = task; 31 | } 32 | 33 | //void HeartRateController::SetService(Pinetime::Controllers::HeartRateService* service) { 34 | // this->service = service; 35 | //} 36 | -------------------------------------------------------------------------------- /sim/components/heartrate/HeartRateController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | //#include 5 | 6 | namespace Pinetime { 7 | namespace Applications { 8 | class HeartRateTask; 9 | } 10 | namespace System { 11 | class SystemTask; 12 | } 13 | namespace Controllers { 14 | class HeartRateController { 15 | public: 16 | enum class States { Stopped, NotEnoughData, NoTouch, Running }; 17 | 18 | HeartRateController() = default; 19 | void Start(); 20 | void Stop(); 21 | void Update(States newState, uint8_t heartRate); 22 | 23 | void SetHeartRateTask(Applications::HeartRateTask* task); 24 | States State() const { 25 | return state; 26 | } 27 | uint8_t HeartRate() const { 28 | return heartRate; 29 | } 30 | 31 | // void SetService(Pinetime::Controllers::HeartRateService* service); 32 | 33 | private: 34 | Applications::HeartRateTask* task = nullptr; 35 | States state = States::Stopped; 36 | uint8_t heartRate = 0; 37 | //Pinetime::Controllers::HeartRateService* service = nullptr; 38 | }; 39 | } 40 | } -------------------------------------------------------------------------------- /sim/displayapp/LittleVgl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace Pinetime { 7 | namespace Drivers { 8 | class St7789; 9 | } 10 | 11 | namespace Components { 12 | class LittleVgl { 13 | public: 14 | enum class FullRefreshDirections { None, Up, Down, Left, Right, LeftAnim, RightAnim }; 15 | LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Controllers::FS& filesystem); 16 | 17 | LittleVgl(const LittleVgl&) = delete; 18 | LittleVgl& operator=(const LittleVgl&) = delete; 19 | LittleVgl(LittleVgl&&) = delete; 20 | LittleVgl& operator=(LittleVgl&&) = delete; 21 | 22 | void Init(); 23 | 24 | void FlushDisplay(const lv_area_t* area, lv_color_t* color_p); 25 | bool GetTouchPadInfo(lv_indev_data_t* ptr); 26 | void SetFullRefresh(FullRefreshDirections direction); 27 | void SetNewTouchPoint(int16_t x, int16_t y, bool contact); 28 | void CancelTap(); 29 | void ClearTouchState(); 30 | 31 | bool GetFullRefresh() { 32 | bool returnValue = fullRefresh; 33 | if (fullRefresh) { 34 | fullRefresh = false; 35 | } 36 | return returnValue; 37 | } 38 | 39 | private: 40 | void InitDisplay(); 41 | void InitTouchpad(); 42 | void InitFileSystem(); 43 | 44 | Pinetime::Drivers::St7789& lcd; 45 | Pinetime::Controllers::FS& filesystem; 46 | 47 | lv_disp_buf_t disp_buf_2; 48 | lv_color_t buf2_1[LV_HOR_RES_MAX * 4]; 49 | lv_color_t buf2_2[LV_HOR_RES_MAX * 4]; 50 | 51 | lv_disp_drv_t disp_drv; 52 | 53 | bool fullRefresh = false; 54 | static constexpr uint8_t nbWriteLines = 4; 55 | static constexpr uint16_t totalNbLines = 320; 56 | static constexpr uint16_t visibleNbLines = 240; 57 | 58 | static constexpr uint8_t MaxScrollOffset() { 59 | return LV_VER_RES_MAX - nbWriteLines; 60 | } 61 | 62 | FullRefreshDirections scrollDirection = FullRefreshDirections::None; 63 | uint16_t writeOffset = 0; 64 | uint16_t scrollOffset = 0; 65 | 66 | lv_point_t touchPoint = {}; 67 | bool tapped = false; 68 | bool isCancelled = false; 69 | }; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /sim/drivers/Bma421.cpp: -------------------------------------------------------------------------------- 1 | #include "drivers/Bma421.h" 2 | #include 3 | #include 4 | #include "drivers/TwiMaster.h" 5 | #include 6 | 7 | using namespace Pinetime::Drivers; 8 | 9 | namespace { 10 | // int8_t user_i2c_read(uint8_t reg_addr, uint8_t* reg_data, uint32_t length, void* intf_ptr) { 11 | // auto bma421 = static_cast(intf_ptr); 12 | // bma421->Read(reg_addr, reg_data, length); 13 | // return 0; 14 | // } 15 | // 16 | // int8_t user_i2c_write(uint8_t reg_addr, const uint8_t* reg_data, uint32_t length, void* intf_ptr) { 17 | // auto bma421 = static_cast(intf_ptr); 18 | // bma421->Write(reg_addr, reg_data, length); 19 | // return 0; 20 | // } 21 | // 22 | // void user_delay(uint32_t period_us, void* intf_ptr) { 23 | // nrf_delay_us(period_us); 24 | // } 25 | } 26 | 27 | Bma421::Bma421(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaster}, deviceAddress {twiAddress} { 28 | // bma.intf = BMA4_I2C_INTF; 29 | // bma.bus_read = user_i2c_read; 30 | // bma.bus_write = user_i2c_write; 31 | // bma.variant = BMA42X_VARIANT; 32 | // bma.intf_ptr = this; 33 | // bma.delay_us = user_delay; 34 | // bma.read_write_len = 16; 35 | } 36 | 37 | void Bma421::Init() { 38 | if (not isResetOk) 39 | return; // Call SoftReset (and reset TWI device) first! 40 | 41 | // auto ret = bma423_init(&bma); 42 | // if (ret != BMA4_OK) 43 | // return; 44 | 45 | switch(bma.chip_id) { 46 | case BMA423_CHIP_ID: deviceType = DeviceTypes::BMA421; break; 47 | case BMA425_CHIP_ID: deviceType = DeviceTypes::BMA425; break; 48 | default: deviceType = DeviceTypes::Unknown; break; 49 | } 50 | 51 | // ret = bma423_write_config_file(&bma); 52 | // if (ret != BMA4_OK) 53 | // return; 54 | // 55 | // ret = bma4_set_interrupt_mode(BMA4_LATCH_MODE, &bma); 56 | // if (ret != BMA4_OK) 57 | // return; 58 | // 59 | // ret = bma423_feature_enable(BMA423_STEP_CNTR, 1, &bma); 60 | // if (ret != BMA4_OK) 61 | // return; 62 | // 63 | // ret = bma423_step_detector_enable(0, &bma); 64 | // if (ret != BMA4_OK) 65 | // return; 66 | // 67 | // ret = bma4_set_accel_enable(1, &bma); 68 | // if (ret != BMA4_OK) 69 | // return; 70 | // 71 | // struct bma4_accel_config accel_conf; 72 | // accel_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; 73 | // accel_conf.range = BMA4_ACCEL_RANGE_2G; 74 | // accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; 75 | // accel_conf.perf_mode = BMA4_CIC_AVG_MODE; 76 | // ret = bma4_set_accel_config(&accel_conf, &bma); 77 | // if (ret != BMA4_OK) 78 | // return; 79 | // 80 | isOk = true; 81 | } 82 | 83 | void Bma421::Reset() { 84 | uint8_t data = 0xb6; 85 | twiMaster.Write(deviceAddress, 0x7E, &data, 1); 86 | } 87 | 88 | void Bma421::Read(uint8_t registerAddress, uint8_t* buffer, size_t size) { 89 | twiMaster.Read(deviceAddress, registerAddress, buffer, size); 90 | } 91 | 92 | void Bma421::Write(uint8_t registerAddress, const uint8_t* data, size_t size) { 93 | twiMaster.Write(deviceAddress, registerAddress, data, size); 94 | } 95 | 96 | Bma421::Values Bma421::Process() { 97 | if (not isOk) 98 | return {}; 99 | // struct bma4_accel data; 100 | // bma4_read_accel_xyz(&data, &bma); 101 | // 102 | // uint32_t steps = 0; 103 | // bma423_step_counter_output(&steps, &bma); 104 | // 105 | // int32_t temperature = 0; 106 | // bma4_get_temperature(&temperature, BMA4_DEG, &bma); 107 | // temperature = temperature / 1000; 108 | // 109 | // uint8_t activity = 0; 110 | // bma423_activity_output(&activity, &bma); 111 | // 112 | // // X and Y axis are swapped because of the way the sensor is mounted in the PineTime 113 | // return {steps, data.y, data.x, data.z}; 114 | return {steps, 0, 0, 0}; 115 | } 116 | bool Bma421::IsOk() const { 117 | return isOk; 118 | } 119 | 120 | void Bma421::ResetStepCounter() { 121 | // bma423_reset_step_counter(&bma); 122 | steps = 0; 123 | } 124 | 125 | void Bma421::SoftReset() { 126 | // auto ret = bma4_soft_reset(&bma); 127 | // if (ret == BMA4_OK) { 128 | // isResetOk = true; 129 | // nrf_delay_ms(1); 130 | // } 131 | } 132 | Bma421::DeviceTypes Bma421::DeviceType() const { 133 | return deviceType; 134 | } 135 | -------------------------------------------------------------------------------- /sim/drivers/Bma421.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Pinetime { 8 | namespace Drivers { 9 | class TwiMaster; 10 | class Bma421 { 11 | public: 12 | enum class DeviceTypes : uint8_t { 13 | Unknown, 14 | BMA421, 15 | BMA425 16 | }; 17 | struct Values { 18 | uint32_t steps; 19 | int16_t x; 20 | int16_t y; 21 | int16_t z; 22 | }; 23 | Bma421(TwiMaster& twiMaster, uint8_t twiAddress); 24 | Bma421(const Bma421&) = delete; 25 | Bma421& operator=(const Bma421&) = delete; 26 | Bma421(Bma421&&) = delete; 27 | Bma421& operator=(Bma421&&) = delete; 28 | 29 | /// The chip freezes the TWI bus after the softreset operation. Softreset is separated from the 30 | /// Init() method to allow the caller to uninit and then reinit the TWI device after the softreset. 31 | void SoftReset(); 32 | void Init(); 33 | Values Process(); 34 | void ResetStepCounter(); 35 | 36 | void Read(uint8_t registerAddress, uint8_t* buffer, size_t size); 37 | void Write(uint8_t registerAddress, const uint8_t* data, size_t size); 38 | 39 | bool IsOk() const; 40 | DeviceTypes DeviceType() const; 41 | 42 | // lv_sim: returned by Process(), public to be modified by main.cpp 43 | uint32_t steps = 0; 44 | 45 | private: 46 | void Reset(); 47 | 48 | TwiMaster& twiMaster; 49 | uint8_t deviceAddress = 0x18; 50 | bma4_dev bma; 51 | bool isOk = true; 52 | bool isResetOk = false; 53 | DeviceTypes deviceType = DeviceTypes::Unknown; 54 | }; 55 | } 56 | } -------------------------------------------------------------------------------- /sim/drivers/Cst816s.cpp: -------------------------------------------------------------------------------- 1 | #include "drivers/Cst816s.h" 2 | #include "lv_drv_conf.h" // MONITOR_ZOOM 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace Pinetime::Drivers; 8 | 9 | /* References : 10 | * This implementation is based on this article : 11 | * https://medium.com/@ly.lee/building-a-rust-driver-for-pinetimes-touch-controller-cbc1a5d5d3e9 Touch panel datasheet (weird chinese 12 | * translation) : https://wiki.pine64.org/images/5/51/CST816S%E6%95%B0%E6%8D%AE%E6%89%8B%E5%86%8CV1.1.en.pdf 13 | * 14 | * TODO : we need a complete datasheet and protocol reference! 15 | * */ 16 | 17 | //Cst816S::Cst816S(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaster}, twiAddress {twiAddress} { 18 | //} 19 | Cst816S::Cst816S() { 20 | } 21 | 22 | bool Cst816S::Init() { 23 | return true; 24 | } 25 | 26 | Cst816S::TouchInfos Cst816S::GetTouchInfo() { 27 | int x, y; 28 | uint32_t buttons = SDL_GetMouseState(&x, &y); 29 | // scale down real mouse coordinates to InfiniTime scale to make zoom work 30 | // the MONITOR_ZOOM-factor is defined in lv_drv_conf.h 31 | x /= MONITOR_ZOOM; 32 | y /= MONITOR_ZOOM; 33 | 34 | Cst816S::TouchInfos info; 35 | info.x = x; 36 | info.y = y; 37 | info.touching = (buttons & SDL_BUTTON_LMASK) != 0; 38 | //info.gesture = gesture; 39 | info.isValid = x > 0 && x <= maxX && y > 0 && y <= maxY; 40 | if(info.isValid) { 41 | if(!is_pressed && info.touching) { 42 | // start klick 43 | pressed_since = std::chrono::steady_clock::now(); 44 | is_pressed = true; 45 | is_long_press = false; 46 | is_swipe = false; 47 | is_stationary = true; 48 | x_start = info.x; 49 | y_start = info.y; 50 | } else if(is_pressed && info.touching) { 51 | // is it long press? 52 | if (is_stationary) { // check if while touching we moved away from the start coordinates 53 | double x_diff = static_cast(info.x) - x_start; 54 | double y_diff = static_cast(info.y) - y_start; 55 | double norm = hypot(x_diff, y_diff); 56 | if(norm > 20) { // we moved out of start area 57 | is_stationary = false; 58 | } 59 | } 60 | if (!is_long_press && !is_swipe) { // check for long-press only if it's not yet a long-press and didn't move 61 | std::chrono::duration press_duration = std::chrono::steady_clock::now() - pressed_since; 62 | if(is_stationary && press_duration.count() > 1.0) { 63 | // longer than 1 second pressed, then it is long-press 64 | is_long_press = true; 65 | info.gesture = Gestures::LongPress; 66 | } else if(!is_stationary) { 67 | // moved mouse fast enough to not be a long-press 68 | is_swipe = true; 69 | double x_diff = static_cast(info.x) - x_start; 70 | double y_diff = static_cast(info.y) - y_start; 71 | if (fabs(x_diff) > fabs(y_diff)) { 72 | // x-swipe 73 | if (x_diff < 0) { 74 | info.gesture = Gestures::SlideLeft; 75 | } else { 76 | info.gesture = Gestures::SlideRight; 77 | } 78 | } else { 79 | // y-swipe 80 | if (y_diff < 0) { 81 | info.gesture = Gestures::SlideUp; 82 | } else { 83 | info.gesture = Gestures::SlideDown; 84 | } 85 | } 86 | } 87 | } 88 | } else if(is_pressed && !info.touching) { 89 | // end klick 90 | is_pressed = false; 91 | 92 | double x_diff = static_cast(info.x) - x_start; 93 | double y_diff = static_cast(info.y) - y_start; 94 | double norm = hypot(x_diff, y_diff); 95 | if(norm < 20) { 96 | if(is_stationary && !is_long_press && !is_swipe) { 97 | // no swipe with less than 5 pixel mouse movement 98 | info.gesture = Gestures::SingleTap; 99 | } 100 | } 101 | } 102 | } 103 | return info; 104 | } 105 | 106 | void Cst816S::Sleep() { 107 | NRF_LOG_INFO("[TOUCHPANEL] Sleep"); 108 | } 109 | 110 | void Cst816S::Wakeup() { 111 | Init(); 112 | NRF_LOG_INFO("[TOUCHPANEL] Wakeup"); 113 | } 114 | 115 | bool Cst816S::CheckDeviceIds() { 116 | return chipId == 0xb4 && vendorId == 0 && fwVersion == 1; 117 | } 118 | -------------------------------------------------------------------------------- /sim/drivers/Cst816s.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //#include "drivers/TwiMaster.h" 4 | #include 5 | #include 6 | 7 | namespace Pinetime { 8 | namespace Drivers { 9 | class Cst816S { 10 | public: 11 | enum class Gestures : uint8_t { 12 | None = 0x00, 13 | SlideDown = 0x01, 14 | SlideUp = 0x02, 15 | SlideLeft = 0x03, 16 | SlideRight = 0x04, 17 | SingleTap = 0x05, 18 | DoubleTap = 0x0B, 19 | LongPress = 0x0C 20 | }; 21 | struct TouchInfos { 22 | uint16_t x = 0; 23 | uint16_t y = 0; 24 | Gestures gesture = Gestures::None; 25 | bool touching = false; 26 | bool isValid = false; 27 | }; 28 | 29 | Cst816S(); 30 | // Cst816S(TwiMaster& twiMaster, uint8_t twiAddress); 31 | Cst816S(const Cst816S&) = delete; 32 | Cst816S& operator=(const Cst816S&) = delete; 33 | Cst816S(Cst816S&&) = delete; 34 | Cst816S& operator=(Cst816S&&) = delete; 35 | 36 | bool Init(); 37 | TouchInfos GetTouchInfo(); 38 | void Sleep(); 39 | void Wakeup(); 40 | 41 | uint8_t GetChipId() const { 42 | return chipId; 43 | } 44 | uint8_t GetVendorId() const { 45 | return vendorId; 46 | } 47 | uint8_t GetFwVersion() const { 48 | return fwVersion; 49 | } 50 | private: 51 | bool CheckDeviceIds(); 52 | 53 | // Unused/Unavailable commented out 54 | static constexpr uint8_t gestureIndex = 1; 55 | static constexpr uint8_t touchPointNumIndex = 2; 56 | //static constexpr uint8_t touchEventIndex = 3; 57 | static constexpr uint8_t touchXHighIndex = 3; 58 | static constexpr uint8_t touchXLowIndex = 4; 59 | //static constexpr uint8_t touchIdIndex = 5; 60 | static constexpr uint8_t touchYHighIndex = 5; 61 | static constexpr uint8_t touchYLowIndex = 6; 62 | //static constexpr uint8_t touchStep = 6; 63 | //static constexpr uint8_t touchXYIndex = 7; 64 | //static constexpr uint8_t touchMiscIndex = 8; 65 | 66 | static constexpr uint8_t maxX = 240; 67 | static constexpr uint8_t maxY = 240; 68 | 69 | // TwiMaster& twiMaster; 70 | // uint8_t twiAddress; 71 | 72 | const uint8_t chipId = 0xb4; 73 | const uint8_t vendorId = 0; 74 | const uint8_t fwVersion = 1; 75 | 76 | 77 | // simulation members for swipe detection from mouse 78 | std::chrono::time_point pressed_since; 79 | bool is_pressed = false; 80 | bool is_long_press = false; 81 | bool is_stationary = true; 82 | bool is_swipe = false; 83 | uint8_t x_start; 84 | uint8_t y_start; 85 | }; 86 | 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /sim/drivers/SpiMaster.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | //#include 8 | //#include 9 | 10 | namespace Pinetime { 11 | namespace Drivers { 12 | class SpiMaster { 13 | public: 14 | enum class SpiModule : uint8_t { SPI0, SPI1 }; 15 | enum class BitOrder : uint8_t { Msb_Lsb, Lsb_Msb }; 16 | enum class Modes : uint8_t { Mode0, Mode1, Mode2, Mode3 }; 17 | enum class Frequencies : uint8_t { Freq8Mhz }; 18 | struct Parameters { 19 | BitOrder bitOrder; 20 | Modes mode; 21 | Frequencies Frequency; 22 | uint8_t pinSCK; 23 | uint8_t pinMOSI; 24 | uint8_t pinMISO; 25 | }; 26 | 27 | SpiMaster(const SpiModule spi, const Parameters& params); 28 | SpiMaster(const SpiMaster&) = delete; 29 | SpiMaster& operator=(const SpiMaster&) = delete; 30 | SpiMaster(SpiMaster&&) = delete; 31 | SpiMaster& operator=(SpiMaster&&) = delete; 32 | 33 | bool Init(); 34 | bool Write(uint8_t pinCsn, const uint8_t* data, size_t size, const std::function& preTransactionHook); 35 | bool Read(uint8_t pinCsn, uint8_t* cmd, size_t cmdSize, uint8_t* data, size_t dataSize); 36 | 37 | bool WriteCmdAndBuffer(uint8_t pinCsn, const uint8_t* cmd, size_t cmdSize, const uint8_t* data, size_t dataSize); 38 | 39 | void OnStartedEvent(); 40 | void OnEndEvent(); 41 | 42 | void Sleep(); 43 | void Wakeup(); 44 | 45 | private: 46 | // void SetupWorkaroundForFtpan58(NRF_SPIM_Type* spim, uint32_t ppi_channel, uint32_t gpiote_channel); 47 | // void DisableWorkaroundForFtpan58(NRF_SPIM_Type* spim, uint32_t ppi_channel, uint32_t gpiote_channel); 48 | // void PrepareTx(const volatile uint32_t bufferAddress, const volatile size_t size); 49 | // void PrepareRx(const volatile uint32_t cmdAddress, 50 | // const volatile size_t cmdSize, 51 | // const volatile uint32_t bufferAddress, 52 | // const volatile size_t size); 53 | 54 | // NRF_SPIM_Type* spiBaseAddress; 55 | uint8_t pinCsn; 56 | 57 | SpiMaster::SpiModule spi; 58 | SpiMaster::Parameters params; 59 | 60 | volatile uint32_t currentBufferAddr = 0; 61 | volatile size_t currentBufferSize = 0; 62 | // volatile TaskHandle_t taskToNotify; 63 | // SemaphoreHandle_t mutex = nullptr; 64 | }; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /sim/drivers/SpiNorFlash.cpp: -------------------------------------------------------------------------------- 1 | #include "drivers/SpiNorFlash.h" 2 | #include 3 | #include 4 | #include "drivers/Spi.h" 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace Pinetime::Drivers; 10 | 11 | SpiNorFlash::SpiNorFlash(const std::string& memoryFilePath) : memoryFilePath{memoryFilePath} { 12 | namespace fs = std::filesystem; 13 | fs::path f{ memoryFilePath }; 14 | if (fs::exists(f)) { 15 | memoryFile = std::fstream(memoryFilePath, std::ios::binary | std::fstream::in | std::fstream::out); 16 | } else { 17 | memoryFile = std::fstream(memoryFilePath, std::ios::trunc | std::ios::binary | std::fstream::in | std::fstream::out); 18 | memoryFile.seekp(memorySize - 1); 19 | memoryFile.write("", 1); 20 | } 21 | } 22 | SpiNorFlash::~SpiNorFlash() { 23 | if (memoryFile.is_open()) { 24 | memoryFile.close(); 25 | } 26 | } 27 | 28 | void SpiNorFlash::Init() { 29 | device_id = ReadIdentification(); 30 | NRF_LOG_INFO( 31 | "[SpiNorFlash] Manufacturer : %d, Memory type : %d, memory density : %d", device_id.manufacturer, device_id.type, device_id.density); 32 | } 33 | 34 | void SpiNorFlash::Uninit() { 35 | } 36 | 37 | void SpiNorFlash::Sleep() { 38 | NRF_LOG_INFO("[SpiNorFlash] Sleep") 39 | } 40 | 41 | void SpiNorFlash::Wakeup() { 42 | NRF_LOG_INFO("[SpiNorFlash] Wakeup") 43 | } 44 | 45 | SpiNorFlash::Identification SpiNorFlash::ReadIdentification() { 46 | return {}; 47 | } 48 | 49 | uint8_t SpiNorFlash::ReadStatusRegister() { 50 | return 0; 51 | } 52 | 53 | bool SpiNorFlash::WriteInProgress() { 54 | return false; 55 | } 56 | 57 | bool SpiNorFlash::WriteEnabled() { 58 | return false; 59 | } 60 | 61 | uint8_t SpiNorFlash::ReadConfigurationRegister() { 62 | return 0; 63 | } 64 | 65 | void SpiNorFlash::Read(uint32_t address, uint8_t* buffer, size_t size) { 66 | static_assert(sizeof(uint8_t) == sizeof(char)); 67 | if (address + size * sizeof(uint8_t) > memorySize) { 68 | throw std::runtime_error("SpiNorFlash::Read out of bounds"); 69 | } 70 | memoryFile.seekp(address); 71 | memoryFile.read(reinterpret_cast(buffer), size); 72 | } 73 | 74 | void SpiNorFlash::WriteEnable() { 75 | 76 | } 77 | 78 | void SpiNorFlash::SectorErase(uint32_t sectorAddress) { 79 | 80 | } 81 | 82 | uint8_t SpiNorFlash::ReadSecurityRegister() { 83 | return 0; 84 | } 85 | 86 | bool SpiNorFlash::ProgramFailed() { 87 | return false; 88 | } 89 | 90 | bool SpiNorFlash::EraseFailed() { 91 | return false; 92 | } 93 | 94 | SpiNorFlash::Identification SpiNorFlash::GetIdentification() const { 95 | return device_id; 96 | } 97 | 98 | void SpiNorFlash::Write(uint32_t address, const uint8_t* buffer, size_t size) { 99 | if (address + size * sizeof(uint8_t) > memorySize) { 100 | throw std::runtime_error("SpiNorFlash::Write out of bounds"); 101 | } 102 | memoryFile.seekp(address); 103 | memoryFile.write(reinterpret_cast(buffer), size); 104 | memoryFile.flush(); 105 | } 106 | -------------------------------------------------------------------------------- /sim/drivers/SpiNorFlash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace Pinetime { 7 | namespace Drivers { 8 | class Spi; 9 | class SpiNorFlash { 10 | public: 11 | explicit SpiNorFlash(const std::string& memoryFilePath); 12 | ~SpiNorFlash(); 13 | SpiNorFlash(const SpiNorFlash&) = delete; 14 | SpiNorFlash& operator=(const SpiNorFlash&) = delete; 15 | SpiNorFlash(SpiNorFlash&&) = delete; 16 | SpiNorFlash& operator=(SpiNorFlash&&) = delete; 17 | 18 | struct __attribute__((packed)) Identification { 19 | uint8_t manufacturer = 0; 20 | uint8_t type = 0; 21 | uint8_t density = 0; 22 | }; 23 | 24 | uint8_t ReadStatusRegister(); 25 | bool WriteInProgress(); 26 | bool WriteEnabled(); 27 | uint8_t ReadConfigurationRegister(); 28 | void Read(uint32_t address, uint8_t* buffer, size_t size); 29 | void Write(uint32_t address, const uint8_t* buffer, size_t size); 30 | void WriteEnable(); 31 | void SectorErase(uint32_t sectorAddress); 32 | uint8_t ReadSecurityRegister(); 33 | bool ProgramFailed(); 34 | bool EraseFailed(); 35 | 36 | Identification GetIdentification() const; 37 | 38 | void Init(); 39 | void Uninit(); 40 | 41 | void Sleep(); 42 | void Wakeup(); 43 | 44 | private: 45 | Identification ReadIdentification(); 46 | 47 | enum class Commands : uint8_t { 48 | PageProgram = 0x02, 49 | Read = 0x03, 50 | ReadStatusRegister = 0x05, 51 | WriteEnable = 0x06, 52 | ReadConfigurationRegister = 0x15, 53 | SectorErase = 0x20, 54 | ReadSecurityRegister = 0x2B, 55 | ReadIdentification = 0x9F, 56 | ReleaseFromDeepPowerDown = 0xAB, 57 | DeepPowerDown = 0xB9 58 | }; 59 | static constexpr uint16_t pageSize = 256; 60 | 61 | static constexpr size_t memorySize {0x400000}; 62 | const std::string& memoryFilePath; 63 | 64 | 65 | Identification device_id; 66 | std::fstream memoryFile; 67 | }; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /sim/drivers/TwiMaster.cpp: -------------------------------------------------------------------------------- 1 | #include "drivers/TwiMaster.h" 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace Pinetime::Drivers; 7 | 8 | // TODO use shortcut to automatically send STOP when receive LastTX, for example 9 | // TODO use DMA/IRQ 10 | 11 | TwiMaster::TwiMaster(NRF_TWIM_Type* module, uint32_t frequency, uint8_t pinSda, uint8_t pinScl) 12 | : module {module}, frequency {frequency}, pinSda {pinSda}, pinScl {pinScl} { 13 | } 14 | 15 | //void TwiMaster::ConfigurePins() const { 16 | // NRF_GPIO->PIN_CNF[pinScl] = 17 | // (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | 18 | // (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | 19 | // (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | 20 | // (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | 21 | // (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); 22 | // 23 | // NRF_GPIO->PIN_CNF[pinSda] = 24 | // (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | 25 | // (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | 26 | // (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | 27 | // (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | 28 | // (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); 29 | //} 30 | 31 | void TwiMaster::Init() { 32 | // if (mutex == nullptr) { 33 | // mutex = xSemaphoreCreateBinary(); 34 | // } 35 | // 36 | // ConfigurePins(); 37 | // 38 | // twiBaseAddress = module; 39 | // 40 | // twiBaseAddress->FREQUENCY = frequency; 41 | // 42 | // twiBaseAddress->PSEL.SCL = pinScl; 43 | // twiBaseAddress->PSEL.SDA = pinSda; 44 | // twiBaseAddress->EVENTS_LASTRX = 0; 45 | // twiBaseAddress->EVENTS_STOPPED = 0; 46 | // twiBaseAddress->EVENTS_LASTTX = 0; 47 | // twiBaseAddress->EVENTS_ERROR = 0; 48 | // twiBaseAddress->EVENTS_RXSTARTED = 0; 49 | // twiBaseAddress->EVENTS_SUSPENDED = 0; 50 | // twiBaseAddress->EVENTS_TXSTARTED = 0; 51 | // 52 | // twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos); 53 | // 54 | // xSemaphoreGive(mutex); 55 | } 56 | 57 | TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* data, size_t size) { 58 | // xSemaphoreTake(mutex, portMAX_DELAY); 59 | // Wakeup(); 60 | // auto ret = Write(deviceAddress, ®isterAddress, 1, false); 61 | // ret = Read(deviceAddress, data, size, true); 62 | // Sleep(); 63 | // xSemaphoreGive(mutex); 64 | // return ret; 65 | return TwiMaster::ErrorCodes::NoError; 66 | } 67 | 68 | TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size) { 69 | // ASSERT(size <= maxDataSize); 70 | // xSemaphoreTake(mutex, portMAX_DELAY); 71 | // Wakeup(); 72 | // internalBuffer[0] = registerAddress; 73 | // std::memcpy(internalBuffer + 1, data, size); 74 | // auto ret = Write(deviceAddress, internalBuffer, size + 1, true); 75 | // Sleep(); 76 | // xSemaphoreGive(mutex); 77 | // return ret; 78 | return TwiMaster::ErrorCodes::NoError; 79 | } 80 | 81 | //TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t* buffer, size_t size, bool stop) { 82 | // twiBaseAddress->ADDRESS = deviceAddress; 83 | // twiBaseAddress->TASKS_RESUME = 0x1UL; 84 | // twiBaseAddress->RXD.PTR = (uint32_t) buffer; 85 | // twiBaseAddress->RXD.MAXCNT = size; 86 | // 87 | // twiBaseAddress->TASKS_STARTRX = 1; 88 | // 89 | // while (!twiBaseAddress->EVENTS_RXSTARTED && !twiBaseAddress->EVENTS_ERROR) 90 | // ; 91 | // twiBaseAddress->EVENTS_RXSTARTED = 0x0UL; 92 | // 93 | // txStartedCycleCount = DWT->CYCCNT; 94 | // uint32_t currentCycleCount; 95 | // while (!twiBaseAddress->EVENTS_LASTRX && !twiBaseAddress->EVENTS_ERROR) { 96 | // currentCycleCount = DWT->CYCCNT; 97 | // if ((currentCycleCount - txStartedCycleCount) > HwFreezedDelay) { 98 | // FixHwFreezed(); 99 | // return ErrorCodes::TransactionFailed; 100 | // } 101 | // } 102 | // twiBaseAddress->EVENTS_LASTRX = 0x0UL; 103 | // 104 | // if (stop || twiBaseAddress->EVENTS_ERROR) { 105 | // twiBaseAddress->TASKS_STOP = 0x1UL; 106 | // while (!twiBaseAddress->EVENTS_STOPPED) 107 | // ; 108 | // twiBaseAddress->EVENTS_STOPPED = 0x0UL; 109 | // } else { 110 | // twiBaseAddress->TASKS_SUSPEND = 0x1UL; 111 | // while (!twiBaseAddress->EVENTS_SUSPENDED) 112 | // ; 113 | // twiBaseAddress->EVENTS_SUSPENDED = 0x0UL; 114 | // } 115 | // 116 | // if (twiBaseAddress->EVENTS_ERROR) { 117 | // twiBaseAddress->EVENTS_ERROR = 0x0UL; 118 | // } 119 | // return ErrorCodes::NoError; 120 | //} 121 | 122 | //TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop) { 123 | // twiBaseAddress->ADDRESS = deviceAddress; 124 | // twiBaseAddress->TASKS_RESUME = 0x1UL; 125 | // twiBaseAddress->TXD.PTR = (uint32_t) data; 126 | // twiBaseAddress->TXD.MAXCNT = size; 127 | // 128 | // twiBaseAddress->TASKS_STARTTX = 1; 129 | // 130 | // while (!twiBaseAddress->EVENTS_TXSTARTED && !twiBaseAddress->EVENTS_ERROR) 131 | // ; 132 | // twiBaseAddress->EVENTS_TXSTARTED = 0x0UL; 133 | // 134 | // txStartedCycleCount = DWT->CYCCNT; 135 | // uint32_t currentCycleCount; 136 | // while (!twiBaseAddress->EVENTS_LASTTX && !twiBaseAddress->EVENTS_ERROR) { 137 | // currentCycleCount = DWT->CYCCNT; 138 | // if ((currentCycleCount - txStartedCycleCount) > HwFreezedDelay) { 139 | // FixHwFreezed(); 140 | // return ErrorCodes::TransactionFailed; 141 | // } 142 | // } 143 | // twiBaseAddress->EVENTS_LASTTX = 0x0UL; 144 | // 145 | // if (stop || twiBaseAddress->EVENTS_ERROR) { 146 | // twiBaseAddress->TASKS_STOP = 0x1UL; 147 | // while (!twiBaseAddress->EVENTS_STOPPED) 148 | // ; 149 | // twiBaseAddress->EVENTS_STOPPED = 0x0UL; 150 | // } else { 151 | // twiBaseAddress->TASKS_SUSPEND = 0x1UL; 152 | // while (!twiBaseAddress->EVENTS_SUSPENDED) 153 | // ; 154 | // twiBaseAddress->EVENTS_SUSPENDED = 0x0UL; 155 | // } 156 | // 157 | // if (twiBaseAddress->EVENTS_ERROR) { 158 | // twiBaseAddress->EVENTS_ERROR = 0x0UL; 159 | // uint32_t error = twiBaseAddress->ERRORSRC; 160 | // twiBaseAddress->ERRORSRC = error; 161 | // } 162 | // 163 | // return ErrorCodes::NoError; 164 | //} 165 | 166 | void TwiMaster::Sleep() { 167 | // twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos); 168 | } 169 | 170 | void TwiMaster::Wakeup() { 171 | // twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos); 172 | } 173 | 174 | /* Sometimes, the TWIM device just freeze and never set the event EVENTS_LASTTX. 175 | * This method disable and re-enable the peripheral so that it works again. 176 | * This is just a workaround, and it would be better if we could find a way to prevent 177 | * this issue from happening. 178 | * */ 179 | //void TwiMaster::FixHwFreezed() { 180 | // NRF_LOG_INFO("I2C device frozen, reinitializing it!"); 181 | // 182 | // uint32_t twi_state = NRF_TWI1->ENABLE; 183 | // 184 | // Sleep(); 185 | // 186 | // twiBaseAddress->ENABLE = twi_state; 187 | //} 188 | -------------------------------------------------------------------------------- /sim/drivers/TwiMaster.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | //#include 4 | #include // NRF_TWIM_Type 5 | #include 6 | 7 | namespace Pinetime { 8 | namespace Drivers { 9 | class TwiMaster { 10 | public: 11 | enum class ErrorCodes { NoError, TransactionFailed }; 12 | 13 | TwiMaster(NRF_TWIM_Type* module, uint32_t frequency, uint8_t pinSda, uint8_t pinScl); 14 | 15 | void Init(); 16 | ErrorCodes Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* buffer, size_t size); 17 | ErrorCodes Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size); 18 | 19 | void Sleep(); 20 | void Wakeup(); 21 | 22 | private: 23 | // ErrorCodes Read(uint8_t deviceAddress, uint8_t* buffer, size_t size, bool stop); 24 | // ErrorCodes Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop); 25 | // void FixHwFreezed(); 26 | // void ConfigurePins() const; 27 | 28 | NRF_TWIM_Type* twiBaseAddress; 29 | // SemaphoreHandle_t mutex = nullptr; 30 | NRF_TWIM_Type* module; 31 | uint32_t frequency; 32 | uint8_t pinSda; 33 | uint8_t pinScl; 34 | static constexpr uint8_t maxDataSize {16}; 35 | static constexpr uint8_t registerSize {1}; 36 | uint8_t internalBuffer[maxDataSize + registerSize]; 37 | uint32_t txStartedCycleCount = 0; 38 | static constexpr uint32_t HwFreezedDelay {161000}; 39 | }; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /sim/heartratetask/HeartRateTask.cpp: -------------------------------------------------------------------------------- 1 | #include "heartratetask/HeartRateTask.h" 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace Pinetime::Applications; 7 | 8 | HeartRateTask::HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller) 9 | : heartRateSensor {heartRateSensor}, controller {controller} { //, ppg{} { 10 | } 11 | 12 | void HeartRateTask::Start() { 13 | messageQueue = xQueueCreate(10, 1); 14 | controller.SetHeartRateTask(this); 15 | 16 | // if (pdPASS != xTaskCreate(HeartRateTask::Process, "Heartrate", 500, this, 0, &taskHandle)) 17 | // APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); 18 | } 19 | 20 | //void HeartRateTask::Process(void* instance) { 21 | // auto* app = static_cast(instance); 22 | // app->Work(); 23 | //} 24 | 25 | void HeartRateTask::Work() { 26 | // int lastBpm = 0; 27 | // while (true) { 28 | // Messages msg; 29 | // uint32_t delay; 30 | // if (state == States::Running) { 31 | // if (measurementStarted) 32 | // delay = 40; 33 | // else 34 | // delay = 100; 35 | // } else 36 | // delay = portMAX_DELAY; 37 | // 38 | // if (xQueueReceive(messageQueue, &msg, delay)) { 39 | // switch (msg) { 40 | // case Messages::GoToSleep: 41 | // StopMeasurement(); 42 | // state = States::Idle; 43 | // break; 44 | // case Messages::WakeUp: 45 | // state = States::Running; 46 | // if (measurementStarted) { 47 | // lastBpm = 0; 48 | // StartMeasurement(); 49 | // } 50 | // break; 51 | // case Messages::StartMeasurement: 52 | // if (measurementStarted) 53 | // break; 54 | // lastBpm = 0; 55 | // StartMeasurement(); 56 | // measurementStarted = true; 57 | // break; 58 | // case Messages::StopMeasurement: 59 | // if (!measurementStarted) 60 | // break; 61 | // StopMeasurement(); 62 | // measurementStarted = false; 63 | // break; 64 | // } 65 | // } 66 | // 67 | // if (measurementStarted) { 68 | // auto hrs = heartRateSensor.ReadHrs(); 69 | // ppg.Preprocess(hrs); 70 | // auto bpm = ppg.HeartRate(); 71 | // 72 | // if (lastBpm == 0 && bpm == 0) 73 | // controller.Update(Controllers::HeartRateController::States::NotEnoughData, 0); 74 | // if (bpm != 0) { 75 | // lastBpm = bpm; 76 | // controller.Update(Controllers::HeartRateController::States::Running, lastBpm); 77 | // } 78 | // } 79 | // } 80 | } 81 | 82 | void HeartRateTask::PushMessage(HeartRateTask::Messages msg) { 83 | BaseType_t xHigherPriorityTaskWoken; 84 | xHigherPriorityTaskWoken = pdFALSE; 85 | xQueueSendFromISR(messageQueue, &msg, &xHigherPriorityTaskWoken); 86 | if (xHigherPriorityTaskWoken) { 87 | /* Actual macro used here is port specific. */ 88 | // TODO : should I do something here? 89 | } 90 | } 91 | 92 | //void HeartRateTask::StartMeasurement() { 93 | // heartRateSensor.Enable(); 94 | // vTaskDelay(100); 95 | // ppg.SetOffset(static_cast(heartRateSensor.ReadHrs())); 96 | //} 97 | // 98 | //void HeartRateTask::StopMeasurement() { 99 | // heartRateSensor.Disable(); 100 | // vTaskDelay(100); 101 | //} 102 | -------------------------------------------------------------------------------- /sim/heartratetask/HeartRateTask.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | //#include 4 | #include 5 | //#include 6 | 7 | namespace Pinetime { 8 | namespace Drivers { 9 | class Hrs3300; 10 | } 11 | namespace Controllers { 12 | class HeartRateController; 13 | } 14 | namespace Applications { 15 | class HeartRateTask { 16 | public: 17 | enum class Messages : uint8_t { GoToSleep, WakeUp, StartMeasurement, StopMeasurement }; 18 | enum class States { Idle, Running }; 19 | 20 | explicit HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller); 21 | void Start(); 22 | void Work(); 23 | void PushMessage(Messages msg); 24 | 25 | private: 26 | //static void Process(void* instance); 27 | //void StartMeasurement(); 28 | //void StopMeasurement(); 29 | 30 | // TaskHandle_t taskHandle; 31 | QueueHandle_t messageQueue; 32 | States state = States::Running; 33 | Drivers::Hrs3300& heartRateSensor; 34 | Controllers::HeartRateController& controller; 35 | // Controllers::Ppg ppg; 36 | bool measurementStarted = false; 37 | }; 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /sim/host/ble_att.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | #ifndef H_BLE_ATT_ 21 | #define H_BLE_ATT_ 22 | 23 | /** 24 | * @brief Bluetooth Attribute Protocol (ATT) 25 | * @defgroup bt_att Bluetooth Attribute Protocol (ATT) 26 | * @ingroup bt_host 27 | * @{ 28 | */ 29 | 30 | // sim: no need for queue 31 | // #include "os/queue.h" 32 | // sim: add inttypes for uintX_t 33 | #include 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | 39 | struct os_mbuf; 40 | 41 | #define BLE_ATT_UUID_PRIMARY_SERVICE 0x2800 42 | #define BLE_ATT_UUID_SECONDARY_SERVICE 0x2801 43 | #define BLE_ATT_UUID_INCLUDE 0x2802 44 | #define BLE_ATT_UUID_CHARACTERISTIC 0x2803 45 | 46 | #define BLE_ATT_ERR_INVALID_HANDLE 0x01 47 | #define BLE_ATT_ERR_READ_NOT_PERMITTED 0x02 48 | #define BLE_ATT_ERR_WRITE_NOT_PERMITTED 0x03 49 | #define BLE_ATT_ERR_INVALID_PDU 0x04 50 | #define BLE_ATT_ERR_INSUFFICIENT_AUTHEN 0x05 51 | #define BLE_ATT_ERR_REQ_NOT_SUPPORTED 0x06 52 | #define BLE_ATT_ERR_INVALID_OFFSET 0x07 53 | #define BLE_ATT_ERR_INSUFFICIENT_AUTHOR 0x08 54 | #define BLE_ATT_ERR_PREPARE_QUEUE_FULL 0x09 55 | #define BLE_ATT_ERR_ATTR_NOT_FOUND 0x0a 56 | #define BLE_ATT_ERR_ATTR_NOT_LONG 0x0b 57 | #define BLE_ATT_ERR_INSUFFICIENT_KEY_SZ 0x0c 58 | #define BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN 0x0d 59 | #define BLE_ATT_ERR_UNLIKELY 0x0e 60 | #define BLE_ATT_ERR_INSUFFICIENT_ENC 0x0f 61 | #define BLE_ATT_ERR_UNSUPPORTED_GROUP 0x10 62 | #define BLE_ATT_ERR_INSUFFICIENT_RES 0x11 63 | 64 | #define BLE_ATT_OP_ERROR_RSP 0x01 65 | #define BLE_ATT_OP_MTU_REQ 0x02 66 | #define BLE_ATT_OP_MTU_RSP 0x03 67 | #define BLE_ATT_OP_FIND_INFO_REQ 0x04 68 | #define BLE_ATT_OP_FIND_INFO_RSP 0x05 69 | #define BLE_ATT_OP_FIND_TYPE_VALUE_REQ 0x06 70 | #define BLE_ATT_OP_FIND_TYPE_VALUE_RSP 0x07 71 | #define BLE_ATT_OP_READ_TYPE_REQ 0x08 72 | #define BLE_ATT_OP_READ_TYPE_RSP 0x09 73 | #define BLE_ATT_OP_READ_REQ 0x0a 74 | #define BLE_ATT_OP_READ_RSP 0x0b 75 | #define BLE_ATT_OP_READ_BLOB_REQ 0x0c 76 | #define BLE_ATT_OP_READ_BLOB_RSP 0x0d 77 | #define BLE_ATT_OP_READ_MULT_REQ 0x0e 78 | #define BLE_ATT_OP_READ_MULT_RSP 0x0f 79 | #define BLE_ATT_OP_READ_GROUP_TYPE_REQ 0x10 80 | #define BLE_ATT_OP_READ_GROUP_TYPE_RSP 0x11 81 | #define BLE_ATT_OP_WRITE_REQ 0x12 82 | #define BLE_ATT_OP_WRITE_RSP 0x13 83 | #define BLE_ATT_OP_PREP_WRITE_REQ 0x16 84 | #define BLE_ATT_OP_PREP_WRITE_RSP 0x17 85 | #define BLE_ATT_OP_EXEC_WRITE_REQ 0x18 86 | #define BLE_ATT_OP_EXEC_WRITE_RSP 0x19 87 | #define BLE_ATT_OP_NOTIFY_REQ 0x1b 88 | #define BLE_ATT_OP_INDICATE_REQ 0x1d 89 | #define BLE_ATT_OP_INDICATE_RSP 0x1e 90 | #define BLE_ATT_OP_WRITE_CMD 0x52 91 | 92 | #define BLE_ATT_ATTR_MAX_LEN 512 93 | 94 | #define BLE_ATT_F_READ 0x01 95 | #define BLE_ATT_F_WRITE 0x02 96 | #define BLE_ATT_F_READ_ENC 0x04 97 | #define BLE_ATT_F_READ_AUTHEN 0x08 98 | #define BLE_ATT_F_READ_AUTHOR 0x10 99 | #define BLE_ATT_F_WRITE_ENC 0x20 100 | #define BLE_ATT_F_WRITE_AUTHEN 0x40 101 | #define BLE_ATT_F_WRITE_AUTHOR 0x80 102 | 103 | #define HA_FLAG_PERM_RW (BLE_ATT_F_READ | BLE_ATT_F_WRITE) 104 | 105 | #define BLE_ATT_ACCESS_OP_READ 1 106 | #define BLE_ATT_ACCESS_OP_WRITE 2 107 | 108 | /** Default ATT MTU. Also the minimum. */ 109 | #define BLE_ATT_MTU_DFLT 23 110 | 111 | /** 112 | * An ATT MTU of 527 allows the largest ATT command (signed write) to contain a 113 | * 512-byte attribute value. 114 | */ 115 | #define BLE_ATT_MTU_MAX 527 116 | 117 | /** 118 | * Reads a locally registered attribute. If the specified attribute handle 119 | * corresponds to a GATT characteristic value or descriptor, the read is 120 | * performed by calling the registered GATT access callback. 121 | * 122 | * @param attr_handle The 16-bit handle of the attribute to read. 123 | * @param out_om On success, this is made to point to a 124 | * newly-allocated mbuf containing the 125 | * attribute data read. 126 | * 127 | * @return 0 on success; 128 | * NimBLE host ATT return code if the attribute 129 | * access callback reports failure; 130 | * NimBLE host core return code on unexpected 131 | * error. 132 | */ 133 | int ble_att_svr_read_local(uint16_t attr_handle, struct os_mbuf **out_om); 134 | 135 | /** 136 | * Writes a locally registered attribute. This function consumes the supplied 137 | * mbuf regardless of the outcome. If the specified attribute handle 138 | * corresponds to a GATT characteristic value or descriptor, the write is 139 | * performed by calling the registered GATT access callback. 140 | * 141 | * @param attr_handle The 16-bit handle of the attribute to write. 142 | * @param om The value to write to the attribute. 143 | * 144 | * @return 0 on success; 145 | * NimBLE host ATT return code if the attribute 146 | * access callback reports failure; 147 | * NimBLE host core return code on unexpected 148 | * error. 149 | */ 150 | int ble_att_svr_write_local(uint16_t attr_handle, struct os_mbuf *om); 151 | 152 | /** 153 | * Retrieves the ATT MTU of the specified connection. If an MTU exchange for 154 | * this connection has occurred, the MTU is the lower of the two peers' 155 | * preferred values. Otherwise, the MTU is the default value of 23. 156 | * 157 | * @param conn_handle The handle of the connection to query. 158 | * 159 | * @return The specified connection's ATT MTU, or 0 if 160 | * there is no such connection. 161 | */ 162 | uint16_t ble_att_mtu(uint16_t conn_handle); 163 | 164 | /** 165 | * Retrieves the preferred ATT MTU. This is the value indicated by the device 166 | * during an ATT MTU exchange. 167 | * 168 | * @return The preferred ATT MTU. 169 | */ 170 | uint16_t ble_att_preferred_mtu(void); 171 | 172 | /** 173 | * Sets the preferred ATT MTU; the device will indicate this value in all 174 | * subsequent ATT MTU exchanges. The ATT MTU of a connection is equal to the 175 | * lower of the two peers' preferred MTU values. The ATT MTU is what dictates 176 | * the maximum size of any message sent during a GATT procedure. 177 | * 178 | * The specified MTU must be within the following range: [23, BLE_ATT_MTU_MAX]. 179 | * 23 is a minimum imposed by the Bluetooth specification; BLE_ATT_MTU_MAX is a 180 | * NimBLE compile-time setting. 181 | * 182 | * @param mtu The preferred ATT MTU. 183 | * 184 | * @return 0 on success; 185 | * BLE_HS_EINVAL if the specified value is not 186 | * within the allowed range. 187 | */ 188 | int ble_att_set_preferred_mtu(uint16_t mtu); 189 | 190 | #ifdef __cplusplus 191 | } 192 | #endif 193 | 194 | /** 195 | * @} 196 | */ 197 | 198 | #endif 199 | -------------------------------------------------------------------------------- /sim/host/ble_gap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | #ifndef H_BLE_GAP_ 21 | #define H_BLE_GAP_ 22 | 23 | /** 24 | * @brief Bluetooth Host Generic Access Profile (GAP) 25 | * @defgroup bt_host_gap Bluetooth Host Generic Access Profile (GAP) 26 | * @ingroup bt_host 27 | * @{ 28 | */ 29 | 30 | #include 31 | #include "host/ble_gatt.h" 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | /** 44 | * @} 45 | */ 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /sim/host/ble_gatt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | #include "host/ble_gatt.h" 21 | 22 | int ble_gattc_notify_custom(uint16_t conn_handle, uint16_t att_handle, 23 | struct os_mbuf *om) 24 | { 25 | return 0; 26 | } 27 | 28 | int 29 | ble_gatts_count_cfg(const struct ble_gatt_svc_def *defs) 30 | { 31 | //struct ble_gatt_resources res = { 0 }; 32 | //int rc; 33 | 34 | //rc = ble_gatts_count_resources(defs, &res); 35 | //if (rc != 0) { 36 | // return rc; 37 | //} 38 | 39 | //ble_hs_max_services += res.svcs; 40 | //ble_hs_max_attrs += res.attrs; 41 | 42 | ///* Reserve an extra CCCD for the cache. */ 43 | //ble_hs_max_client_configs += 44 | // res.cccds * (MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1); 45 | 46 | return 0; 47 | } 48 | 49 | int 50 | ble_gatts_add_svcs(const struct ble_gatt_svc_def *svcs) 51 | { 52 | // void *p; 53 | // int rc; 54 | // 55 | // ble_hs_lock(); 56 | // if (!ble_gatts_mutable()) { 57 | // rc = BLE_HS_EBUSY; 58 | // goto done; 59 | // } 60 | // 61 | // p = realloc(ble_gatts_svc_defs, 62 | // (ble_gatts_num_svc_defs + 1) * sizeof *ble_gatts_svc_defs); 63 | // if (p == NULL) { 64 | // rc = BLE_HS_ENOMEM; 65 | // goto done; 66 | // } 67 | // 68 | // ble_gatts_svc_defs = p; 69 | // ble_gatts_svc_defs[ble_gatts_num_svc_defs] = svcs; 70 | // ble_gatts_num_svc_defs++; 71 | // 72 | // rc = 0; 73 | // 74 | //done: 75 | // ble_hs_unlock(); 76 | // return rc; 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /sim/host/ble_hs_mbuf.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | #include "host/ble_hs_mbuf.h" 21 | 22 | 23 | struct os_mbuf *ble_hs_mbuf_from_flat(const void *buf, uint16_t len) 24 | { 25 | return (os_mbuf *)nullptr; 26 | } 27 | -------------------------------------------------------------------------------- /sim/host/ble_hs_mbuf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | #ifndef H_BLE_HS_MBUF_ 21 | #define H_BLE_HS_MBUF_ 22 | 23 | /** 24 | * @brief Bluetooth Host chained memory buffer (mbuf) 25 | * @defgroup bt_host_mbuf Bluetooth Host chained memory buffer (mbuf) 26 | * @ingroup bt_host 27 | * @{ 28 | */ 29 | 30 | #include 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | // sim: copied from ble_hs.h 36 | /** Connection handle not present */ 37 | #define BLE_HS_CONN_HANDLE_NONE 0xffff 38 | // sim: end copied from ble_hs.h 39 | 40 | 41 | struct os_mbuf; 42 | 43 | /** 44 | * Allocates an mbuf suitable for an ATT command packet. The resulting packet 45 | * has sufficient leading space for: 46 | * - ACL data header 47 | * - L2CAP B-frame header 48 | * - Largest ATT command base (prepare write request / response). 49 | * 50 | * @return An empty mbuf on success, NULL on error. 51 | */ 52 | //struct os_mbuf *ble_hs_mbuf_att_pkt(void); 53 | 54 | /** 55 | * Allocates an mbuf and fills it with the contents of the specified flat 56 | * buffer. 57 | * 58 | * @param buf The flat buffer to copy from. 59 | * @param len The length of the flat buffer. 60 | * 61 | * @return A newly-allocated mbuf on success, NULL on error. 62 | */ 63 | struct os_mbuf *ble_hs_mbuf_from_flat(const void *buf, uint16_t len); 64 | 65 | /** 66 | * Copies the contents of an mbuf into the specified flat buffer. If the flat 67 | * buffer is too small to contain the mbuf's contents, it is filled to capacity 68 | * and BLE_HS_EMSGSIZE is returned. 69 | * 70 | * @param om The mbuf to copy from. 71 | * @param flat The destination flat buffer. 72 | * @param max_len The size of the flat buffer. 73 | * @param out_copy_len The number of bytes actually copied gets written here. 74 | * 75 | * @return 0 on success or BLE host core return code on error. 76 | */ 77 | //int ble_hs_mbuf_to_flat(const struct os_mbuf *om, void *flat, uint16_t max_len, 78 | // uint16_t *out_copy_len); 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | 84 | /** 85 | * @} 86 | */ 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /sim/host/ble_uuid.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | #include "host/ble_uuid.h" 21 | 22 | 23 | int 24 | ble_uuid_cmp(const ble_uuid_t *uuid1, const ble_uuid_t *uuid2) 25 | { 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /sim/host/ble_uuid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | #ifndef H_BLE_UUID_ 21 | #define H_BLE_UUID_ 22 | 23 | /** 24 | * @brief Bluetooth UUID 25 | * @defgroup bt_uuid Bluetooth UUID 26 | * @ingroup bt_host 27 | * @{ 28 | */ 29 | 30 | #include 31 | #include 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | struct os_mbuf; 38 | 39 | /** Type of UUID */ 40 | enum { 41 | /** 16-bit UUID (BT SIG assigned) */ 42 | BLE_UUID_TYPE_16 = 16, 43 | 44 | /** 32-bit UUID (BT SIG assigned) */ 45 | BLE_UUID_TYPE_32 = 32, 46 | 47 | /** 128-bit UUID */ 48 | BLE_UUID_TYPE_128 = 128, 49 | }; 50 | 51 | /** Generic UUID type, to be used only as a pointer */ 52 | typedef struct { 53 | /** Type of the UUID */ 54 | uint8_t type; 55 | } ble_uuid_t; 56 | 57 | /** 16-bit UUID */ 58 | typedef struct { 59 | ble_uuid_t u; 60 | uint16_t value; 61 | } ble_uuid16_t; 62 | 63 | /** 32-bit UUID */ 64 | typedef struct { 65 | ble_uuid_t u; 66 | uint32_t value; 67 | } ble_uuid32_t; 68 | 69 | /** 128-bit UUID */ 70 | typedef struct { 71 | ble_uuid_t u; 72 | uint8_t value[16]; 73 | } ble_uuid128_t; 74 | 75 | /** Universal UUID type, to be used for any-UUID static allocation */ 76 | typedef union { 77 | ble_uuid_t u; 78 | ble_uuid16_t u16; 79 | ble_uuid32_t u32; 80 | ble_uuid128_t u128; 81 | } ble_uuid_any_t; 82 | 83 | /** @brief Compares two Bluetooth UUIDs. 84 | * 85 | * @param uuid1 The first UUID to compare. 86 | * @param uuid2 The second UUID to compare. 87 | * 88 | * @return 0 if the two UUIDs are equal, nonzero if the UUIDs differ. 89 | */ 90 | int ble_uuid_cmp(const ble_uuid_t *uuid1, const ble_uuid_t *uuid2); 91 | 92 | #ifdef __cplusplus 93 | } 94 | #endif 95 | 96 | /** 97 | * @} 98 | */ 99 | 100 | #endif /* _BLE_HOST_UUID_H */ 101 | -------------------------------------------------------------------------------- /sim/host/os_mbuf.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | #include "host/os_mbuf.h" 21 | 22 | 23 | int 24 | os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst) 25 | { 26 | return 0; 27 | } 28 | 29 | int 30 | os_mbuf_append(struct os_mbuf *om, const void *data, uint16_t len) 31 | { 32 | return 0; 33 | } -------------------------------------------------------------------------------- /sim/host/os_mbuf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | 21 | /** 22 | * @addtogroup OSKernel 23 | * @{ 24 | * @defgroup OSMbuf Chained Memory Buffers 25 | * @{ 26 | */ 27 | 28 | 29 | #ifndef _OS_MBUF_H 30 | #define _OS_MBUF_H 31 | 32 | #include 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | 39 | /** 40 | * A packet header structure that preceeds the mbuf packet headers. 41 | */ 42 | struct os_mbuf_pkthdr { 43 | /** 44 | * Overall length of the packet. 45 | */ 46 | uint16_t omp_len; 47 | /** 48 | * Flags 49 | */ 50 | uint16_t omp_flags; 51 | 52 | // sim: disabled 53 | // STAILQ_ENTRY(os_mbuf_pkthdr) omp_next; 54 | }; 55 | 56 | /** 57 | * Chained memory buffer. 58 | */ 59 | struct os_mbuf { 60 | /** 61 | * Current pointer to data in the structure 62 | */ 63 | uint8_t *om_data; 64 | /** 65 | * Flags associated with this buffer, see OS_MBUF_F_* defintions 66 | */ 67 | uint8_t om_flags; 68 | /** 69 | * Length of packet header 70 | */ 71 | uint8_t om_pkthdr_len; 72 | /** 73 | * Length of data in this buffer 74 | */ 75 | uint16_t om_len; 76 | 77 | // sim: disabled, not used by InfiniSim 78 | ///** 79 | // * The mbuf pool this mbuf was allocated out of 80 | // */ 81 | //struct os_mbuf_pool *om_omp; 82 | 83 | //SLIST_ENTRY(os_mbuf) om_next; 84 | 85 | /** 86 | * Pointer to the beginning of the data, after this buffer 87 | */ 88 | uint8_t om_databuf[0]; 89 | }; 90 | 91 | 92 | /** Get a packet header pointer given an mbuf pointer */ 93 | #define OS_MBUF_PKTHDR(__om) ((struct os_mbuf_pkthdr *) \ 94 | ((uint8_t *)&(__om)->om_data + sizeof(struct os_mbuf))) 95 | 96 | /** 97 | * Gets the length of an entire mbuf chain. The specified mbuf must have a 98 | * packet header. 99 | */ 100 | #define OS_MBUF_PKTLEN(__om) (OS_MBUF_PKTHDR(__om)->omp_len) 101 | 102 | // sim: function from os_mbuf.h 103 | /* 104 | * Copy data from an mbuf chain starting "off" bytes from the beginning, 105 | * continuing for "len" bytes, into the indicated buffer. 106 | * 107 | * @param m The mbuf chain to copy from 108 | * @param off The offset into the mbuf chain to begin copying from 109 | * @param len The length of the data to copy 110 | * @param dst The destination buffer to copy into 111 | * 112 | * @return 0 on success; 113 | * -1 if the mbuf does not contain enough data. 114 | */ 115 | int os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst); 116 | 117 | 118 | /** 119 | * Append data onto a mbuf 120 | * 121 | * @param om The mbuf to append the data onto 122 | * @param data The data to append onto the mbuf 123 | * @param len The length of the data to append 124 | * 125 | * @return 0 on success, and an error code on failure 126 | */ 127 | int os_mbuf_append(struct os_mbuf *m, const void *, uint16_t); 128 | 129 | 130 | #ifdef __cplusplus 131 | } 132 | #endif 133 | 134 | /** 135 | * @} 136 | */ 137 | 138 | #endif 139 | -------------------------------------------------------------------------------- /sim/libraries/delay/nrf_delay.cpp: -------------------------------------------------------------------------------- 1 | #include "libraries/delay/nrf_delay.h" 2 | #include 3 | 4 | void nrf_delay_ms(uint32_t ms_time) 5 | { 6 | SDL_Delay(ms_time); 7 | } -------------------------------------------------------------------------------- /sim/libraries/delay/nrf_delay.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2011 - 2019, Nordic Semiconductor ASA 3 | * 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this 10 | * list of conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form, except as embedded into a Nordic 13 | * Semiconductor ASA integrated circuit in a product or a software update for 14 | * such product, must reproduce the above copyright notice, this list of 15 | * conditions and the following disclaimer in the documentation and/or other 16 | * materials provided with the distribution. 17 | * 18 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 19 | * contributors may be used to endorse or promote products derived from this 20 | * software without specific prior written permission. 21 | * 22 | * 4. This software, with or without modification, must only be used with a 23 | * Nordic Semiconductor ASA integrated circuit. 24 | * 25 | * 5. Any software provided in binary form under this license must not be reverse 26 | * engineered, decompiled, modified and/or disassembled. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 29 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 32 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 34 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 37 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | */ 40 | 41 | #ifndef _NRF_DELAY_H 42 | #define _NRF_DELAY_H 43 | 44 | #include 45 | 46 | /** 47 | * @brief Function for delaying execution for a number of milliseconds. 48 | * 49 | * @param ms_time Number of milliseconds to wait. 50 | */ 51 | 52 | void nrf_delay_ms(uint32_t ms_time); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /sim/libraries/gpiote/app_gpiote.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "hal/nrf_gpio.h" 3 | -------------------------------------------------------------------------------- /sim/libraries/log/nrf_log.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016 - 2019, Nordic Semiconductor ASA 3 | * 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this 10 | * list of conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form, except as embedded into a Nordic 13 | * Semiconductor ASA integrated circuit in a product or a software update for 14 | * such product, must reproduce the above copyright notice, this list of 15 | * conditions and the following disclaimer in the documentation and/or other 16 | * materials provided with the distribution. 17 | * 18 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 19 | * contributors may be used to endorse or promote products derived from this 20 | * software without specific prior written permission. 21 | * 22 | * 4. This software, with or without modification, must only be used with a 23 | * Nordic Semiconductor ASA integrated circuit. 24 | * 25 | * 5. Any software provided in binary form under this license must not be reverse 26 | * engineered, decompiled, modified and/or disassembled. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 29 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 32 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 34 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 37 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | */ 40 | /**@file 41 | * 42 | * @defgroup nrf_log Logger module 43 | * @{ 44 | * @ingroup app_common 45 | * 46 | * @brief The nrf_log module interface. 47 | */ 48 | 49 | #ifndef NRF_LOG_H_ 50 | #define NRF_LOG_H_ 51 | 52 | #include 53 | 54 | #define NRF_LOG_ERROR(...) do {printf("error: "); printf( __VA_ARGS__ ); printf("\n"); } while(false); 55 | #define NRF_LOG_WARNING(...) do {printf("warn: "); printf( __VA_ARGS__ ); printf("\n"); } while(false); 56 | #define NRF_LOG_INFO(...) do {printf("info: "); printf( __VA_ARGS__ ); printf("\n"); } while(false); 57 | #define NRF_LOG_DEBUG(...) do {printf("debug: "); printf( __VA_ARGS__ ); printf("\n"); } while(false); 58 | 59 | 60 | #endif // NRF_LOG_H_ 61 | -------------------------------------------------------------------------------- /sim/nrf_assert.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #ifndef ASSERT 5 | #define ASSERT(expr) assert(expr) 6 | #endif 7 | -------------------------------------------------------------------------------- /sim/nrfx/drivers/include/nrfx_twi.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 3 | * 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this 10 | * list of conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form, except as embedded into a Nordic 13 | * Semiconductor ASA integrated circuit in a product or a software update for 14 | * such product, must reproduce the above copyright notice, this list of 15 | * conditions and the following disclaimer in the documentation and/or other 16 | * materials provided with the distribution. 17 | * 18 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 19 | * contributors may be used to endorse or promote products derived from this 20 | * software without specific prior written permission. 21 | * 22 | * 4. This software, with or without modification, must only be used with a 23 | * Nordic Semiconductor ASA integrated circuit. 24 | * 25 | * 5. Any software provided in binary form under this license must not be reverse 26 | * engineered, decompiled, modified and/or disassembled. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 29 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 32 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 34 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 37 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | */ 40 | 41 | #ifndef NRFX_TWI_H__ 42 | #define NRFX_TWI_H__ 43 | 44 | #include 45 | 46 | /** 47 | * @brief I2C compatible Two-Wire Master Interface with EasyDMA 0 (TWIM0) 48 | */ 49 | 50 | struct NRF_TWIM_Type { /*!< (@ 0x40003000) TWIM0 Structure */ 51 | uint32_t TASKS_STARTRX; /*!< (@ 0x00000000) Start TWI receive sequence */ 52 | uint32_t RESERVED; 53 | uint32_t TASKS_STARTTX; /*!< (@ 0x00000008) Start TWI transmit sequence */ 54 | uint32_t RESERVED1[2]; 55 | uint32_t TASKS_STOP; /*!< (@ 0x00000014) Stop TWI transaction. Must be issued while the 56 | TWI master is not suspended. */ 57 | uint32_t RESERVED2; 58 | uint32_t TASKS_SUSPEND; /*!< (@ 0x0000001C) Suspend TWI transaction */ 59 | uint32_t TASKS_RESUME; /*!< (@ 0x00000020) Resume TWI transaction */ 60 | uint32_t RESERVED3[56]; 61 | uint32_t EVENTS_STOPPED; /*!< (@ 0x00000104) TWI stopped */ 62 | uint32_t RESERVED4[7]; 63 | uint32_t EVENTS_ERROR; /*!< (@ 0x00000124) TWI error */ 64 | uint32_t RESERVED5[8]; 65 | uint32_t EVENTS_SUSPENDED; /*!< (@ 0x00000148) Last byte has been sent out after the SUSPEND 66 | task has been issued, TWI traffic is now 67 | suspended. */ 68 | uint32_t EVENTS_RXSTARTED; /*!< (@ 0x0000014C) Receive sequence started */ 69 | uint32_t EVENTS_TXSTARTED; /*!< (@ 0x00000150) Transmit sequence started */ 70 | uint32_t RESERVED6[2]; 71 | uint32_t EVENTS_LASTRX; /*!< (@ 0x0000015C) Byte boundary, starting to receive the last byte */ 72 | uint32_t EVENTS_LASTTX; /*!< (@ 0x00000160) Byte boundary, starting to transmit the last 73 | byte */ 74 | uint32_t RESERVED7[39]; 75 | uint32_t SHORTS; /*!< (@ 0x00000200) Shortcut register */ 76 | uint32_t RESERVED8[63]; 77 | uint32_t INTEN; /*!< (@ 0x00000300) Enable or disable interrupt */ 78 | uint32_t INTENSET; /*!< (@ 0x00000304) Enable interrupt */ 79 | uint32_t INTENCLR; /*!< (@ 0x00000308) Disable interrupt */ 80 | uint32_t RESERVED9[110]; 81 | uint32_t ERRORSRC; /*!< (@ 0x000004C4) Error source */ 82 | uint32_t RESERVED10[14]; 83 | uint32_t ENABLE; /*!< (@ 0x00000500) Enable TWIM */ 84 | uint32_t RESERVED11; 85 | /// TWIM_PSEL_Type PSEL; /*!< (@ 0x00000508) Unspecified */ 86 | uint32_t RESERVED12[5]; 87 | uint32_t FREQUENCY; /*!< (@ 0x00000524) TWI frequency */ 88 | uint32_t RESERVED13[3]; 89 | // TWIM_RXD_Type RXD; /*!< (@ 0x00000534) RXD EasyDMA channel */ 90 | // TWIM_TXD_Type TXD; /*!< (@ 0x00000544) TXD EasyDMA channel */ 91 | uint32_t RESERVED14[13]; 92 | uint32_t ADDRESS; /*!< (@ 0x00000588) Address used in the TWI transfer */ 93 | }; /*!< Size = 1420 (0x58c) */ 94 | 95 | #endif // NRFX_TWI_H__ 96 | -------------------------------------------------------------------------------- /sim/nrfx/hal/nrf_gpio.cpp: -------------------------------------------------------------------------------- 1 | #include "hal/nrf_gpio.h" 2 | 3 | #include "drivers/PinMap.h" 4 | 5 | #include 6 | #include 7 | #include // std::to_string 8 | 9 | bool motor_running = false; 10 | 11 | void nrf_gpio_cfg_default(uint32_t pin_number) { 12 | if (pin_number == Pinetime::PinMap::Motor) 13 | { 14 | motor_running = true; 15 | } 16 | } 17 | void nrf_gpio_pin_set(uint32_t pin_number) { 18 | if (pin_number == Pinetime::PinMap::Motor) 19 | { 20 | motor_running = false; 21 | } 22 | } 23 | uint32_t nrf_gpio_pin_read(uint32_t pin_number) 24 | { 25 | if (pin_number == Pinetime::PinMap::Button) { 26 | int x, y; 27 | uint32_t buttons = SDL_GetMouseState(&x, &y); 28 | bool right_click = (buttons & SDL_BUTTON_RMASK) != 0; 29 | return right_click; 30 | } 31 | else if (pin_number == Pinetime::PinMap::Motor) 32 | { 33 | return motor_running; 34 | } 35 | throw std::runtime_error("nrf_gpio_pin_read: unhandled pin_number: " + std::to_string(pin_number)); 36 | return 0; 37 | } 38 | 39 | void nrf_gpio_cfg_output(uint32_t pin_number) {} 40 | void nrf_gpio_pin_clear(uint32_t pin_number) { 41 | if (pin_number == Pinetime::PinMap::Motor) 42 | { 43 | motor_running = true; 44 | } 45 | } 46 | void nrf_gpio_range_cfg_input(uint32_t pin_range_start, 47 | uint32_t pin_range_end, 48 | nrf_gpio_pin_pull_t pull_config) {} 49 | void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config) {} 50 | 51 | void nrfx_gpiote_in_init(uint32_t pin_number, nrfx_gpiote_in_config_t *config, nrfx_gpiote_event_handler_t) {} 52 | void nrfx_gpiote_in_event_enable(uint32_t pin_number, bool enable) {} 53 | void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pin_pull, nrf_gpio_pin_sense_t sense) {} 54 | 55 | bool nrfx_gpiote_is_init() { return true; } 56 | void nrfx_gpiote_init() {} 57 | 58 | void APP_GPIOTE_INIT(uint32_t max_users) {} 59 | -------------------------------------------------------------------------------- /sim/nrfx/hal/nrf_gpio.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 3 | * 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this 10 | * list of conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form, except as embedded into a Nordic 13 | * Semiconductor ASA integrated circuit in a product or a software update for 14 | * such product, must reproduce the above copyright notice, this list of 15 | * conditions and the following disclaimer in the documentation and/or other 16 | * materials provided with the distribution. 17 | * 18 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 19 | * contributors may be used to endorse or promote products derived from this 20 | * software without specific prior written permission. 21 | * 22 | * 4. This software, with or without modification, must only be used with a 23 | * Nordic Semiconductor ASA integrated circuit. 24 | * 25 | * 5. Any software provided in binary form under this license must not be reverse 26 | * engineered, decompiled, modified and/or disassembled. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 29 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 32 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 34 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 37 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | */ 40 | 41 | #ifndef NRF_GPIO_H__ 42 | #define NRF_GPIO_H__ 43 | 44 | #include 45 | 46 | /** 47 | * @brief Enumerator used for selecting the pin to be pulled down or up at the time of pin configuration. 48 | */ 49 | // lv_sim: values copied from nrf52810_bifiellds.h 50 | enum nrf_gpio_pin_pull_t 51 | { 52 | NRF_GPIO_PIN_NOPULL = 0, // GPIO_PIN_CNF_PULL_Disabled, ///< Pin pull-up resistor disabled. 53 | NRF_GPIO_PIN_PULLDOWN = 1, // GPIO_PIN_CNF_PULL_Pulldown, ///< Pin pull-down resistor enabled. 54 | NRF_GPIO_PIN_PULLUP = 3, // GPIO_PIN_CNF_PULL_Pullup, ///< Pin pull-up resistor enabled. 55 | }; 56 | constexpr uint16_t GPIO_PIN_CNF_PULL_Pulldown = 1; 57 | constexpr uint16_t GPIO_PIN_CNF_PULL_Pullup = 3; 58 | 59 | using nrf_gpiote_polarity_t = uint32_t; 60 | constexpr uint16_t NRF_GPIOTE_POLARITY_HITOLO = 2; 61 | constexpr uint16_t NRF_GPIOTE_POLARITY_TOGGLE = 3; 62 | 63 | using nrfx_gpiote_pin_t = uint32_t; 64 | typedef void (*nrfx_gpiote_event_handler_t)(nrfx_gpiote_pin_t, nrf_gpiote_polarity_t); 65 | 66 | using nrf_gpio_pin_sense_t = uint32_t; 67 | constexpr uint16_t GPIO_PIN_CNF_SENSE_Low = 3; 68 | 69 | struct nrfx_gpiote_in_config_t { 70 | bool skip_gpio_setup = false; 71 | bool hi_accuracy = false; 72 | bool is_watcher = false; 73 | nrf_gpiote_polarity_t sense; 74 | nrf_gpio_pin_pull_t pull; 75 | }; 76 | 77 | /** 78 | * @brief Function for resetting pin configuration to its default state. 79 | * 80 | * @param pin_number Specifies the pin number. 81 | */ 82 | void nrf_gpio_cfg_default(uint32_t pin_number); 83 | 84 | /** 85 | * @brief Function for setting a GPIO pin. 86 | * 87 | * Note that the pin must be configured as an output for this function to have any effect. 88 | * 89 | * @param pin_number Specifies the pin number to set. 90 | */ 91 | void nrf_gpio_pin_set(uint32_t pin_number); 92 | 93 | // read pin stub, intended to forward right mouse button as PinMap::Button 94 | uint32_t nrf_gpio_pin_read(uint32_t pin_number); 95 | 96 | /** 97 | * @brief Function for configuring the given GPIO pin number as output, hiding inner details. 98 | * This function can be used to configure a pin as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). 99 | * 100 | * @param pin_number Specifies the pin number. 101 | * 102 | * @note Sense capability on the pin is disabled and input is disconnected from the buffer as the pins are configured as output. 103 | */ 104 | void nrf_gpio_cfg_output(uint32_t pin_number); 105 | 106 | /** 107 | * @brief Function for clearing a GPIO pin. 108 | * 109 | * Note that the pin must be configured as an output for this 110 | * function to have any effect. 111 | * 112 | * @param pin_number Specifies the pin number to clear. 113 | */ 114 | void nrf_gpio_pin_clear(uint32_t pin_number); 115 | 116 | /** 117 | * @brief Function for configuring the GPIO pin range as input pins with given initial value set, hiding inner details. 118 | * This function can be used to configure pin range as simple input. 119 | * 120 | * @param pin_range_start Specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30). 121 | * 122 | * @param pin_range_end Specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30). 123 | * 124 | * @param pull_config State of the pin range pull resistor (no pull, pulled down, or pulled high). 125 | * 126 | * @note For configuring only one pin as input, use @ref nrf_gpio_cfg_input. 127 | * Sense capability on the pin is disabled and input is connected to buffer so that the GPIO->IN register is readable. 128 | */ 129 | void nrf_gpio_range_cfg_input(uint32_t pin_range_start, 130 | uint32_t pin_range_end, 131 | nrf_gpio_pin_pull_t pull_config); 132 | 133 | /** 134 | * @brief Function for configuring the given GPIO pin number as input, hiding inner details. 135 | * This function can be used to configure a pin as simple input. 136 | * 137 | * @param pin_number Specifies the pin number. 138 | * @param pull_config State of the pin range pull resistor (no pull, pulled down, or pulled high). 139 | * 140 | * @note Sense capability on the pin is disabled and input is connected to buffer so that the GPIO->IN register is readable. 141 | */ 142 | void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config); 143 | 144 | void nrfx_gpiote_in_init(uint32_t pin_number, nrfx_gpiote_in_config_t *config, nrfx_gpiote_event_handler_t); 145 | void nrfx_gpiote_in_event_enable(uint32_t pin_number, bool enable); 146 | void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pin_pull, nrf_gpio_pin_sense_t sense); 147 | 148 | bool nrfx_gpiote_is_init(); 149 | void nrfx_gpiote_init(); 150 | 151 | void APP_GPIOTE_INIT(uint32_t max_users); 152 | 153 | #endif // NRF_GPIO_H__ 154 | -------------------------------------------------------------------------------- /sim/nrfx/hal/nrf_rtc.cpp: -------------------------------------------------------------------------------- 1 | #include "hal/nrf_rtc.h" 2 | 3 | #include "task.h" 4 | #include 5 | #include 6 | #include // std::to_string 7 | 8 | uint32_t nrf_rtc_counter_get(NRF_RTC_Type p_reg) 9 | { 10 | if (p_reg == portNRF_RTC_REG) { 11 | TickType_t ticks_now = xTaskGetTickCount(); 12 | return ticks_now; 13 | } 14 | throw std::runtime_error("nrf_rtc_counter_get: unhandled NRF_RTC_Type: " + std::to_string(p_reg)); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /sim/nrfx/hal/nrf_rtc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "portmacro_cmsis.h" 4 | 5 | // normal version has pointer to register 'NRF_RTC_Type * p_reg', but we just simulate 6 | // the return value according to known register pointer 7 | uint32_t nrf_rtc_counter_get(NRF_RTC_Type p_reg); 8 | -------------------------------------------------------------------------------- /sim/nrfx/hal/nrfx_gpiote.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /sim/nrfx/mdk/nrf.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2010 - 2018, Nordic Semiconductor ASA 4 | 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, 8 | are permitted provided that the following conditions are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | 2. Redistributions in binary form, except as embedded into a Nordic 14 | Semiconductor ASA integrated circuit in a product or a software update for 15 | such product, must reproduce the above copyright notice, this list of 16 | conditions and the following disclaimer in the documentation and/or other 17 | materials provided with the distribution. 18 | 19 | 3. Neither the name of Nordic Semiconductor ASA nor the names of its 20 | contributors may be used to endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | 4. This software, with or without modification, must only be used with a 24 | Nordic Semiconductor ASA integrated circuit. 25 | 26 | 5. Any software provided in binary form under this license must not be reverse 27 | engineered, decompiled, modified and/or disassembled. 28 | 29 | THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 30 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 31 | OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 32 | DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 33 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 34 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 35 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 38 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | 40 | */ 41 | 42 | // shortened version containing just the bits needed for the simulator 43 | 44 | #ifndef NRF_H 45 | #define NRF_H 46 | 47 | /* MDK version */ 48 | #define MDK_MAJOR_VERSION 8 49 | #define MDK_MINOR_VERSION 24 50 | #define MDK_MICRO_VERSION 1 51 | 52 | #include "nrf52.h" 53 | #include "nrf52_bitfields.h" 54 | 55 | #endif /* NRF_H */ 56 | 57 | -------------------------------------------------------------------------------- /sim/nrfx/mdk/nrf52.cpp: -------------------------------------------------------------------------------- 1 | #include "mdk/nrf52.h" 2 | 3 | // pointer variable used by the rest of the code, and its initialization 4 | NRF_WDT_Type *NRF_WDT; 5 | void init_NRF_WDT() 6 | { 7 | static NRF_WDT_Type NRF_WDT_object; 8 | NRF_WDT = &NRF_WDT_object; 9 | } 10 | 11 | // pointer variable used by the rest of the code, and its initialization 12 | NRF_POWER_Type *NRF_POWER; 13 | void init_NRF_POWER() 14 | { 15 | static NRF_POWER_Type NRF_POWER_object; 16 | NRF_POWER = &NRF_POWER_object; 17 | // sim: always return ResetPin as reason for reboot 18 | NRF_POWER->RESETREAS = 0x01; 19 | } 20 | -------------------------------------------------------------------------------- /sim/nrfx/mdk/nrf52.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 - 2018, Nordic Semiconductor ASA 3 | * 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this 10 | * list of conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form, except as embedded into a Nordic 13 | * Semiconductor ASA integrated circuit in a product or a software update for 14 | * such product, must reproduce the above copyright notice, this list of 15 | * conditions and the following disclaimer in the documentation and/or other 16 | * materials provided with the distribution. 17 | * 18 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 19 | * contributors may be used to endorse or promote products derived from this 20 | * software without specific prior written permission. 21 | * 22 | * 4. This software, with or without modification, must only be used with a 23 | * Nordic Semiconductor ASA integrated circuit. 24 | * 25 | * 5. Any software provided in binary form under this license must not be reverse 26 | * engineered, decompiled, modified and/or disassembled. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 29 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 32 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 34 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 37 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | * @file nrf52.h 40 | * @brief CMSIS HeaderFile 41 | * @version 1 42 | * @date 08. February 2019 43 | * @note Generated by SVDConv V3.3.18 on Friday, 08.02.2019 16:48:11 44 | * from File 'nrf52.svd', 45 | * last modified on Friday, 08.02.2019 15:48:07 46 | */ 47 | 48 | 49 | 50 | /** @addtogroup Nordic Semiconductor 51 | * @{ 52 | */ 53 | 54 | 55 | /** @addtogroup nrf52 56 | * @{ 57 | */ 58 | 59 | 60 | #ifndef NRF52_H 61 | #define NRF52_H 62 | 63 | #ifdef __cplusplus 64 | extern "C" { 65 | #endif 66 | 67 | #include 68 | 69 | // define empty to make original WDT struct work 70 | #define __OM 71 | #define __IM 72 | #define __IOM 73 | 74 | /* =========================================================================================================================== */ 75 | /* ================ WDT ================ */ 76 | /* =========================================================================================================================== */ 77 | 78 | 79 | /** 80 | * @brief Watchdog Timer (WDT) 81 | */ 82 | 83 | typedef struct { /*!< (@ 0x40010000) WDT Structure */ 84 | __OM uint32_t TASKS_START; /*!< (@ 0x00000000) Start the watchdog */ 85 | __IM uint32_t RESERVED[63]; 86 | __IOM uint32_t EVENTS_TIMEOUT; /*!< (@ 0x00000100) Watchdog timeout */ 87 | __IM uint32_t RESERVED1[128]; 88 | __IOM uint32_t INTENSET; /*!< (@ 0x00000304) Enable interrupt */ 89 | __IOM uint32_t INTENCLR; /*!< (@ 0x00000308) Disable interrupt */ 90 | __IM uint32_t RESERVED2[61]; 91 | __IM uint32_t RUNSTATUS; /*!< (@ 0x00000400) Run status */ 92 | __IM uint32_t REQSTATUS; /*!< (@ 0x00000404) Request status */ 93 | __IM uint32_t RESERVED3[63]; 94 | __IOM uint32_t CRV; /*!< (@ 0x00000504) Counter reload value */ 95 | __IOM uint32_t RREN; /*!< (@ 0x00000508) Enable register for reload request registers */ 96 | __IOM uint32_t CONFIG; /*!< (@ 0x0000050C) Configuration register */ 97 | __IM uint32_t RESERVED4[60]; 98 | __OM uint32_t RR[8]; /*!< (@ 0x00000600) Description collection[0]: Reload request 0 */ 99 | } NRF_WDT_Type; /*!< Size = 1568 (0x620) */ 100 | 101 | // simulator specific pointer and initialization function 102 | extern NRF_WDT_Type *NRF_WDT; 103 | void init_NRF_WDT(); 104 | 105 | 106 | /* =========================================================================================================================== */ 107 | /* ================ POWER ================ */ 108 | /* =========================================================================================================================== */ 109 | 110 | 111 | /** 112 | * @brief Power control (POWER) 113 | */ 114 | 115 | typedef struct { /*!< (@ 0x40000000) POWER Structure */ 116 | // __IM uint32_t RESERVED[30]; 117 | // __OM uint32_t TASKS_CONSTLAT; /*!< (@ 0x00000078) Enable constant latency mode */ 118 | // __OM uint32_t TASKS_LOWPWR; /*!< (@ 0x0000007C) Enable low power mode (variable latency) */ 119 | // __IM uint32_t RESERVED1[34]; 120 | // __IOM uint32_t EVENTS_POFWARN; /*!< (@ 0x00000108) Power failure warning */ 121 | // __IM uint32_t RESERVED2[2]; 122 | // __IOM uint32_t EVENTS_SLEEPENTER; /*!< (@ 0x00000114) CPU entered WFI/WFE sleep */ 123 | // __IOM uint32_t EVENTS_SLEEPEXIT; /*!< (@ 0x00000118) CPU exited WFI/WFE sleep */ 124 | // __IM uint32_t RESERVED3[122]; 125 | // __IOM uint32_t INTENSET; /*!< (@ 0x00000304) Enable interrupt */ 126 | // __IOM uint32_t INTENCLR; /*!< (@ 0x00000308) Disable interrupt */ 127 | // __IM uint32_t RESERVED4[61]; 128 | __IOM uint32_t RESETREAS; /*!< (@ 0x00000400) Reset reason */ 129 | // __IM uint32_t RESERVED5[9]; 130 | // __IM uint32_t RAMSTATUS; /*!< (@ 0x00000428) Deprecated register - RAM status register */ 131 | // __IM uint32_t RESERVED6[53]; 132 | // __OM uint32_t SYSTEMOFF; /*!< (@ 0x00000500) System OFF register */ 133 | // __IM uint32_t RESERVED7[3]; 134 | // __IOM uint32_t POFCON; /*!< (@ 0x00000510) Power failure comparator configuration */ 135 | // __IM uint32_t RESERVED8[2]; 136 | // __IOM uint32_t GPREGRET; /*!< (@ 0x0000051C) General purpose retention register */ 137 | // __IOM uint32_t GPREGRET2; /*!< (@ 0x00000520) General purpose retention register */ 138 | // __IOM uint32_t RAMON; /*!< (@ 0x00000524) Deprecated register - RAM on/off register (this 139 | // register is retained) */ 140 | // __IM uint32_t RESERVED9[11]; 141 | // __IOM uint32_t RAMONB; /*!< (@ 0x00000554) Deprecated register - RAM on/off register (this 142 | // register is retained) */ 143 | // __IM uint32_t RESERVED10[8]; 144 | // __IOM uint32_t DCDCEN; /*!< (@ 0x00000578) DC/DC enable register */ 145 | // __IM uint32_t RESERVED11[225]; 146 | // __IOM POWER_RAM_Type RAM[8]; /*!< (@ 0x00000900) Unspecified */ 147 | } NRF_POWER_Type; /*!< Size = 2432 (0x980) */ 148 | 149 | // simulator specific pointer and initialization function 150 | extern NRF_POWER_Type *NRF_POWER; 151 | void init_NRF_POWER(); 152 | 153 | #ifdef __cplusplus 154 | } 155 | #endif 156 | 157 | #endif /* NRF52_H */ 158 | 159 | 160 | /** @} */ /* End of group nrf52 */ 161 | 162 | /** @} */ /* End of group Nordic Semiconductor */ 163 | -------------------------------------------------------------------------------- /sim/nrfx/nrfx_log.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016 - 2019, Nordic Semiconductor ASA 3 | * 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this 10 | * list of conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form, except as embedded into a Nordic 13 | * Semiconductor ASA integrated circuit in a product or a software update for 14 | * such product, must reproduce the above copyright notice, this list of 15 | * conditions and the following disclaimer in the documentation and/or other 16 | * materials provided with the distribution. 17 | * 18 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 19 | * contributors may be used to endorse or promote products derived from this 20 | * software without specific prior written permission. 21 | * 22 | * 4. This software, with or without modification, must only be used with a 23 | * Nordic Semiconductor ASA integrated circuit. 24 | * 25 | * 5. Any software provided in binary form under this license must not be reverse 26 | * engineered, decompiled, modified and/or disassembled. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 29 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 32 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 34 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 37 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | */ 40 | /**@file 41 | * 42 | * @defgroup nrf_log Logger module 43 | * @{ 44 | * @ingroup app_common 45 | * 46 | * @brief The nrfx_log module interface. 47 | */ 48 | 49 | #ifndef NRFX_LOG_H_ 50 | #define NRFX_LOG_H_ 51 | 52 | #include "libraries/log/nrf_log.h" 53 | 54 | #endif // NRFX_LOG_H_ 55 | -------------------------------------------------------------------------------- /sim/portmacro_cmsis.cpp: -------------------------------------------------------------------------------- 1 | #include "portmacro_cmsis.h" 2 | 3 | void portYIELD_FROM_ISR(BaseType_t) {} 4 | -------------------------------------------------------------------------------- /sim/portmacro_cmsis.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.0 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. If you wish to use our Amazon 14 | * FreeRTOS name, please do so in a fair use way that does not cause confusion. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | * http://www.FreeRTOS.org 24 | * http://aws.amazon.com/freertos 25 | * 26 | * 1 tab == 4 spaces! 27 | */ 28 | 29 | #ifndef PORTMACRO_CMSIS_H 30 | #define PORTMACRO_CMSIS_H 31 | 32 | // ########## macro taken from app_util.h 33 | /**@brief Macro for performing rounded integer division (as opposed to truncating the result). 34 | * 35 | * @param[in] A Numerator. 36 | * @param[in] B Denominator. 37 | * 38 | * @return Rounded (integer) result of dividing A by B. 39 | */ 40 | #define ROUNDED_DIV(A, B) (((A) + ((B) / 2)) / (B)) 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | #include 47 | 48 | typedef uint32_t TickType_t; 49 | #define portMAX_DELAY ( TickType_t ) 0xffffffffUL 50 | #define portNRF_RTC_MAXTICKS ((1U<<24)-1U) 51 | 52 | typedef long BaseType_t; 53 | typedef unsigned long UBaseType_t; 54 | 55 | /* RTC register */ 56 | typedef uint32_t NRF_RTC_Type; 57 | const NRF_RTC_Type portNRF_RTC_REG = 1; 58 | 59 | void portYIELD_FROM_ISR(BaseType_t); 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif /* PORTMACRO_CMSIS_H */ 66 | -------------------------------------------------------------------------------- /sim/projdefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.0 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. If you wish to use our Amazon 14 | * FreeRTOS name, please do so in a fair use way that does not cause confusion. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | * http://www.FreeRTOS.org 24 | * http://aws.amazon.com/freertos 25 | * 26 | * 1 tab == 4 spaces! 27 | */ 28 | 29 | #ifndef PROJDEFS_H 30 | #define PROJDEFS_H 31 | 32 | /* 33 | * Defines the prototype to which task functions must conform. Defined in this 34 | * file to ensure the type is known before portable.h is included. 35 | */ 36 | typedef void (*TaskFunction_t)( void * ); 37 | 38 | /* Converts a time in milliseconds to a time in ticks. This macro can be 39 | overridden by a macro of the same name defined in FreeRTOSConfig.h in case the 40 | definition here is not suitable for your application. */ 41 | #ifndef pdMS_TO_TICKS 42 | #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) 43 | #endif 44 | 45 | #define pdFALSE ( ( BaseType_t ) 0 ) 46 | #define pdTRUE ( ( BaseType_t ) 1 ) 47 | 48 | #define pdPASS ( pdTRUE ) 49 | #define pdFAIL ( pdFALSE ) 50 | #define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) 51 | #define errQUEUE_FULL ( ( BaseType_t ) 0 ) 52 | 53 | /* FreeRTOS error definitions. */ 54 | #define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) 55 | #define errQUEUE_BLOCKED ( -4 ) 56 | #define errQUEUE_YIELD ( -5 ) 57 | 58 | /* Macros used for basic data corruption checks. */ 59 | #ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 60 | #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 61 | #endif 62 | 63 | #if( configUSE_16_BIT_TICKS == 1 ) 64 | #define pdINTEGRITY_CHECK_VALUE 0x5a5a 65 | #else 66 | #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL 67 | #endif 68 | 69 | /* The following errno values are used by FreeRTOS+ components, not FreeRTOS 70 | itself. */ 71 | #define pdFREERTOS_ERRNO_NONE 0 /* No errors */ 72 | #define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ 73 | #define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ 74 | #define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ 75 | #define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ 76 | #define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ 77 | #define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ 78 | #define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ 79 | #define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ 80 | #define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ 81 | #define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ 82 | #define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ 83 | #define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ 84 | #define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ 85 | #define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ 86 | #define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ 87 | #define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ 88 | #define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ 89 | #define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ 90 | #define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ 91 | #define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ 92 | #define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ 93 | #define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ 94 | #define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ 95 | #define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ 96 | #define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ 97 | #define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ 98 | #define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ 99 | #define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ 100 | #define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ 101 | #define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ 102 | #define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ 103 | #define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ 104 | #define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ 105 | #define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ 106 | #define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ 107 | #define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ 108 | #define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ 109 | #define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ 110 | #define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ 111 | 112 | /* The following endian values are used by FreeRTOS+ components, not FreeRTOS 113 | itself. */ 114 | #define pdFREERTOS_LITTLE_ENDIAN 0 115 | #define pdFREERTOS_BIG_ENDIAN 1 116 | 117 | /* Re-defining endian values for generic naming. */ 118 | #define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN 119 | #define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN 120 | 121 | 122 | #endif /* PROJDEFS_H */ 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /sim/queue.cpp: -------------------------------------------------------------------------------- 1 | #include "FreeRTOS.h" 2 | #include "queue.h" 3 | #include 4 | #include 5 | 6 | QueueHandle_t xQueueCreate(const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize) 7 | { 8 | Queue_t *xQueue = new Queue_t; 9 | if (uxItemSize != 1) { 10 | throw std::runtime_error("uxItemSize must be 1"); 11 | } 12 | xQueue->queue.reserve(uxQueueLength); 13 | return xQueue; 14 | } 15 | 16 | BaseType_t xQueueSend(QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait) 17 | { 18 | Queue_t* pxQueue = ( Queue_t * ) xQueue; 19 | std::lock_guard guard(pxQueue->mutex); 20 | pxQueue->queue.push_back(*reinterpret_cast(pvItemToQueue)); 21 | return true; 22 | } 23 | 24 | BaseType_t xQueueSendFromISR(QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t *xHigherPriorityTaskWoken) 25 | { 26 | TickType_t xTicksToWait = 0; 27 | *xHigherPriorityTaskWoken = pdFALSE; 28 | return xQueueSend(xQueue, pvItemToQueue, 0.0); 29 | } 30 | 31 | BaseType_t xQueueReceive(QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait) 32 | { 33 | Queue_t* pxQueue = ( Queue_t * ) xQueue; 34 | while (pxQueue->queue.empty()) { 35 | if (xTicksToWait <= 25) { 36 | return false; 37 | } 38 | SDL_Delay(25); 39 | xTicksToWait -= 25; 40 | } 41 | if (pxQueue->queue.empty()) { 42 | return false; 43 | } 44 | std::lock_guard guard(pxQueue->mutex); 45 | uint8_t *buf = reinterpret_cast(pvBuffer); 46 | *buf = pxQueue->queue.at(0); 47 | pxQueue->queue.erase(pxQueue->queue.begin()); 48 | return true; 49 | } 50 | 51 | UBaseType_t uxQueueMessagesWaiting(const QueueHandle_t xQueue) 52 | { 53 | UBaseType_t uxReturn; 54 | SDL_assert(xQueue); 55 | Queue_t* pxQueue = ( Queue_t * ) xQueue; 56 | // taskENTER_CRITICAL(); 57 | { 58 | std::lock_guard guard(pxQueue->mutex); 59 | uxReturn = static_cast(pxQueue->queue.size()); 60 | } 61 | // taskEXIT_CRITICAL(); 62 | return uxReturn; 63 | } 64 | -------------------------------------------------------------------------------- /sim/queue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /** 7 | * Type by which queues are referenced. For example, a call to xQueueCreate() 8 | * returns an QueueHandle_t variable that can then be used as a parameter to 9 | * xQueueSend(), xQueueReceive(), etc. 10 | */ 11 | typedef void * QueueHandle_t; 12 | struct Queue_t { 13 | std::mutex mutex; 14 | std::vector queue; 15 | Queue_t() {} 16 | Queue_t(const Queue_t &o) { 17 | queue=o.queue; 18 | } 19 | Queue_t &operator=(const Queue_t &o) { 20 | queue=o.queue; 21 | return *this; 22 | } 23 | }; 24 | //using QueueHandle_t = std::vector; 25 | 26 | QueueHandle_t xQueueCreate(const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize); 27 | BaseType_t xQueueSend(QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait); 28 | BaseType_t xQueueSendFromISR(QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t *xHigherPriorityTaskWoken); 29 | BaseType_t xQueueReceive(QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ); 30 | UBaseType_t uxQueueMessagesWaiting(const QueueHandle_t xQueue); 31 | -------------------------------------------------------------------------------- /sim/semphr.cpp: -------------------------------------------------------------------------------- 1 | #include "semphr.h" 2 | #include 3 | #include 4 | 5 | QueueHandle_t xSemaphoreCreateMutex() { 6 | SemaphoreHandle_t xSemaphore = xQueueCreate(1, 1); 7 | Queue_t *pxQueue = (Queue_t *)xSemaphore; 8 | // Queue full represents taken semaphore/locked mutex 9 | pxQueue->queue.push_back(0); 10 | return xSemaphore; 11 | } 12 | 13 | BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore, 14 | TickType_t xTicksToWait) { 15 | Queue_t *pxQueue = (Queue_t *)xSemaphore; 16 | constexpr TickType_t DELAY_BETWEEN_ATTEMPTS = 25; 17 | do { 18 | if (pxQueue->mutex.try_lock()) { 19 | std::lock_guard lock(pxQueue->mutex, std::adopt_lock); 20 | if (pxQueue->queue.empty()) { 21 | pxQueue->queue.push_back(0); 22 | return true; 23 | } 24 | } 25 | // Prevent underflow 26 | if (xTicksToWait >= DELAY_BETWEEN_ATTEMPTS) { 27 | // Someone else is modifying queue, wait for them to finish 28 | SDL_Delay(DELAY_BETWEEN_ATTEMPTS); 29 | xTicksToWait -= DELAY_BETWEEN_ATTEMPTS; 30 | } 31 | } while (xTicksToWait >= DELAY_BETWEEN_ATTEMPTS); 32 | return false; 33 | } 34 | 35 | BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore) { 36 | Queue_t *pxQueue = (Queue_t *)xSemaphore; 37 | std::lock_guard guard(pxQueue->mutex); 38 | if (pxQueue->queue.size() != 1) { 39 | throw std::runtime_error("Mutex released without being held"); 40 | } 41 | pxQueue->queue.pop_back(); 42 | return true; 43 | } 44 | -------------------------------------------------------------------------------- /sim/semphr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "FreeRTOS.h" 4 | #include "queue.h" 5 | 6 | typedef QueueHandle_t SemaphoreHandle_t; 7 | 8 | QueueHandle_t xSemaphoreCreateMutex(); 9 | 10 | BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait); 11 | BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore); 12 | -------------------------------------------------------------------------------- /sim/task.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.0 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. If you wish to use our Amazon 14 | * FreeRTOS name, please do so in a fair use way that does not cause confusion. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | * http://www.FreeRTOS.org 24 | * http://aws.amazon.com/freertos 25 | * 26 | * 1 tab == 4 spaces! 27 | */ 28 | 29 | #include 30 | 31 | /* Standard includes. */ 32 | #include 33 | 34 | /* FreeRTOS includes. */ 35 | #include "FreeRTOS.h" 36 | #include "task.h" 37 | //#include "timers.h" 38 | //#include "stack_macros.h" 39 | 40 | 41 | TickType_t xTaskGetTickCount() 42 | { 43 | static auto start = std::chrono::steady_clock::now(); 44 | auto now = std::chrono::steady_clock::now(); 45 | auto diff = std::chrono::duration_cast>>(now - start); 46 | return diff.count(); 47 | } 48 | /*-----------------------------------------------------------*/ 49 | 50 | UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime) { 51 | return 0; 52 | } 53 | 54 | void vTaskDelay( const TickType_t xTicksToDelay ) { 55 | SDL_Delay(xTicksToDelay); 56 | } 57 | 58 | int sdl_function_wrapper(void *instance) 59 | { 60 | TaskHandle_t * task_handle = static_cast(instance); 61 | task_handle->task_fn(task_handle->instance); 62 | return 0; 63 | } 64 | 65 | BaseType_t xTaskCreate( 66 | TaskFunction_t pxTaskCode, 67 | const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ 68 | const configSTACK_DEPTH_TYPE usStackDepth, 69 | void * const pvParameters, 70 | UBaseType_t uxPriority, 71 | TaskHandle_t * const pxCreatedTask ) 72 | { 73 | pxCreatedTask->task_fn = pxTaskCode; 74 | pxCreatedTask->instance = pvParameters; 75 | pxCreatedTask->thread_handle = SDL_CreateThread(sdl_function_wrapper, pcName, pxCreatedTask); 76 | return pxCreatedTask->thread_handle != nullptr; 77 | } 78 | 79 | BaseType_t xTaskNotifyGive(TaskHandle_t xTaskToNotify) { 80 | return pdPASS; 81 | } 82 | TaskHandle_t xTaskGetCurrentTaskHandle() { 83 | return {}; 84 | } 85 | BaseType_t xTaskGetSchedulerState() { 86 | return taskSCHEDULER_NOT_STARTED; 87 | } 88 | -------------------------------------------------------------------------------- /sim/timers.cpp: -------------------------------------------------------------------------------- 1 | #include "timers.h" 2 | #include 3 | 4 | uint32_t timer_callback_wrapper(uint32_t interval, void *param) { 5 | TimerHandle_t *xTimer = static_cast(param); 6 | if (!xTimer->running) { 7 | return 0; 8 | } 9 | xTimer->running = false; 10 | xTimer->pxCallbackFunction(*xTimer); 11 | if (xTimer->auto_reload) { 12 | return xTimer->timer_period_in_ms; 13 | } 14 | return 0; // cancel timer 15 | } 16 | 17 | void *pvTimerGetTimerID(const TimerHandle_t &xTimer) { // return pvTimerID from xTimerCreate 18 | return xTimer.pvTimerID; 19 | } 20 | void vTimerSetTimerID(TimerHandle_t &xTimer, void *pvNewID) { 21 | xTimer.pvTimerID = pvNewID; 22 | } 23 | 24 | TimerHandle_t xTimerCreate(const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ 25 | const TickType_t xTimerPeriodInTicks, 26 | const UBaseType_t uxAutoReload, // false=one-shot, true=recurring 27 | void * const pvTimerID, // pointer passed to callback 28 | TimerCallbackFunction_t pxCallbackFunction) 29 | { 30 | TimerHandle_t xTimer; 31 | xTimer.timer_period_in_ms = pdTICKS_TO_MS(xTimerPeriodInTicks); 32 | xTimer.auto_reload = uxAutoReload == pdTRUE; 33 | xTimer.timer_name = pcTimerName; 34 | xTimer.pvTimerID = pvTimerID; 35 | xTimer.pxCallbackFunction = pxCallbackFunction; 36 | return xTimer; 37 | } 38 | 39 | bool xTimerStart(TimerHandle_t &xTimer, TickType_t xTicksToWait) { 40 | xTimer.running = true; 41 | xTimer.expiry_time = xTaskGetTickCount() + pdMS_TO_TICKS(xTimer.timer_period_in_ms); 42 | xTimer.timer_id = SDL_AddTimer(xTimer.timer_period_in_ms, timer_callback_wrapper, &xTimer); 43 | if (xTimer.pxCallbackFunction == nullptr) { 44 | throw std::runtime_error("xTimerStart called before xTimerCreate"); 45 | } 46 | return xTimer.timer_id != 0; 47 | } 48 | 49 | bool xTimerChangePeriod(TimerHandle_t &xTimer, TickType_t xNewPeriod, TickType_t xTicksToWait) { 50 | if (xTimer.running) { 51 | xTimerStop(xTimer, xTicksToWait); 52 | xTimer.timer_period_in_ms = pdTICKS_TO_MS(xNewPeriod); 53 | xTimerStart(xTimer, xTicksToWait); 54 | } else { 55 | xTimer.timer_period_in_ms = pdTICKS_TO_MS(xNewPeriod); 56 | } 57 | return true; 58 | } 59 | 60 | bool xTimerReset(TimerHandle_t &xTimer, TickType_t xTicksToWait) { 61 | if (xTimer.running) { 62 | xTimerStop(xTimer, xTicksToWait); 63 | } 64 | return xTimerStart(xTimer, xTicksToWait); 65 | } 66 | 67 | bool xTimerStop(TimerHandle_t &xTimer, TickType_t xTicksToWait) { 68 | xTimer.running = false; 69 | return SDL_RemoveTimer(xTimer.timer_id); 70 | } 71 | 72 | TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) 73 | { 74 | return xTimer.expiry_time; 75 | } 76 | 77 | BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) { 78 | return xTimer.running; 79 | } 80 | -------------------------------------------------------------------------------- /sim/timers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.0 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. If you wish to use our Amazon 14 | * FreeRTOS name, please do so in a fair use way that does not cause confusion. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | * http://www.FreeRTOS.org 24 | * http://aws.amazon.com/freertos 25 | * 26 | * 1 tab == 4 spaces! 27 | */ 28 | 29 | #pragma once 30 | 31 | #include "FreeRTOS.h" // TickType_t 32 | #include "task.h" // configTICK_RATE_HZ 33 | 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | class TimerHandle_t; 41 | /* 42 | * Defines the prototype to which timer callback functions must conform. 43 | */ 44 | typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer ); 45 | 46 | struct TimerHandle_t { 47 | bool running = false; 48 | bool auto_reload = false; 49 | SDL_TimerID timer_id = 0; 50 | TickType_t timer_period_in_ms; 51 | TickType_t expiry_time; 52 | std::string timer_name; 53 | void * pvTimerID; 54 | TimerCallbackFunction_t pxCallbackFunction; 55 | }; 56 | 57 | 58 | // function only available in Simulator 59 | constexpr uint32_t pdTICKS_TO_MS(uint32_t ticks) { 60 | return ticks * 1000 / configTICK_RATE_HZ; 61 | } 62 | 63 | /** 64 | * void *pvTimerGetTimerID( TimerHandle_t xTimer ); 65 | * 66 | * Returns the ID assigned to the timer. 67 | * 68 | * IDs are assigned to timers using the pvTimerID parameter of the call to 69 | * xTimerCreated() that was used to create the timer, and by calling the 70 | * vTimerSetTimerID() API function. 71 | * 72 | * If the same callback function is assigned to multiple timers then the timer 73 | * ID can be used as time specific (timer local) storage. 74 | * 75 | * @param xTimer The timer being queried. 76 | * 77 | * @return The ID assigned to the timer being queried. 78 | * 79 | * Example usage: 80 | * 81 | * See the xTimerCreate() API function example usage scenario. 82 | */ 83 | void *pvTimerGetTimerID(const TimerHandle_t &xTimer ); // return pvTimerID from xTimerCreate 84 | 85 | /** 86 | * void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); 87 | * 88 | * Sets the ID assigned to the timer. 89 | * 90 | * IDs are assigned to timers using the pvTimerID parameter of the call to 91 | * xTimerCreated() that was used to create the timer. 92 | * 93 | * If the same callback function is assigned to multiple timers then the timer 94 | * ID can be used as time specific (timer local) storage. 95 | * 96 | * @param xTimer The timer being updated. 97 | * 98 | * @param pvNewID The ID to assign to the timer. 99 | * 100 | * Example usage: 101 | * 102 | * See the xTimerCreate() API function example usage scenario. 103 | */ 104 | void vTimerSetTimerID(TimerHandle_t &xTimer, void *pvNewID); 105 | 106 | 107 | TimerHandle_t xTimerCreate(const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ 108 | const TickType_t xTimerPeriodInTicks, 109 | const UBaseType_t uxAutoReload, // false=one-shot, true=recurring 110 | void * const pvTimerID, // pointer passed to callback 111 | TimerCallbackFunction_t pxCallbackFunction); 112 | 113 | /** 114 | * @param xTicksToWait Specifies the time, in ticks, that the calling task should 115 | * be held in the Blocked state to wait for the stop command to be successfully 116 | * sent to the timer command queue, should the queue already be full when 117 | * xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called 118 | * before the scheduler is started. 119 | */ 120 | bool xTimerStart(TimerHandle_t &xTimer, TickType_t xTicksToWait); 121 | /* 122 | * xTimerChangePeriod() changes the period of a timer that was previously 123 | * created using the xTimerCreate() API function. 124 | * 125 | * xTimerChangePeriod() can be called to change the period of an active or 126 | * dormant state timer. 127 | * 128 | * The configUSE_TIMERS configuration constant must be set to 1 for 129 | * xTimerChangePeriod() to be available. 130 | */ 131 | bool xTimerChangePeriod(TimerHandle_t &xTimer, TickType_t xNewPeriod, TickType_t xTicksToWait); 132 | 133 | /** 134 | * xTimerReset() re-starts a timer that was previously created using the 135 | * xTimerCreate() API function. If the timer had already been started and was 136 | * already in the active state, then xTimerReset() will cause the timer to 137 | * re-evaluate its expiry time so that it is relative to when xTimerReset() was 138 | * called. If the timer was in the dormant state then xTimerReset() has 139 | * equivalent functionality to the xTimerStart() API function. 140 | * 141 | * Resetting a timer ensures the timer is in the active state. If the timer 142 | * is not stopped, deleted, or reset in the mean time, the callback function 143 | * associated with the timer will get called 'n' ticks after xTimerReset() was 144 | * called, where 'n' is the timers defined period. 145 | * 146 | * It is valid to call xTimerReset() before the scheduler has been started, but 147 | * when this is done the timer will not actually start until the scheduler is 148 | * started, and the timers expiry time will be relative to when the scheduler is 149 | * started, not relative to when xTimerReset() was called. 150 | */ 151 | bool xTimerReset(TimerHandle_t &xTimer, TickType_t xTicksToWait); 152 | 153 | bool xTimerStop(TimerHandle_t &xTimer, TickType_t xTicksToWait); 154 | 155 | /** 156 | * TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ); 157 | * 158 | * Returns the time in ticks at which the timer will expire. If this is less 159 | * than the current tick count then the expiry time has overflowed from the 160 | * current time. 161 | * 162 | * @param xTimer The handle of the timer being queried. 163 | * 164 | * @return If the timer is running then the time in ticks at which the timer 165 | * will next expire is returned. If the timer is not running then the return 166 | * value is undefined. 167 | */ 168 | TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ); 169 | 170 | /** 171 | * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); 172 | * 173 | * Queries a timer to see if it is active or dormant. 174 | * 175 | * A timer will be dormant if: 176 | * 1) It has been created but not started, or 177 | * 2) It is an expired one-shot timer that has not been restarted. 178 | * 179 | * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), 180 | * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and 181 | * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the 182 | * active state. 183 | * 184 | * @param xTimer The timer being queried. 185 | * 186 | * @return pdFALSE will be returned if the timer is dormant. A value other than 187 | * pdFALSE will be returned if the timer is active. 188 | * 189 | * Example usage: 190 | * @verbatim 191 | * // This function assumes xTimer has already been created. 192 | * void vAFunction( TimerHandle_t xTimer ) 193 | * { 194 | * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" 195 | * { 196 | * // xTimer is active, do something. 197 | * } 198 | * else 199 | * { 200 | * // xTimer is not active, do something else. 201 | * } 202 | * } 203 | * @endverbatim 204 | */ 205 | BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); 206 | --------------------------------------------------------------------------------