Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
46a0a7e
Add GNSS_CONTROL characteristic
crwper May 8, 2025
24e356e
Add control characteristic for live data
crwper May 9, 2025
f85bcb2
Fix issue building live GNSS data structure
crwper May 14, 2025
76a0f3c
Fix issues with GNSS control characteristic
crwper May 16, 2025
30e810d
Factor out CRS TX queue
crwper May 16, 2025
660202e
Write CRS data directly to TX buffer
crwper May 16, 2025
9df633d
Move characteristic opcode into buffer
crwper May 16, 2025
3a9ef9c
Rename CRS_TX_Queue to BLE_TX_Queue
crwper May 16, 2025
97c20cd
Convert GNSS_PV and START_RESULT to use CRS_TX_Queue
crwper May 16, 2025
e6252fe
Create function to add to BLE_TX_Queue with a single call
crwper May 17, 2025
33d298e
Add callback after BLE_TX_Queue item is sent
crwper May 17, 2025
59c89f6
Use new structures for server operation
crwper Feb 12, 2025
f290446
Add skeleton for BLE central role
crwper Feb 13, 2025
eb9f9c1
Connect to Activelook glasses
crwper Feb 15, 2025
dad3cbd
Disconnect from Activelook when exiting active mode
crwper Feb 15, 2025
8418deb
Continue advertising while scanning
crwper Feb 15, 2025
fbceaa1
Add skeleton for writing to ActiveLook
crwper Feb 15, 2025
c6dbbd6
Clear display and show hello world
crwper Feb 16, 2025
6f66e51
Make capitalization of ActiveLook consistent
crwper Feb 16, 2025
abb555a
Display GNSS TOW on ActiveLook
crwper Feb 16, 2025
4718e1e
Add state to ActiveLook update
crwper Feb 16, 2025
1732b43
Write multiple lines to ActiveLook display
crwper Feb 16, 2025
73ce4c6
Adjust text position
crwper Feb 17, 2025
e81bd5d
Fix issue with display clear
crwper Feb 17, 2025
745a5f9
Add task definition
crwper Feb 17, 2025
925545a
Use layout for first row
crwper Feb 18, 2025
bd563db
Use separate layout for each row
crwper Feb 18, 2025
a7f5e4e
Display all layouts in a single page
crwper Feb 18, 2025
72b603e
Add unit text to each row
crwper Feb 18, 2025
e75d924
Adjust display format
crwper Feb 21, 2025
803c6f8
Update ActiveLook display on timer
crwper Feb 21, 2025
e966aea
Add skeleton for config options
crwper Feb 22, 2025
b7a571e
Use config file to define display rows
crwper Feb 22, 2025
67e5569
Fix heading format
crwper Feb 26, 2025
5f3a441
Decrease connection interval
crwper Mar 8, 2025
300c267
Add other display parameters
crwper Apr 8, 2025
50ae7b2
Add unit definitions
crwper Apr 8, 2025
bdc25b2
Configure units and precision for ActiveLook
crwper Apr 8, 2025
6ec9647
Add configurable ActiveLook ID
crwper Apr 8, 2025
be9db59
Clear 'device found' flag before scan
crwper Apr 8, 2025
a0a0a46
Add air density correction to ActiveLook displays
crwper Apr 10, 2025
24482e6
Handle invalid values and nav limits
crwper Apr 10, 2025
86eea60
Copy device ID to config to enable nav modes
crwper Apr 11, 2025
29d3c3d
Add header row in ActiveLook display
crwper Apr 11, 2025
4c260df
Add FlySight battery percentage
crwper Apr 11, 2025
4a66fcd
Read battery level from ActiveLook
crwper Apr 11, 2025
728ea03
Add initial read of ActiveLook battery level
crwper Apr 11, 2025
bc5a62d
Fix issue with display units
crwper Apr 15, 2025
c0b47b4
Add BLE documentation
crwper May 9, 2025
b93e9ad
Add skeleton for BLE central role
crwper Feb 13, 2025
cb3d293
Add skeleton for writing to ActiveLook
crwper Feb 15, 2025
b388792
Add Mode characteristic to CRS service
crwper Apr 12, 2025
45bd276
Handle Mode characteristic and notifications
crwper Apr 12, 2025
c51d6ad
Fix mode characteristic UUID
crwper Apr 13, 2025
02d482c
Fix issue with rebase
crwper May 17, 2025
72fe958
Reorganize BLE services and characteristics
crwper May 17, 2025
99e5c22
Update documentation to reflect new structure
crwper May 17, 2025
c8cd2fd
Add more detail to documentation
crwper May 17, 2025
3dfc41d
Change control point length to 20 bytes (variable)
crwper May 17, 2025
779796c
Change control points from notification to indication
crwper May 18, 2025
c2eed8d
Implement standard response format for control points
crwper May 18, 2025
6244d33
Update documentation to include control point request/response
crwper May 18, 2025
0082c03
Fix issues with device state service
crwper May 18, 2025
d07b7ad
Add deployment script
crwper May 19, 2025
3791c5f
Initial documentation for deployment
crwper May 19, 2025
6d7fa75
Update documentation
crwper May 19, 2025
479e31d
Update .gitignore
crwper May 19, 2025
a9a9b0b
Rename documentation file
crwper May 19, 2025
3487e26
Handle negative nanoseconds part of UTC time
crwper May 31, 2025
4d17505
Add unit test for normalizeGNSSTime
crwper May 31, 2025
deb4c41
Update .gitignore
crwper May 31, 2025
6dc58d7
Add battery level service
crwper May 31, 2025
19943b7
Add configurable rate for ActiveLook
crwper May 31, 2025
9cc46fb
Add BLE Battery Service to documentation
crwper Jun 1, 2025
934f398
Merge branch 'master' into develop
crwper Sep 16, 2025
92e0de2
Merge branch 'master' into develop
crwper Sep 20, 2025
8331253
Merge branch 'clean_up_resources' into develop
crwper Sep 30, 2025
57d850f
Use BLE queue for mode and VBAT
crwper Sep 30, 2025
25cf889
Merge branch 'master' into develop
crwper Sep 30, 2025
961e669
Fix maximum number of timers
crwper Sep 30, 2025
eacfc1f
Reset characteristic flags on disconnect
crwper Sep 30, 2025
a02b7b2
Merge branch 'master' into develop
crwper Oct 8, 2025
2b671a6
Merge branch 'master' into develop
crwper Feb 13, 2026
2a4a80c
Fix build errors after merge
crwper Feb 13, 2026
7ea9ba4
Add activelook glasses layout with B612Mono font and icons
May 20, 2026
59e98d3
Revert unintended deploy_firmware.py changes
May 20, 2026
9a65669
Improve active look connection - reconnect after connection is lost, …
May 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .cproject
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.1316473902" name="Debug" parent="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileBaseName}.elf&quot; &quot;UserApp.bin&quot; &amp;&amp; arm-none-eabi-size &quot;${BuildArtifactFileName}&quot;" prebuildStep="../prebuild.sh">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.1316473902" name="Debug" parent="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileBaseName}.elf&quot; &quot;UserApp.bin&quot; &amp;&amp; arm-none-eabi-size &quot;${BuildArtifactFileName}&quot; &amp;&amp; cp &quot;UserApp.bin&quot; &quot;../Deploy/Firmware_As_Built/UserApp.bin&quot;" prebuildStep="../prebuild.sh">
<folderInfo id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.1316473902." name="/" resourcePath="">
<toolChain id="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.debug.569694880" name="MCU ARM GCC" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.debug">
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu.373619157" name="MCU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32WB5MMGHx" valueType="string"/>
Expand All @@ -25,6 +25,7 @@
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.1368736295" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="genericBoard" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.369744518" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.6 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32WB5MMGHx || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Core/Inc | ../Drivers/STM32WBxx_HAL_Driver/Inc | ../Drivers/STM32WBxx_HAL_Driver/Inc/Legacy | ../Drivers/CMSIS/Device/ST/STM32WBxx/Include | ../Drivers/CMSIS/Include | ../FATFS/Target | ../FATFS/App | ../STM32_WPAN/App | ../USB_Device/App | ../USB_Device/Target | ../Utilities/lpm/tiny_lpm | ../Middlewares/Third_Party/FatFs/src | ../Middlewares/ST/STM32_WPAN | ../Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread | ../Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl | ../Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/shci | ../Middlewares/ST/STM32_WPAN/utilities | ../Middlewares/ST/STM32_WPAN/ble/core | ../Middlewares/ST/STM32_WPAN/ble/core/auto | ../Middlewares/ST/STM32_WPAN/ble/core/template | ../Middlewares/ST/STM32_WPAN/ble/svc/Inc | ../Middlewares/ST/STM32_WPAN/ble/svc/Src | ../Middlewares/ST/STM32_USB_Device_Library/Core/Inc | ../Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc | ../Utilities/sequencer | ../Middlewares/ST/STM32_WPAN/ble || || || USE_HAL_DRIVER | STM32WB5Mxx || || USB_Device | Utilities | Drivers | STM32_WPAN | Core/Startup | Middlewares | Core | FATFS || || || ${workspace_loc:/${ProjName}/STM32WB5MMGHX_FLASH.ld} || true || NonSecure || || secure_nsclib.o || || None || || || " valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.debug.option.cpuclock.589475122" name="Cpu clock frequence" superClass="com.st.stm32cube.ide.mcu.debug.option.cpuclock" useByScannerDiscovery="false" value="64" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat.1943016217" name="Use float with printf from newlib-nano (-u _printf_float)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.1132392883" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
<builder buildPath="${workspace_loc:/flysight-2-firmware}/Debug" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.307986665" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.1599855123" name="MCU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
Expand Down Expand Up @@ -123,7 +124,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.1591110137" name="Release" parent="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileBaseName}.elf&quot; &quot;UserApp.bin&quot; &amp;&amp; arm-none-eabi-size &quot;${BuildArtifactFileName}&quot;" prebuildStep="..\prebuild.bat">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.1591110137" name="Release" parent="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileBaseName}.elf&quot; &quot;UserApp.bin&quot; &amp;&amp; arm-none-eabi-size &quot;${BuildArtifactFileName}&quot;" prebuildStep="../prebuild.sh">
<folderInfo id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.1591110137." name="/" resourcePath="">
<toolChain id="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.release.1963239428" name="MCU ARM GCC" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.release">
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu.931808695" name="MCU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32WB5MMGHx" valueType="string"/>
Expand All @@ -134,6 +135,7 @@
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.851921181" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="genericBoard" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.1662089201" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.6 || Release || false || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32WB5MMGHx || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Core/Inc | ../Drivers/STM32WBxx_HAL_Driver/Inc | ../Drivers/STM32WBxx_HAL_Driver/Inc/Legacy | ../Drivers/CMSIS/Device/ST/STM32WBxx/Include | ../Drivers/CMSIS/Include | ../FATFS/Target | ../FATFS/App | ../STM32_WPAN/App | ../USB_Device/App | ../USB_Device/Target | ../Utilities/lpm/tiny_lpm | ../Middlewares/Third_Party/FatFs/src | ../Middlewares/ST/STM32_WPAN | ../Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread | ../Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl | ../Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/shci | ../Middlewares/ST/STM32_WPAN/utilities | ../Middlewares/ST/STM32_WPAN/ble/core | ../Middlewares/ST/STM32_WPAN/ble/core/auto | ../Middlewares/ST/STM32_WPAN/ble/core/template | ../Middlewares/ST/STM32_WPAN/ble/svc/Inc | ../Middlewares/ST/STM32_WPAN/ble/svc/Src | ../Middlewares/ST/STM32_USB_Device_Library/Core/Inc | ../Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc | ../Utilities/sequencer | ../Middlewares/ST/STM32_WPAN/ble || || || USE_HAL_DRIVER | STM32WB5Mxx || || USB_Device | Utilities | Drivers | STM32_WPAN | Core/Startup | Middlewares | Core | FATFS || || || ${workspace_loc:/${ProjName}/STM32WB5MMGHX_FLASH.ld} || true || NonSecure || || secure_nsclib.o || || None || || || " valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.debug.option.cpuclock.1897362676" name="Cpu clock frequence" superClass="com.st.stm32cube.ide.mcu.debug.option.cpuclock" useByScannerDiscovery="false" value="64" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat.704960018" name="Use float with printf from newlib-nano (-u _printf_float)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.928917703" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
<builder buildPath="${workspace_loc:/flysight-2-firmware}/Release" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.248188091" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.2040549644" name="MCU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
Expand Down
13 changes: 12 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,23 @@

# Build folders
Debug/
Disable_BLE/
Release/
Binary/
Deploy/Firmware_As_Built/*
Deploy/Firmware_To_Deploy/*

# Created in prebuild scrip
/FlySight/version.h

# Locally stored "Eclipse launch configurations"
*.launch

# Test build products
Tests/*.exe

# OS artifacts
.DS_Store

# Python
__pycache__/
*.pyc
94 changes: 94 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# FlySight 2 Firmware

## Project Overview

FlySight 2 is a high-precision GPS data logger for skydiving and BASE jumping by Bionic Avionics Inc. The firmware runs on an STM32WB5MMGHx dual-core MCU (Cortex-M4 application + Cortex-M0+ BLE radio). It provides real-time audio feedback during freefall, multi-sensor data logging, BLE connectivity, USB mass storage, and an ActiveLook HUD display on Engo smart glasses.

### Key Features
- GNSS/GPS tracking at up to 25 Hz (u-blox MAX-M8)
- 6-axis IMU (LSM6DSO), barometer, magnetometer, humidity sensor
- Real-time audio tone/speech feedback based on flight parameters
- Data logging to SD card via FatFS
- BLE connectivity (STM32 WPAN stack) for phone app and ActiveLook glasses
- USB mass storage for file transfer
- ActiveLook HUD display: 2x2 grid layout with icons, B612 aviation font

### Build System
- **IDE**: STM32CubeIDE (Eclipse-based, ARM GCC toolchain)
- **MCU**: STM32WB5MMGHx (dual-core M4+M0+, BLE 5.x)
- **No Makefile/CMake** -- build is defined in `.cproject`/`.project` files
- **Pre-build**: `prebuild.sh` generates `version.h` from git tag
- **Post-build**: generates `UserApp.bin` and copies to `Deploy/Firmware_As_Built/`

### Branch Structure
- `master` -- stable releases
- `develop` -- active development (ActiveLook integration, new features)

## Rules for Claude Code

### Language Server Protocol (LSP)
- **ALWAYS use LSP** (documentSymbol, hover, goToDefinition, findReferences, callHierarchy) when analyzing or reading C/C++ source files
- Prefer LSP over Read tool or grep for understanding code structure
- Only fall back to Read for non-code files (configs, scripts, docs) or when LSP can't resolve symbols due to missing STM32 HAL headers
- Use LSP for Python files as well when available

### ActiveLook Development
- **ALWAYS consult the ActiveLook API documentation** before any implementation: https://github.com/ActiveLook/Activelook-API-Documentation/blob/main/ActiveLook_API.md
- **Never guess coordinates or protocol details** -- read the documentation first
- ActiveLook display coordinate system: (0,0) = bottom-right visually (optical mirror flips both axes)
- High X = visually LEFT, Low X = visually RIGHT
- High Y = visually TOP, Low Y = visually BOTTOM
- Rotation 4 = normal readable text with centered anchor
- Page coordinates are NOT mirrored (standard: x=0 left, higher y = higher on screen)
- Layout-internal coordinates (extra sub-commands) ARE mirrored
- Images must be rotated 180 degrees before upload to compensate for optical mirror
- Config names use NUL-terminated strings (NOT padded to 12 bytes) when used with Config-Generator, but FlySight firmware pads to 12 bytes
- `cfgWrite` requires the correct password if config already exists (FlySight uses password `0x01020304`)
- `cfgSet` must be called to activate a config before its fonts/images are available
- Font upload uses `fontSave` with header `[id, size_hi, size_lo]` then data chunks
- Image upload uses `imgSave` with header `[id, size_u32, width_u16, format]` then data chunks
- Maximum BLE write payload = MTU - 3 (currently 253 bytes with MTU=256)
- Reference the ActiveLook Visual Assets for pre-loaded icons: https://github.com/ActiveLook/Activelook-Visual-Assets
- Reference the ActiveLook Config-Generator for font/image conversion: https://github.com/ActiveLook/Config-Generator

### STM32/Embedded Best Practices
- Follow existing code patterns -- the project uses STM32 HAL, WPAN middleware, and a cooperative scheduler (UTIL_SEQ), not FreeRTOS
- One BLE command per scheduler task invocation -- never send multiple BLE writes in a tight loop
- Use `UTIL_SEQ_SetTask()` to schedule the next step, not blocking delays
- Respect the watchdog timer (IWDG, 3-second timeout)
- All sensor I/O is DMA-based and interrupt-driven -- never block in ISR context
- Stack is limited (0x400 bytes) -- avoid large local arrays; use static buffers
- Flash is limited to 454 KB for the application (bootloader occupies lower flash)
- RAM1 is 256 KB, RAM_SHARED is 10 KB (BLE radio)
- Use `static` for file-scope variables and functions
- The project uses `newlib-nano` with float printf enabled (`-u _printf_float`)

### C Language Style
- Follow existing project conventions (Bionic Avionics coding style)
- Prefix all public functions with `FS_` (FlySight namespace)
- Use `typedef enum` and `typedef struct` with `_t` suffix
- State machines use function pointer tables (see `mode.c`, `crs.c`, `activelook.c`)
- Ring buffers for producer/consumer patterns (see `log.c`, `sensor.c`)
- No dynamic memory allocation (`malloc`/`free`) -- use static arrays
- Error handling: log events via `FS_Log_WriteEvent()`, set LED color for health status
- Configuration is file-based (text config on SD card, parsed at startup)

### Code Quality
- Do not add unnecessary comments -- the code should be self-documenting
- Do not add features beyond what was requested
- Do not guess at protocol details -- verify against documentation or test empirically
- When modifying ActiveLook layout code, make one change at a time and test
- The clangd LSP will show false errors for STM32 HAL symbols (can't resolve `main.h`) -- these are expected and don't affect the actual STM32CubeIDE build

### Deployment
- Build with STM32CubeIDE (Debug or Release configuration)
- Deploy via encrypted `.sfb` firmware update files (see `Deploy/deploy_firmware.py`)
- Each device batch has a specific public key -- check `flysight.txt` on device for `Pubkey_X`
- ActiveLook config (fonts/images) uploaded separately via `Config-Generator/upload_ble.py`

### Key Directories
- `FlySight/` -- main application code (sensors, audio, logging, modes, ActiveLook)
- `Core/Src/` -- STM32 HAL initialization, main loop, interrupt handlers
- `STM32_WPAN/App/` -- BLE application layer (app_ble.c, custom services, ActiveLook client)
- `Deploy/` -- firmware deployment scripts and tools
- `Config-Generator/` (external, at `~/Projects/Config-Generator/`) -- ActiveLook font/image preparation tool
27 changes: 18 additions & 9 deletions Core/Inc/app_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,13 @@
#define L2CAP_TIMEOUT_MULTIPLIER 0x1F4

/* USER CODE BEGIN Specific_Parameters */

#define SCAN_P (0x320)
#define SCAN_L (0x320)
#define CONN_P1 (CONN_P(200))
#define CONN_P2 (CONN_P(1000))
#define SUPERV_TIMEOUT (400)
#define CONN_L1 (CONN_L(10))
#define CONN_L2 (CONN_L(10))
/* USER CODE END Specific_Parameters */

/******************************************************************************
Expand All @@ -197,7 +203,7 @@
* Maximum number of simultaneous connections that the device will support.
* Valid values are from 1 to 8
*/
#define CFG_BLE_NUM_LINK 1
#define CFG_BLE_NUM_LINK 2

/**
* Maximum number of Services that can be stored in the GATT database.
Expand Down Expand Up @@ -673,8 +679,15 @@ typedef enum
#endif
CFG_TASK_HCI_ASYNCH_EVT_ID,
/* USER CODE BEGIN CFG_Task_Id_With_HCI_Cmd_t */
CFG_TASK_LINK_CONFIG_ID,
CFG_TASK_ADV_UPDATE_ID,
CFG_TASK_LINK_CONFIG_ID,
CFG_TASK_ADV_UPDATE_ID,
CFG_TASK_START_SCAN_ID,
CFG_TASK_CONN_DEV_1_ID,
CFG_TASK_DISCONN_DEV_1_ID,
CFG_TASK_BLE_TX_QUEUE_TRANSMIT_ID,
CFG_TASK_FS_CRS_UPDATE_ID,
CFG_TASK_FS_START_UPDATE_ID,
CFG_TASK_FS_ACTIVELOOK_ID,
/* USER CODE END CFG_Task_Id_With_HCI_Cmd_t */
CFG_LAST_TASK_ID_WITH_HCICMD, /**< Shall be LAST in the list */
} CFG_Task_Id_With_HCI_Cmd_t;
Expand All @@ -693,11 +706,7 @@ typedef enum
CFG_TASK_FS_AUDIO_CONTROL_PRODUCER_ID,
CFG_TASK_FS_AUDIO_CONTROL_CONSUMER_ID,
CFG_TASK_FS_CONFIG_UPDATE_ID,
CFG_TASK_CUSTOM_CRS_TRANSMIT_ID,
CFG_TASK_CUSTOM_GNSS_TRANSMIT_ID,
CFG_TASK_FS_CRS_UPDATE_ID,
CFG_TASK_FS_START_UPDATE_ID,
CFG_TASK_CUSTOM_START_TRANSMIT_ID,
CFG_TASK_FS_VBAT_LOG_ERROR_ID,
CFG_TASK_FS_WATCHDOG_UPDATE_ID,
/* USER CODE END CFG_Task_Id_With_NO_HCI_Cmd_t */
CFG_LAST_TASK_ID_WITH_NO_HCICMD /**< Shall be LAST in the list */
Expand Down
2 changes: 1 addition & 1 deletion Core/Inc/hw_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
* The user may define the maximum number of virtual timers supported.
* It shall not exceed 255
*/
#define CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER 19
#define CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER 20

/**
* The user may define the priority in the NVIC of the RTC_WKUP interrupt handler that is used to manage the
Expand Down
Loading