├── .gitignore ├── LICENSE ├── README.md ├── ecad ├── .gitignore ├── board │ ├── kfchess.kicad_pcb │ ├── kfchess.kicad_pro │ ├── kfchess.kicad_sch │ ├── leds.kicad_sch │ ├── place_footprints.ini │ ├── row.kicad_sch │ └── square.kicad_sch ├── edge1 │ ├── edge1.kicad_pcb │ ├── edge1.kicad_pro │ └── edge1.kicad_sch ├── edge2 │ ├── edge1.kicad_pcb │ ├── edge1.kicad_pro │ └── edge1.kicad_sch ├── edge3 │ ├── edge1.kicad_pcb │ ├── edge1.kicad_pro │ └── edge1.kicad_sch └── edge4 │ ├── edge1.kicad_mod │ ├── edge1.kicad_pcb │ ├── edge1.kicad_pro │ └── edge1.kicad_sch └── firmware ├── .gitignore ├── build.py ├── include └── goertzel.h ├── lib └── freertos-teensy │ ├── .clang-format │ ├── .gitignore │ ├── MISRA.md │ ├── README.md │ ├── cspell.config.yaml │ ├── docs │ ├── cpp │ │ ├── LICENSE.html │ │ └── README.md │ └── freertos │ │ ├── GitHub-FreeRTOS-Kernel-Home.url │ │ ├── History.txt │ │ ├── LICENSE.md │ │ ├── Quick_Start_Guide.url │ │ └── README.md │ ├── example │ ├── blink │ │ ├── .gitignore │ │ ├── .vscode │ │ │ └── extensions.json │ │ ├── platformio.ini │ │ └── src │ │ │ └── main.cpp │ ├── sdfat │ │ ├── .clang-format │ │ ├── .gitignore │ │ ├── .vscode │ │ │ └── extensions.json │ │ ├── platformio.ini │ │ └── src │ │ │ └── main.cpp │ ├── stdjthread │ │ ├── .gitignore │ │ ├── .vscode │ │ │ └── extensions.json │ │ ├── platformio.ini │ │ └── src │ │ │ └── main.cpp │ └── stdthread │ │ ├── .gitignore │ │ ├── .vscode │ │ └── extensions.json │ │ ├── platformio.ini │ │ └── src │ │ └── main.cpp │ ├── lib │ ├── cpp │ │ ├── LICENSE.txt │ │ └── src │ │ │ ├── bits │ │ │ └── gthr-default.h │ │ │ ├── condition_variable.cpp │ │ │ ├── condition_variable.h │ │ │ ├── gthr_key.cpp │ │ │ ├── gthr_key.h │ │ │ ├── gthr_key_type.h │ │ │ ├── thread.cpp │ │ │ └── thread_gthread.h │ └── gcc │ │ ├── LICENSE.txt │ │ ├── condition_variable.cc │ │ ├── future.cc │ │ └── mutex.cc │ ├── library.json │ ├── library.properties │ ├── manifest.yml │ ├── run_format.sh │ ├── sbom.spdx │ └── src │ ├── FreeRTOS.h │ ├── FreeRTOSConfig.h │ ├── StackMacros.h │ ├── arduino_freertos.h │ ├── atomic.h │ ├── critical_section.h │ ├── croutine.c │ ├── croutine.h │ ├── deprecated_definitions.h │ ├── event_groups.c │ ├── event_groups.h │ ├── freertos_tasks_c_additions.h │ ├── list.c │ ├── list.h │ ├── message_buffer.h │ ├── mpu_prototypes.h │ ├── mpu_syscall_numbers.h │ ├── mpu_wrappers.h │ ├── newlib-freertos.h │ ├── picolibc-freertos.h │ ├── portable.h │ ├── portable │ ├── .clang-format │ ├── event_responder_support.cpp │ ├── event_responder_support.h │ ├── newlib_support.cpp │ ├── port.c │ ├── portmacro.h │ ├── readme.txt │ ├── teensy.h │ ├── teensy_3.cpp │ ├── teensy_4.cpp │ └── teensy_common.cpp │ ├── projdefs.h │ ├── queue.c │ ├── queue.h │ ├── semphr.h │ ├── stack_macros.h │ ├── stdint.readme │ ├── stream_buffer.c │ ├── stream_buffer.h │ ├── task.h │ ├── tasks.c │ ├── timers.c │ └── timers.h ├── platformio.ini └── src ├── goertzel.cpp ├── main.cpp └── video_config.h /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .cache 3 | compile_commands.json 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Xander Naumenko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |
4 | Real Time Chess 5 |

6 |

7 | A physical chess board without the concept of turns 8 |

9 |

10 | Video explanation: https://youtu.be/y7VtSK23_Jg 11 |

12 | 13 | # Pitch 14 | 15 | Chess is boring. I'm boring too so I enjoy it anyways, but I can't help but think "I could design it better." Normally in chess players move sequentially in turns, but this introduces a huge latency bug that the developers of chess forgot to patch: you spend literally half the time waiting for your opponent! 16 | 17 | The obvious solution is just get rid of the concept of turns in chess altogether and let players move whenever they want. Real time strategy games like StarCraft and Age of Empires are much more fun and spectator friendly than chess, so this should be a pretty uncontroversial minor rules update that can be implemented before the next world championship. To prevent things from getting too chaotic over the board each piece has an individual cooldown, so once it's been moved it can't move for a fixed period afterwards. 18 | 19 | However there's an unfortunate roadblock to the widespread adoption of real time chess: as the [Niemann controversy](https://www.cnn.com/2023/09/26/sport/hans-niemann-denies-sex-toys-cheating-chess-spt-intl/index.html) has made all too clear, chess is [not immune](https://www.youtube.com/watch?v=QNuu8KTUEwU) from accusations of cheating through spectator **ass**istance or outside **anal**isys tools. Trying to have players self enforce these piece cooldowns is impossible. However where the intrinsic goodness of the human psyche fails, engineering is always ready to step in. This project is a physical chess board that keeps track and displays the cooldown remaining for each piece, and even physically holds them in place so no accidental cheating can occur. 20 | 21 | # Design Files 22 | 23 | The firmware and pcb kicad files are in this repo. For the physical design, see [the design on OnShape](https://cad.onshape.com/documents/ad9a4c8f8eed1cb460895551/w/e793072796f18b5ae284597f/e/b7ae406cfa566c5c0e6fed4b). Other than those parts that were cnced, here were the off the shelf components used: 24 | 25 | - [Insulating washers](https://www.mcmaster.com/catalog/130/3683/95225A340): One under each electromagnet, to keep them isolated from the casing 26 | - [Plastic screws](https://www.mcmaster.com/catalog/130/3446/92492A728): To attach electromagnets to base, plastic to prevent electrical connection 27 | - [These](https://www.mcmaster.com/catalog/130/3435/92095A182) and [these](https://www.mcmaster.com/catalog/130/3435/92095A177) screws: to attach the internal supports and squares respectively 28 | - [Spacers](https://www.mcmaster.com/catalog/94669A095): For an offset between the decorative and functional pcbs 29 | - [Electromagnets](https://www.adafruit.com/product/3873): Most expensive part other than the machining, ~$600 per board. Could probably get them cheaper from China or something but for low quantities this was easiest 30 | 31 | # Known Issues 32 | 33 | - Power distribution: Traces on the pcbs are way undersized given there are many amps running through them, so there are large voltage drops when many pieces are on cooldown simultaneously. To solve this these traces should be much wider 34 | - Tolerances: The pcbs have extremely tight tolerances which makes assmbling the board extremely annoying. The edges and holes should probably have more room 35 | - Pin heights: The height of the pins for the banana connectors are taller than the mechanical design allows for, these are fairly easy to shorten using a dremel but probably something that should be fixed 36 | - Corner screws: Given the order of assembly, it's impossible to insert/fasten the 4 corner screws 37 | -------------------------------------------------------------------------------- /ecad/.gitignore: -------------------------------------------------------------------------------- 1 | jlcpcb/ 2 | *.lck 3 | *.log 4 | 5 | # Temporary files 6 | *.000 7 | *.bak 8 | *.bck 9 | *.kicad_pcb-bak 10 | *.kicad_sch-bak 11 | *-backups 12 | *.kicad_prl 13 | *.sch-bak 14 | *~ 15 | _autosave-* 16 | *.tmp 17 | *-save.pro 18 | *-save.kicad_pcb 19 | fp-info-cache 20 | 21 | # Netlist files (exported from Eeschema) 22 | *.net 23 | 24 | # Autorouter files (exported from Pcbnew) 25 | *.dsn 26 | *.ses 27 | 28 | # Exported BOM files 29 | *.xml 30 | *.csv 31 | -------------------------------------------------------------------------------- /ecad/board/leds.kicad_sch: -------------------------------------------------------------------------------- 1 | (kicad_sch 2 | (version 20231120) 3 | (generator "eeschema") 4 | (generator_version "8.0") 5 | (uuid "2f8e8149-bc25-4807-b07b-c4da7bd15d11") 6 | (paper "A5") 7 | (lib_symbols 8 | (symbol "XY308-2_54-8P:XY308-2_54-8P" 9 | (exclude_from_sim no) 10 | (in_bom yes) 11 | (on_board yes) 12 | (property "Reference" "U" 13 | (at 0 1.27 0) 14 | (effects 15 | (font 16 | (size 1.27 1.27) 17 | ) 18 | ) 19 | ) 20 | (property "Value" "XY308-2_54-8P" 21 | (at 0 -2.54 0) 22 | (effects 23 | (font 24 | (size 1.27 1.27) 25 | ) 26 | ) 27 | ) 28 | (property "Footprint" "footprint:CONN-TH_XY308-2.54-8P" 29 | (at 0 -10.16 0) 30 | (effects 31 | (font 32 | (size 1.27 1.27) 33 | (italic yes) 34 | ) 35 | (hide yes) 36 | ) 37 | ) 38 | (property "Datasheet" "https://item.szlcsc.com/989799.html?ref=editor&logined=true" 39 | (at -2.286 0.127 0) 40 | (effects 41 | (font 42 | (size 1.27 1.27) 43 | ) 44 | (justify left) 45 | (hide yes) 46 | ) 47 | ) 48 | (property "Description" "" 49 | (at 0 0 0) 50 | (effects 51 | (font 52 | (size 1.27 1.27) 53 | ) 54 | (hide yes) 55 | ) 56 | ) 57 | (property "LCSC" "C915917" 58 | (at 0 0 0) 59 | (effects 60 | (font 61 | (size 1.27 1.27) 62 | ) 63 | (hide yes) 64 | ) 65 | ) 66 | (property "ki_keywords" "C915917" 67 | (at 0 0 0) 68 | (effects 69 | (font 70 | (size 1.27 1.27) 71 | ) 72 | (hide yes) 73 | ) 74 | ) 75 | (symbol "XY308-2_54-8P_0_1" 76 | (rectangle 77 | (start -2.54 11.43) 78 | (end 2.54 -11.43) 79 | (stroke 80 | (width 0) 81 | (type default) 82 | ) 83 | (fill 84 | (type background) 85 | ) 86 | ) 87 | (circle 88 | (center -1.27 10.16) 89 | (radius 0.381) 90 | (stroke 91 | (width 0) 92 | (type default) 93 | ) 94 | (fill 95 | (type background) 96 | ) 97 | ) 98 | (pin unspecified line 99 | (at -5.08 8.89 0) 100 | (length 2.54) 101 | (name "1" 102 | (effects 103 | (font 104 | (size 1 1) 105 | ) 106 | ) 107 | ) 108 | (number "1" 109 | (effects 110 | (font 111 | (size 1 1) 112 | ) 113 | ) 114 | ) 115 | ) 116 | (pin unspecified line 117 | (at -5.08 6.35 0) 118 | (length 2.54) 119 | (name "2" 120 | (effects 121 | (font 122 | (size 1 1) 123 | ) 124 | ) 125 | ) 126 | (number "2" 127 | (effects 128 | (font 129 | (size 1 1) 130 | ) 131 | ) 132 | ) 133 | ) 134 | (pin unspecified line 135 | (at -5.08 3.81 0) 136 | (length 2.54) 137 | (name "3" 138 | (effects 139 | (font 140 | (size 1 1) 141 | ) 142 | ) 143 | ) 144 | (number "3" 145 | (effects 146 | (font 147 | (size 1 1) 148 | ) 149 | ) 150 | ) 151 | ) 152 | (pin unspecified line 153 | (at -5.08 1.27 0) 154 | (length 2.54) 155 | (name "4" 156 | (effects 157 | (font 158 | (size 1 1) 159 | ) 160 | ) 161 | ) 162 | (number "4" 163 | (effects 164 | (font 165 | (size 1 1) 166 | ) 167 | ) 168 | ) 169 | ) 170 | (pin unspecified line 171 | (at -5.08 -1.27 0) 172 | (length 2.54) 173 | (name "5" 174 | (effects 175 | (font 176 | (size 1 1) 177 | ) 178 | ) 179 | ) 180 | (number "5" 181 | (effects 182 | (font 183 | (size 1 1) 184 | ) 185 | ) 186 | ) 187 | ) 188 | (pin unspecified line 189 | (at -5.08 -3.81 0) 190 | (length 2.54) 191 | (name "6" 192 | (effects 193 | (font 194 | (size 1 1) 195 | ) 196 | ) 197 | ) 198 | (number "6" 199 | (effects 200 | (font 201 | (size 1 1) 202 | ) 203 | ) 204 | ) 205 | ) 206 | (pin unspecified line 207 | (at -5.08 -6.35 0) 208 | (length 2.54) 209 | (name "7" 210 | (effects 211 | (font 212 | (size 1 1) 213 | ) 214 | ) 215 | ) 216 | (number "7" 217 | (effects 218 | (font 219 | (size 1 1) 220 | ) 221 | ) 222 | ) 223 | ) 224 | (pin unspecified line 225 | (at -5.08 -8.89 0) 226 | (length 2.54) 227 | (name "8" 228 | (effects 229 | (font 230 | (size 1 1) 231 | ) 232 | ) 233 | ) 234 | (number "8" 235 | (effects 236 | (font 237 | (size 1 1) 238 | ) 239 | ) 240 | ) 241 | ) 242 | ) 243 | ) 244 | ) 245 | (symbol 246 | (lib_id "XY308-2_54-8P:XY308-2_54-8P") 247 | (at 54.61 101.6 0) 248 | (unit 1) 249 | (exclude_from_sim no) 250 | (in_bom yes) 251 | (on_board yes) 252 | (dnp no) 253 | (fields_autoplaced yes) 254 | (uuid "2433052b-bbd2-4d58-a91c-fb26447cdeec") 255 | (property "Reference" "U2" 256 | (at 58.42 100.3299 0) 257 | (effects 258 | (font 259 | (size 1.27 1.27) 260 | ) 261 | (justify left) 262 | ) 263 | ) 264 | (property "Value" "XY308-2_54-8P" 265 | (at 58.42 102.8699 0) 266 | (effects 267 | (font 268 | (size 1.27 1.27) 269 | ) 270 | (justify left) 271 | ) 272 | ) 273 | (property "Footprint" "footprint:CONN-TH_XY308-2.54-8P" 274 | (at 54.61 111.76 0) 275 | (effects 276 | (font 277 | (size 1.27 1.27) 278 | (italic yes) 279 | ) 280 | (hide yes) 281 | ) 282 | ) 283 | (property "Datasheet" "https://item.szlcsc.com/989799.html?ref=editor&logined=true" 284 | (at 52.324 101.473 0) 285 | (effects 286 | (font 287 | (size 1.27 1.27) 288 | ) 289 | (justify left) 290 | (hide yes) 291 | ) 292 | ) 293 | (property "Description" "" 294 | (at 54.61 101.6 0) 295 | (effects 296 | (font 297 | (size 1.27 1.27) 298 | ) 299 | (hide yes) 300 | ) 301 | ) 302 | (property "LCSC" "C915917" 303 | (at 54.61 101.6 0) 304 | (effects 305 | (font 306 | (size 1.27 1.27) 307 | ) 308 | (hide yes) 309 | ) 310 | ) 311 | (pin "7" 312 | (uuid "807af45d-46bb-4f21-8f60-633ce4170492") 313 | ) 314 | (pin "5" 315 | (uuid "e615dba8-7cf8-4d8e-a5fa-6b46d643fd79") 316 | ) 317 | (pin "6" 318 | (uuid "f76ae832-8459-4fd7-9dd7-a34ef0df363b") 319 | ) 320 | (pin "4" 321 | (uuid "7549fcb3-3bc5-4313-886c-773278509db6") 322 | ) 323 | (pin "8" 324 | (uuid "0d7742e2-8f28-4dd5-9770-387e9cc694c4") 325 | ) 326 | (pin "3" 327 | (uuid "8742ea4c-cd9f-4175-8632-1097e7e1cbfe") 328 | ) 329 | (pin "2" 330 | (uuid "7a129414-47c3-4167-9362-4dd1c772d651") 331 | ) 332 | (pin "1" 333 | (uuid "f831aeb7-8b56-4766-b64b-652068ea6664") 334 | ) 335 | (instances 336 | (project "kfchess" 337 | (path "/d706098d-c574-48d0-bc99-bc3e7fab44dd/fe0ec028-d893-45c3-a211-4d8503b44d10" 338 | (reference "U2") 339 | (unit 1) 340 | ) 341 | ) 342 | ) 343 | ) 344 | ) -------------------------------------------------------------------------------- /ecad/board/place_footprints.ini: -------------------------------------------------------------------------------- 1 | [sheet] 2 | arrangement = Matrix 3 | 4 | [sheet.linear] 5 | step_x = 50 6 | step_y = 0 7 | nth_rotate = 1 8 | nth_rotate_angle = 0 9 | 10 | [sheet.matrix] 11 | step_x = 50 12 | step_y = 50 13 | columns = 4 14 | nth_rotate = 1 15 | nth_rotate_angle = 0 16 | 17 | [reference] 18 | arrangement = Circular 19 | 20 | [reference.circular] 21 | angle = -45.000 22 | radial_step = 0.0 23 | radius = 18 24 | nth_rotate = 1 25 | nth_rotate_angle = 0 26 | 27 | -------------------------------------------------------------------------------- /ecad/edge1/edge1.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "3dviewports": [], 4 | "design_settings": { 5 | "defaults": { 6 | "apply_defaults_to_fp_fields": false, 7 | "apply_defaults_to_fp_shapes": false, 8 | "apply_defaults_to_fp_text": false, 9 | "board_outline_line_width": 0.05, 10 | "copper_line_width": 0.2, 11 | "copper_text_italic": false, 12 | "copper_text_size_h": 1.5, 13 | "copper_text_size_v": 1.5, 14 | "copper_text_thickness": 0.3, 15 | "copper_text_upright": false, 16 | "courtyard_line_width": 0.05, 17 | "dimension_precision": 4, 18 | "dimension_units": 3, 19 | "dimensions": { 20 | "arrow_length": 1270000, 21 | "extension_offset": 500000, 22 | "keep_text_aligned": true, 23 | "suppress_zeroes": false, 24 | "text_position": 0, 25 | "units_format": 1 26 | }, 27 | "fab_line_width": 0.1, 28 | "fab_text_italic": false, 29 | "fab_text_size_h": 1.0, 30 | "fab_text_size_v": 1.0, 31 | "fab_text_thickness": 0.15, 32 | "fab_text_upright": false, 33 | "other_line_width": 0.1, 34 | "other_text_italic": false, 35 | "other_text_size_h": 1.0, 36 | "other_text_size_v": 1.0, 37 | "other_text_thickness": 0.15, 38 | "other_text_upright": false, 39 | "pads": { 40 | "drill": 0.762, 41 | "height": 1.524, 42 | "width": 1.524 43 | }, 44 | "silk_line_width": 0.1, 45 | "silk_text_italic": false, 46 | "silk_text_size_h": 1.0, 47 | "silk_text_size_v": 1.0, 48 | "silk_text_thickness": 0.1, 49 | "silk_text_upright": false, 50 | "zones": { 51 | "min_clearance": 0.5 52 | } 53 | }, 54 | "diff_pair_dimensions": [], 55 | "drc_exclusions": [], 56 | "meta": { 57 | "version": 2 58 | }, 59 | "rule_severities": { 60 | "annular_width": "error", 61 | "clearance": "error", 62 | "connection_width": "warning", 63 | "copper_edge_clearance": "error", 64 | "copper_sliver": "warning", 65 | "courtyards_overlap": "error", 66 | "diff_pair_gap_out_of_range": "error", 67 | "diff_pair_uncoupled_length_too_long": "error", 68 | "drill_out_of_range": "error", 69 | "duplicate_footprints": "warning", 70 | "extra_footprint": "warning", 71 | "footprint": "error", 72 | "footprint_symbol_mismatch": "warning", 73 | "footprint_type_mismatch": "ignore", 74 | "hole_clearance": "error", 75 | "hole_near_hole": "error", 76 | "holes_co_located": "warning", 77 | "invalid_outline": "error", 78 | "isolated_copper": "warning", 79 | "item_on_disabled_layer": "error", 80 | "items_not_allowed": "error", 81 | "length_out_of_range": "error", 82 | "lib_footprint_issues": "warning", 83 | "lib_footprint_mismatch": "warning", 84 | "malformed_courtyard": "error", 85 | "microvia_drill_out_of_range": "error", 86 | "missing_courtyard": "ignore", 87 | "missing_footprint": "warning", 88 | "net_conflict": "warning", 89 | "npth_inside_courtyard": "ignore", 90 | "padstack": "warning", 91 | "pth_inside_courtyard": "ignore", 92 | "shorting_items": "error", 93 | "silk_edge_clearance": "warning", 94 | "silk_over_copper": "warning", 95 | "silk_overlap": "warning", 96 | "skew_out_of_range": "error", 97 | "solder_mask_bridge": "error", 98 | "starved_thermal": "error", 99 | "text_height": "warning", 100 | "text_thickness": "warning", 101 | "through_hole_pad_without_hole": "error", 102 | "too_many_vias": "error", 103 | "track_dangling": "warning", 104 | "track_width": "error", 105 | "tracks_crossing": "error", 106 | "unconnected_items": "error", 107 | "unresolved_variable": "error", 108 | "via_dangling": "warning", 109 | "zones_intersect": "error" 110 | }, 111 | "rules": { 112 | "max_error": 0.005, 113 | "min_clearance": 0.0, 114 | "min_connection": 0.0, 115 | "min_copper_edge_clearance": 0.5, 116 | "min_hole_clearance": 0.25, 117 | "min_hole_to_hole": 0.25, 118 | "min_microvia_diameter": 0.2, 119 | "min_microvia_drill": 0.1, 120 | "min_resolved_spokes": 2, 121 | "min_silk_clearance": 0.0, 122 | "min_text_height": 0.8, 123 | "min_text_thickness": 0.08, 124 | "min_through_hole_diameter": 0.3, 125 | "min_track_width": 0.0, 126 | "min_via_annular_width": 0.1, 127 | "min_via_diameter": 0.5, 128 | "solder_mask_to_copper_clearance": 0.0, 129 | "use_height_for_length_calcs": true 130 | }, 131 | "teardrop_options": [ 132 | { 133 | "td_onpadsmd": true, 134 | "td_onroundshapesonly": false, 135 | "td_ontrackend": false, 136 | "td_onviapad": true 137 | } 138 | ], 139 | "teardrop_parameters": [ 140 | { 141 | "td_allow_use_two_tracks": true, 142 | "td_curve_segcount": 0, 143 | "td_height_ratio": 1.0, 144 | "td_length_ratio": 0.5, 145 | "td_maxheight": 2.0, 146 | "td_maxlen": 1.0, 147 | "td_on_pad_in_zone": false, 148 | "td_target_name": "td_round_shape", 149 | "td_width_to_size_filter_ratio": 0.9 150 | }, 151 | { 152 | "td_allow_use_two_tracks": true, 153 | "td_curve_segcount": 0, 154 | "td_height_ratio": 1.0, 155 | "td_length_ratio": 0.5, 156 | "td_maxheight": 2.0, 157 | "td_maxlen": 1.0, 158 | "td_on_pad_in_zone": false, 159 | "td_target_name": "td_rect_shape", 160 | "td_width_to_size_filter_ratio": 0.9 161 | }, 162 | { 163 | "td_allow_use_two_tracks": true, 164 | "td_curve_segcount": 0, 165 | "td_height_ratio": 1.0, 166 | "td_length_ratio": 0.5, 167 | "td_maxheight": 2.0, 168 | "td_maxlen": 1.0, 169 | "td_on_pad_in_zone": false, 170 | "td_target_name": "td_track_end", 171 | "td_width_to_size_filter_ratio": 0.9 172 | } 173 | ], 174 | "track_widths": [], 175 | "tuning_pattern_settings": { 176 | "diff_pair_defaults": { 177 | "corner_radius_percentage": 80, 178 | "corner_style": 1, 179 | "max_amplitude": 1.0, 180 | "min_amplitude": 0.2, 181 | "single_sided": false, 182 | "spacing": 1.0 183 | }, 184 | "diff_pair_skew_defaults": { 185 | "corner_radius_percentage": 80, 186 | "corner_style": 1, 187 | "max_amplitude": 1.0, 188 | "min_amplitude": 0.2, 189 | "single_sided": false, 190 | "spacing": 0.6 191 | }, 192 | "single_track_defaults": { 193 | "corner_radius_percentage": 80, 194 | "corner_style": 1, 195 | "max_amplitude": 1.0, 196 | "min_amplitude": 0.2, 197 | "single_sided": false, 198 | "spacing": 0.6 199 | } 200 | }, 201 | "via_dimensions": [], 202 | "zones_allow_external_fillets": false 203 | }, 204 | "ipc2581": { 205 | "dist": "", 206 | "distpn": "", 207 | "internal_id": "", 208 | "mfg": "", 209 | "mpn": "" 210 | }, 211 | "layer_presets": [], 212 | "viewports": [] 213 | }, 214 | "boards": [], 215 | "cvpcb": { 216 | "equivalence_files": [] 217 | }, 218 | "libraries": { 219 | "pinned_footprint_libs": [], 220 | "pinned_symbol_libs": [] 221 | }, 222 | "meta": { 223 | "filename": "edge1.kicad_pro", 224 | "version": 1 225 | }, 226 | "net_settings": { 227 | "classes": [ 228 | { 229 | "bus_width": 12, 230 | "clearance": 0.2, 231 | "diff_pair_gap": 0.25, 232 | "diff_pair_via_gap": 0.25, 233 | "diff_pair_width": 0.2, 234 | "line_style": 0, 235 | "microvia_diameter": 0.3, 236 | "microvia_drill": 0.1, 237 | "name": "Default", 238 | "pcb_color": "rgba(0, 0, 0, 0.000)", 239 | "schematic_color": "rgba(0, 0, 0, 0.000)", 240 | "track_width": 0.2, 241 | "via_diameter": 0.6, 242 | "via_drill": 0.3, 243 | "wire_width": 6 244 | } 245 | ], 246 | "meta": { 247 | "version": 3 248 | }, 249 | "net_colors": null, 250 | "netclass_assignments": null, 251 | "netclass_patterns": [] 252 | }, 253 | "pcbnew": { 254 | "last_paths": { 255 | "gencad": "", 256 | "idf": "", 257 | "netlist": "", 258 | "plot": "", 259 | "pos_files": "", 260 | "specctra_dsn": "", 261 | "step": "", 262 | "svg": "", 263 | "vrml": "" 264 | }, 265 | "page_layout_descr_file": "" 266 | }, 267 | "schematic": { 268 | "legacy_lib_dir": "", 269 | "legacy_lib_list": [] 270 | }, 271 | "sheets": [], 272 | "text_variables": {} 273 | } 274 | -------------------------------------------------------------------------------- /ecad/edge1/edge1.kicad_sch: -------------------------------------------------------------------------------- 1 | (kicad_sch (version 20231120) (generator "eeschema") (generator_version "8.0") 2 | (paper "A4") 3 | (lib_symbols) 4 | (symbol_instances) 5 | ) 6 | -------------------------------------------------------------------------------- /ecad/edge2/edge1.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "3dviewports": [], 4 | "design_settings": { 5 | "defaults": { 6 | "apply_defaults_to_fp_fields": false, 7 | "apply_defaults_to_fp_shapes": false, 8 | "apply_defaults_to_fp_text": false, 9 | "board_outline_line_width": 0.05, 10 | "copper_line_width": 0.2, 11 | "copper_text_italic": false, 12 | "copper_text_size_h": 1.5, 13 | "copper_text_size_v": 1.5, 14 | "copper_text_thickness": 0.3, 15 | "copper_text_upright": false, 16 | "courtyard_line_width": 0.05, 17 | "dimension_precision": 4, 18 | "dimension_units": 3, 19 | "dimensions": { 20 | "arrow_length": 1270000, 21 | "extension_offset": 500000, 22 | "keep_text_aligned": true, 23 | "suppress_zeroes": false, 24 | "text_position": 0, 25 | "units_format": 1 26 | }, 27 | "fab_line_width": 0.1, 28 | "fab_text_italic": false, 29 | "fab_text_size_h": 1.0, 30 | "fab_text_size_v": 1.0, 31 | "fab_text_thickness": 0.15, 32 | "fab_text_upright": false, 33 | "other_line_width": 0.1, 34 | "other_text_italic": false, 35 | "other_text_size_h": 1.0, 36 | "other_text_size_v": 1.0, 37 | "other_text_thickness": 0.15, 38 | "other_text_upright": false, 39 | "pads": { 40 | "drill": 0.762, 41 | "height": 1.524, 42 | "width": 1.524 43 | }, 44 | "silk_line_width": 0.1, 45 | "silk_text_italic": false, 46 | "silk_text_size_h": 1.0, 47 | "silk_text_size_v": 1.0, 48 | "silk_text_thickness": 0.1, 49 | "silk_text_upright": false, 50 | "zones": { 51 | "min_clearance": 0.5 52 | } 53 | }, 54 | "diff_pair_dimensions": [], 55 | "drc_exclusions": [], 56 | "meta": { 57 | "version": 2 58 | }, 59 | "rule_severities": { 60 | "annular_width": "error", 61 | "clearance": "error", 62 | "connection_width": "warning", 63 | "copper_edge_clearance": "error", 64 | "copper_sliver": "warning", 65 | "courtyards_overlap": "error", 66 | "diff_pair_gap_out_of_range": "error", 67 | "diff_pair_uncoupled_length_too_long": "error", 68 | "drill_out_of_range": "error", 69 | "duplicate_footprints": "warning", 70 | "extra_footprint": "warning", 71 | "footprint": "error", 72 | "footprint_symbol_mismatch": "warning", 73 | "footprint_type_mismatch": "ignore", 74 | "hole_clearance": "error", 75 | "hole_near_hole": "error", 76 | "holes_co_located": "warning", 77 | "invalid_outline": "error", 78 | "isolated_copper": "warning", 79 | "item_on_disabled_layer": "error", 80 | "items_not_allowed": "error", 81 | "length_out_of_range": "error", 82 | "lib_footprint_issues": "warning", 83 | "lib_footprint_mismatch": "warning", 84 | "malformed_courtyard": "error", 85 | "microvia_drill_out_of_range": "error", 86 | "missing_courtyard": "ignore", 87 | "missing_footprint": "warning", 88 | "net_conflict": "warning", 89 | "npth_inside_courtyard": "ignore", 90 | "padstack": "warning", 91 | "pth_inside_courtyard": "ignore", 92 | "shorting_items": "error", 93 | "silk_edge_clearance": "warning", 94 | "silk_over_copper": "warning", 95 | "silk_overlap": "warning", 96 | "skew_out_of_range": "error", 97 | "solder_mask_bridge": "error", 98 | "starved_thermal": "error", 99 | "text_height": "warning", 100 | "text_thickness": "warning", 101 | "through_hole_pad_without_hole": "error", 102 | "too_many_vias": "error", 103 | "track_dangling": "warning", 104 | "track_width": "error", 105 | "tracks_crossing": "error", 106 | "unconnected_items": "error", 107 | "unresolved_variable": "error", 108 | "via_dangling": "warning", 109 | "zones_intersect": "error" 110 | }, 111 | "rules": { 112 | "max_error": 0.005, 113 | "min_clearance": 0.0, 114 | "min_connection": 0.0, 115 | "min_copper_edge_clearance": 0.5, 116 | "min_hole_clearance": 0.25, 117 | "min_hole_to_hole": 0.25, 118 | "min_microvia_diameter": 0.2, 119 | "min_microvia_drill": 0.1, 120 | "min_resolved_spokes": 2, 121 | "min_silk_clearance": 0.0, 122 | "min_text_height": 0.8, 123 | "min_text_thickness": 0.08, 124 | "min_through_hole_diameter": 0.3, 125 | "min_track_width": 0.0, 126 | "min_via_annular_width": 0.1, 127 | "min_via_diameter": 0.5, 128 | "solder_mask_to_copper_clearance": 0.0, 129 | "use_height_for_length_calcs": true 130 | }, 131 | "teardrop_options": [ 132 | { 133 | "td_onpadsmd": true, 134 | "td_onroundshapesonly": false, 135 | "td_ontrackend": false, 136 | "td_onviapad": true 137 | } 138 | ], 139 | "teardrop_parameters": [ 140 | { 141 | "td_allow_use_two_tracks": true, 142 | "td_curve_segcount": 0, 143 | "td_height_ratio": 1.0, 144 | "td_length_ratio": 0.5, 145 | "td_maxheight": 2.0, 146 | "td_maxlen": 1.0, 147 | "td_on_pad_in_zone": false, 148 | "td_target_name": "td_round_shape", 149 | "td_width_to_size_filter_ratio": 0.9 150 | }, 151 | { 152 | "td_allow_use_two_tracks": true, 153 | "td_curve_segcount": 0, 154 | "td_height_ratio": 1.0, 155 | "td_length_ratio": 0.5, 156 | "td_maxheight": 2.0, 157 | "td_maxlen": 1.0, 158 | "td_on_pad_in_zone": false, 159 | "td_target_name": "td_rect_shape", 160 | "td_width_to_size_filter_ratio": 0.9 161 | }, 162 | { 163 | "td_allow_use_two_tracks": true, 164 | "td_curve_segcount": 0, 165 | "td_height_ratio": 1.0, 166 | "td_length_ratio": 0.5, 167 | "td_maxheight": 2.0, 168 | "td_maxlen": 1.0, 169 | "td_on_pad_in_zone": false, 170 | "td_target_name": "td_track_end", 171 | "td_width_to_size_filter_ratio": 0.9 172 | } 173 | ], 174 | "track_widths": [], 175 | "tuning_pattern_settings": { 176 | "diff_pair_defaults": { 177 | "corner_radius_percentage": 80, 178 | "corner_style": 1, 179 | "max_amplitude": 1.0, 180 | "min_amplitude": 0.2, 181 | "single_sided": false, 182 | "spacing": 1.0 183 | }, 184 | "diff_pair_skew_defaults": { 185 | "corner_radius_percentage": 80, 186 | "corner_style": 1, 187 | "max_amplitude": 1.0, 188 | "min_amplitude": 0.2, 189 | "single_sided": false, 190 | "spacing": 0.6 191 | }, 192 | "single_track_defaults": { 193 | "corner_radius_percentage": 80, 194 | "corner_style": 1, 195 | "max_amplitude": 1.0, 196 | "min_amplitude": 0.2, 197 | "single_sided": false, 198 | "spacing": 0.6 199 | } 200 | }, 201 | "via_dimensions": [], 202 | "zones_allow_external_fillets": false 203 | }, 204 | "ipc2581": { 205 | "dist": "", 206 | "distpn": "", 207 | "internal_id": "", 208 | "mfg": "", 209 | "mpn": "" 210 | }, 211 | "layer_presets": [], 212 | "viewports": [] 213 | }, 214 | "boards": [], 215 | "cvpcb": { 216 | "equivalence_files": [] 217 | }, 218 | "libraries": { 219 | "pinned_footprint_libs": [], 220 | "pinned_symbol_libs": [] 221 | }, 222 | "meta": { 223 | "filename": "edge1.kicad_pro", 224 | "version": 1 225 | }, 226 | "net_settings": { 227 | "classes": [ 228 | { 229 | "bus_width": 12, 230 | "clearance": 0.2, 231 | "diff_pair_gap": 0.25, 232 | "diff_pair_via_gap": 0.25, 233 | "diff_pair_width": 0.2, 234 | "line_style": 0, 235 | "microvia_diameter": 0.3, 236 | "microvia_drill": 0.1, 237 | "name": "Default", 238 | "pcb_color": "rgba(0, 0, 0, 0.000)", 239 | "schematic_color": "rgba(0, 0, 0, 0.000)", 240 | "track_width": 0.2, 241 | "via_diameter": 0.6, 242 | "via_drill": 0.3, 243 | "wire_width": 6 244 | } 245 | ], 246 | "meta": { 247 | "version": 3 248 | }, 249 | "net_colors": null, 250 | "netclass_assignments": null, 251 | "netclass_patterns": [] 252 | }, 253 | "pcbnew": { 254 | "last_paths": { 255 | "gencad": "", 256 | "idf": "", 257 | "netlist": "", 258 | "plot": "", 259 | "pos_files": "", 260 | "specctra_dsn": "", 261 | "step": "", 262 | "svg": "", 263 | "vrml": "" 264 | }, 265 | "page_layout_descr_file": "" 266 | }, 267 | "schematic": { 268 | "legacy_lib_dir": "", 269 | "legacy_lib_list": [] 270 | }, 271 | "sheets": [], 272 | "text_variables": {} 273 | } 274 | -------------------------------------------------------------------------------- /ecad/edge2/edge1.kicad_sch: -------------------------------------------------------------------------------- 1 | (kicad_sch (version 20231120) (generator "eeschema") (generator_version "8.0") 2 | (paper "A4") 3 | (lib_symbols) 4 | (symbol_instances) 5 | ) 6 | -------------------------------------------------------------------------------- /ecad/edge3/edge1.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "3dviewports": [], 4 | "design_settings": { 5 | "defaults": { 6 | "apply_defaults_to_fp_fields": false, 7 | "apply_defaults_to_fp_shapes": false, 8 | "apply_defaults_to_fp_text": false, 9 | "board_outline_line_width": 0.05, 10 | "copper_line_width": 0.2, 11 | "copper_text_italic": false, 12 | "copper_text_size_h": 1.5, 13 | "copper_text_size_v": 1.5, 14 | "copper_text_thickness": 0.3, 15 | "copper_text_upright": false, 16 | "courtyard_line_width": 0.05, 17 | "dimension_precision": 4, 18 | "dimension_units": 3, 19 | "dimensions": { 20 | "arrow_length": 1270000, 21 | "extension_offset": 500000, 22 | "keep_text_aligned": true, 23 | "suppress_zeroes": false, 24 | "text_position": 0, 25 | "units_format": 1 26 | }, 27 | "fab_line_width": 0.1, 28 | "fab_text_italic": false, 29 | "fab_text_size_h": 1.0, 30 | "fab_text_size_v": 1.0, 31 | "fab_text_thickness": 0.15, 32 | "fab_text_upright": false, 33 | "other_line_width": 0.1, 34 | "other_text_italic": false, 35 | "other_text_size_h": 1.0, 36 | "other_text_size_v": 1.0, 37 | "other_text_thickness": 0.15, 38 | "other_text_upright": false, 39 | "pads": { 40 | "drill": 0.762, 41 | "height": 1.524, 42 | "width": 1.524 43 | }, 44 | "silk_line_width": 0.1, 45 | "silk_text_italic": false, 46 | "silk_text_size_h": 1.0, 47 | "silk_text_size_v": 1.0, 48 | "silk_text_thickness": 0.1, 49 | "silk_text_upright": false, 50 | "zones": { 51 | "min_clearance": 0.5 52 | } 53 | }, 54 | "diff_pair_dimensions": [], 55 | "drc_exclusions": [], 56 | "meta": { 57 | "version": 2 58 | }, 59 | "rule_severities": { 60 | "annular_width": "error", 61 | "clearance": "error", 62 | "connection_width": "warning", 63 | "copper_edge_clearance": "error", 64 | "copper_sliver": "warning", 65 | "courtyards_overlap": "error", 66 | "diff_pair_gap_out_of_range": "error", 67 | "diff_pair_uncoupled_length_too_long": "error", 68 | "drill_out_of_range": "error", 69 | "duplicate_footprints": "warning", 70 | "extra_footprint": "warning", 71 | "footprint": "error", 72 | "footprint_symbol_mismatch": "warning", 73 | "footprint_type_mismatch": "ignore", 74 | "hole_clearance": "error", 75 | "hole_near_hole": "error", 76 | "holes_co_located": "warning", 77 | "invalid_outline": "error", 78 | "isolated_copper": "warning", 79 | "item_on_disabled_layer": "error", 80 | "items_not_allowed": "error", 81 | "length_out_of_range": "error", 82 | "lib_footprint_issues": "warning", 83 | "lib_footprint_mismatch": "warning", 84 | "malformed_courtyard": "error", 85 | "microvia_drill_out_of_range": "error", 86 | "missing_courtyard": "ignore", 87 | "missing_footprint": "warning", 88 | "net_conflict": "warning", 89 | "npth_inside_courtyard": "ignore", 90 | "padstack": "warning", 91 | "pth_inside_courtyard": "ignore", 92 | "shorting_items": "error", 93 | "silk_edge_clearance": "warning", 94 | "silk_over_copper": "warning", 95 | "silk_overlap": "warning", 96 | "skew_out_of_range": "error", 97 | "solder_mask_bridge": "error", 98 | "starved_thermal": "error", 99 | "text_height": "warning", 100 | "text_thickness": "warning", 101 | "through_hole_pad_without_hole": "error", 102 | "too_many_vias": "error", 103 | "track_dangling": "warning", 104 | "track_width": "error", 105 | "tracks_crossing": "error", 106 | "unconnected_items": "error", 107 | "unresolved_variable": "error", 108 | "via_dangling": "warning", 109 | "zones_intersect": "error" 110 | }, 111 | "rules": { 112 | "max_error": 0.005, 113 | "min_clearance": 0.0, 114 | "min_connection": 0.0, 115 | "min_copper_edge_clearance": 0.5, 116 | "min_hole_clearance": 0.25, 117 | "min_hole_to_hole": 0.25, 118 | "min_microvia_diameter": 0.2, 119 | "min_microvia_drill": 0.1, 120 | "min_resolved_spokes": 2, 121 | "min_silk_clearance": 0.0, 122 | "min_text_height": 0.8, 123 | "min_text_thickness": 0.08, 124 | "min_through_hole_diameter": 0.3, 125 | "min_track_width": 0.0, 126 | "min_via_annular_width": 0.1, 127 | "min_via_diameter": 0.5, 128 | "solder_mask_to_copper_clearance": 0.0, 129 | "use_height_for_length_calcs": true 130 | }, 131 | "teardrop_options": [ 132 | { 133 | "td_onpadsmd": true, 134 | "td_onroundshapesonly": false, 135 | "td_ontrackend": false, 136 | "td_onviapad": true 137 | } 138 | ], 139 | "teardrop_parameters": [ 140 | { 141 | "td_allow_use_two_tracks": true, 142 | "td_curve_segcount": 0, 143 | "td_height_ratio": 1.0, 144 | "td_length_ratio": 0.5, 145 | "td_maxheight": 2.0, 146 | "td_maxlen": 1.0, 147 | "td_on_pad_in_zone": false, 148 | "td_target_name": "td_round_shape", 149 | "td_width_to_size_filter_ratio": 0.9 150 | }, 151 | { 152 | "td_allow_use_two_tracks": true, 153 | "td_curve_segcount": 0, 154 | "td_height_ratio": 1.0, 155 | "td_length_ratio": 0.5, 156 | "td_maxheight": 2.0, 157 | "td_maxlen": 1.0, 158 | "td_on_pad_in_zone": false, 159 | "td_target_name": "td_rect_shape", 160 | "td_width_to_size_filter_ratio": 0.9 161 | }, 162 | { 163 | "td_allow_use_two_tracks": true, 164 | "td_curve_segcount": 0, 165 | "td_height_ratio": 1.0, 166 | "td_length_ratio": 0.5, 167 | "td_maxheight": 2.0, 168 | "td_maxlen": 1.0, 169 | "td_on_pad_in_zone": false, 170 | "td_target_name": "td_track_end", 171 | "td_width_to_size_filter_ratio": 0.9 172 | } 173 | ], 174 | "track_widths": [], 175 | "tuning_pattern_settings": { 176 | "diff_pair_defaults": { 177 | "corner_radius_percentage": 80, 178 | "corner_style": 1, 179 | "max_amplitude": 1.0, 180 | "min_amplitude": 0.2, 181 | "single_sided": false, 182 | "spacing": 1.0 183 | }, 184 | "diff_pair_skew_defaults": { 185 | "corner_radius_percentage": 80, 186 | "corner_style": 1, 187 | "max_amplitude": 1.0, 188 | "min_amplitude": 0.2, 189 | "single_sided": false, 190 | "spacing": 0.6 191 | }, 192 | "single_track_defaults": { 193 | "corner_radius_percentage": 80, 194 | "corner_style": 1, 195 | "max_amplitude": 1.0, 196 | "min_amplitude": 0.2, 197 | "single_sided": false, 198 | "spacing": 0.6 199 | } 200 | }, 201 | "via_dimensions": [], 202 | "zones_allow_external_fillets": false 203 | }, 204 | "ipc2581": { 205 | "dist": "", 206 | "distpn": "", 207 | "internal_id": "", 208 | "mfg": "", 209 | "mpn": "" 210 | }, 211 | "layer_presets": [], 212 | "viewports": [] 213 | }, 214 | "boards": [], 215 | "cvpcb": { 216 | "equivalence_files": [] 217 | }, 218 | "libraries": { 219 | "pinned_footprint_libs": [], 220 | "pinned_symbol_libs": [] 221 | }, 222 | "meta": { 223 | "filename": "edge1.kicad_pro", 224 | "version": 1 225 | }, 226 | "net_settings": { 227 | "classes": [ 228 | { 229 | "bus_width": 12, 230 | "clearance": 0.2, 231 | "diff_pair_gap": 0.25, 232 | "diff_pair_via_gap": 0.25, 233 | "diff_pair_width": 0.2, 234 | "line_style": 0, 235 | "microvia_diameter": 0.3, 236 | "microvia_drill": 0.1, 237 | "name": "Default", 238 | "pcb_color": "rgba(0, 0, 0, 0.000)", 239 | "schematic_color": "rgba(0, 0, 0, 0.000)", 240 | "track_width": 0.2, 241 | "via_diameter": 0.6, 242 | "via_drill": 0.3, 243 | "wire_width": 6 244 | } 245 | ], 246 | "meta": { 247 | "version": 3 248 | }, 249 | "net_colors": null, 250 | "netclass_assignments": null, 251 | "netclass_patterns": [] 252 | }, 253 | "pcbnew": { 254 | "last_paths": { 255 | "gencad": "", 256 | "idf": "", 257 | "netlist": "", 258 | "plot": "", 259 | "pos_files": "", 260 | "specctra_dsn": "", 261 | "step": "", 262 | "svg": "", 263 | "vrml": "" 264 | }, 265 | "page_layout_descr_file": "" 266 | }, 267 | "schematic": { 268 | "legacy_lib_dir": "", 269 | "legacy_lib_list": [] 270 | }, 271 | "sheets": [], 272 | "text_variables": {} 273 | } 274 | -------------------------------------------------------------------------------- /ecad/edge3/edge1.kicad_sch: -------------------------------------------------------------------------------- 1 | (kicad_sch (version 20231120) (generator "eeschema") (generator_version "8.0") 2 | (paper "A4") 3 | (lib_symbols) 4 | (symbol_instances) 5 | ) 6 | -------------------------------------------------------------------------------- /ecad/edge4/edge1.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "3dviewports": [], 4 | "design_settings": { 5 | "defaults": { 6 | "apply_defaults_to_fp_fields": false, 7 | "apply_defaults_to_fp_shapes": false, 8 | "apply_defaults_to_fp_text": false, 9 | "board_outline_line_width": 0.05, 10 | "copper_line_width": 0.2, 11 | "copper_text_italic": false, 12 | "copper_text_size_h": 1.5, 13 | "copper_text_size_v": 1.5, 14 | "copper_text_thickness": 0.3, 15 | "copper_text_upright": false, 16 | "courtyard_line_width": 0.05, 17 | "dimension_precision": 4, 18 | "dimension_units": 3, 19 | "dimensions": { 20 | "arrow_length": 1270000, 21 | "extension_offset": 500000, 22 | "keep_text_aligned": true, 23 | "suppress_zeroes": false, 24 | "text_position": 0, 25 | "units_format": 1 26 | }, 27 | "fab_line_width": 0.1, 28 | "fab_text_italic": false, 29 | "fab_text_size_h": 1.0, 30 | "fab_text_size_v": 1.0, 31 | "fab_text_thickness": 0.15, 32 | "fab_text_upright": false, 33 | "other_line_width": 0.1, 34 | "other_text_italic": false, 35 | "other_text_size_h": 1.0, 36 | "other_text_size_v": 1.0, 37 | "other_text_thickness": 0.15, 38 | "other_text_upright": false, 39 | "pads": { 40 | "drill": 0.762, 41 | "height": 1.524, 42 | "width": 1.524 43 | }, 44 | "silk_line_width": 0.1, 45 | "silk_text_italic": false, 46 | "silk_text_size_h": 1.0, 47 | "silk_text_size_v": 1.0, 48 | "silk_text_thickness": 0.1, 49 | "silk_text_upright": false, 50 | "zones": { 51 | "min_clearance": 0.5 52 | } 53 | }, 54 | "diff_pair_dimensions": [], 55 | "drc_exclusions": [], 56 | "meta": { 57 | "version": 2 58 | }, 59 | "rule_severities": { 60 | "annular_width": "error", 61 | "clearance": "error", 62 | "connection_width": "warning", 63 | "copper_edge_clearance": "error", 64 | "copper_sliver": "warning", 65 | "courtyards_overlap": "error", 66 | "diff_pair_gap_out_of_range": "error", 67 | "diff_pair_uncoupled_length_too_long": "error", 68 | "drill_out_of_range": "error", 69 | "duplicate_footprints": "warning", 70 | "extra_footprint": "warning", 71 | "footprint": "error", 72 | "footprint_symbol_mismatch": "warning", 73 | "footprint_type_mismatch": "ignore", 74 | "hole_clearance": "error", 75 | "hole_near_hole": "error", 76 | "holes_co_located": "warning", 77 | "invalid_outline": "error", 78 | "isolated_copper": "warning", 79 | "item_on_disabled_layer": "error", 80 | "items_not_allowed": "error", 81 | "length_out_of_range": "error", 82 | "lib_footprint_issues": "warning", 83 | "lib_footprint_mismatch": "warning", 84 | "malformed_courtyard": "error", 85 | "microvia_drill_out_of_range": "error", 86 | "missing_courtyard": "ignore", 87 | "missing_footprint": "warning", 88 | "net_conflict": "warning", 89 | "npth_inside_courtyard": "ignore", 90 | "padstack": "warning", 91 | "pth_inside_courtyard": "ignore", 92 | "shorting_items": "error", 93 | "silk_edge_clearance": "warning", 94 | "silk_over_copper": "warning", 95 | "silk_overlap": "warning", 96 | "skew_out_of_range": "error", 97 | "solder_mask_bridge": "error", 98 | "starved_thermal": "error", 99 | "text_height": "warning", 100 | "text_thickness": "warning", 101 | "through_hole_pad_without_hole": "error", 102 | "too_many_vias": "error", 103 | "track_dangling": "warning", 104 | "track_width": "error", 105 | "tracks_crossing": "error", 106 | "unconnected_items": "error", 107 | "unresolved_variable": "error", 108 | "via_dangling": "warning", 109 | "zones_intersect": "error" 110 | }, 111 | "rules": { 112 | "max_error": 0.005, 113 | "min_clearance": 0.0, 114 | "min_connection": 0.0, 115 | "min_copper_edge_clearance": 0.5, 116 | "min_hole_clearance": 0.25, 117 | "min_hole_to_hole": 0.25, 118 | "min_microvia_diameter": 0.2, 119 | "min_microvia_drill": 0.1, 120 | "min_resolved_spokes": 2, 121 | "min_silk_clearance": 0.0, 122 | "min_text_height": 0.8, 123 | "min_text_thickness": 0.08, 124 | "min_through_hole_diameter": 0.3, 125 | "min_track_width": 0.0, 126 | "min_via_annular_width": 0.1, 127 | "min_via_diameter": 0.5, 128 | "solder_mask_to_copper_clearance": 0.0, 129 | "use_height_for_length_calcs": true 130 | }, 131 | "teardrop_options": [ 132 | { 133 | "td_onpadsmd": true, 134 | "td_onroundshapesonly": false, 135 | "td_ontrackend": false, 136 | "td_onviapad": true 137 | } 138 | ], 139 | "teardrop_parameters": [ 140 | { 141 | "td_allow_use_two_tracks": true, 142 | "td_curve_segcount": 0, 143 | "td_height_ratio": 1.0, 144 | "td_length_ratio": 0.5, 145 | "td_maxheight": 2.0, 146 | "td_maxlen": 1.0, 147 | "td_on_pad_in_zone": false, 148 | "td_target_name": "td_round_shape", 149 | "td_width_to_size_filter_ratio": 0.9 150 | }, 151 | { 152 | "td_allow_use_two_tracks": true, 153 | "td_curve_segcount": 0, 154 | "td_height_ratio": 1.0, 155 | "td_length_ratio": 0.5, 156 | "td_maxheight": 2.0, 157 | "td_maxlen": 1.0, 158 | "td_on_pad_in_zone": false, 159 | "td_target_name": "td_rect_shape", 160 | "td_width_to_size_filter_ratio": 0.9 161 | }, 162 | { 163 | "td_allow_use_two_tracks": true, 164 | "td_curve_segcount": 0, 165 | "td_height_ratio": 1.0, 166 | "td_length_ratio": 0.5, 167 | "td_maxheight": 2.0, 168 | "td_maxlen": 1.0, 169 | "td_on_pad_in_zone": false, 170 | "td_target_name": "td_track_end", 171 | "td_width_to_size_filter_ratio": 0.9 172 | } 173 | ], 174 | "track_widths": [], 175 | "tuning_pattern_settings": { 176 | "diff_pair_defaults": { 177 | "corner_radius_percentage": 80, 178 | "corner_style": 1, 179 | "max_amplitude": 1.0, 180 | "min_amplitude": 0.2, 181 | "single_sided": false, 182 | "spacing": 1.0 183 | }, 184 | "diff_pair_skew_defaults": { 185 | "corner_radius_percentage": 80, 186 | "corner_style": 1, 187 | "max_amplitude": 1.0, 188 | "min_amplitude": 0.2, 189 | "single_sided": false, 190 | "spacing": 0.6 191 | }, 192 | "single_track_defaults": { 193 | "corner_radius_percentage": 80, 194 | "corner_style": 1, 195 | "max_amplitude": 1.0, 196 | "min_amplitude": 0.2, 197 | "single_sided": false, 198 | "spacing": 0.6 199 | } 200 | }, 201 | "via_dimensions": [], 202 | "zones_allow_external_fillets": false 203 | }, 204 | "ipc2581": { 205 | "dist": "", 206 | "distpn": "", 207 | "internal_id": "", 208 | "mfg": "", 209 | "mpn": "" 210 | }, 211 | "layer_presets": [], 212 | "viewports": [] 213 | }, 214 | "boards": [], 215 | "cvpcb": { 216 | "equivalence_files": [] 217 | }, 218 | "libraries": { 219 | "pinned_footprint_libs": [], 220 | "pinned_symbol_libs": [] 221 | }, 222 | "meta": { 223 | "filename": "edge1.kicad_pro", 224 | "version": 1 225 | }, 226 | "net_settings": { 227 | "classes": [ 228 | { 229 | "bus_width": 12, 230 | "clearance": 0.2, 231 | "diff_pair_gap": 0.25, 232 | "diff_pair_via_gap": 0.25, 233 | "diff_pair_width": 0.2, 234 | "line_style": 0, 235 | "microvia_diameter": 0.3, 236 | "microvia_drill": 0.1, 237 | "name": "Default", 238 | "pcb_color": "rgba(0, 0, 0, 0.000)", 239 | "schematic_color": "rgba(0, 0, 0, 0.000)", 240 | "track_width": 0.2, 241 | "via_diameter": 0.6, 242 | "via_drill": 0.3, 243 | "wire_width": 6 244 | } 245 | ], 246 | "meta": { 247 | "version": 3 248 | }, 249 | "net_colors": null, 250 | "netclass_assignments": null, 251 | "netclass_patterns": [] 252 | }, 253 | "pcbnew": { 254 | "last_paths": { 255 | "gencad": "", 256 | "idf": "", 257 | "netlist": "", 258 | "plot": "jlcpcb", 259 | "pos_files": "", 260 | "specctra_dsn": "", 261 | "step": "", 262 | "svg": "", 263 | "vrml": "" 264 | }, 265 | "page_layout_descr_file": "" 266 | }, 267 | "schematic": { 268 | "legacy_lib_dir": "", 269 | "legacy_lib_list": [] 270 | }, 271 | "sheets": [], 272 | "text_variables": {} 273 | } 274 | -------------------------------------------------------------------------------- /ecad/edge4/edge1.kicad_sch: -------------------------------------------------------------------------------- 1 | (kicad_sch (version 20231120) (generator "eeschema") (generator_version "8.0") 2 | (paper "A4") 3 | (lib_symbols) 4 | (symbol_instances) 5 | ) 6 | -------------------------------------------------------------------------------- /firmware/.gitignore: -------------------------------------------------------------------------------- 1 | assets/ 2 | src/video.c 3 | -------------------------------------------------------------------------------- /firmware/build.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # This should be run manually whenever the video is changed, don't expect this to be often 4 | 5 | # Taken and adapted from here: 6 | # https://github.com/AlexandreSenpai/Bad-Apple/blob/main/run.py 7 | 8 | from multiprocessing.pool import ThreadPool 9 | from multiprocessing import cpu_count 10 | from typing import Tuple 11 | import time 12 | 13 | import cv2 14 | import tqdm 15 | import numpy as np 16 | import matplotlib.pyplot as plt 17 | from matplotlib.animation import FuncAnimation 18 | import argparse 19 | 20 | 21 | video_path = './assets/rickroll_square.mp4' 22 | # video_path = './assets/bad-apple.mp4' 23 | code_gen_path = './src/video.c' 24 | files, ranks, leds = (8, 8, 8) 25 | frame_skip = 1 26 | 27 | parser = argparse.ArgumentParser(description="Generates video file for board") 28 | parser.add_argument("-v", "--visual", action="store_true", help="Visualize frame") 29 | 30 | args = parser.parse_args() 31 | 32 | # Set 1 33 | start_frame = 1 34 | end_frame = 200 35 | # Set 2 36 | # start_frame = 326 37 | # end_frame = 326*2 38 | # Set 3 39 | # start_frame = 326*2 40 | # end_frame = 326*3 41 | # Set 4 42 | # start_frame = 326*3 43 | # end_frame = 326*4 44 | # Set 5 45 | # start_frame = 326*4 46 | # end_frame = 326*5 47 | # Set 5 48 | # start_frame = 326*5 49 | # end_frame = 326*6 50 | # 51 | 52 | last_frame = None 53 | pixels = [] 54 | 55 | 56 | def write_frame(frame_information: Tuple[int, cv2.VideoCapture]): 57 | 58 | order, frame = frame_information 59 | if args.visual: 60 | global last_frame 61 | last_frame = frame 62 | 63 | y, x, _ = frame.shape 64 | pixel_row = 0 65 | 66 | if args.visual: 67 | global pixels 68 | pixels += [[]] 69 | 70 | frame_str = ' {\n' 71 | for i in range(files): 72 | frame_str += ' {\n' 73 | for j in range(ranks): 74 | frame_str += ' {' 75 | for led in range(leds): 76 | x_cm = i * 5 + 2.5 77 | y_cm = j * 5 + 2.5 78 | led_theta = led * 2 * np.pi / 8 + np.pi 79 | if i <= 3 and j <= 3: 80 | led_theta += np.pi / 2 81 | elif i > 3 and j <= 3: 82 | led_theta += np.pi 83 | elif i > 3 and j > 3: 84 | led_theta += 3 * np.pi / 2 85 | 86 | x_cm += 1.8 * np.cos(led_theta) 87 | y_cm += 1.8 * np.sin(led_theta) 88 | 89 | pixel = frame[int(np.round((1 - y_cm / 40) * y)), int(np.round(x_cm / 40 * x))] 90 | r = pixel[2] 91 | g = pixel[1] 92 | b = pixel[0] 93 | 94 | if args.visual: 95 | pixels[-1] += [[x_cm, y_cm, r, g, b]] 96 | 97 | frame_str += f'0x{r:02x}{g:02x}{b:02x}' 98 | frame_str += ', ' 99 | frame_str += '},\n' 100 | 101 | frame_str += '},\n' 102 | frame_str += ' },\n' 103 | 104 | return order, frame_str 105 | 106 | 107 | def generate_frames(video: cv2.VideoCapture): 108 | success = True 109 | order = 0 110 | i = 0 111 | 112 | while success and i < end_frame: 113 | i += 1 114 | success, frame = video.read() 115 | if i < start_frame: 116 | continue 117 | 118 | if i % frame_skip != 0: 119 | continue 120 | 121 | if frame is None: 122 | break 123 | 124 | yield order, frame 125 | 126 | order += 1 127 | 128 | if __name__ == '__main__': 129 | 130 | video = cv2.VideoCapture(video_path) 131 | frame_cnt = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) 132 | 133 | with ThreadPool(processes=cpu_count()) as pool: 134 | frames = list(tqdm.tqdm(pool.imap(write_frame, generate_frames(video)), total=min(frame_cnt, (end_frame-start_frame)/2))) 135 | pool.close() 136 | pool.join() 137 | 138 | if args.visual: 139 | 140 | # cv2.imshow('frame', last_frame) 141 | 142 | fig, ax = plt.subplots() 143 | scatter = ax.scatter([], []) 144 | ax.set_aspect('equal', adjustable='box') 145 | 146 | plt.xlim(0, 40) 147 | plt.ylim(0, 40) 148 | 149 | def update(pix): 150 | pix = np.array(pix) 151 | x = pix[:, 0] 152 | y = pix[:, 1] 153 | colors = pix[:, 2:] / 255.0 154 | scatter.set_offsets(pix[:, 0:2]) 155 | scatter.set_facecolors(colors) 156 | return scatter, 157 | 158 | # Create the animation 159 | ani = FuncAnimation( 160 | fig, update, frames=pixels, interval=1000 / (video.get(cv2.CAP_PROP_FPS) / frame_skip), blit=True 161 | ) 162 | plt.show() 163 | 164 | 165 | frames = sorted(frames, key=lambda x: x[0]) 166 | 167 | with open(code_gen_path, 'w') as f: 168 | f.write('// This is an autogenerated array of pixel data made through build.py, do not edit this manually\n') 169 | # f.write('use tdriver::graphics;\n') 170 | # f.write(f'pub const FRAMES: [[[u32; graphics::WORDS]; graphics::HEIGHT]; {len(frames)}] = [\n') 171 | 172 | f.write(f'#include \n') 173 | f.write(f'#include \n') 174 | f.write(f'#include \n') 175 | f.write('\n') 176 | f.write(f'const uint32_t num_frames = {len(frames)};\n') 177 | f.write(f'const float frame_rate = {video.get(cv2.CAP_PROP_FPS) / frame_skip};\n') 178 | f.write('\n') 179 | f.write(f'#if LINK_VIDEO\n') 180 | f.write('\n') 181 | f.write(f'const uint32_t frames[{len(frames)}][{files}][{ranks}][{leds}] PROGMEM = {{\n') 182 | for _, frame in frames: 183 | f.write(frame) 184 | f.write('};\n') 185 | f.write(f'#else\n') 186 | f.write(f'const uint32_t frames[0][{files}][{ranks}][{leds}] PROGMEM = {{}};\n') 187 | f.write(f'#endif\n') 188 | -------------------------------------------------------------------------------- /firmware/include/goertzel.h: -------------------------------------------------------------------------------- 1 | #ifndef GOERTZEL_H 2 | #define GOERTZEL_H 3 | 4 | #include 5 | #include 6 | 7 | class Goertzel { 8 | public: 9 | Goertzel(double targetFreq, double sampleRate, size_t windowSize); 10 | void addSample(double sample); 11 | double getMagnitude(); 12 | 13 | private: 14 | double targetFreq; 15 | double sampleRate; 16 | size_t windowSize; 17 | int k; 18 | double omega; 19 | double coeff; 20 | double s1; 21 | double s2; 22 | std::vector samples; 23 | size_t currentIndex; 24 | }; 25 | 26 | #endif // GOERTZEL_H 27 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | DisableFormat: true 3 | SortIncludes: false 4 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/MISRA.md: -------------------------------------------------------------------------------- 1 | # MISRA Compliance 2 | 3 | FreeRTOS-Kernel conforms to [MISRA C:2012](https://www.misra.org.uk/misra-c) 4 | guidelines, with the deviations listed below. Compliance is checked with 5 | Coverity static analysis. Since the FreeRTOS kernel is designed for 6 | small-embedded devices, it needs to have a very small memory footprint and 7 | has to be efficient. To achieve that and to increase the performance, it 8 | deviates from some MISRA rules. The specific deviations, suppressed inline, 9 | are listed below. 10 | 11 | Additionally, [MISRA configuration file](examples/coverity/coverity_misra.config) 12 | contains project wide deviations. 13 | 14 | ### Suppressed with Coverity Comments 15 | To find the violation references in the source files run grep on the source code 16 | with ( Assuming rule 8.4 violation; with justification in point 1 ): 17 | ``` 18 | grep 'MISRA Ref 8.4.1' . -rI 19 | ``` 20 | 21 | #### Rule 8.4 22 | 23 | MISRA C:2012 Rule 8.4: A compatible declaration shall be visible when an 24 | object or function with external linkage is defined. 25 | 26 | _Ref 8.4.1_ 27 | - pxCurrentTCB(s) is defined with external linkage but it is only referenced 28 | from the assembly code in the port files. Therefore, adding a declaration in 29 | header file is not useful as the assembly code will still need to declare it 30 | separately. 31 | 32 | _Ref 8.4.2_ 33 | - xQueueRegistry is defined with external linkage because it is accessed by the 34 | kernel unit tests. It is not meant to be directly accessed by the application 35 | and therefore, not declared in a header file. 36 | 37 | #### Rule 8.6 38 | 39 | MISRA C:2012 Rule 8.6: An identifier with external linkage shall have exactly 40 | one external definition. 41 | 42 | _Ref 8.6.1_ 43 | - This rule prohibits an identifier with external linkage to have multiple 44 | definitions or no definition. FreeRTOS hook functions are implemented in 45 | the application and therefore, have no definition in the Kernel code. 46 | 47 | #### Rule 11.1 48 | MISRA C:2012 Rule 11.1: Conversions shall not be performed between a pointer to 49 | function and any other type. 50 | 51 | _Ref 11.1.1_ 52 | - The pointer to function is casted into void to avoid unused parameter 53 | compiler warning when Stream Buffer's Tx and Rx Completed callback feature is 54 | not used. 55 | 56 | #### Rule 11.3 57 | 58 | MISRA C:2012 Rule 11.3: A cast shall not be performed between a pointer to 59 | object type and a pointer to a different object type. 60 | 61 | _Ref 11.3.1_ 62 | - This rule prohibits casting a pointer to object into a pointer to a 63 | different object because it may result in an incorrectly aligned pointer, 64 | leading to undefined behavior. Even if the casting produces a correctly 65 | aligned pointer, the behavior may be still undefined if the pointer is 66 | used to access an object. FreeRTOS deliberately creates external aliases 67 | for all the kernel object types (StaticEventGroup_t, StaticQueue_t, 68 | StaticStreamBuffer_t, StaticTimer_t and StaticTask_t) for data hiding 69 | purposes. The internal object types and the corresponding external 70 | aliases are guaranteed to have the same size and alignment which is 71 | checked using configASSERT. 72 | 73 | 74 | #### Rule 11.5 75 | 76 | MISRA C:2012 Rule 11.5: A conversion should not be performed from pointer to 77 | void into pointer to object. 78 | This rule prohibits conversion of a pointer to void into a pointer to 79 | object because it may result in an incorrectly aligned pointer leading 80 | to undefined behavior. 81 | 82 | _Ref 11.5.1_ 83 | - The memory blocks returned by pvPortMalloc() are guaranteed to meet the 84 | architecture alignment requirements specified by portBYTE_ALIGNMENT. 85 | The casting of the pointer to void returned by pvPortMalloc() is, 86 | therefore, safe because it is guaranteed to be aligned. 87 | 88 | _Ref 11.5.2_ 89 | - The conversion from a pointer to void into a pointer to EventGroup_t is 90 | safe because it is a pointer to EventGroup_t, which is returned to the 91 | application at the time of event group creation for data hiding 92 | purposes. 93 | 94 | _Ref 11.5.3_ 95 | - The conversion from a pointer to void in list macros for list item owner 96 | is safe because the type of the pointer stored and retrieved is the 97 | same. 98 | 99 | _Ref 11.5.4_ 100 | - The conversion from a pointer to void into a pointer to EventGroup_t is 101 | safe because it is a pointer to EventGroup_t, which is passed as a 102 | parameter to the xTimerPendFunctionCallFromISR API when the callback is 103 | pended. 104 | 105 | _Ref 11.5.5_ 106 | - The conversion from a pointer to void into a pointer to uint8_t is safe 107 | because data storage buffers are implemented as uint8_t arrays for the 108 | ease of sizing, alignment and access. 109 | 110 | #### Rule 21.6 111 | 112 | MISRA C-2012 Rule 21.6: The Standard Library input/output functions shall not 113 | be used. 114 | 115 | _Ref 21.6.1_ 116 | - The Standard Library function snprintf is used in vTaskListTasks and 117 | vTaskGetRunTimeStatistics APIs, both of which are utility functions only and 118 | are not considered part of core kernel implementation. 119 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/README.md: -------------------------------------------------------------------------------- 1 | # FreeRTOS Port for Teensy 3.5, 3.6, 4.0, 4.1 2 | 3 | This is a basic port of [FreeRTOS][FreeRTOS] for the [Teensy 3.5][Teensy], [Teensy 3.6][Teensy], [Teensy 4.0][Teensy] and [Teensy 4.1][Teensy] boards. 4 | 5 | ## Introduction 6 | 7 | To make FreeRTOS work on the teensy boards I had to adjust the `EventResponder` class of the Teensy Arduino core library and optimized some minor parts. Therefore a custom [platform setting][TeensyPlatform] is used (`platform = https://github.com/tsandmann/platform-teensy`). It uses a more recent [compiler toolchain][ARMCrossCompiler] (e.g. to support C++20) and a slightly modified [Arduino core library][TeensyLibCore]. The latter is needed because FreeRTOS needs some interrupt vectors that are also used by the Arduino core (`SysTick` and `PendSV` for `EventResponder`) to be set up for the RTOS. The modified core library supports these services by running them ontop of the RTOS. 8 | 9 | ### Notice 10 | 11 | Consider this as experimental code and work in progress. *If it breaks, you get to keep both pieces.* 12 | 13 | ## Current Limitations 14 | 15 | * Updated libraries may cause some incompatibilities with the custom core library. More testing and documentation is needed before the custom core library change may be integrated in the official library. 16 | * This is a port of FreeRTOS to run its kernel on the Teensy boards. It does **not** include thread-safe peripheral drivers, thread-safe teensy libraries and so on! If you want to use peripherals (e.g. serial ports, I2C, SPI, etc.) from different tasks, you may have to synchronize the access. On the other hand C-library calls like `malloc` or `free` are thread-safe due to provided guards for newlib. 17 | * Documentation is very limited (including this readme). 18 | 19 | ## PlatformIO Usage 20 | 21 | 1. Install PlatformIO core as described [here][PIOInstall] 22 | 1. Clone this git repository: `git clone https://github.com/tsandmann/freertos-teensy` 23 | 1. Open an example of the cloned repo, e.g. `freertos-teensy/example/blink` 24 | 1. Select the correct project environment [PlatformIO toolbar][PIOToolbar] for your Teensy board, e.g. `teensy41` 25 | 1. Build project: use `Build` button on the [PlatformIO toolbar][PIOToolbar] or shortcut (`ctrl/cmd+alt+b`) 26 | 1. Upload firmware image 27 | * Connect USB cable to teensy board 28 | * Use `Upload` button on the [PlatformIO toolbar][PIOToolbar] or shortcut (`ctrl/cmd+alt+t`) and select "PlatformIO: Upload" 29 | 1. Use a terminal program (e.g. minicom) to connect to the USB serial device 30 | * If you use minicom: goto `Serial port setup` settings and set `Serial Device` to your serial device (typically sth. like `/dev/cu.usbmodemXXXXXXX` or `/dev/tty.usbmodemXXXXXXX`) 31 | 32 | ## Teensyduino Usage 33 | 34 | There is a test version available which can be used with Teensyduino. If you want to try it out: 35 | 36 | 1. Download the library [here](https://github.com/tsandmann/freertos-teensy/releases) as a zip archive. 37 | 1. In Teensyduino select "Sketch -> Include Library -> Add .ZIP Library" and specify the downloaded zip archive. 38 | 1. Create a new sketch in Teensyduino, e.g. `blink.ino`. 39 | 1. Copy the contents of [main.cpp](https://github.com/tsandmann/freertos-teensy/blob/master/example/blink/src/main.cpp) to it. 40 | 1. Compile and upload the sketch as usual. 41 | 42 | Currently there are the following limitations for Teensyduino projects: 43 | 44 | - There is no support for C++'s [`std::thread`][StdThread], [`std::jthread`][StdThread] or [Futures][StdThread] (custom compiler options for the library would be necessary which is currently not possible with arduino's IDE). 45 | - If the sketch (or any included library) uses the `EventResponder` [class](https://github.com/PaulStoffregen/cores/blob/bf413538ce5d331a4ac768e50c5668b9b6c1901f/teensy4/EventResponder.h#L67), the `EventResponder::attachInterrupt()` [variant](https://github.com/PaulStoffregen/cores/blob/bf413538ce5d331a4ac768e50c5668b9b6c1901f/teensy4/EventResponder.h#L111) must not be used, otherwise FreeRTOS will stop working. An update of the Teenys core library is required to make this work (this [Pull request](https://github.com/PaulStoffregen/cores/pull/683) needs to be merged for this). 46 | - For Teensy 4.x: To print useful stack traces (see [`void HardFault_HandlerC(unsigned int* hardfault_args)`](https://github.com/tsandmann/freertos-teensy/blob/master/src/portable/teensy_4.cpp#L351) and [`_Unwind_Reason_Code trace_fcn(_Unwind_Context* ctx, void* depth)`](https://github.com/tsandmann/freertos-teensy/blob/master/src/portable/teensy_common.cpp#L179)) in case of a crash or an exception, the code must be compiled by using the `-fasynchronous-unwind-tables` option to tell gcc to generate the needed unwind tables. Furthermore, an updated linker script is needed to put `.ARM.exidx` and `.ARM.extab` in the right place and some (startup) code to copy these tables into RAM. (libgcc's unwind code requires the unwind table at an address reachable by a 31-bit signed offset (+/- 0x3FFFFFFF) from executed instructions). To support call traces over C-library calls, newlib has to be compiled with `-fasynchronous-unwind-tables` option as well. 47 | - I haven't done much testing so far as I don't use Teensyduino for my projects. 48 | 49 | ## Continuous Integration Tests 50 | 51 | TBD 52 | 53 | [FreeRTOS]: https://www.freertos.org 54 | [Teensy]: https://www.pjrc.com/teensy/index.html 55 | [PlatformIO]: https://platformio.org 56 | [PIOGithub]: https://github.com/platformio/platformio-core 57 | [PIOInstall]: https://docs.platformio.org/en/latest/integration/ide/vscode.html#installation 58 | [PioCliInstall]: https://docs.platformio.org/en/latest/core/installation.html#install-shell-commands 59 | [PIOToolbar]: https://docs.platformio.org/en/latest/integration/ide/vscode.html#platformio-toolbar 60 | [VSCode]: https://github.com/Microsoft/vscode 61 | [PlatformIOIDE]: http://docs.platformio.org/en/latest/ide.html#ide 62 | [TeensyPlatform]: https://github.com/tsandmann/platform-teensy 63 | [ARMCrossCompiler]: https://github.com/tsandmann/arm-cortexm-toolchain-linux 64 | [TeensyLibCore]: https://github.com/tsandmann/teensy-cores 65 | [StdThread]: https://en.cppreference.com/w/cpp/thread 66 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/cspell.config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json 3 | version: '0.2' 4 | # Allows things like stringLength 5 | allowCompoundWords: true 6 | 7 | # Read files not to spell check from the git ignore 8 | useGitignore: true 9 | 10 | # Language settings for C 11 | languageSettings: 12 | - caseSensitive: false 13 | enabled: true 14 | languageId: c 15 | locale: "*" 16 | 17 | # Add a dictionary, and the path to the word list 18 | dictionaryDefinitions: 19 | - name: freertos-words 20 | path: '.github/.cSpellWords.txt' 21 | addWords: true 22 | 23 | dictionaries: 24 | - freertos-words 25 | 26 | # Paths and files to ignore 27 | ignorePaths: 28 | - 'dependency' 29 | - 'docs' 30 | - 'ThirdParty' 31 | - 'History.txt' 32 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/docs/freertos/GitHub-FreeRTOS-Kernel-Home.url: -------------------------------------------------------------------------------- 1 | [{000214A0-0000-0000-C000-000000000046}] 2 | Prop3=19,2 3 | [InternetShortcut] 4 | URL=https://github.com/FreeRTOS/FreeRTOS-Kernel 5 | IconIndex=0 6 | IDList= 7 | HotKey=0 8 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/docs/freertos/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/docs/freertos/Quick_Start_Guide.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=https://www.FreeRTOS.org/FreeRTOS-quick-start-guide.html 3 | IDList= 4 | [{000214A0-0000-0000-C000-000000000046}] 5 | Prop3=19,2 6 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/docs/freertos/README.md: -------------------------------------------------------------------------------- 1 | ## Getting started 2 | This repository contains FreeRTOS kernel source/header files and kernel ports only. This repository is referenced as a submodule in [FreeRTOS/FreeRTOS](https://github.com/FreeRTOS/FreeRTOS) repository, which contains pre-configured demo application projects under ```FreeRTOS/Demo``` directory. 3 | 4 | The easiest way to use FreeRTOS is to start with one of the pre-configured demo application projects. That way you will have the correct FreeRTOS source files included, and the correct include paths configured. Once a demo application is building and executing you can remove the demo application files, and start to add in your own application source files. See the [FreeRTOS Kernel Quick Start Guide](https://www.FreeRTOS.org/FreeRTOS-quick-start-guide.html) for detailed instructions and other useful links. 5 | 6 | Additionally, for FreeRTOS kernel feature information refer to the [Developer Documentation](https://www.FreeRTOS.org/features.html), and [API Reference](https://www.FreeRTOS.org/a00106.html). 7 | 8 | ### Getting help 9 | If you have any questions or need assistance troubleshooting your FreeRTOS project, we have an active community that can help on the [FreeRTOS Community Support Forum](https://forums.freertos.org). 10 | 11 | ## Cloning this repository 12 | 13 | To clone using HTTPS: 14 | ``` 15 | git clone https://github.com/FreeRTOS/FreeRTOS-Kernel.git 16 | ``` 17 | Using SSH: 18 | ``` 19 | git clone git@github.com:FreeRTOS/FreeRTOS-Kernel.git 20 | ``` 21 | 22 | ## Repository structure 23 | - The root of this repository contains the three files that are common to 24 | every port - list.c, queue.c and tasks.c. The kernel is contained within these 25 | three files. croutine.c implements the optional co-routine functionality - which 26 | is normally only used on very memory limited systems. 27 | 28 | - The ```./portable``` directory contains the files that are specific to a particular microcontroller and/or compiler. 29 | See the readme file in the ```./portable``` directory for more information. 30 | 31 | - The ```./include``` directory contains the real time kernel header files. 32 | 33 | ### Code Formatting 34 | FreeRTOS files are formatted using the "uncrustify" tool. The configuration file used by uncrustify can be found in the [FreeRTOS/FreeRTOS repository](https://github.com/FreeRTOS/FreeRTOS/blob/main/tools/uncrustify.cfg). 35 | 36 | ### Spelling 37 | *lexicon.txt* contains words that are not traditionally found in an English dictionary. It is used by the spellchecker to verify the various jargon, variable names, and other odd words used in the FreeRTOS code base. If your pull request fails to pass the spelling and you believe this is a mistake, then add the word to *lexicon.txt*. 38 | Note that only the FreeRTOS Kernel source files are checked for proper spelling, the portable section is ignored. 39 | 40 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/blink/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/blink/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/blink/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:teensy36] 12 | platform = https://github.com/tsandmann/platform-teensy.git 13 | board = teensy36 14 | framework = arduino 15 | lib_deps = https://github.com/tsandmann/freertos-teensy.git 16 | build_flags = -Wformat=1 -DUSB_SERIAL -DTEENSY_OPT_SMALLEST_CODE_LTO 17 | upload_protocol = teensy-cli 18 | 19 | [env:teensy40] 20 | platform = https://github.com/tsandmann/platform-teensy.git 21 | board = teensy40 22 | framework = arduino 23 | lib_deps = https://github.com/tsandmann/freertos-teensy.git 24 | build_flags = -Wformat=1 -DUSB_SERIAL -DTEENSY_OPT_FASTER_LTO 25 | upload_flags = -v 26 | upload_protocol = teensy-cli 27 | 28 | [env:teensy41] 29 | platform = https://github.com/tsandmann/platform-teensy.git 30 | board = teensy41 31 | framework = arduino 32 | lib_deps = https://github.com/tsandmann/freertos-teensy.git 33 | build_flags = -Wformat=1 -DUSB_SERIAL -DTEENSY_OPT_FASTER_LTO 34 | upload_flags = -v 35 | upload_protocol = teensy-cli 36 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/blink/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the FreeRTOS port to Teensy boards. 3 | * Copyright (c) 2020-2024 Timo Sandmann 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library. If not, see . 17 | */ 18 | 19 | /** 20 | * @file main.cpp 21 | * @brief FreeRTOS example for Teensy boards 22 | * @author Timo Sandmann 23 | * @date 17.05.2020 24 | */ 25 | 26 | #include "arduino_freertos.h" 27 | #include "avr/pgmspace.h" 28 | 29 | 30 | static void task1(void*) { 31 | pinMode(arduino::LED_BUILTIN, arduino::OUTPUT); 32 | while (true) { 33 | digitalWriteFast(arduino::LED_BUILTIN, arduino::LOW); 34 | vTaskDelay(pdMS_TO_TICKS(500)); 35 | 36 | digitalWriteFast(arduino::LED_BUILTIN, arduino::HIGH); 37 | vTaskDelay(pdMS_TO_TICKS(500)); 38 | } 39 | } 40 | 41 | static void task2(void*) { 42 | Serial.begin(0); 43 | while (true) { 44 | Serial.println("TICK"); 45 | vTaskDelay(pdMS_TO_TICKS(1'000)); 46 | 47 | Serial.println("TOCK"); 48 | vTaskDelay(pdMS_TO_TICKS(1'000)); 49 | } 50 | } 51 | 52 | FLASHMEM __attribute__((noinline)) void setup() { 53 | Serial.begin(0); 54 | delay(2'000); 55 | 56 | if (CrashReport) { 57 | Serial.print(CrashReport); 58 | Serial.println(); 59 | Serial.flush(); 60 | } 61 | 62 | Serial.println(PSTR("\r\nBooting FreeRTOS kernel " tskKERNEL_VERSION_NUMBER ". Built by gcc " __VERSION__ " (newlib " _NEWLIB_VERSION ") on " __DATE__ ". ***\r\n")); 63 | 64 | xTaskCreate(task1, "task1", 128, nullptr, 2, nullptr); 65 | xTaskCreate(task2, "task2", 128, nullptr, 2, nullptr); 66 | 67 | Serial.println("setup(): starting scheduler..."); 68 | Serial.flush(); 69 | 70 | vTaskStartScheduler(); 71 | } 72 | 73 | void loop() {} 74 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/sdfat/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | AccessModifierOffset: -4 3 | AlignAfterOpenBracket: DontAlign 4 | AlignConsecutiveAssignments: false 5 | AlignConsecutiveDeclarations: false 6 | AlignEscapedNewlinesLeft: true 7 | AlignOperands: false 8 | AlignTrailingComments: false 9 | AllowAllParametersOfDeclarationOnNextLine: false 10 | AllowShortBlocksOnASingleLine: false 11 | AllowShortCaseLabelsOnASingleLine: true 12 | AllowShortFunctionsOnASingleLine: Empty 13 | AllowShortIfStatementsOnASingleLine: false 14 | AllowShortLoopsOnASingleLine: false 15 | AlwaysBreakAfterDefinitionReturnType: None 16 | AlwaysBreakAfterReturnType: None 17 | AlwaysBreakBeforeMultilineStrings: false 18 | AlwaysBreakTemplateDeclarations: true 19 | BinPackArguments: true 20 | BinPackParameters: true 21 | BraceWrapping: 22 | AfterClass: false 23 | AfterControlStatement: false 24 | AfterEnum: false 25 | AfterFunction: false 26 | AfterNamespace: false 27 | AfterObjCDeclaration: false 28 | AfterStruct: false 29 | AfterUnion: false 30 | BeforeCatch: false 31 | BeforeElse: false 32 | IndentBraces: false 33 | SplitEmptyFunction: false 34 | SplitEmptyRecord: false 35 | SplitEmptyNamespace: false 36 | BreakBeforeBinaryOperators: NonAssignment 37 | BreakBeforeBraces: Attach 38 | BreakBeforeTernaryOperators: false 39 | BreakConstructorInitializersBeforeComma: false 40 | BreakStringLiterals: true 41 | ColumnLimit: 160 42 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 43 | ConstructorInitializerIndentWidth: 4 44 | ContinuationIndentWidth: 4 45 | Cpp11BracedListStyle: false 46 | DerivePointerAlignment: false 47 | DisableFormat: false 48 | FixNamespaceComments: true 49 | IncludeBlocks: Regroup 50 | IndentCaseLabels: true 51 | IndentWidth: 4 52 | IndentWrappedFunctionNames: true 53 | KeepEmptyLinesAtTheStartOfBlocks: false 54 | Language: Cpp 55 | MaxEmptyLinesToKeep: 2 56 | NamespaceIndentation: None 57 | ObjCBlockIndentWidth: 4 58 | PenaltyBreakBeforeFirstCallParameter: 1 59 | PenaltyBreakComment: 300 60 | PenaltyBreakFirstLessLess: 120 61 | PenaltyBreakString: 1000 62 | PenaltyExcessCharacter: 1000000 63 | PenaltyReturnTypeOnItsOwnLine: 200 64 | PointerAlignment: Left 65 | ReflowComments: true 66 | SortIncludes: false 67 | SpaceAfterCStyleCast: true 68 | SpaceBeforeAssignmentOperators: true 69 | SpaceBeforeCpp11BracedList: true 70 | SpaceBeforeCtorInitializerColon: true 71 | SpaceBeforeInheritanceColon: true 72 | SpaceBeforeParens: ControlStatements 73 | SpaceBeforeRangeBasedForLoopColon: true 74 | SpaceInEmptyParentheses: false 75 | SpacesBeforeTrailingComments: 1 76 | SpacesInAngles: false 77 | SpacesInContainerLiterals: true 78 | SpacesInCStyleCastParentheses: false 79 | SpacesInParentheses: false 80 | SpacesInSquareBrackets: false 81 | Standard: Cpp11 82 | TabWidth: 4 83 | UseTab: Never 84 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/sdfat/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/sdfat/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/sdfat/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = teensy41 13 | 14 | [env:teensy36] 15 | platform = https://github.com/tsandmann/platform-teensy.git 16 | board = teensy36 17 | framework = arduino 18 | lib_deps = 19 | https://github.com/tsandmann/freertos-teensy.git 20 | https://github.com/PaulStoffregen/SD.git#c7cae3caeb3a596614add9d4174e5efbe5c1af56 21 | https://github.com/PaulStoffregen/SdFat.git#bc39d275f0576ea9fcc496342385115fc53cd282 22 | https://github.com/PaulStoffregen/SPI.git#574ab8c7a8a45ea21cc56dcc6b7361da90868e86 23 | build_flags = -Wformat=1 -DTEENSY_OPT_SMALLEST_CODE_LTO ; -DUSE_ARDUINO_DEFINES 24 | upload_protocol = teensy-cli 25 | 26 | [env:teensy41] 27 | platform = https://github.com/tsandmann/platform-teensy.git 28 | board = teensy41 29 | framework = arduino 30 | lib_deps = 31 | https://github.com/tsandmann/freertos-teensy.git 32 | https://github.com/PaulStoffregen/SD.git#c7cae3caeb3a596614add9d4174e5efbe5c1af56 33 | https://github.com/PaulStoffregen/SdFat.git#bc39d275f0576ea9fcc496342385115fc53cd282 34 | https://github.com/PaulStoffregen/SPI.git#574ab8c7a8a45ea21cc56dcc6b7361da90868e86 35 | build_flags = -Wformat=1 -DTEENSY_OPT_FASTER_LTO ; -DUSE_ARDUINO_DEFINES 36 | upload_flags = -v 37 | upload_protocol = teensy-cli 38 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/sdfat/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the FreeRTOS port to Teensy boards. 3 | * Copyright (c) 2020 Timo Sandmann 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library. If not, see . 17 | */ 18 | 19 | /** 20 | * @file main.cpp 21 | * @brief FreeRTOS with SdFat library example for Teensy boards 22 | * @author Timo Sandmann 23 | * @date 11.11.2020 24 | */ 25 | 26 | #include "arduino_freertos.h" 27 | #include "avr/pgmspace.h" 28 | 29 | #include "SD.h" 30 | 31 | 32 | static void task1(void*) { 33 | while (true) { 34 | #ifndef USE_ARDUINO_DEFINES 35 | arduino::digitalWriteFast(arduino::LED_BUILTIN, arduino::LOW); 36 | #else 37 | digitalWriteFast(LED_BUILTIN, LOW); 38 | #endif 39 | ::vTaskDelay(pdMS_TO_TICKS(500)); 40 | 41 | #ifndef USE_ARDUINO_DEFINES 42 | arduino::digitalWriteFast(arduino::LED_BUILTIN, arduino::HIGH); 43 | #else 44 | digitalWriteFast(LED_BUILTIN, HIGH); 45 | #endif 46 | ::vTaskDelay(pdMS_TO_TICKS(500)); 47 | } 48 | } 49 | 50 | static void task2(void*) { 51 | if (!SD.begin(BUILTIN_SDCARD)) { 52 | arduino::Serial.println("initialization failed!"); 53 | } else { 54 | arduino::Serial.println("initialization done."); 55 | } 56 | 57 | File root; 58 | while (true) { 59 | arduino::Serial.println("TICK"); 60 | ::vTaskDelay(pdMS_TO_TICKS(1'000)); 61 | 62 | arduino::Serial.println("TOCK"); 63 | ::vTaskDelay(pdMS_TO_TICKS(1'000)); 64 | 65 | 66 | root = SD.open("/"); 67 | if (!root.isDirectory()) { 68 | arduino::Serial.println("open / failed!"); 69 | if (!SD.begin(BUILTIN_SDCARD)) { 70 | arduino::Serial.println("initialization failed!"); 71 | continue; 72 | } 73 | arduino::Serial.println("initialization done."); 74 | root = SD.open("/"); 75 | if (!root.isDirectory()) { 76 | arduino::Serial.println("open / failed!"); 77 | continue; 78 | } 79 | } 80 | 81 | while (true) { 82 | auto entry { root.openNextFile() }; 83 | if (!entry) { 84 | break; 85 | } 86 | 87 | ::Serial.print(entry.name()); 88 | if (!entry.isDirectory()) { 89 | arduino::Serial.print("\t\t"); 90 | arduino::Serial.println(entry.size()); 91 | } else { 92 | arduino::Serial.println(); 93 | } 94 | 95 | entry.close(); 96 | } 97 | root.close(); 98 | #ifdef SDFAT_BASE 99 | SD.sdfs.end(); 100 | #endif 101 | arduino::Serial.println("\n"); 102 | } 103 | } 104 | 105 | FLASHMEM __attribute__((noinline)) void setup() { 106 | ::Serial.begin(115'200); 107 | #ifndef USE_ARDUINO_DEFINES 108 | ::pinMode(arduino::LED_BUILTIN, arduino::OUTPUT); 109 | ::digitalWriteFast(arduino::LED_BUILTIN, arduino::HIGH); 110 | #else 111 | ::pinMode(LED_BUILTIN, OUTPUT); 112 | ::digitalWriteFast(LED_BUILTIN, HIGH); 113 | #endif 114 | ::delay(5'000); 115 | 116 | ::Serial.println(PSTR("\r\nBooting FreeRTOS kernel " tskKERNEL_VERSION_NUMBER ". Built by gcc " __VERSION__ " (newlib " _NEWLIB_VERSION ") on " __DATE__ ". ***\r\n")); 117 | 118 | ::xTaskCreate(task1, "task1", 128, nullptr, 2, nullptr); 119 | ::xTaskCreate(task2, "task2", 2048, nullptr, 2, nullptr); 120 | 121 | ::Serial.println("setup(): starting scheduler..."); 122 | ::Serial.flush(); 123 | 124 | ::vTaskStartScheduler(); 125 | } 126 | 127 | void loop() {} 128 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/stdjthread/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/stdjthread/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/stdjthread/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = teensy41 13 | 14 | [env:teensy36] 15 | platform = https://github.com/tsandmann/platform-teensy.git 16 | board = teensy36 17 | framework = arduino 18 | lib_deps = https://github.com/tsandmann/freertos-teensy.git 19 | build_unflags = -std=gnu++17 20 | build_flags = -std=gnu++20 -Wformat=1 -DUSB_SERIAL -DTEENSY_OPT_SMALLEST_CODE_LTO 21 | upload_flags = -v 22 | upload_protocol = teensy-cli 23 | 24 | [env:teensy40] 25 | platform = https://github.com/tsandmann/platform-teensy.git 26 | board = teensy40 27 | framework = arduino 28 | lib_deps = https://github.com/tsandmann/freertos-teensy.git 29 | build_unflags = -std=gnu++17 30 | build_flags = -std=gnu++20 -Wformat=1 -DUSB_SERIAL -DTEENSY_OPT_FASTER_LTO 31 | upload_flags = -v 32 | upload_protocol = teensy-cli 33 | 34 | [env:teensy41] 35 | platform = https://github.com/tsandmann/platform-teensy.git 36 | board = teensy41 37 | framework = arduino 38 | lib_deps = https://github.com/tsandmann/freertos-teensy.git 39 | build_unflags = -std=gnu++17 40 | build_flags = -std=gnu++20 -Wformat=1 -DUSB_SERIAL -DTEENSY_OPT_FASTER_LTO 41 | upload_flags = -v 42 | upload_protocol = teensy-cli 43 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/stdjthread/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the FreeRTOS port to Teensy boards. 3 | * Copyright (c) 2020 Timo Sandmann 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library. If not, see . 17 | */ 18 | 19 | /** 20 | * @file main.cpp 21 | * @brief FreeRTOS example for Teensy boards 22 | * @author Timo Sandmann 23 | * @date 17.05.2020 24 | */ 25 | 26 | #include "arduino_freertos.h" 27 | #if _GCC_VERSION < 60100 28 | #error "Compiler too old for std::thread support with FreeRTOS." 29 | #endif 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | 38 | using namespace std::chrono_literals; 39 | 40 | static std::jthread* g_t1 {}; 41 | 42 | static bool print_time() { 43 | std::string tmp (32, '\0'); 44 | struct timeval tv; 45 | ::gettimeofday(&tv, nullptr); 46 | std::time_t t { tv.tv_sec }; 47 | struct tm* info { std::localtime(&t) }; 48 | 49 | if (std::strftime(tmp.data(), tmp.size(), PSTR("%c UTC"), info) > 0) { 50 | ::Serial.println(tmp.c_str()); 51 | return true; 52 | } 53 | 54 | return false; 55 | } 56 | 57 | static void task1(void*) { 58 | while (true) { 59 | ::digitalWrite(arduino::LED_BUILTIN, arduino::LOW); 60 | ::vTaskDelay(pdMS_TO_TICKS(250)); 61 | 62 | ::digitalWrite(arduino::LED_BUILTIN, arduino::HIGH); 63 | ::vTaskDelay(pdMS_TO_TICKS(250)); 64 | } 65 | } 66 | 67 | static void task2(void*) { 68 | g_t1 = new std::jthread { [](std::stop_token stop) { 69 | ::vTaskPrioritySet(nullptr, 3); 70 | 71 | while (!stop.stop_requested()) { 72 | ::Serial.println(PSTR("TICK")); 73 | std::this_thread::sleep_for(500ms); 74 | 75 | ::Serial.print(PSTR("TOCK\tnow: ")); 76 | print_time(); 77 | std::this_thread::sleep_for(500ms); 78 | } 79 | ::Serial.println(PSTR("Thread stopped.")); 80 | ::Serial.flush(); 81 | } }; 82 | configASSERT(g_t1); 83 | 84 | ::vTaskSuspend(nullptr); 85 | } 86 | 87 | static void task3(void*) { 88 | ::Serial.println("task3:"); 89 | ::Serial.flush(); 90 | 91 | std::this_thread::sleep_for(5s); 92 | 93 | ::Serial.println(PSTR("task3: creating futures...")); 94 | ::Serial.flush(); 95 | 96 | std::future result0 { std::async([]() -> int32_t { return 2; }) }; 97 | std::future result1 { std::async(std::launch::async, []() -> int32_t { return 3; }) }; 98 | std::future result2 { std::async(std::launch::deferred, []() -> int32_t { return 5; }) }; 99 | 100 | int32_t r { result0.get() + result1.get() + result2.get() }; 101 | ::Serial.printf(PSTR("r=%d\n\r"), r); 102 | configASSERT(2 + 3 + 5 == r); 103 | 104 | { 105 | // future from a packaged_task 106 | std::packaged_task task { [] { return 7; } }; // wrap the function 107 | std::future f1 { task.get_future() }; // get a future 108 | std::jthread t2 { std::move(task) }; // launch on a thread 109 | 110 | // future from an async() 111 | std::future f2 { std::async(std::launch::async, [] { return 8; }) }; 112 | 113 | // future from a promise 114 | std::promise p; 115 | std::future f3 { p.get_future() }; 116 | std::thread([&p] { p.set_value_at_thread_exit(9); }).detach(); 117 | 118 | ::Serial.println(PSTR("Waiting...")); 119 | ::Serial.flush(); 120 | f1.wait(); 121 | f2.wait(); 122 | f3.wait(); 123 | const auto r1 { f1.get() }; 124 | const auto r2 { f2.get() }; 125 | const auto r3 { f3.get() }; 126 | ::Serial.printf(PSTR("Done!\nResults are: %d %d %d\n\r"), r1, r2, r3); 127 | configASSERT(7 + 8 + 9 == r1 + r2 + r3); 128 | } 129 | 130 | if (g_t1->request_stop()) { 131 | ::Serial.println(PSTR("t1 stop_request successful.")); 132 | } else { 133 | ::Serial.println(PSTR("t1 stop_request failed.")); 134 | } 135 | ::Serial.flush(); 136 | 137 | delete g_t1; 138 | g_t1 = nullptr; 139 | 140 | ::Serial.println(PSTR("t1 deleted.")); 141 | ::Serial.flush(); 142 | 143 | ::vTaskSuspend(nullptr); 144 | } 145 | 146 | void setup() { 147 | ::Serial.begin(115'200); 148 | ::pinMode(arduino::LED_BUILTIN, arduino::OUTPUT); 149 | ::digitalWriteFast(arduino::LED_BUILTIN, arduino::HIGH); 150 | 151 | while (::millis() < 2'000) { 152 | } 153 | 154 | ::Serial.println(PSTR("\r\nBooting FreeRTOS kernel " tskKERNEL_VERSION_NUMBER ". Built by gcc " __VERSION__ " (newlib " _NEWLIB_VERSION ") on " __DATE__ ". ***\r\n")); 155 | 156 | ::xTaskCreate(task1, "task1", 128, nullptr, 2, nullptr); 157 | ::xTaskCreate(task2, "task2", 8192, nullptr, configMAX_PRIORITIES - 1, nullptr); 158 | ::xTaskCreate(task3, "task3", 8192, nullptr, 3, nullptr); 159 | 160 | ::Serial.println(PSTR("\n\rsetup(): starting scheduler...")); 161 | ::Serial.flush(); 162 | 163 | ::vTaskStartScheduler(); 164 | } 165 | 166 | void loop() {} 167 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/stdthread/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/stdthread/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/stdthread/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = teensy41 13 | 14 | [env:teensy40] 15 | platform = https://github.com/tsandmann/platform-teensy.git 16 | board = teensy40 17 | framework = arduino 18 | lib_deps = https://github.com/tsandmann/freertos-teensy.git 19 | build_flags = -Wformat=1 -DUSB_SERIAL -DTEENSY_OPT_FASTER_LTO 20 | upload_flags = -v 21 | upload_protocol = teensy-cli 22 | 23 | [env:teensy41] 24 | platform = https://github.com/tsandmann/platform-teensy.git 25 | board = teensy41 26 | framework = arduino 27 | lib_deps = https://github.com/tsandmann/freertos-teensy.git 28 | build_flags = -Wformat=1 -DUSB_SERIAL -DTEENSY_OPT_FASTER_LTO 29 | upload_flags = -v 30 | upload_protocol = teensy-cli 31 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/example/stdthread/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the FreeRTOS port to Teensy boards. 3 | * Copyright (c) 2020 Timo Sandmann 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library. If not, see . 17 | */ 18 | 19 | /** 20 | * @file main.cpp 21 | * @brief FreeRTOS example for Teensy boards 22 | * @author Timo Sandmann 23 | * @date 17.05.2020 24 | */ 25 | 26 | #include "arduino_freertos.h" 27 | #if _GCC_VERSION < 60100 28 | #error "Compiler too old for std::thread support with FreeRTOS." 29 | #endif 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | 38 | using namespace std::chrono_literals; 39 | 40 | static bool print_time() { 41 | std::string tmp (32, '\0'); 42 | struct timeval tv; 43 | ::gettimeofday(&tv, nullptr); 44 | std::time_t t { tv.tv_sec }; 45 | struct tm* info { std::localtime(&t) }; 46 | 47 | if (std::strftime(tmp.data(), tmp.size(), PSTR("%c UTC"), info) > 0) { 48 | ::Serial.println(tmp.c_str()); 49 | return true; 50 | } 51 | 52 | return false; 53 | } 54 | 55 | static void task1(void*) { 56 | while (true) { 57 | ::digitalWrite(arduino::LED_BUILTIN, arduino::LOW); 58 | ::vTaskDelay(pdMS_TO_TICKS(250)); 59 | 60 | ::digitalWrite(arduino::LED_BUILTIN, arduino::HIGH); 61 | ::vTaskDelay(pdMS_TO_TICKS(250)); 62 | } 63 | } 64 | 65 | static void task2(void*) { 66 | std::thread t1 { []() { 67 | ::vTaskPrioritySet(nullptr, 3); 68 | 69 | while (true) { 70 | ::Serial.println(PSTR("TICK")); 71 | std::this_thread::sleep_for(500ms); 72 | 73 | ::Serial.print(PSTR("TOCK\tnow: ")); 74 | print_time(); 75 | std::this_thread::sleep_for(500ms); 76 | } 77 | } }; 78 | 79 | ::vTaskSuspend(nullptr); 80 | } 81 | 82 | static void task3(void*) { 83 | ::Serial.println("task3:"); 84 | ::Serial.flush(); 85 | 86 | std::this_thread::sleep_for(5s); 87 | 88 | ::Serial.println(PSTR("task3: creating futures...")); 89 | ::Serial.flush(); 90 | 91 | std::future result0 { std::async([]() -> int32_t { return 2; }) }; 92 | std::future result1 { std::async(std::launch::async, []() -> int32_t { return 3; }) }; 93 | std::future result2 { std::async(std::launch::deferred, []() -> int32_t { return 5; }) }; 94 | 95 | int32_t r { result0.get() + result1.get() + result2.get() }; 96 | ::Serial.printf(PSTR("r=%d\n\r"), r); 97 | configASSERT(2 + 3 + 5 == r); 98 | 99 | 100 | // future from a packaged_task 101 | std::packaged_task task([] { return 7; }); // wrap the function 102 | std::future f1 = task.get_future(); // get a future 103 | std::thread t2(std::move(task)); // launch on a thread 104 | 105 | // future from an async() 106 | std::future f2 = std::async(std::launch::async, [] { return 8; }); 107 | 108 | // future from a promise 109 | std::promise p; 110 | std::future f3 = p.get_future(); 111 | std::thread([&p] { p.set_value_at_thread_exit(9); }).detach(); 112 | 113 | ::Serial.println(PSTR("Waiting...")); 114 | ::Serial.flush(); 115 | f1.wait(); 116 | f2.wait(); 117 | f3.wait(); 118 | const auto r1 { f1.get() }; 119 | const auto r2 { f2.get() }; 120 | const auto r3 { f3.get() }; 121 | ::Serial.printf(PSTR("Done!\nResults are: %d %d %d\n\r"), r1, r2, r3); 122 | ::Serial.flush(); 123 | configASSERT(7 + 8 + 9 == r1 + r2 + r3); 124 | t2.join(); 125 | 126 | ::vTaskSuspend(nullptr); 127 | } 128 | 129 | void setup() { 130 | ::Serial.begin(115'200); 131 | ::pinMode(arduino::LED_BUILTIN, arduino::OUTPUT); 132 | ::digitalWriteFast(arduino::LED_BUILTIN, arduino::HIGH); 133 | 134 | while (::millis() < 2'000) { 135 | } 136 | 137 | ::Serial.println(PSTR("\r\nBooting FreeRTOS kernel " tskKERNEL_VERSION_NUMBER ". Built by gcc " __VERSION__ " (newlib " _NEWLIB_VERSION ") on " __DATE__ ". ***\r\n")); 138 | 139 | ::xTaskCreate(task1, "task1", 128, nullptr, 2, nullptr); 140 | ::xTaskCreate(task2, "task2", 8192, nullptr, configMAX_PRIORITIES - 1, nullptr); 141 | ::xTaskCreate(task3, "task3", 8192, nullptr, 3, nullptr); 142 | 143 | 144 | { 145 | freertos::clock::sync_rtc(); 146 | print_time(); 147 | 148 | ::rtc_set(::rtc_get() + 3'600); 149 | freertos::clock::sync_rtc(); 150 | 151 | print_time(); 152 | } 153 | 154 | ::Serial.println(PSTR("setup(): starting scheduler...")); 155 | ::Serial.flush(); 156 | 157 | ::vTaskStartScheduler(); 158 | } 159 | 160 | void loop() {} 161 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/lib/cpp/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2019 Piotr Grygorczuk 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | o Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | o Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | o My name may not be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/lib/cpp/src/bits/gthr-default.h: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// 3 | /// @author: Piotr Grygorczuk grygorek@gmail.com 4 | /// 5 | /// @copyright Copyright 2019 Piotr Grygorczuk 6 | /// All rights reserved. 7 | /// 8 | /// Redistribution and use in source and binary forms, with or without 9 | /// modification, are permitted provided that the following conditions are met: 10 | /// 11 | /// o Redistributions of source code must retain the above copyright notice, 12 | /// this list of conditions and the following disclaimer. 13 | /// 14 | /// o Redistributions in binary form must reproduce the above copyright notice, 15 | /// this list of conditions and the following disclaimer in the documentation 16 | /// and/or other materials provided with the distribution. 17 | /// 18 | /// o My name may not be used to endorse or promote products derived from this 19 | /// software without specific prior written permission. 20 | /// 21 | /// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | /// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | /// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | /// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | /// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | /// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | /// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | /// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | /// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | /// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | /// POSSIBILITY OF SUCH DAMAGE. 32 | /// 33 | /// adapted for use with the teensy FreeRTOS port by Timo Sandmann 34 | /// 35 | 36 | #pragma once 37 | 38 | #include "arduino_freertos.h" 39 | #include "semphr.h" 40 | 41 | #if _GCC_VERSION >= 60100 && defined PLATFORMIO 42 | #include "thread_gthread.h" 43 | #include "condition_variable.h" 44 | #include "gthr_key.h" 45 | 46 | #include 47 | #include 48 | 49 | 50 | typedef free_rtos_std::gthr_freertos __gthread_t; 51 | 52 | extern "C" { 53 | 54 | #define _GLIBCXX_HAS_GTHREADS 1 55 | #define __GTHREADS 1 56 | #define __GTHREADS_CXX0X 1 57 | #define __GTHREAD_ONCE_INIT 0 58 | #define _GLIBCXX_USE_SCHED_YIELD 59 | #define __GTHREAD_COND_INIT {} 60 | 61 | typedef free_rtos_std::Key* __gthread_key_t; 62 | typedef int __gthread_once_t; 63 | typedef SemaphoreHandle_t __gthread_mutex_t; 64 | typedef SemaphoreHandle_t __gthread_recursive_mutex_t; 65 | typedef free_rtos_std::cv_task_list __gthread_cond_t; 66 | 67 | 68 | static inline void __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(__gthread_recursive_mutex_t* mutex) { 69 | *mutex = ::xSemaphoreCreateRecursiveMutex(); 70 | } 71 | static inline void __GTHREAD_MUTEX_INIT_FUNCTION(__gthread_mutex_t* mutex) { 72 | *mutex = ::xSemaphoreCreateMutex(); 73 | } 74 | 75 | int __gthread_active_p(); 76 | int __gthread_once(__gthread_once_t*, void (*)(void)); 77 | 78 | static inline int __gthread_key_create(__gthread_key_t* keyp, void (*dtor)(void*)) { 79 | return free_rtos_std::freertos_gthread_key_create(keyp, dtor); 80 | } 81 | 82 | static inline int __gthread_key_delete(__gthread_key_t key) { 83 | return free_rtos_std::freertos_gthread_key_delete(key); 84 | } 85 | 86 | static inline void* __gthread_getspecific(__gthread_key_t key) { 87 | return free_rtos_std::freertos_gthread_getspecific(key); 88 | } 89 | 90 | static inline int __gthread_setspecific(__gthread_key_t key, const void* ptr) { 91 | return free_rtos_std::freertos_gthread_setspecific(key, ptr); 92 | } 93 | 94 | 95 | static inline int __gthread_mutex_destroy(__gthread_mutex_t* mutex) { 96 | ::vSemaphoreDelete(*mutex); 97 | return 0; 98 | } 99 | static inline int __gthread_recursive_mutex_destroy(__gthread_recursive_mutex_t* mutex) { 100 | ::vSemaphoreDelete(*mutex); 101 | return 0; 102 | } 103 | 104 | static inline int __gthread_mutex_lock(__gthread_mutex_t* mutex) { 105 | return (::xSemaphoreTake(*mutex, portMAX_DELAY) == pdTRUE) ? 0 : 1; 106 | } 107 | static inline int __gthread_mutex_trylock(__gthread_mutex_t* mutex) { 108 | return (::xSemaphoreTake(*mutex, 0) == pdTRUE) ? 0 : 1; 109 | } 110 | static inline int __gthread_mutex_unlock(__gthread_mutex_t* mutex) { 111 | return (::xSemaphoreGive(*mutex) == pdTRUE) ? 0 : 1; 112 | } 113 | 114 | static inline int __gthread_recursive_mutex_lock(__gthread_recursive_mutex_t* mutex) { 115 | return (::xSemaphoreTakeRecursive(*mutex, portMAX_DELAY) == pdTRUE) ? 0 : 1; 116 | } 117 | static inline int __gthread_recursive_mutex_trylock(__gthread_recursive_mutex_t* mutex) { 118 | return (::xSemaphoreTakeRecursive(*mutex, 0) == pdTRUE) ? 0 : 1; 119 | } 120 | static inline int __gthread_recursive_mutex_unlock(__gthread_recursive_mutex_t* mutex) { 121 | return (::xSemaphoreGiveRecursive(*mutex) == pdTRUE) ? 0 : 1; 122 | } 123 | 124 | 125 | struct __gthread_time_t { 126 | std::time_t sec; 127 | long nsec; 128 | int64_t milliseconds() const { 129 | return static_cast(sec) * 1'000LL + nsec / 1'000'000LL; 130 | } 131 | 132 | int64_t microseconds() const { 133 | return static_cast(sec) * 1'000'000LL + nsec / 1'000LL; 134 | } 135 | }; 136 | 137 | static inline __gthread_time_t operator-(const __gthread_time_t& lhs, const timeval& rhs) { 138 | auto s { lhs.sec - rhs.tv_sec }; 139 | int64_t ns { lhs.nsec - rhs.tv_usec * 1'000LL }; 140 | if (ns < 0) { 141 | --s; 142 | ns += 1'000'000'000LL; 143 | } else if (ns > 1'000'000'000LL) { 144 | ++s; 145 | ns -= 1'000'000'000LL; 146 | } 147 | 148 | return __gthread_time_t { s, static_cast(ns) }; 149 | } 150 | 151 | static inline int __gthread_mutex_timedlock(__gthread_mutex_t* m, const __gthread_time_t* abs_timeout) { 152 | timeval now {}; 153 | gettimeofday(&now, NULL); 154 | 155 | auto t_us { (*abs_timeout - now).microseconds() }; 156 | if (t_us < 0) { 157 | t_us = 0; 158 | } 159 | // add 2 ticks to avoid rounding error because of tick resolution 160 | return (::xSemaphoreTake(*m, pdUS_TO_TICKS(t_us) + 2) == pdTRUE) ? 0 : 1; 161 | } 162 | 163 | static inline int __gthread_recursive_mutex_timedlock(__gthread_recursive_mutex_t* m, const __gthread_time_t* abs_timeout) { 164 | timeval now {}; 165 | gettimeofday(&now, NULL); 166 | 167 | auto t_us { (*abs_timeout - now).microseconds() }; 168 | if (t_us < 0) { 169 | t_us = 0; 170 | } 171 | // add 2 ticks to avoid rounding error because of tick resolution 172 | return (::xSemaphoreTakeRecursive(*m, pdUS_TO_TICKS(t_us) + 2) == pdTRUE) ? 0 : 1; 173 | } 174 | 175 | // All functions returning int should return zero on success or the error number. If the operation is not supported, -1 is returned. 176 | 177 | static inline int __gthread_create(__gthread_t* thread, void (*func)(void*), void* args) { 178 | return thread->create_thread(func, args) ? 0 : 1; 179 | } 180 | static inline int __gthread_join(__gthread_t& thread, void** value_ptr) { 181 | thread.join(); 182 | return 0; 183 | } 184 | static inline int __gthread_detach(__gthread_t& thread) { 185 | thread.detach(); 186 | return 0; 187 | } 188 | static inline int __gthread_equal(const __gthread_t& t1, const __gthread_t& t2) { 189 | return t1 == t2 ? 0 : 1; 190 | } 191 | static inline __gthread_t __gthread_self(void) { 192 | return __gthread_t::self(); 193 | } 194 | 195 | 196 | static inline int __gthread_yield(void) { 197 | taskYIELD(); 198 | return 0; 199 | } 200 | 201 | 202 | int __gthread_cond_timedwait(__gthread_cond_t*, __gthread_mutex_t*, const __gthread_time_t*); 203 | int __gthread_cond_wait(__gthread_cond_t*, __gthread_mutex_t*); 204 | int __gthread_cond_signal(__gthread_cond_t*); 205 | int __gthread_cond_broadcast(__gthread_cond_t*); 206 | 207 | 208 | static inline int __gthread_cond_destroy(__gthread_cond_t*) { 209 | return 0; 210 | } 211 | 212 | } // extern "C" 213 | #elif !defined PLATFORMIO 214 | #warning "std::thread support not available with Teensyduino." 215 | #undef _GLIBCXX_HAS_GTHREADS 216 | #undef __GTHREADS 217 | typedef SemaphoreHandle_t __gthread_mutex_t; 218 | typedef SemaphoreHandle_t __gthread_recursive_mutex_t; 219 | #else 220 | #warning "Compiler too old for std::thread support with FreeRTOS." 221 | #undef _GLIBCXX_HAS_GTHREADS 222 | #undef __GTHREADS 223 | typedef SemaphoreHandle_t __gthread_mutex_t; 224 | typedef SemaphoreHandle_t __gthread_recursive_mutex_t; 225 | #endif // _GCC_VERSION 226 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/lib/cpp/src/condition_variable.cpp: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// 3 | /// @author: Piotr Grygorczuk grygorek@gmail.com 4 | /// 5 | /// @copyright Copyright 2019 Piotr Grygorczuk 6 | /// All rights reserved. 7 | /// 8 | /// Redistribution and use in source and binary forms, with or without 9 | /// modification, are permitted provided that the following conditions are met: 10 | /// 11 | /// o Redistributions of source code must retain the above copyright notice, 12 | /// this list of conditions and the following disclaimer. 13 | /// 14 | /// o Redistributions in binary form must reproduce the above copyright notice, 15 | /// this list of conditions and the following disclaimer in the documentation 16 | /// and/or other materials provided with the distribution. 17 | /// 18 | /// o My name may not be used to endorse or promote products derived from this 19 | /// software without specific prior written permission. 20 | /// 21 | /// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | /// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | /// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | /// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | /// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | /// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | /// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | /// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | /// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | /// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | /// POSSIBILITY OF SUCH DAMAGE. 32 | /// 33 | /// adapted for use with the teensy FreeRTOS port by Timo Sandmann 34 | /// 35 | 36 | #if __GNUC__ < 11 37 | #include "arduino_freertos.h" 38 | #include "semphr.h" 39 | 40 | #if _GCC_VERSION >= 60100 41 | #include 42 | 43 | namespace std { 44 | 45 | condition_variable::condition_variable() = default; 46 | 47 | condition_variable::~condition_variable() { // It is only safe to invoke the destructor if all threads have been notified. 48 | // if (!_M_cond.empty()) { 49 | // std::__throw_system_error(117); // POSIX error: structure needs cleaning 50 | // } 51 | configASSERT(_M_cond.empty()); 52 | } 53 | 54 | void condition_variable::wait(std::unique_lock& m) { // pre-condition: m is taken!! 55 | _M_cond.lock(); 56 | _M_cond.push(__gthread_t::native_task_handle()); 57 | _M_cond.unlock(); 58 | 59 | m.unlock(); 60 | 61 | ::ulTaskNotifyTakeIndexed(configTASK_NOTIFICATION_ARRAY_ENTRIES - 1, pdTRUE, portMAX_DELAY); 62 | 63 | m.lock(); 64 | } 65 | 66 | void condition_variable::notify_one() { 67 | _M_cond.lock(); 68 | if (!_M_cond.empty()) { 69 | auto t = _M_cond.front(); 70 | _M_cond.pop(); 71 | ::xTaskNotifyGiveIndexed(t, configTASK_NOTIFICATION_ARRAY_ENTRIES - 1); 72 | } 73 | _M_cond.unlock(); 74 | } 75 | 76 | void condition_variable::notify_all() { 77 | _M_cond.lock(); 78 | while (!_M_cond.empty()) { 79 | auto t = _M_cond.front(); 80 | _M_cond.pop(); 81 | ::xTaskNotifyGiveIndexed(t, configTASK_NOTIFICATION_ARRAY_ENTRIES - 1); 82 | } 83 | _M_cond.unlock(); 84 | } 85 | 86 | } // namespace std 87 | #endif // _GCC_VERSION >= 60100 88 | #endif // __GNUC__ < 11 89 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/lib/cpp/src/condition_variable.h: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// 3 | /// @author: Piotr Grygorczuk grygorek@gmail.com 4 | /// 5 | /// @copyright Copyright 2019 Piotr Grygorczuk 6 | /// All rights reserved. 7 | /// 8 | /// Redistribution and use in source and binary forms, with or without 9 | /// modification, are permitted provided that the following conditions are met: 10 | /// 11 | /// o Redistributions of source code must retain the above copyright notice, 12 | /// this list of conditions and the following disclaimer. 13 | /// 14 | /// o Redistributions in binary form must reproduce the above copyright notice, 15 | /// this list of conditions and the following disclaimer in the documentation 16 | /// and/or other materials provided with the distribution. 17 | /// 18 | /// o My name may not be used to endorse or promote products derived from this 19 | /// software without specific prior written permission. 20 | /// 21 | /// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | /// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | /// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | /// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | /// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | /// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | /// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | /// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | /// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | /// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | /// POSSIBILITY OF SUCH DAMAGE. 32 | /// 33 | /// adapted for use with the teensy FreeRTOS port by Timo Sandmann 34 | /// 35 | 36 | #pragma once 37 | 38 | #include "arduino_freertos.h" 39 | #include "semphr.h" 40 | #include "thread_gthread.h" 41 | 42 | #include 43 | 44 | 45 | namespace free_rtos_std { 46 | 47 | class semaphore { 48 | public: 49 | semaphore() { 50 | vSemaphoreCreateBinary(_xSemaphore); 51 | // if (!_xSemaphore) { 52 | // std::__throw_system_error(12); // POSIX error: no memory 53 | // } 54 | configASSERT(_xSemaphore); 55 | } 56 | 57 | void lock() { 58 | ::xSemaphoreTake(_xSemaphore, portMAX_DELAY); 59 | } 60 | void unlock() { 61 | ::xSemaphoreGive(_xSemaphore); 62 | } 63 | 64 | ~semaphore() { 65 | ::vSemaphoreDelete(_xSemaphore); 66 | } 67 | 68 | semaphore(const semaphore&) = delete; 69 | semaphore(semaphore&&) = delete; 70 | semaphore& operator=(semaphore&) = delete; 71 | semaphore& operator=(semaphore&&) = delete; 72 | 73 | private: 74 | SemaphoreHandle_t _xSemaphore; 75 | }; 76 | 77 | // Internal free rtos task's container to support condition variable. 78 | // Condition variable must know all the threads waiting in a queue. 79 | // 80 | class cv_task_list { 81 | public: 82 | using __gthread_t = free_rtos_std::gthr_freertos; 83 | using thrd_type = __gthread_t::native_task_type; 84 | using queue_type = std::list; 85 | 86 | cv_task_list() = default; 87 | 88 | void remove(thrd_type thrd) { 89 | _que.remove(thrd); 90 | } 91 | void push(thrd_type thrd) { 92 | _que.push_back(thrd); 93 | } 94 | void pop() { 95 | _que.pop_front(); 96 | } 97 | bool empty() const { 98 | return _que.empty(); 99 | } 100 | 101 | ~cv_task_list() { 102 | lock(); 103 | _que = queue_type {}; 104 | unlock(); 105 | } 106 | 107 | // no copy and no move 108 | cv_task_list& operator=(const cv_task_list& r) = delete; 109 | cv_task_list& operator=(cv_task_list&& r) = delete; 110 | cv_task_list(cv_task_list&&) = delete; 111 | cv_task_list(const cv_task_list&) = delete; 112 | 113 | thrd_type& front() { 114 | return _que.front(); 115 | } 116 | const thrd_type& front() const { 117 | return _que.front(); 118 | } 119 | thrd_type& back() { 120 | return _que.back(); 121 | } 122 | const thrd_type& back() const { 123 | return _que.back(); 124 | } 125 | 126 | void lock() { 127 | _sem.lock(); 128 | } 129 | void unlock() { 130 | _sem.unlock(); 131 | } 132 | 133 | private: 134 | queue_type _que; 135 | semaphore _sem; 136 | }; 137 | } // namespace free_rtos_std 138 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/lib/cpp/src/gthr_key.cpp: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// 3 | /// @author: Piotr Grygorczuk grygorek@gmail.com 4 | /// 5 | /// @copyright Copyright 2019 Piotr Grygorczuk 6 | /// All rights reserved. 7 | /// 8 | /// Redistribution and use in source and binary forms, with or without 9 | /// modification, are permitted provided that the following conditions are met: 10 | /// 11 | /// o Redistributions of source code must retain the above copyright notice, 12 | /// this list of conditions and the following disclaimer. 13 | /// 14 | /// o Redistributions in binary form must reproduce the above copyright notice, 15 | /// this list of conditions and the following disclaimer in the documentation 16 | /// and/or other materials provided with the distribution. 17 | /// 18 | /// o My name may not be used to endorse or promote products derived from this 19 | /// software without specific prior written permission. 20 | /// 21 | /// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | /// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | /// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | /// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | /// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | /// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | /// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | /// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | /// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | /// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | /// POSSIBILITY OF SUCH DAMAGE. 32 | /// 33 | /// adapted for use with the teensy FreeRTOS port by Timo Sandmann 34 | /// 35 | 36 | 37 | #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 60100 38 | #include "gthr_key_type.h" 39 | 40 | 41 | namespace free_rtos_std { 42 | 43 | Key* s_key; 44 | 45 | int freertos_gthread_key_create(Key** keyp, void (*dtor)(void*)) { 46 | // There is only one key for all threads. If more keys are needed 47 | // a list must be implemented. 48 | configASSERT(!s_key); 49 | s_key = new Key(dtor); 50 | 51 | *keyp = s_key; 52 | return 0; 53 | } 54 | 55 | int freertos_gthread_key_delete(Key*) { 56 | // no synchronization here: 57 | // It is up to the applicaiton to delete (or maintain a reference) 58 | // the thread specific data associated with the key. 59 | delete s_key; 60 | s_key = nullptr; 61 | return 0; 62 | } 63 | 64 | void* freertos_gthread_getspecific(Key* key) { 65 | std::lock_guard lg { key->_mtx }; 66 | 67 | auto item = key->_specValue.find(__gthread_t::self().native_task_handle()); 68 | if (item == key->_specValue.end()) { 69 | return nullptr; 70 | } 71 | return const_cast(item->second); 72 | } 73 | 74 | int freertos_gthread_setspecific(Key* key, const void* ptr) { 75 | std::lock_guard lg { key->_mtx }; 76 | 77 | auto& cont { key->_specValue }; 78 | auto task { __gthread_t::self().native_task_handle() }; 79 | if (ptr) { 80 | cont[task] = ptr; 81 | } else { 82 | (void) cont.erase(task); 83 | } 84 | return 0; 85 | } 86 | 87 | } // namespace free_rtos_std 88 | #endif // GCC VERSION >= 60100 89 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/lib/cpp/src/gthr_key.h: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// 3 | /// @author: Piotr Grygorczuk grygorek@gmail.com 4 | /// 5 | /// @copyright Copyright 2019 Piotr Grygorczuk 6 | /// All rights reserved. 7 | /// 8 | /// Redistribution and use in source and binary forms, with or without 9 | /// modification, are permitted provided that the following conditions are met: 10 | /// 11 | /// o Redistributions of source code must retain the above copyright notice, 12 | /// this list of conditions and the following disclaimer. 13 | /// 14 | /// o Redistributions in binary form must reproduce the above copyright notice, 15 | /// this list of conditions and the following disclaimer in the documentation 16 | /// and/or other materials provided with the distribution. 17 | /// 18 | /// o My name may not be used to endorse or promote products derived from this 19 | /// software without specific prior written permission. 20 | /// 21 | /// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | /// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | /// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | /// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | /// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | /// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | /// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | /// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | /// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | /// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | /// POSSIBILITY OF SUCH DAMAGE. 32 | /// 33 | /// adapted for use with the teensy FreeRTOS port by Timo Sandmann 34 | /// 35 | 36 | #pragma once 37 | 38 | namespace free_rtos_std { 39 | struct Key; 40 | 41 | int freertos_gthread_key_create(Key** keyp, void (*dtor)(void*)); 42 | int freertos_gthread_key_delete(Key* key); 43 | void* freertos_gthread_getspecific(Key* key); 44 | int freertos_gthread_setspecific(Key* key, const void* ptr); 45 | } // namespace free_rtos_std 46 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/lib/cpp/src/gthr_key_type.h: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// 3 | /// @author: Piotr Grygorczuk grygorek@gmail.com 4 | /// 5 | /// @copyright Copyright 2019 Piotr Grygorczuk 6 | /// All rights reserved. 7 | /// 8 | /// Redistribution and use in source and binary forms, with or without 9 | /// modification, are permitted provided that the following conditions are met: 10 | /// 11 | /// o Redistributions of source code must retain the above copyright notice, 12 | /// this list of conditions and the following disclaimer. 13 | /// 14 | /// o Redistributions in binary form must reproduce the above copyright notice, 15 | /// this list of conditions and the following disclaimer in the documentation 16 | /// and/or other materials provided with the distribution. 17 | /// 18 | /// o My name may not be used to endorse or promote products derived from this 19 | /// software without specific prior written permission. 20 | /// 21 | /// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | /// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | /// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | /// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | /// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | /// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | /// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | /// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | /// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | /// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | /// POSSIBILITY OF SUCH DAMAGE. 32 | /// 33 | /// adapted for use with the teensy FreeRTOS port by Timo Sandmann 34 | /// 35 | 36 | #pragma once 37 | 38 | #include "thread_gthread.h" 39 | 40 | #include 41 | #include 42 | 43 | namespace free_rtos_std { 44 | 45 | struct Key { 46 | using __gthread_t = free_rtos_std::gthr_freertos; 47 | typedef void (*DestructorFoo)(void*); 48 | 49 | Key() = delete; 50 | explicit Key(DestructorFoo des) : _desFoo { des } {} 51 | 52 | void CallDestructor(__gthread_t::native_task_type task) { 53 | void* val; 54 | 55 | { 56 | std::lock_guard lg { _mtx }; 57 | 58 | auto item { _specValue.find(task) }; 59 | if (item == _specValue.end()) { 60 | return; 61 | } 62 | 63 | val = const_cast(item->second); 64 | _specValue.erase(item); 65 | } 66 | 67 | if (_desFoo && val) { 68 | _desFoo(val); 69 | } 70 | } 71 | 72 | std::mutex _mtx; 73 | DestructorFoo _desFoo; 74 | std::unordered_map<__gthread_t::native_task_type, const void*> _specValue; 75 | }; 76 | 77 | } // namespace free_rtos_std 78 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/lib/cpp/src/thread.cpp: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// 3 | /// @author: Piotr Grygorczuk grygorek@gmail.com 4 | /// 5 | /// @copyright Copyright 2019 Piotr Grygorczuk 6 | /// All rights reserved. 7 | /// 8 | /// Redistribution and use in source and binary forms, with or without 9 | /// modification, are permitted provided that the following conditions are met: 10 | /// 11 | /// o Redistributions of source code must retain the above copyright notice, 12 | /// this list of conditions and the following disclaimer. 13 | /// 14 | /// o Redistributions in binary form must reproduce the above copyright notice, 15 | /// this list of conditions and the following disclaimer in the documentation 16 | /// and/or other materials provided with the distribution. 17 | /// 18 | /// o My name may not be used to endorse or promote products derived from this 19 | /// software without specific prior written permission. 20 | /// 21 | /// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | /// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | /// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | /// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | /// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | /// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | /// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | /// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | /// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | /// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | /// POSSIBILITY OF SUCH DAMAGE. 32 | /// 33 | /// adapted for use with the teensy FreeRTOS port by Timo Sandmann 34 | /// 35 | 36 | #define _GLIBCXX_THREAD_IMPL 37 | #include "arduino_freertos.h" 38 | 39 | #if _GCC_VERSION >= 60100 40 | #include "gthr_key_type.h" 41 | 42 | #include 43 | #include 44 | #include 45 | 46 | 47 | // trick to fool libgcc and make it detects we are using threads 48 | void __pthread_key_create() {} 49 | void pthread_cancel() {} 50 | 51 | extern "C" { 52 | int __gthread_once(__gthread_once_t* once, void (*func)(void)) { 53 | static __gthread_mutex_t s_m { xSemaphoreCreateMutex() }; 54 | if (!s_m) { 55 | return 12; // POSIX error: ENOMEM 56 | } 57 | 58 | __gthread_once_t flag { true }; 59 | xSemaphoreTakeRecursive(s_m, portMAX_DELAY); 60 | std::swap(*once, flag); 61 | xSemaphoreGiveRecursive(s_m); 62 | 63 | if (flag == false) { 64 | func(); 65 | } 66 | 67 | return 0; 68 | } 69 | 70 | // returns: 1 - thread system is active; 0 - thread system is not active 71 | int __gthread_active_p() { 72 | return 1; 73 | } 74 | 75 | 76 | int __gthread_cond_timedwait(__gthread_cond_t* cond, __gthread_mutex_t* mutex, const __gthread_time_t* abs_timeout) { 77 | auto this_thrd_hndl { __gthread_t::native_task_handle() }; 78 | cond->lock(); 79 | cond->push(this_thrd_hndl); 80 | cond->unlock(); 81 | 82 | timeval now {}; 83 | gettimeofday(&now, NULL); 84 | 85 | auto t_us { static_cast((*abs_timeout - now).microseconds()) }; 86 | if (t_us < 0) { 87 | t_us = 0; 88 | } 89 | 90 | __gthread_mutex_unlock(mutex); 91 | // add 2 ticks to avoid rounding error because of tick resolution 92 | const auto fTimeout { 0 == ulTaskNotifyTakeIndexed(configTASK_NOTIFICATION_ARRAY_ENTRIES - 1, pdTRUE, pdUS_TO_TICKS(t_us) + 2) }; 93 | __gthread_mutex_lock(mutex); 94 | 95 | int result {}; 96 | if (fTimeout) { // timeout - remove the thread from the waiting list 97 | cond->lock(); 98 | cond->remove(this_thrd_hndl); 99 | cond->unlock(); 100 | result = 138; // posix ETIMEDOUT 101 | } 102 | 103 | return result; 104 | } 105 | 106 | int __gthread_cond_wait(__gthread_cond_t* cond, __gthread_mutex_t* mutex) { 107 | auto this_thrd_hndl { __gthread_t::native_task_handle() }; 108 | cond->lock(); 109 | cond->push(this_thrd_hndl); 110 | cond->unlock(); 111 | 112 | __gthread_mutex_unlock(mutex); 113 | const auto res { ::ulTaskNotifyTakeIndexed(configTASK_NOTIFICATION_ARRAY_ENTRIES - 1, pdTRUE, portMAX_DELAY) }; 114 | __gthread_mutex_lock(mutex); 115 | configASSERT(res == pdTRUE); 116 | 117 | return static_cast(res); 118 | } 119 | 120 | int __gthread_cond_signal(__gthread_cond_t* cond) { 121 | configASSERT(cond); 122 | 123 | cond->lock(); 124 | if (!cond->empty()) { 125 | auto t = cond->front(); 126 | cond->pop(); 127 | ::xTaskNotifyGiveIndexed(t, configTASK_NOTIFICATION_ARRAY_ENTRIES - 1); 128 | } 129 | cond->unlock(); 130 | 131 | return 0; // FIXME: return value? 132 | } 133 | 134 | int __gthread_cond_broadcast(__gthread_cond_t* cond) { 135 | configASSERT(cond); 136 | 137 | cond->lock(); 138 | while (!cond->empty()) { 139 | auto t = cond->front(); 140 | cond->pop(); 141 | ::xTaskNotifyGiveIndexed(t, configTASK_NOTIFICATION_ARRAY_ENTRIES - 1); 142 | } 143 | cond->unlock(); 144 | return 0; // FIXME: return value? 145 | } 146 | 147 | } // extern C 148 | 149 | namespace free_rtos_std { 150 | extern Key* s_key; 151 | } // namespace free_rtos_std 152 | 153 | namespace std { 154 | 155 | static void __execute_native_thread_routine(void* __p) { 156 | __gthread_t local { *static_cast<__gthread_t*>(__p) }; // copy 157 | 158 | { // we own the arg now; it must be deleted after run() returns 159 | thread::_State_ptr __t { static_cast(local.arg()) }; 160 | local.notify_started(); // copy has been made; tell we are running 161 | __t->_M_run(); 162 | } 163 | 164 | if (free_rtos_std::s_key) { 165 | free_rtos_std::s_key->CallDestructor(__gthread_t::self().native_task_handle()); 166 | } 167 | 168 | local.notify_joined(); // finished; release joined threads 169 | } 170 | 171 | thread::_State::~_State() = default; 172 | 173 | void thread::_M_start_thread(_State_ptr state, void (*)()) { 174 | const int err = __gthread_create(&_M_id._M_thread, __execute_native_thread_routine, state.get()); 175 | 176 | // if (err) { 177 | // __throw_system_error(err); 178 | // } 179 | configASSERT(!err); 180 | 181 | state.release(); 182 | } 183 | 184 | void thread::join() { 185 | id invalid; 186 | if (_M_id._M_thread != invalid._M_thread) { 187 | __gthread_join(_M_id._M_thread, nullptr); 188 | } else { 189 | // __throw_system_error(EINVAL); 190 | configASSERT(EINVAL == -1); 191 | } 192 | 193 | // destroy the handle explicitly - next call to join/detach will throw 194 | _M_id = std::move(invalid); 195 | } 196 | 197 | void thread::detach() { 198 | id invalid; 199 | if (_M_id._M_thread != invalid._M_thread) { 200 | __gthread_detach(_M_id._M_thread); 201 | } else { 202 | // __throw_system_error(EINVAL); 203 | configASSERT(EINVAL == -1); 204 | } 205 | 206 | // destroy the handle explicitly - next call to join/detach will throw 207 | _M_id = std::move(invalid); 208 | } 209 | 210 | // Returns the number of concurrent threads supported by the implementation. 211 | // The value should be considered only a hint. 212 | // 213 | // Return value 214 | // Number of concurrent threads supported. If the value is not well defined 215 | // or not computable, returns ​0​. 216 | unsigned int thread::hardware_concurrency() noexcept { 217 | return 1; 218 | } 219 | 220 | namespace this_thread { 221 | void __sleep_for(chrono::seconds sec, chrono::nanoseconds nsec) { 222 | long ms = nsec.count() / 1'000'000; 223 | if (sec.count() == 0 && ms == 0 && nsec.count() > 0) { 224 | ms = 1; // round up to 1 ms => if sleep time != 0, sleep at least 1ms 225 | } 226 | 227 | vTaskDelay(pdMS_TO_TICKS(chrono::milliseconds(sec).count() + ms)); 228 | } 229 | } // namespace this_thread 230 | } // namespace std 231 | 232 | namespace free_rtos_std { 233 | 234 | StackType_t gthr_freertos::next_stack_size_ {}; 235 | 236 | StackType_t gthr_freertos::set_next_stacksize(const StackType_t size) { 237 | const StackType_t last { next_stack_size_ }; 238 | next_stack_size_ = size; 239 | return last; 240 | } 241 | 242 | void gthr_freertos::set_priority(std::thread* p_thread, const uint32_t prio) { 243 | ::vTaskPrioritySet(p_thread->native_handle().get_native_handle(), prio); 244 | } 245 | 246 | void gthr_freertos::set_name(std::thread* p_thread, const char* task_name) { 247 | auto p_name { ::pcTaskGetName(p_thread->native_handle().get_native_handle()) }; 248 | std::strncpy(p_name, task_name, configMAX_TASK_NAME_LEN - 1); 249 | p_name[configMAX_TASK_NAME_LEN - 1] = 0; 250 | } 251 | 252 | void gthr_freertos::suspend(std::thread* p_thread) { 253 | ::vTaskSuspend(p_thread->native_handle().get_native_handle()); 254 | } 255 | 256 | void gthr_freertos::resume(std::thread* p_thread) { 257 | ::vTaskResume(p_thread->native_handle().get_native_handle()); 258 | } 259 | 260 | TaskHandle_t gthr_freertos::get_freertos_handle(std::thread* p_thread) { 261 | return p_thread->native_handle().get_native_handle(); 262 | } 263 | 264 | } // namespace free_rtos_std 265 | #endif // _GCC_VERSION >= 60100 266 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/lib/gcc/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2009-2018 Free Software Foundation, Inc. 2 | 3 | This file is part of the GNU ISO C++ Library. This library is free 4 | software; you can redistribute it and/or modify it under the 5 | terms of the GNU General Public License as published by the 6 | Free Software Foundation; either version 3, or (at your option) 7 | any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | Under Section 7 of GPL version 3, you are granted additional 15 | permissions described in the GCC Runtime Library Exception, version 16 | 3.1, as published by the Free Software Foundation. 17 | 18 | You should have received a copy of the GNU General Public License and 19 | a copy of the GCC Runtime Library Exception along with this program; 20 | see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 21 | . -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/lib/gcc/condition_variable.cc: -------------------------------------------------------------------------------- 1 | // condition_variable -*- C++ -*- 2 | 3 | // Copyright (C) 2008-2021 Free Software Foundation, Inc. 4 | // 5 | // This file is part of the GNU ISO C++ Library. This library is free 6 | // software; you can redistribute it and/or modify it under the 7 | // terms of the GNU General Public License as published by the 8 | // Free Software Foundation; either version 3, or (at your option) 9 | // any later version. 10 | 11 | // This library is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | 16 | // Under Section 7 of GPL version 3, you are granted additional 17 | // permissions described in the GCC Runtime Library Exception, version 18 | // 3.1, as published by the Free Software Foundation. 19 | 20 | // You should have received a copy of the GNU General Public License and 21 | // a copy of the GCC Runtime Library Exception along with this program; 22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 | // . 24 | 25 | #define __GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 26 | #if __GCC_VERSION >= 60100 27 | 28 | #include 29 | #include 30 | 31 | #ifdef _GLIBCXX_HAS_GTHREADS 32 | 33 | namespace std _GLIBCXX_VISIBILITY(default) 34 | { 35 | _GLIBCXX_BEGIN_NAMESPACE_VERSION 36 | 37 | #if __GNUC__ >= 11 38 | condition_variable::condition_variable() noexcept = default; 39 | 40 | condition_variable::~condition_variable() noexcept = default; 41 | 42 | void 43 | condition_variable::wait(unique_lock& __lock) noexcept 44 | { 45 | _M_cond.wait(*__lock.mutex()); 46 | } 47 | 48 | void 49 | condition_variable::notify_one() noexcept 50 | { 51 | _M_cond.notify_one(); 52 | } 53 | 54 | void 55 | condition_variable::notify_all() noexcept 56 | { 57 | _M_cond.notify_all(); 58 | } 59 | #endif // __GNUC__ >= 11 60 | 61 | extern void 62 | __at_thread_exit(__at_thread_exit_elt*); 63 | 64 | namespace 65 | { 66 | __gthread_key_t key; 67 | 68 | void run(void* p) 69 | { 70 | auto elt = (__at_thread_exit_elt*)p; 71 | while (elt) 72 | { 73 | auto next = elt->_M_next; 74 | elt->_M_cb(elt); 75 | elt = next; 76 | } 77 | } 78 | 79 | void run() 80 | { 81 | auto elt = (__at_thread_exit_elt*)__gthread_getspecific(key); 82 | __gthread_setspecific(key, nullptr); 83 | run(elt); 84 | } 85 | 86 | struct notifier final : __at_thread_exit_elt 87 | { 88 | notifier(condition_variable& cv, unique_lock& l) 89 | : cv(&cv), mx(l.release()) 90 | { 91 | _M_cb = ¬ifier::run; 92 | __at_thread_exit(this); 93 | } 94 | 95 | ~notifier() 96 | { 97 | mx->unlock(); 98 | cv->notify_all(); 99 | } 100 | 101 | condition_variable* cv; 102 | mutex* mx; 103 | 104 | static void run(void* p) { delete static_cast(p); } 105 | }; 106 | 107 | 108 | void key_init() { 109 | struct key_s { 110 | key_s() { __gthread_key_create (&key, run); } 111 | ~key_s() { __gthread_key_delete (key); } 112 | }; 113 | static key_s ks; 114 | // Also make sure the callbacks are run by std::exit. 115 | std::atexit (run); 116 | } 117 | } 118 | 119 | void 120 | __at_thread_exit(__at_thread_exit_elt* elt) 121 | { 122 | static __gthread_once_t once = __GTHREAD_ONCE_INIT; 123 | __gthread_once (&once, key_init); 124 | 125 | elt->_M_next = (__at_thread_exit_elt*)__gthread_getspecific(key); 126 | __gthread_setspecific(key, elt); 127 | } 128 | 129 | void 130 | notify_all_at_thread_exit(condition_variable& cv, unique_lock l) 131 | { 132 | (void) new notifier{cv, l}; 133 | } 134 | 135 | _GLIBCXX_END_NAMESPACE_VERSION 136 | } // namespace 137 | 138 | #endif // _GLIBCXX_HAS_GTHREADS 139 | #endif // __GCC_VERSION >= 60100 140 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/lib/gcc/future.cc: -------------------------------------------------------------------------------- 1 | // future -*- C++ -*- 2 | 3 | // Copyright (C) 2009-2021 Free Software Foundation, Inc. 4 | // 5 | // This file is part of the GNU ISO C++ Library. This library is free 6 | // software; you can redistribute it and/or modify it under the 7 | // terms of the GNU General Public License as published by the 8 | // Free Software Foundation; either version 3, or (at your option) 9 | // any later version. 10 | 11 | // This library is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | 16 | // Under Section 7 of GPL version 3, you are granted additional 17 | // permissions described in the GCC Runtime Library Exception, version 18 | // 3.1, as published by the Free Software Foundation. 19 | 20 | // You should have received a copy of the GNU General Public License and 21 | // a copy of the GCC Runtime Library Exception along with this program; 22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 | // . 24 | 25 | #define __GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 26 | #if __GCC_VERSION >= 60100 27 | 28 | #include 29 | #include 30 | 31 | namespace 32 | { 33 | struct future_error_category : public std::error_category 34 | { 35 | virtual const char* 36 | name() const noexcept 37 | { return "future"; } 38 | 39 | _GLIBCXX_DEFAULT_ABI_TAG 40 | virtual std::string message(int __ec) const 41 | { 42 | std::string __msg; 43 | switch (std::future_errc(__ec)) 44 | { 45 | case std::future_errc::broken_promise: 46 | __msg = "Broken promise"; 47 | break; 48 | case std::future_errc::future_already_retrieved: 49 | __msg = "Future already retrieved"; 50 | break; 51 | case std::future_errc::promise_already_satisfied: 52 | __msg = "Promise already satisfied"; 53 | break; 54 | case std::future_errc::no_state: 55 | __msg = "No associated state"; 56 | break; 57 | default: 58 | __msg = "Unknown error"; 59 | break; 60 | } 61 | return __msg; 62 | } 63 | }; 64 | 65 | const future_error_category& 66 | __future_category_instance() noexcept 67 | { 68 | static const future_error_category __fec{}; 69 | return __fec; 70 | } 71 | } 72 | 73 | namespace std _GLIBCXX_VISIBILITY(default) 74 | { 75 | _GLIBCXX_BEGIN_NAMESPACE_VERSION 76 | 77 | void 78 | __throw_future_error(int __i __attribute__((unused))) 79 | { _GLIBCXX_THROW_OR_ABORT(future_error(make_error_code(future_errc(__i)))); } 80 | 81 | const error_category& future_category() noexcept 82 | { return __future_category_instance(); } 83 | 84 | future_error::~future_error() noexcept { } 85 | 86 | const char* 87 | future_error::what() const noexcept { return logic_error::what(); } 88 | 89 | #ifdef _GLIBCXX_HAS_GTHREADS 90 | __future_base::_Result_base::_Result_base() = default; 91 | 92 | __future_base::_Result_base::~_Result_base() = default; 93 | 94 | void 95 | __future_base::_State_baseV2::_Make_ready::_S_run(void* p) 96 | { 97 | unique_ptr<_Make_ready> mr{static_cast<_Make_ready*>(p)}; 98 | if (auto state = mr->_M_shared_state.lock()) 99 | { 100 | // Use release MO to synchronize with observers of the ready state. 101 | state->_M_status._M_store_notify_all(_Status::__ready, 102 | memory_order_release); 103 | } 104 | } 105 | 106 | // defined in src/c++11/condition_variable.cc 107 | extern void 108 | __at_thread_exit(__at_thread_exit_elt* elt); 109 | 110 | void 111 | __future_base::_State_baseV2::_Make_ready::_M_set() 112 | { 113 | _M_cb = &_Make_ready::_S_run; 114 | __at_thread_exit(this); 115 | } 116 | #endif // _GLIBCXX_HAS_GTHREADS 117 | 118 | _GLIBCXX_END_NAMESPACE_VERSION 119 | } // namespace std 120 | #endif // __GCC_VERSION >= 60100 121 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/lib/gcc/mutex.cc: -------------------------------------------------------------------------------- 1 | // mutex -*- C++ -*- 2 | 3 | // Copyright (C) 2008-2021 Free Software Foundation, Inc. 4 | // 5 | // This file is part of the GNU ISO C++ Library. This library is free 6 | // software; you can redistribute it and/or modify it under the 7 | // terms of the GNU General Public License as published by the 8 | // Free Software Foundation; either version 3, or (at your option) 9 | // any later version. 10 | 11 | // This library is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | 16 | // Under Section 7 of GPL version 3, you are granted additional 17 | // permissions described in the GCC Runtime Library Exception, version 18 | // 3.1, as published by the Free Software Foundation. 19 | 20 | // You should have received a copy of the GNU General Public License and 21 | // a copy of the GCC Runtime Library Exception along with this program; 22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 | // . 24 | 25 | #define __GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 26 | #if __GCC_VERSION >= 60100 27 | 28 | #include 29 | 30 | #ifdef _GLIBCXX_HAS_GTHREADS 31 | 32 | namespace std _GLIBCXX_VISIBILITY(default) 33 | { 34 | _GLIBCXX_BEGIN_NAMESPACE_VERSION 35 | 36 | #ifdef _GLIBCXX_HAVE_TLS 37 | __thread void* __once_callable; 38 | __thread void (*__once_call)(); 39 | 40 | extern "C" void __once_proxy() 41 | { 42 | // The caller stored a function pointer in __once_call. If it requires 43 | // any state, it gets it from __once_callable. 44 | __once_call(); 45 | } 46 | 47 | #else // ! TLS 48 | 49 | // Explicit instantiation due to -fno-implicit-instantiation. 50 | template class function; 51 | 52 | function __once_functor; 53 | 54 | mutex& 55 | __get_once_mutex() 56 | { 57 | static mutex once_mutex; 58 | return once_mutex; 59 | } 60 | 61 | namespace 62 | { 63 | // Store ptr in a global variable and return the previous value. 64 | inline unique_lock* 65 | set_lock_ptr(unique_lock* ptr) 66 | { 67 | static unique_lock* __once_functor_lock_ptr = nullptr; 68 | return std::__exchange(__once_functor_lock_ptr, ptr); 69 | } 70 | } 71 | 72 | // code linked against ABI 3.4.12 and later uses this 73 | void 74 | __set_once_functor_lock_ptr(unique_lock* __ptr) 75 | { 76 | (void) set_lock_ptr(__ptr); 77 | } 78 | 79 | // unsafe - retained for compatibility with ABI 3.4.11 80 | unique_lock& 81 | __get_once_functor_lock() 82 | { 83 | static unique_lock once_functor_lock(__get_once_mutex(), defer_lock); 84 | return once_functor_lock; 85 | } 86 | 87 | // This is called via pthread_once while __get_once_mutex() is locked. 88 | extern "C" void 89 | __once_proxy() 90 | { 91 | // Get the callable out of the global functor. 92 | function callable = std::move(__once_functor); 93 | 94 | // Then unlock the global mutex 95 | if (unique_lock* lock = set_lock_ptr(nullptr)) 96 | { 97 | // Caller is using the new ABI and provided a pointer to its lock. 98 | lock->unlock(); 99 | } 100 | else 101 | __get_once_functor_lock().unlock(); // global lock 102 | 103 | // Finally, invoke the callable. 104 | callable(); 105 | } 106 | #endif // ! TLS 107 | 108 | _GLIBCXX_END_NAMESPACE_VERSION 109 | } // namespace std 110 | 111 | #endif // _GLIBCXX_HAS_GTHREADS 112 | #endif // __GCC_VERSION >= 60100 113 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "freertos-teensy", 3 | "keywords": "FreeRTOS, Teensy", 4 | "description": "FreeRTOS port for Teensy 3.5, 3.6, 4.0, 4.1", 5 | "license": "MIT", 6 | "homepage": "https://www.freertos.org", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/tsandmann/freertos-teensy" 10 | }, 11 | "version": "11.0.1-1", 12 | "authors": [ 13 | { 14 | "name": "Richard Barry", 15 | "email": "info@freertos.org" 16 | }, 17 | { 18 | "name": "Piotr Grygorczuk", 19 | "email": "grygorek@gmail.com" 20 | }, 21 | { 22 | "name": "Timo Sandmann", 23 | "maintainer": true 24 | } 25 | ], 26 | "frameworks": "arduino", 27 | "platforms": [ "teensy", "teensy-ts" ], 28 | "build": { 29 | "flags": [ 30 | "-Ilib/cpp/src/bits", 31 | "-Ilib/cpp/src", 32 | "-I../../../../src" 33 | ], 34 | "srcFilter": [ 35 | "+<../lib/cpp/src/bits/*>", 36 | "+<../lib/cpp/src/*>", 37 | "+<../lib/gcc/*>", 38 | "+<*>" 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/library.properties: -------------------------------------------------------------------------------- 1 | name=freertos-teensy 2 | version=11.0.1-1 3 | author=Richard Barry 4 | maintainer=Timo Sandmann 5 | sentence=

FreeRTOS Real Time Operating System implemented for Teensy (3.5, 3.6, 4.0, 4.1).

6 | paragraph=The primary design goals are: Easy to use, Small footprint, Robust. 7 | category=Timing 8 | url=https://www.freertos.org 9 | license=MIT 10 | architectures=* 11 | includes=arduino_freertos.h 12 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/manifest.yml: -------------------------------------------------------------------------------- 1 | name : "FreeRTOS-Kernel" 2 | version: "v11.0.1" 3 | description: "FreeRTOS Kernel." 4 | license: "MIT" 5 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/run_format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | find src -iname *.h -o -iname *.c -o -iname *.cpp | xargs clang-format -i 3 | 4 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/StackMacros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V11.0.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | * 24 | * https://www.FreeRTOS.org 25 | * https://github.com/FreeRTOS 26 | * 27 | */ 28 | 29 | 30 | #ifndef _MSC_VER /* Visual Studio doesn't support #warning. */ 31 | #warning The name of this file has changed to stack_macros.h. Please update your code accordingly. This source file (which has the original name) will be removed in a future release. 32 | #endif 33 | 34 | #include "stack_macros.h" 35 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/arduino_freertos.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-2024 Timo Sandmann 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, version 3. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | * General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | /** 18 | * @file arduino_freertos.h 19 | * @brief Collection of workarounds and fixes to avoid some annoying stuff of Arduino.h 20 | * @author Timo Sandmann 21 | * @date 17.05.2020 22 | */ 23 | 24 | #pragma once 25 | 26 | #ifndef _GLIBCXX_HAS_GTHREADS 27 | #define _GLIBCXX_HAS_GTHREADS 28 | #endif 29 | 30 | #ifndef _GCC_VERSION 31 | #define _GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 32 | #endif 33 | 34 | #include "FreeRTOS.h" 35 | #include "task.h" 36 | #include "HardwareSerial.h" 37 | #include "Arduino.h" 38 | #include "Print.h" 39 | #if defined(__has_include) && __has_include("Wire.h") 40 | #include "Wire.h" 41 | #endif 42 | #if defined(__has_include) && __has_include("SPI.h") 43 | #include "SPI.h" 44 | #endif 45 | #if defined(__has_include) && __has_include("FS.h") 46 | #include "FS.h" 47 | #endif 48 | #if defined(__has_include) && __has_include("SdFat.h") 49 | #include "SdFat.h" 50 | #endif 51 | #if defined(__has_include) && __has_include("SpiDriver/SdSpiArduinoDriver.h") 52 | #include "SpiDriver/SdSpiDriver.h" 53 | #include "SpiDriver/SdSpiArduinoDriver.h" 54 | #endif 55 | 56 | /* get rid of these stupid macros, as they are incompatible with C++ stdlib */ 57 | #undef false 58 | #undef true 59 | #undef bit 60 | #undef word 61 | #undef min 62 | #undef max 63 | #undef abs 64 | #undef round 65 | 66 | #ifndef USE_ARDUINO_DEFINES 67 | #undef F 68 | #undef constrain 69 | #undef radians 70 | #undef degrees 71 | #undef sq 72 | #undef stricmp 73 | #undef sei 74 | #undef cli 75 | #undef clockCyclesPerMicrosecond 76 | #undef clockCyclesToMicroseconds 77 | #undef microsecondsToClockCycles 78 | #undef lowByte 79 | #undef highByte 80 | #undef bitRead 81 | #undef bitSet 82 | #undef bitClear 83 | #undef bitWrite 84 | #undef BIN 85 | #undef OCT 86 | #undef DEC 87 | #undef HEX 88 | #undef BYTE 89 | #undef HIGH 90 | #undef LOW 91 | #undef INPUT 92 | #undef OUTPUT 93 | #undef INPUT_PULLUP 94 | #undef INPUT_PULLDOWN 95 | #undef OUTPUT_OPENDRAIN 96 | #undef INPUT_DISABLE 97 | #undef LSBFIRST 98 | #undef MSBFIRST 99 | #undef _BV 100 | #undef CHANGE 101 | #undef FALLING 102 | #undef RISING 103 | #undef digitalPinHasPWM 104 | #undef LED_BUILTIN 105 | #endif // USE_ARDUINO_DEFINES 106 | 107 | namespace arduino { 108 | using ::analogRead; 109 | using ::analogReadAveraging; 110 | using ::analogReadResolution; 111 | using ::analogReference; 112 | using ::analogWrite; 113 | using ::analogWriteFrequency; 114 | using ::analogWriteResolution; 115 | using ::attachInterrupt; 116 | using ::digitalReadFast; 117 | using ::digitalWriteFast; 118 | using ::pinMode; 119 | 120 | using ::delay; 121 | using ::delayMicroseconds; 122 | using ::micros; 123 | using ::millis; 124 | using ::yield; 125 | 126 | using ::Serial; 127 | #if !defined DISABLE_ARDUINO_HWSERIAL 128 | using ::HardwareSerial; 129 | using ::Serial1; 130 | using ::Serial2; 131 | using ::Serial3; 132 | using ::Serial4; 133 | using ::Serial5; 134 | using ::Serial6; 135 | #if defined ARDUINO_TEENSY40 || defined ARDUINO_TEENSY41 136 | using ::Serial7; 137 | #endif 138 | #ifdef ARDUINO_TEENSY41 139 | using ::Serial8; 140 | #endif 141 | #endif // !DISABLE_ARDUINO_HWSERIAL 142 | #if defined(__has_include) && __has_include("SPI.h") && !defined DISABLE_ARDUINO_SPI 143 | using ::SPI; 144 | using ::SPI1; 145 | using ::SPI2; 146 | #endif // SPI.h 147 | using ::Stream; 148 | #if defined(__has_include) && __has_include("Wire.h") && !defined DISABLE_ARDUINO_WIRE 149 | using ::TwoWire; 150 | using ::Wire; 151 | using ::Wire1; 152 | using ::Wire2; 153 | #ifdef WIRE_IMPLEMENT_WIRE3 154 | using ::Wire3; 155 | #endif 156 | #endif // Wire.h 157 | 158 | using ::String; 159 | 160 | template ::value, int> = 0> 161 | T map(T x, T in_min, T in_max, T out_min, T out_max) { 162 | return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 163 | } 164 | 165 | template ::value, int> = 0, 166 | typename std::enable_if_t::type>::value, int> = 0> 167 | T map(const T x, const T in_min, const T in_max, const T out_min, const T out_max) { 168 | return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 169 | } 170 | 171 | #ifndef USE_ARDUINO_DEFINES 172 | static constexpr uint8_t INPUT { 0 }; 173 | static constexpr uint8_t OUTPUT { 1 }; 174 | static constexpr uint8_t INPUT_PULLUP { 2 }; 175 | static constexpr uint8_t INPUT_PULLDOWN { 3 }; 176 | static constexpr uint8_t OUTPUT_OPENDRAIN { 4 }; 177 | static constexpr uint8_t INPUT_DISABLE { 5 }; 178 | 179 | static constexpr uint8_t LSBFIRST { 0 }; 180 | static constexpr uint8_t MSBFIRST { 1 }; 181 | 182 | static constexpr uint8_t LED_BUILTIN { 13 }; 183 | 184 | static constexpr uint8_t LOW { 0 }; 185 | static constexpr uint8_t HIGH { 1 }; 186 | 187 | static constexpr uint8_t FALLING { 2 }; 188 | static constexpr uint8_t RISING { 3 }; 189 | static constexpr uint8_t CHANGE { 4 }; 190 | 191 | static constexpr uint8_t DEC { 10 }; 192 | static constexpr uint8_t HEX { 16 }; 193 | static constexpr uint8_t OCT { 8 }; 194 | static constexpr uint8_t BIN { 2 }; 195 | 196 | #if defined __IMXRT1062__ && defined ARDUINO_TEENSY40 197 | static constexpr bool digitalPinHasPWM(uint8_t p) { 198 | return ((p) <= 15 || (p) == 18 || (p) == 19 || ((p) >= 22 && (p) <= 25) || ((p) >= 28 && (p) <= 31) || (p) == 33); 199 | } 200 | #elif defined __IMXRT1062__ && defined ARDUINO_TEENSY41 201 | static constexpr bool digitalPinHasPWM(uint8_t p) { 202 | return ((p) <= 15 || (p) == 18 || (p) == 19 || ((p) >= 22 && (p) <= 25) || ((p) >= 28 && (p) <= 31) || (p) == 33); 203 | } 204 | #elif defined __MK64FX512__ 205 | static constexpr bool digitalPinHasPWM(uint8_t p) { 206 | return ((p) >= 2 && (p) <= 10) || (p) == 14 || ((p) >= 20 && (p) <= 23) || (p) == 29 || (p) == 30 || ((p) >= 35 && (p) <= 38); 207 | } 208 | #elif defined __MK66FX1M0__ 209 | static constexpr bool digitalPinHasPWM(uint8_t p) { 210 | return ((p) >= 2 && (p) <= 10) || (p) == 14 || (p) == 16 || (p) == 17 || ((p) >= 20 && (p) <= 23) || (p) == 29 || (p) == 30 || ((p) >= 35 && (p) <= 38); 211 | } 212 | #endif 213 | #endif // USE_ARDUINO_DEFINES 214 | 215 | } // namespace arduino 216 | 217 | #include "portable/teensy.h" 218 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/critical_section.h: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// 3 | /// @author: Piotr Grygorczuk grygorek@gmail.com 4 | /// 5 | /// @copyright Copyright 2019 Piotr Grygorczuk 6 | /// All rights reserved. 7 | /// 8 | /// Redistribution and use in source and binary forms, with or without 9 | /// modification, are permitted provided that the following conditions are met: 10 | /// 11 | /// o Redistributions of source code must retain the above copyright notice, 12 | /// this list of conditions and the following disclaimer. 13 | /// 14 | /// o Redistributions in binary form must reproduce the above copyright notice, 15 | /// this list of conditions and the following disclaimer in the documentation 16 | /// and/or other materials provided with the distribution. 17 | /// 18 | /// o My name may not be used to endorse or promote products derived from this 19 | /// software without specific prior written permission. 20 | /// 21 | /// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | /// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | /// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | /// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | /// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | /// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | /// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | /// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | /// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | /// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | /// POSSIBILITY OF SUCH DAMAGE. 32 | /// 33 | /// adapted for use with the teensy FreeRTOS port by Timo Sandmann 34 | /// 35 | 36 | #pragma once 37 | 38 | #include "arduino_freertos.h" 39 | 40 | 41 | namespace free_rtos_std { 42 | struct critical_section { 43 | critical_section() { 44 | ::vTaskSuspendAll(); 45 | } 46 | 47 | ~critical_section() { 48 | ::xTaskResumeAll(); 49 | } 50 | }; 51 | } // namespace free_rtos_std 52 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/deprecated_definitions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V11.0.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | * 24 | * https://www.FreeRTOS.org 25 | * https://github.com/FreeRTOS 26 | * 27 | */ 28 | 29 | #ifndef DEPRECATED_DEFINITIONS_H 30 | #define DEPRECATED_DEFINITIONS_H 31 | 32 | 33 | /* Each FreeRTOS port has a unique portmacro.h header file. Originally a 34 | * pre-processor definition was used to ensure the pre-processor found the correct 35 | * portmacro.h file for the port being used. That scheme was deprecated in favour 36 | * of setting the compiler's include path such that it found the correct 37 | * portmacro.h file - removing the need for the constant and allowing the 38 | * portmacro.h file to be located anywhere in relation to the port being used. The 39 | * definitions below remain in the code for backward compatibility only. New 40 | * projects should not use them. */ 41 | 42 | #ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT 43 | #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" 44 | typedef void ( __interrupt __far * pxISR )(); 45 | #endif 46 | 47 | #ifdef OPEN_WATCOM_FLASH_LITE_186_PORT 48 | #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" 49 | typedef void ( __interrupt __far * pxISR )(); 50 | #endif 51 | 52 | #ifdef GCC_MEGA_AVR 53 | #include "../portable/GCC/ATMega323/portmacro.h" 54 | #endif 55 | 56 | #ifdef IAR_MEGA_AVR 57 | #include "../portable/IAR/ATMega323/portmacro.h" 58 | #endif 59 | 60 | #ifdef MPLAB_PIC24_PORT 61 | #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" 62 | #endif 63 | 64 | #ifdef MPLAB_DSPIC_PORT 65 | #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" 66 | #endif 67 | 68 | #ifdef MPLAB_PIC18F_PORT 69 | #include "../../Source/portable/MPLAB/PIC18F/portmacro.h" 70 | #endif 71 | 72 | #ifdef MPLAB_PIC32MX_PORT 73 | #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" 74 | #endif 75 | 76 | #ifdef _FEDPICC 77 | #include "libFreeRTOS/Include/portmacro.h" 78 | #endif 79 | 80 | #ifdef SDCC_CYGNAL 81 | #include "../../Source/portable/SDCC/Cygnal/portmacro.h" 82 | #endif 83 | 84 | #ifdef GCC_ARM7 85 | #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" 86 | #endif 87 | 88 | #ifdef GCC_ARM7_ECLIPSE 89 | #include "portmacro.h" 90 | #endif 91 | 92 | #ifdef ROWLEY_LPC23xx 93 | #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" 94 | #endif 95 | 96 | #ifdef IAR_MSP430 97 | #include "..\..\Source\portable\IAR\MSP430\portmacro.h" 98 | #endif 99 | 100 | #ifdef GCC_MSP430 101 | #include "../../Source/portable/GCC/MSP430F449/portmacro.h" 102 | #endif 103 | 104 | #ifdef ROWLEY_MSP430 105 | #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" 106 | #endif 107 | 108 | #ifdef ARM7_LPC21xx_KEIL_RVDS 109 | #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" 110 | #endif 111 | 112 | #ifdef SAM7_GCC 113 | #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" 114 | #endif 115 | 116 | #ifdef SAM7_IAR 117 | #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" 118 | #endif 119 | 120 | #ifdef SAM9XE_IAR 121 | #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" 122 | #endif 123 | 124 | #ifdef LPC2000_IAR 125 | #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" 126 | #endif 127 | 128 | #ifdef STR71X_IAR 129 | #include "..\..\Source\portable\IAR\STR71x\portmacro.h" 130 | #endif 131 | 132 | #ifdef STR75X_IAR 133 | #include "..\..\Source\portable\IAR\STR75x\portmacro.h" 134 | #endif 135 | 136 | #ifdef STR75X_GCC 137 | #include "..\..\Source\portable\GCC\STR75x\portmacro.h" 138 | #endif 139 | 140 | #ifdef STR91X_IAR 141 | #include "..\..\Source\portable\IAR\STR91x\portmacro.h" 142 | #endif 143 | 144 | #ifdef GCC_H8S 145 | #include "../../Source/portable/GCC/H8S2329/portmacro.h" 146 | #endif 147 | 148 | #ifdef GCC_AT91FR40008 149 | #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" 150 | #endif 151 | 152 | #ifdef RVDS_ARMCM3_LM3S102 153 | #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" 154 | #endif 155 | 156 | #ifdef GCC_ARMCM3_LM3S102 157 | #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" 158 | #endif 159 | 160 | #ifdef GCC_ARMCM3 161 | #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" 162 | #endif 163 | 164 | #ifdef IAR_ARM_CM3 165 | #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" 166 | #endif 167 | 168 | #ifdef IAR_ARMCM3_LM 169 | #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" 170 | #endif 171 | 172 | #ifdef HCS12_CODE_WARRIOR 173 | #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" 174 | #endif 175 | 176 | #ifdef MICROBLAZE_GCC 177 | #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" 178 | #endif 179 | 180 | #ifdef TERN_EE 181 | #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" 182 | #endif 183 | 184 | #ifdef GCC_HCS12 185 | #include "../../Source/portable/GCC/HCS12/portmacro.h" 186 | #endif 187 | 188 | #ifdef GCC_MCF5235 189 | #include "../../Source/portable/GCC/MCF5235/portmacro.h" 190 | #endif 191 | 192 | #ifdef COLDFIRE_V2_GCC 193 | #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" 194 | #endif 195 | 196 | #ifdef COLDFIRE_V2_CODEWARRIOR 197 | #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" 198 | #endif 199 | 200 | #ifdef GCC_PPC405 201 | #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" 202 | #endif 203 | 204 | #ifdef GCC_PPC440 205 | #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" 206 | #endif 207 | 208 | #ifdef _16FX_SOFTUNE 209 | #include "..\..\Source\portable\Softune\MB96340\portmacro.h" 210 | #endif 211 | 212 | #ifdef BCC_INDUSTRIAL_PC_PORT 213 | 214 | /* A short file name has to be used in place of the normal 215 | * FreeRTOSConfig.h when using the Borland compiler. */ 216 | #include "frconfig.h" 217 | #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" 218 | typedef void ( __interrupt __far * pxISR )(); 219 | #endif 220 | 221 | #ifdef BCC_FLASH_LITE_186_PORT 222 | 223 | /* A short file name has to be used in place of the normal 224 | * FreeRTOSConfig.h when using the Borland compiler. */ 225 | #include "frconfig.h" 226 | #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" 227 | typedef void ( __interrupt __far * pxISR )(); 228 | #endif 229 | 230 | #ifdef __GNUC__ 231 | #ifdef __AVR32_AVR32A__ 232 | #include "portmacro.h" 233 | #endif 234 | #endif 235 | 236 | #ifdef __ICCAVR32__ 237 | #ifdef __CORE__ 238 | #if __CORE__ == __AVR32A__ 239 | #include "portmacro.h" 240 | #endif 241 | #endif 242 | #endif 243 | 244 | #ifdef __91467D 245 | #include "portmacro.h" 246 | #endif 247 | 248 | #ifdef __96340 249 | #include "portmacro.h" 250 | #endif 251 | 252 | 253 | #ifdef __IAR_V850ES_Fx3__ 254 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 255 | #endif 256 | 257 | #ifdef __IAR_V850ES_Jx3__ 258 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 259 | #endif 260 | 261 | #ifdef __IAR_V850ES_Jx3_L__ 262 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 263 | #endif 264 | 265 | #ifdef __IAR_V850ES_Jx2__ 266 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 267 | #endif 268 | 269 | #ifdef __IAR_V850ES_Hx2__ 270 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 271 | #endif 272 | 273 | #ifdef __IAR_78K0R_Kx3__ 274 | #include "../../Source/portable/IAR/78K0R/portmacro.h" 275 | #endif 276 | 277 | #ifdef __IAR_78K0R_Kx3L__ 278 | #include "../../Source/portable/IAR/78K0R/portmacro.h" 279 | #endif 280 | 281 | #endif /* DEPRECATED_DEFINITIONS_H */ 282 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/freertos_tasks_c_additions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V11.0.1 task additions 3 | * Copyright (C) 2021-2024 Timo Sandmann. 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. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | /** 24 | * @file freertos_tasks_c_additions.h 25 | * @brief FreeRTOS task additions 26 | * @author Timo Sandmann 27 | * @date 12.03.2021 28 | */ 29 | 30 | #pragma once 31 | 32 | #include "FreeRTOS.h" 33 | #include "task.h" 34 | 35 | #include 36 | 37 | 38 | static TaskHandle_t prvStackWithinList(List_t* pxList, StackType_t* pxStack) { 39 | UBaseType_t uxQueue = configMAX_PRIORITIES; 40 | TCB_t* pxNextTCB = NULL; 41 | 42 | do { 43 | uxQueue--; 44 | configLIST_VOLATILE TCB_t* pxFirstTCB; 45 | 46 | if (listCURRENT_LIST_LENGTH(pxList) > (UBaseType_t) 0) { 47 | listGET_OWNER_OF_NEXT_ENTRY(pxFirstTCB, pxList); 48 | do { 49 | listGET_OWNER_OF_NEXT_ENTRY(pxNextTCB, pxList); 50 | if (pxNextTCB && pxStack >= pxNextTCB->pxStack && pxStack <= pxNextTCB->pxEndOfStack) { 51 | return pxNextTCB; 52 | } 53 | } while (pxNextTCB != pxFirstTCB); 54 | } 55 | } while (uxQueue > (UBaseType_t) tskIDLE_PRIORITY); 56 | 57 | return NULL; 58 | } 59 | 60 | TaskHandle_t pxGetTaskFromStack(StackType_t* pxStack) { 61 | extern TCB_t* volatile pxCurrentTCB; 62 | if (pxCurrentTCB && pxStack >= pxCurrentTCB->pxStack && pxStack <= pxCurrentTCB->pxEndOfStack) { 63 | return pxCurrentTCB; 64 | } 65 | 66 | if ((portNVIC_INT_CTRL_REG & 0xff) == 0) { 67 | portENTER_CRITICAL(); 68 | } 69 | 70 | TaskHandle_t pxTask = NULL; 71 | UBaseType_t uxQueue = configMAX_PRIORITIES; 72 | do { 73 | uxQueue--; 74 | pxTask = prvStackWithinList(&pxReadyTasksLists[uxQueue], pxStack); 75 | } while (uxQueue > (UBaseType_t) tskIDLE_PRIORITY && pxTask == NULL); 76 | 77 | if (!pxTask) { 78 | pxTask = prvStackWithinList(pxDelayedTaskList, pxStack); 79 | } 80 | if (!pxTask) { 81 | pxTask = prvStackWithinList(pxOverflowDelayedTaskList, pxStack); 82 | } 83 | #if INCLUDE_vTaskDelete == 1 84 | if (!pxTask) { 85 | pxTask = prvStackWithinList(&xTasksWaitingTermination, pxStack); 86 | } 87 | #endif 88 | #if INCLUDE_vTaskSuspend == 1 89 | if (!pxTask) { 90 | pxTask = prvStackWithinList(&xSuspendedTaskList, pxStack); 91 | } 92 | #endif 93 | 94 | if ((portNVIC_INT_CTRL_REG & 0xff) == 0) { 95 | portEXIT_CRITICAL(); 96 | } 97 | 98 | return pxTask; 99 | } 100 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/mpu_syscall_numbers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V11.0.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | * 24 | * https://www.FreeRTOS.org 25 | * https://github.com/FreeRTOS 26 | * 27 | */ 28 | 29 | #ifndef MPU_SYSCALL_NUMBERS_H 30 | #define MPU_SYSCALL_NUMBERS_H 31 | 32 | /* Numbers assigned to various system calls. */ 33 | #define SYSTEM_CALL_xTaskGenericNotify 0 34 | #define SYSTEM_CALL_xTaskGenericNotifyWait 1 35 | #define SYSTEM_CALL_xTimerGenericCommandFromTask 2 36 | #define SYSTEM_CALL_xEventGroupWaitBits 3 37 | #define SYSTEM_CALL_xTaskDelayUntil 4 38 | #define SYSTEM_CALL_xTaskAbortDelay 5 39 | #define SYSTEM_CALL_vTaskDelay 6 40 | #define SYSTEM_CALL_uxTaskPriorityGet 7 41 | #define SYSTEM_CALL_eTaskGetState 8 42 | #define SYSTEM_CALL_vTaskGetInfo 9 43 | #define SYSTEM_CALL_xTaskGetIdleTaskHandle 10 44 | #define SYSTEM_CALL_vTaskSuspend 11 45 | #define SYSTEM_CALL_vTaskResume 12 46 | #define SYSTEM_CALL_xTaskGetTickCount 13 47 | #define SYSTEM_CALL_uxTaskGetNumberOfTasks 14 48 | #define SYSTEM_CALL_ulTaskGetRunTimeCounter 15 49 | #define SYSTEM_CALL_ulTaskGetRunTimePercent 16 50 | #define SYSTEM_CALL_ulTaskGetIdleRunTimePercent 17 51 | #define SYSTEM_CALL_ulTaskGetIdleRunTimeCounter 18 52 | #define SYSTEM_CALL_vTaskSetApplicationTaskTag 19 53 | #define SYSTEM_CALL_xTaskGetApplicationTaskTag 20 54 | #define SYSTEM_CALL_vTaskSetThreadLocalStoragePointer 21 55 | #define SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer 22 56 | #define SYSTEM_CALL_uxTaskGetSystemState 23 57 | #define SYSTEM_CALL_uxTaskGetStackHighWaterMark 24 58 | #define SYSTEM_CALL_uxTaskGetStackHighWaterMark2 25 59 | #define SYSTEM_CALL_xTaskGetCurrentTaskHandle 26 60 | #define SYSTEM_CALL_xTaskGetSchedulerState 27 61 | #define SYSTEM_CALL_vTaskSetTimeOutState 28 62 | #define SYSTEM_CALL_xTaskCheckForTimeOut 29 63 | #define SYSTEM_CALL_ulTaskGenericNotifyTake 30 64 | #define SYSTEM_CALL_xTaskGenericNotifyStateClear 31 65 | #define SYSTEM_CALL_ulTaskGenericNotifyValueClear 32 66 | #define SYSTEM_CALL_xQueueGenericSend 33 67 | #define SYSTEM_CALL_uxQueueMessagesWaiting 34 68 | #define SYSTEM_CALL_uxQueueSpacesAvailable 35 69 | #define SYSTEM_CALL_xQueueReceive 36 70 | #define SYSTEM_CALL_xQueuePeek 37 71 | #define SYSTEM_CALL_xQueueSemaphoreTake 38 72 | #define SYSTEM_CALL_xQueueGetMutexHolder 39 73 | #define SYSTEM_CALL_xQueueTakeMutexRecursive 40 74 | #define SYSTEM_CALL_xQueueGiveMutexRecursive 41 75 | #define SYSTEM_CALL_xQueueSelectFromSet 42 76 | #define SYSTEM_CALL_xQueueAddToSet 43 77 | #define SYSTEM_CALL_vQueueAddToRegistry 44 78 | #define SYSTEM_CALL_vQueueUnregisterQueue 45 79 | #define SYSTEM_CALL_pcQueueGetName 46 80 | #define SYSTEM_CALL_pvTimerGetTimerID 47 81 | #define SYSTEM_CALL_vTimerSetTimerID 48 82 | #define SYSTEM_CALL_xTimerIsTimerActive 49 83 | #define SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle 50 84 | #define SYSTEM_CALL_pcTimerGetName 51 85 | #define SYSTEM_CALL_vTimerSetReloadMode 52 86 | #define SYSTEM_CALL_xTimerGetReloadMode 53 87 | #define SYSTEM_CALL_uxTimerGetReloadMode 54 88 | #define SYSTEM_CALL_xTimerGetPeriod 55 89 | #define SYSTEM_CALL_xTimerGetExpiryTime 56 90 | #define SYSTEM_CALL_xEventGroupClearBits 57 91 | #define SYSTEM_CALL_xEventGroupSetBits 58 92 | #define SYSTEM_CALL_xEventGroupSync 59 93 | #define SYSTEM_CALL_uxEventGroupGetNumber 60 94 | #define SYSTEM_CALL_vEventGroupSetNumber 61 95 | #define SYSTEM_CALL_xStreamBufferSend 62 96 | #define SYSTEM_CALL_xStreamBufferReceive 63 97 | #define SYSTEM_CALL_xStreamBufferIsFull 64 98 | #define SYSTEM_CALL_xStreamBufferIsEmpty 65 99 | #define SYSTEM_CALL_xStreamBufferSpacesAvailable 66 100 | #define SYSTEM_CALL_xStreamBufferBytesAvailable 67 101 | #define SYSTEM_CALL_xStreamBufferSetTriggerLevel 68 102 | #define SYSTEM_CALL_xStreamBufferNextMessageLengthBytes 69 103 | #define NUM_SYSTEM_CALLS 70 /* Total number of system calls. */ 104 | 105 | #endif /* MPU_SYSCALL_NUMBERS_H */ 106 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/newlib-freertos.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V11.0.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | * 24 | * https://www.FreeRTOS.org 25 | * https://github.com/FreeRTOS 26 | * 27 | */ 28 | 29 | #ifndef INC_NEWLIB_FREERTOS_H 30 | #define INC_NEWLIB_FREERTOS_H 31 | 32 | /* Note Newlib support has been included by popular demand, but is not 33 | * used by the FreeRTOS maintainers themselves. FreeRTOS is not 34 | * responsible for resulting newlib operation. User must be familiar with 35 | * newlib and must provide system-wide implementations of the necessary 36 | * stubs. Be warned that (at the time of writing) the current newlib design 37 | * implements a system-wide malloc() that must be provided with locks. 38 | * 39 | * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html 40 | * for additional information. */ 41 | 42 | #include 43 | 44 | #define configUSE_C_RUNTIME_TLS_SUPPORT 1 45 | 46 | #ifndef configTLS_BLOCK_TYPE 47 | #define configTLS_BLOCK_TYPE struct _reent 48 | #endif 49 | 50 | #ifndef configINIT_TLS_BLOCK 51 | #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) _REENT_INIT_PTR( &( xTLSBlock ) ) 52 | #endif 53 | 54 | #ifndef configSET_TLS_BLOCK 55 | #define configSET_TLS_BLOCK( xTLSBlock ) ( _impure_ptr = &( xTLSBlock ) ) 56 | #endif 57 | 58 | #ifndef configDEINIT_TLS_BLOCK 59 | #define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) ) 60 | #endif 61 | 62 | #endif /* INC_NEWLIB_FREERTOS_H */ 63 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/picolibc-freertos.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V11.0.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | * 24 | * https://www.FreeRTOS.org 25 | * https://github.com/FreeRTOS 26 | * 27 | */ 28 | 29 | #ifndef INC_PICOLIBC_FREERTOS_H 30 | #define INC_PICOLIBC_FREERTOS_H 31 | 32 | /* Use picolibc TLS support to allocate space for __thread variables, 33 | * initialize them at thread creation and set the TLS context at 34 | * thread switch time. 35 | * 36 | * See the picolibc TLS docs: 37 | * https://github.com/picolibc/picolibc/blob/main/doc/tls.md 38 | * for additional information. */ 39 | 40 | #include 41 | 42 | #define configUSE_C_RUNTIME_TLS_SUPPORT 1 43 | 44 | #define configTLS_BLOCK_TYPE void * 45 | 46 | #define picolibcTLS_SIZE ( ( portPOINTER_SIZE_TYPE ) _tls_size() ) 47 | #define picolibcSTACK_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) 48 | 49 | #if __PICOLIBC_MAJOR__ > 1 || __PICOLIBC_MINOR__ >= 8 50 | 51 | /* Picolibc 1.8 and newer have explicit alignment values provided 52 | * by the _tls_align() inline */ 53 | #define picolibcTLS_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) ( _tls_align() - 1 ) ) 54 | #else 55 | 56 | /* For older Picolibc versions, use the general port alignment value */ 57 | #define picolibcTLS_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) 58 | #endif 59 | 60 | /* Allocate thread local storage block off the end of the 61 | * stack. The picolibcTLS_SIZE macro returns the size (in 62 | * bytes) of the total TLS area used by the application. 63 | * Calculate the top of stack address. */ 64 | #if ( portSTACK_GROWTH < 0 ) 65 | 66 | #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \ 67 | do { \ 68 | xTLSBlock = ( void * ) ( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) - \ 69 | picolibcTLS_SIZE ) & \ 70 | ~picolibcTLS_ALIGNMENT_MASK ); \ 71 | pxTopOfStack = ( StackType_t * ) ( ( ( ( portPOINTER_SIZE_TYPE ) xTLSBlock ) - 1 ) & \ 72 | ~picolibcSTACK_ALIGNMENT_MASK ); \ 73 | _init_tls( xTLSBlock ); \ 74 | } while( 0 ) 75 | #else /* portSTACK_GROWTH */ 76 | #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \ 77 | do { \ 78 | xTLSBlock = ( void * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack + \ 79 | picolibcTLS_ALIGNMENT_MASK ) & ~picolibcTLS_ALIGNMENT_MASK ); \ 80 | pxTopOfStack = ( StackType_t * ) ( ( ( ( ( portPOINTER_SIZE_TYPE ) xTLSBlock ) + \ 81 | picolibcTLS_SIZE ) + picolibcSTACK_ALIGNMENT_MASK ) & \ 82 | ~picolibcSTACK_ALIGNMENT_MASK ); \ 83 | _init_tls( xTLSBlock ); \ 84 | } while( 0 ) 85 | #endif /* portSTACK_GROWTH */ 86 | 87 | #define configSET_TLS_BLOCK( xTLSBlock ) _set_tls( xTLSBlock ) 88 | 89 | #define configDEINIT_TLS_BLOCK( xTLSBlock ) 90 | 91 | #endif /* INC_PICOLIBC_FREERTOS_H */ 92 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/portable/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | AccessModifierOffset: -4 3 | AlignAfterOpenBracket: DontAlign 4 | AlignConsecutiveAssignments: false 5 | AlignConsecutiveDeclarations: false 6 | AlignEscapedNewlinesLeft: true 7 | AlignOperands: false 8 | AlignTrailingComments: false 9 | AllowAllParametersOfDeclarationOnNextLine: false 10 | AllowShortBlocksOnASingleLine: false 11 | AllowShortCaseLabelsOnASingleLine: true 12 | AllowShortFunctionsOnASingleLine: Empty 13 | AllowShortIfStatementsOnASingleLine: false 14 | AllowShortLoopsOnASingleLine: false 15 | AlwaysBreakAfterDefinitionReturnType: None 16 | AlwaysBreakAfterReturnType: None 17 | AlwaysBreakBeforeMultilineStrings: false 18 | AlwaysBreakTemplateDeclarations: true 19 | BinPackArguments: true 20 | BinPackParameters: true 21 | BraceWrapping: 22 | AfterClass: false 23 | AfterControlStatement: false 24 | AfterEnum: false 25 | AfterFunction: false 26 | AfterNamespace: false 27 | AfterObjCDeclaration: false 28 | AfterStruct: false 29 | AfterUnion: false 30 | BeforeCatch: false 31 | BeforeElse: false 32 | IndentBraces: false 33 | SplitEmptyFunction: false 34 | SplitEmptyRecord: false 35 | SplitEmptyNamespace: false 36 | BreakBeforeBinaryOperators: NonAssignment 37 | BreakBeforeBraces: Attach 38 | BreakBeforeTernaryOperators: false 39 | BreakConstructorInitializersBeforeComma: false 40 | BreakStringLiterals: true 41 | ColumnLimit: 160 42 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 43 | ConstructorInitializerIndentWidth: 4 44 | ContinuationIndentWidth: 4 45 | Cpp11BracedListStyle: false 46 | DerivePointerAlignment: false 47 | DisableFormat: false 48 | FixNamespaceComments: true 49 | IncludeBlocks: Regroup 50 | IndentCaseLabels: true 51 | IndentWidth: 4 52 | IndentWrappedFunctionNames: true 53 | KeepEmptyLinesAtTheStartOfBlocks: false 54 | Language: Cpp 55 | MaxEmptyLinesToKeep: 2 56 | NamespaceIndentation: None 57 | ObjCBlockIndentWidth: 4 58 | PenaltyBreakBeforeFirstCallParameter: 1 59 | PenaltyBreakComment: 300 60 | PenaltyBreakFirstLessLess: 120 61 | PenaltyBreakString: 1000 62 | PenaltyExcessCharacter: 1000000 63 | PenaltyReturnTypeOnItsOwnLine: 200 64 | PointerAlignment: Left 65 | ReflowComments: true 66 | SortIncludes: false 67 | SpaceAfterCStyleCast: true 68 | SpaceBeforeAssignmentOperators: true 69 | SpaceBeforeCpp11BracedList: true 70 | SpaceBeforeCtorInitializerColon: true 71 | SpaceBeforeInheritanceColon: true 72 | SpaceBeforeParens: ControlStatements 73 | SpaceBeforeRangeBasedForLoopColon: true 74 | SpaceInEmptyParentheses: false 75 | SpacesBeforeTrailingComments: 1 76 | SpacesInAngles: false 77 | SpacesInContainerLiterals: true 78 | SpacesInCStyleCastParentheses: false 79 | SpacesInParentheses: false 80 | SpacesInSquareBrackets: false 81 | Standard: Cpp11 82 | TabWidth: 4 83 | UseTab: Never 84 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/portable/event_responder_support.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the FreeRTOS port to Teensy boards. 3 | * Copyright (c) 2020-2024 Timo Sandmann 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library. If not, see . 17 | */ 18 | 19 | /** 20 | * @file event_responder_support.cpp 21 | * @brief FreeRTOS support implementations for Teensy EventResponder 22 | * @author Timo Sandmann 23 | * @date 20.05.2020 24 | */ 25 | 26 | #include "event_responder_support.h" 27 | #include "teensy.h" 28 | 29 | #include "arduino_freertos.h" 30 | #include "timers.h" 31 | #include "EventResponder.h" 32 | 33 | 34 | namespace freertos { 35 | TaskHandle_t g_yield_task {}; 36 | TaskHandle_t g_event_responder_task {}; 37 | 38 | void setup_event_responder() { 39 | ::xTaskCreate( 40 | [](void*) { 41 | while (true) { 42 | ::xTaskNotifyWait(0, 0, nullptr, pdMS_TO_TICKS(YIELD_TASK_PERIOD_MS)); 43 | freertos::yield(); 44 | } 45 | }, 46 | PSTR("YIELD"), YIELD_TASK_STACK_SIZE, nullptr, YIELD_TASK_PRIORITY, &g_yield_task); 47 | 48 | auto p_event_timer_ { ::xTimerCreate(PSTR("event_t"), pdMS_TO_TICKS(1), true, nullptr, [](TimerHandle_t) { ::MillisTimer::runFromTimer(); }) }; 49 | xTimerStart(p_event_timer_, 0); 50 | 51 | ::xTaskCreate( 52 | [](void*) { 53 | while (true) { 54 | ::xTaskNotifyWait(0, 0, nullptr, portMAX_DELAY); 55 | ::EventResponder::runFromInterrupt(); 56 | } 57 | }, 58 | PSTR("EVENT"), EVENT_TASK_STACK_SIZE, nullptr, configMAX_PRIORITIES - 2, &g_event_responder_task); 59 | } 60 | } // namespace freertos 61 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/portable/event_responder_support.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the FreeRTOS port to Teensy boards. 3 | * Copyright (c) 2020-2024 Timo Sandmann 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library. If not, see . 17 | */ 18 | 19 | /** 20 | * @file event_responder_support.h 21 | * @brief FreeRTOS support implementations for Teensy EventResponder 22 | * @author Timo Sandmann 23 | * @date 20.05.2020 24 | */ 25 | 26 | #pragma once 27 | 28 | #include 29 | 30 | 31 | typedef struct tskTaskControlBlock* TaskHandle_t; 32 | 33 | namespace freertos { 34 | static constexpr uint16_t YIELD_TASK_PERIOD_MS { 10 }; 35 | static constexpr uint8_t YIELD_TASK_PRIORITY { 0 }; 36 | static constexpr uint16_t YIELD_TASK_STACK_SIZE { 256 }; 37 | static constexpr uint16_t EVENT_TASK_STACK_SIZE { 256 }; 38 | 39 | extern TaskHandle_t g_yield_task; 40 | extern TaskHandle_t g_event_responder_task; 41 | 42 | void setup_event_responder(); 43 | } // namespace freertos 44 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/portable/readme.txt: -------------------------------------------------------------------------------- 1 | Each real time kernel port consists of three files that contain the core kernel 2 | components and are common to every port, and one or more files that are 3 | specific to a particular microcontroller and/or compiler. 4 | 5 | 6 | + The FreeRTOS/Source/Portable/MemMang directory contains the five sample 7 | memory allocators as described on the https://www.FreeRTOS.org WEB site. 8 | 9 | + The other directories each contain files specific to a particular 10 | microcontroller or compiler, where the directory name denotes the compiler 11 | specific files the directory contains. 12 | 13 | 14 | 15 | For example, if you are interested in the [compiler] port for the [architecture] 16 | microcontroller, then the port specific files are contained in 17 | FreeRTOS/Source/Portable/[compiler]/[architecture] directory. If this is the 18 | only port you are interested in then all the other directories can be 19 | ignored. 20 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/portable/teensy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the FreeRTOS port to Teensy boards. 3 | * Copyright (c) 2020-2024 Timo Sandmann 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library. If not, see . 17 | */ 18 | 19 | /** 20 | * @file teensy.h 21 | * @brief FreeRTOS support implementations for Teensy boards with newlib 4 22 | * @author Timo Sandmann 23 | * @date 04.06.2023 24 | */ 25 | 26 | #pragma once 27 | 28 | #include "arduino_freertos.h" 29 | 30 | #include 31 | #include 32 | 33 | 34 | namespace std { 35 | template 36 | class tuple; 37 | } 38 | 39 | #ifdef PRINT_DEBUG_STUFF 40 | #define EXC_PRINTF(...) exc_printf(putchar_debug, __VA_ARGS__) 41 | #define EXC_FLUSH() 42 | #else 43 | #define EXC_PRINTF(...) exc_printf(serialport_put, __VA_ARGS__) 44 | #define EXC_FLUSH() ::serialport_flush() 45 | #endif 46 | 47 | 48 | extern "C" { 49 | uint8_t get_debug_led_pin(); 50 | 51 | void exc_printf(void (*print)(const char), const char* format, ...) __attribute__((format(printf, 2, 3))); 52 | 53 | /** 54 | * @brief Write character c to Serial 55 | * @param[in] c: Character to be written 56 | */ 57 | void serialport_put(const char c); 58 | 59 | /** 60 | * @brief Write every character from the null-terminated C-string str and one additional newline character '\n' to Serial 61 | * @param[in] str: Character C-string to be written 62 | */ 63 | void serialport_puts(const char* str); 64 | 65 | void serialport_flush(); 66 | 67 | /** 68 | * @brief Print assert message and blink one short pulse every two seconds 69 | * @param[in] file: Filename as C-string 70 | * @param[in] line: Line number 71 | * @param[in] func: Function name as C-string 72 | * @param[in] expr: Expression that failed as C-string 73 | */ 74 | void assert_blink(const char* file, int line, const char* func, const char* expr) __attribute__((noreturn)); 75 | 76 | void mcu_shutdown() __attribute__((noreturn, used)); 77 | } // extern C 78 | 79 | namespace freertos { 80 | void yield(); 81 | 82 | /** 83 | * @brief Delay between led error flashes 84 | * @param[in] ms: Milliseconds to delay 85 | * @note Doesn't use a timer to work with interrupts disabled 86 | */ 87 | void delay_ms(const uint32_t ms); 88 | 89 | /** 90 | * @brief Indicate an error with the onboard LED 91 | * @param[in] n: Number of short LED pulses to encode the error 92 | */ 93 | void error_blink(const uint8_t n) __attribute__((noreturn)); 94 | 95 | /** 96 | * @brief Get amount of used and free RAM1 97 | * @return Tuple of: free RAM in byte, used data in byte, used bss in byte, used heap in byte, system free in byte, size of itcm in byte, ram size in byte 98 | */ 99 | std::tuple ram1_usage(); 100 | 101 | /** 102 | * @brief Get amount of used and free RAM2 103 | * @return Tuple of: free RAM in byte, ram size in byte 104 | */ 105 | std::tuple ram2_usage(); 106 | 107 | /** 108 | * @brief Get amount of used and free external RAM on teensy 4.1 109 | * @return Tuple of: free RAM in byte, ram size of external RAM in byte 110 | */ 111 | std::tuple ram3_usage(); 112 | 113 | /** 114 | * @brief Print amount of used and free RAM to Serial 115 | */ 116 | void print_ram_usage(); 117 | 118 | /** 119 | * @brief Get the current time in microseconds 120 | * @return Current time in us 121 | */ 122 | uint64_t get_us(); 123 | 124 | uint64_t get_us_from_isr(); 125 | 126 | /** 127 | * @brief Get the current time in milliseconds 128 | * @return Current time in ms 129 | */ 130 | static inline uint32_t get_ms() __attribute__((always_inline, unused)); 131 | static inline uint32_t get_ms() { 132 | return ::millis(); 133 | } 134 | 135 | void print_stack_trace(TaskHandle_t task); 136 | 137 | class clock { 138 | static timeval offset_; 139 | 140 | public: 141 | static void sync_rtc(); 142 | 143 | static inline const timeval* get_offset() { 144 | return &offset_; 145 | } 146 | }; 147 | } // namespace freertos 148 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/projdefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V11.0.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | * 24 | * https://www.FreeRTOS.org 25 | * https://github.com/FreeRTOS 26 | * 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 * arg ); 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 ) ( ( ( uint64_t ) ( xTimeInMs ) * ( uint64_t ) configTICK_RATE_HZ ) / ( uint64_t ) 1000U ) ) 43 | #endif 44 | 45 | /* Converts a time in microseconds to a time in ticks. This macro can be 46 | * overridden by a macro of the same name defined in FreeRTOSConfig.h in case the 47 | * definition here is not suitable for your application. */ 48 | #ifndef pdUS_TO_TICKS 49 | #define pdUS_TO_TICKS( xTimeInUs ) ( ( TickType_t ) ( ( ( uint64_t ) ( xTimeInUs ) * ( uint64_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000000ULL ) ) 50 | #endif 51 | 52 | /* Converts a time in ticks to a time in milliseconds. This macro can be 53 | * overridden by a macro of the same name defined in FreeRTOSConfig.h in case the 54 | * definition here is not suitable for your application. */ 55 | #ifndef pdTICKS_TO_MS 56 | #define pdTICKS_TO_MS( xTimeInTicks ) ( ( TickType_t ) ( ( ( uint64_t ) ( xTimeInTicks ) * ( uint64_t ) 1000U ) / ( uint64_t ) configTICK_RATE_HZ ) ) 57 | #endif 58 | 59 | /* Converts a time in ticks to a time in microseconds. This macro can be 60 | * overridden by a macro of the same name defined in FreeRTOSConfig.h in case the 61 | * definition here is not suitable for your application. */ 62 | #ifndef pdTICKS_TO_US 63 | #define pdTICKS_TO_US( xTicks ) ( ( ( TickType_t ) ( xTicks ) * 1000000ULL ) / configTICK_RATE_HZ ) 64 | #endif 65 | 66 | #define pdFALSE ( ( BaseType_t ) 0 ) 67 | #define pdTRUE ( ( BaseType_t ) 1 ) 68 | #define pdFALSE_SIGNED ( ( BaseType_t ) 0 ) 69 | #define pdTRUE_SIGNED ( ( BaseType_t ) 1 ) 70 | #define pdFALSE_UNSIGNED ( ( UBaseType_t ) 0 ) 71 | #define pdTRUE_UNSIGNED ( ( UBaseType_t ) 1 ) 72 | 73 | #define pdPASS ( pdTRUE ) 74 | #define pdFAIL ( pdFALSE ) 75 | #define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) 76 | #define errQUEUE_FULL ( ( BaseType_t ) 0 ) 77 | 78 | /* FreeRTOS error definitions. */ 79 | #define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) 80 | #define errQUEUE_BLOCKED ( -4 ) 81 | #define errQUEUE_YIELD ( -5 ) 82 | 83 | /* Macros used for basic data corruption checks. */ 84 | #ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 85 | #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 86 | #endif 87 | 88 | #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) 89 | #define pdINTEGRITY_CHECK_VALUE 0x5a5a 90 | #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) 91 | #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL 92 | #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS ) 93 | #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5a5a5a5a5aULL 94 | #else 95 | #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. 96 | #endif 97 | 98 | /* The following errno values are used by FreeRTOS+ components, not FreeRTOS 99 | * itself. */ 100 | #define pdFREERTOS_ERRNO_NONE 0 /* No errors */ 101 | #define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ 102 | #define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ 103 | #define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ 104 | #define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ 105 | #define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ 106 | #define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ 107 | #define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ 108 | #define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ 109 | #define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ 110 | #define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ 111 | #define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ 112 | #define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ 113 | #define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ 114 | #define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ 115 | #define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ 116 | #define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ 117 | #define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ 118 | #define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ 119 | #define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ 120 | #define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ 121 | #define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ 122 | #define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ 123 | #define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ 124 | #define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ 125 | #define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ 126 | #define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ 127 | #define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ 128 | #define pdFREERTOS_ERRNO_EAFNOSUPPORT 97 /* Address family not supported by protocol */ 129 | #define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ 130 | #define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ 131 | #define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ 132 | #define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ 133 | #define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ 134 | #define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ 135 | #define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ 136 | #define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ 137 | #define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ 138 | #define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ 139 | #define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ 140 | #define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ 141 | 142 | /* The following endian values are used by FreeRTOS+ components, not FreeRTOS 143 | * itself. */ 144 | #define pdFREERTOS_LITTLE_ENDIAN 0 145 | #define pdFREERTOS_BIG_ENDIAN 1 146 | 147 | /* Re-defining endian values for generic naming. */ 148 | #define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN 149 | #define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN 150 | 151 | 152 | #endif /* PROJDEFS_H */ 153 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/stack_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V11.0.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | * 24 | * https://www.FreeRTOS.org 25 | * https://github.com/FreeRTOS 26 | * 27 | */ 28 | 29 | #ifndef STACK_MACROS_H 30 | #define STACK_MACROS_H 31 | 32 | /* 33 | * Call the stack overflow hook function if the stack of the task being swapped 34 | * out is currently overflowed, or looks like it might have overflowed in the 35 | * past. 36 | * 37 | * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check 38 | * the current stack state only - comparing the current top of stack value to 39 | * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 40 | * will also cause the last few stack bytes to be checked to ensure the value 41 | * to which the bytes were set when the task was created have not been 42 | * overwritten. Note this second test does not guarantee that an overflowed 43 | * stack will always be recognised. 44 | */ 45 | 46 | /*-----------------------------------------------------------*/ 47 | 48 | /* 49 | * portSTACK_LIMIT_PADDING is a number of extra words to consider to be in 50 | * use on the stack. 51 | */ 52 | #ifndef portSTACK_LIMIT_PADDING 53 | #define portSTACK_LIMIT_PADDING 0 54 | #endif 55 | 56 | #if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) 57 | 58 | /* Only the current stack state is to be checked. */ 59 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 60 | do { \ 61 | /* Is the currently saved stack pointer within the stack limit? */ \ 62 | if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \ 63 | { \ 64 | char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ 65 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ 66 | } \ 67 | } while( 0 ) 68 | 69 | #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ 70 | /*-----------------------------------------------------------*/ 71 | 72 | #if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) 73 | 74 | /* Only the current stack state is to be checked. */ 75 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 76 | do { \ 77 | \ 78 | /* Is the currently saved stack pointer within the stack limit? */ \ 79 | if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \ 80 | { \ 81 | char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ 82 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ 83 | } \ 84 | } while( 0 ) 85 | 86 | #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ 87 | /*-----------------------------------------------------------*/ 88 | 89 | #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) 90 | 91 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 92 | do { \ 93 | const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ 94 | const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \ 95 | \ 96 | if( ( pulStack[ 0 ] != ulCheckValue ) || \ 97 | ( pulStack[ 1 ] != ulCheckValue ) || \ 98 | ( pulStack[ 2 ] != ulCheckValue ) || \ 99 | ( pulStack[ 3 ] != ulCheckValue ) ) \ 100 | { \ 101 | char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ 102 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ 103 | } \ 104 | } while( 0 ) 105 | 106 | #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 107 | /*-----------------------------------------------------------*/ 108 | 109 | #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) 110 | 111 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 112 | do { \ 113 | int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ 114 | static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 115 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 116 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 117 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 118 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ 119 | \ 120 | \ 121 | pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ 122 | \ 123 | /* Has the extremity of the task stack ever been written over? */ \ 124 | if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ 125 | { \ 126 | char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ 127 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ 128 | } \ 129 | } while( 0 ) 130 | 131 | #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 132 | /*-----------------------------------------------------------*/ 133 | 134 | /* Remove stack overflow macro if not being used. */ 135 | #ifndef taskCHECK_FOR_STACK_OVERFLOW 136 | #define taskCHECK_FOR_STACK_OVERFLOW() 137 | #endif 138 | 139 | 140 | 141 | #endif /* STACK_MACROS_H */ 142 | -------------------------------------------------------------------------------- /firmware/lib/freertos-teensy/src/stdint.readme: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V11.0.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | * 24 | * https://www.FreeRTOS.org 25 | * https://github.com/FreeRTOS 26 | * 27 | */ 28 | 29 | #ifndef FREERTOS_STDINT 30 | #define FREERTOS_STDINT 31 | 32 | /******************************************************************************* 33 | * THIS IS NOT A FULL stdint.h IMPLEMENTATION - It only contains the definitions 34 | * necessary to build the FreeRTOS code. It is provided to allow FreeRTOS to be 35 | * built using compilers that do not provide their own stdint.h definition. 36 | * 37 | * To use this file: 38 | * 39 | * 1) Copy this file into the directory that contains your FreeRTOSConfig.h 40 | * header file, as that directory will already be in the compiler's include 41 | * path. 42 | * 43 | * 2) Rename the copied file stdint.h. 44 | * 45 | */ 46 | 47 | typedef signed char int8_t; 48 | typedef unsigned char uint8_t; 49 | typedef short int16_t; 50 | typedef unsigned short uint16_t; 51 | typedef long int32_t; 52 | typedef unsigned long uint32_t; 53 | 54 | #ifndef SIZE_MAX 55 | #define SIZE_MAX ( ( size_t ) -1 ) 56 | #endif 57 | 58 | #endif /* FREERTOS_STDINT */ 59 | -------------------------------------------------------------------------------- /firmware/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:teensy41] 12 | platform = https://github.com/tsandmann/platform-teensy.git 13 | board = teensy41 14 | framework = arduino 15 | monitor_speed = 115200 16 | lib_deps = 17 | kosme/arduinoFFT@^2.0 18 | mkalkbrenner/WS2812Serial@^0.1.0 19 | ; https://github.com/tsandmann/freertos-teensy.git 20 | ; build_flags = 21 | ; -Iinclude 22 | 23 | -------------------------------------------------------------------------------- /firmware/src/goertzel.cpp: -------------------------------------------------------------------------------- 1 | #include "goertzel.h" 2 | 3 | Goertzel::Goertzel(double targetFreq, double sampleRate, size_t windowSize) 4 | : targetFreq(targetFreq), sampleRate(sampleRate), windowSize(windowSize), 5 | k(static_cast(0.5 + (windowSize * targetFreq) / sampleRate)), 6 | omega((2.0 * M_PI * k) / windowSize), 7 | coeff(2.0 * cos(omega)), s1(0.0), s2(0.0), samples(windowSize, 0.0), currentIndex(0) {} 8 | 9 | void Goertzel::addSample(double sample) { 10 | // Chatgpt suggested subtracting old sample here, voodoo magic 11 | // Partial explanation here, still not 100% on this personally: 12 | // https://dsp.stackexchange.com/questions/94264/why-does-this-sliding-window-goertzel-filter-trick-work 13 | double s = coeff * s1 - s2 + sample - samples[currentIndex]; 14 | s2 = s1; 15 | s1 = s; 16 | samples[currentIndex] = sample; 17 | currentIndex = (currentIndex + 1) % windowSize; 18 | } 19 | 20 | double Goertzel::getMagnitude() { 21 | double real = s1 - s2 * cos(omega); 22 | double imag = s2 * sin(omega); 23 | return sqrt(real * real + imag * imag); 24 | } 25 | -------------------------------------------------------------------------------- /firmware/src/video_config.h: -------------------------------------------------------------------------------- 1 | 2 | #define LINK_VIDEO 0 3 | 4 | 5 | --------------------------------------------------------------------------------