|
| 1 | +# Contributing |
| 2 | + |
| 3 | +This repository contains the OpenEarable 2 firmware for the `openearable_v2/nrf5340/cpuapp` target. Contributions should match the current nRF Connect SDK and Zephyr-based build, keep the codebase maintainable, and leave enough documentation for the next contributor to extend the work safely. |
| 4 | + |
| 5 | +## Core Principles |
| 6 | + |
| 7 | +- Keep changes small, focused, and easy to review. |
| 8 | +- Prefer extending the existing module boundaries over adding new cross-cutting abstractions. |
| 9 | +- Preserve a linear Git history by rebasing instead of merging `main` into feature branches. |
| 10 | +- Use conventional commits so history stays searchable and automation-friendly. |
| 11 | +- Document architecture, public APIs, and non-obvious logic as part of the change. |
| 12 | + |
| 13 | +## Repository Overview |
| 14 | + |
| 15 | +The main firmware lives at the repository root and is built through Zephyr and the nRF Connect SDK. |
| 16 | + |
| 17 | +- `src/audio`, `src/bluetooth`, `src/modules`: runtime audio, Bluetooth, and application modules. |
| 18 | +- `src/SensorManager`, `src/Battery`, `src/SD_Card`, `src/time_sync`: sensor, power, storage, and synchronization subsystems. |
| 19 | +- `src/drivers`, `src/Wire`, `src/utils`, `src/buttons`, `src/ParseInfo`: reusable device support and shared utilities. |
| 20 | +- `boards/`, `dts/`: board overlays and devicetree bindings for the OpenEarable hardware. |
| 21 | +- `tools/flash`, `tools/buildprog`, `tools/uart_terminal`: local developer tooling for flashing and diagnostics. |
| 22 | +- `.github/workflows/`: CI builds and release automation. |
| 23 | + |
| 24 | +Before introducing a new directory or abstraction, verify that an existing subsystem is not already the correct extension point. |
| 25 | + |
| 26 | +## Development Setup |
| 27 | + |
| 28 | +Use the same toolchain versions the repository expects. |
| 29 | + |
| 30 | +1. Install Visual Studio Code and the nRF Connect for VS Code extension. |
| 31 | +2. Install the J-Link Software and Documentation Package. |
| 32 | +3. Install `nrfutil` and ensure it is available on your `PATH`. |
| 33 | +4. Install nRF Connect SDK `v3.0.1`. |
| 34 | +5. Install toolchain `v3.0.1`. |
| 35 | +6. Open this repository as an application in the nRF Connect extension. |
| 36 | + |
| 37 | +The manifest in [west.yml](west.yml) pins the workspace to `sdk-nrf` `v3.0.1`. Keep documentation and local validation aligned with that version unless the repository is explicitly upgraded. |
| 38 | + |
| 39 | +## Build And Flash |
| 40 | + |
| 41 | +For local development, the primary target is `openearable_v2/nrf5340/cpuapp`. |
| 42 | + |
| 43 | +### Recommended VS Code Build |
| 44 | + |
| 45 | +- Use the nRF Connect extension to add a build configuration for `openearable_v2/nrf5340/cpuapp`. |
| 46 | +- For FOTA builds, set `-DFILE_SUFFIX="fota"` and use a build directory such as `build_fota`. |
| 47 | +- For non-FOTA builds, use the standard project configuration without the FOTA suffix. |
| 48 | + |
| 49 | +### Command-Line Build |
| 50 | + |
| 51 | +When working from a Zephyr workspace, mirror the CI build: |
| 52 | + |
| 53 | +```bash |
| 54 | +west build --board openearable_v2/nrf5340/cpuapp --pristine=always . -- -DFILE_SUFFIX="fota" |
| 55 | +``` |
| 56 | + |
| 57 | +If you are building from a workspace where this repository is checked out as an application directory, point `west build` at the repository path instead of `.`. |
| 58 | + |
| 59 | +### Flashing And Recovery |
| 60 | + |
| 61 | +- Use [tools/flash/flash_fota.sh](tools/flash/flash_fota.sh) to flash a FOTA build with the correct left/right and hardware configuration flags. |
| 62 | +- Use [tools/flash/recover.sh](tools/flash/recover.sh) if the board needs a full recover before reflashing. |
| 63 | +- Keep the device powered through USB or a sufficiently charged battery during flashing and recovery. |
| 64 | + |
| 65 | +Update this guide when the build directory names, flashing scripts, board targets, or required tool versions change. |
| 66 | + |
| 67 | +## Branching And Commit Workflow |
| 68 | + |
| 69 | +- Create a dedicated branch from the latest `main`. |
| 70 | +- Rebase regularly onto `main`. |
| 71 | +- Do not merge `main` into your branch. |
| 72 | +- When pushing rebased history, use `git push --force-with-lease`. |
| 73 | + |
| 74 | +Recommended workflow: |
| 75 | + |
| 76 | +```bash |
| 77 | +git checkout main |
| 78 | +git pull --rebase origin main |
| 79 | +git checkout -b <topic-branch> |
| 80 | +``` |
| 81 | + |
| 82 | +Before opening or updating a pull request: |
| 83 | + |
| 84 | +```bash |
| 85 | +git checkout main |
| 86 | +git pull --rebase origin main |
| 87 | +git checkout <topic-branch> |
| 88 | +git rebase main |
| 89 | +``` |
| 90 | + |
| 91 | +## Conventional Commits |
| 92 | + |
| 93 | +All commits must follow the [Conventional Commits](https://www.conventionalcommits.org/) format: |
| 94 | + |
| 95 | +```text |
| 96 | +<type>(<scope>): <short summary> |
| 97 | +``` |
| 98 | + |
| 99 | +Examples: |
| 100 | + |
| 101 | +```text |
| 102 | +feat(sensor-manager): add runtime sampling guard for PPG |
| 103 | +fix(flash): validate hardware version before writing UICR |
| 104 | +docs(contributing): align contributor guide with Zephyr firmware workflow |
| 105 | +refactor(bluetooth): split stream setup from connection state handling |
| 106 | +test(ci): add build coverage for release headset configuration |
| 107 | +``` |
| 108 | + |
| 109 | +Allowed types: |
| 110 | + |
| 111 | +- `feat` |
| 112 | +- `fix` |
| 113 | +- `refactor` |
| 114 | +- `docs` |
| 115 | +- `test` |
| 116 | +- `chore` |
| 117 | +- `build` |
| 118 | +- `ci` |
| 119 | +- `perf` |
| 120 | + |
| 121 | +## Code Quality Expectations |
| 122 | + |
| 123 | +### Architecture |
| 124 | + |
| 125 | +- Keep module responsibilities explicit and cohesive. |
| 126 | +- Avoid mixing hardware access, business logic, and transport logic in the same change unless the behavior truly spans those layers. |
| 127 | +- Reuse the existing subsystem layout in `src/` before introducing a new top-level concept. |
| 128 | +- Remove dead code and stale indirection when touching a relevant area. |
| 129 | +- If a new abstraction is necessary, document why the existing structure is not sufficient. |
| 130 | + |
| 131 | +### Documentation |
| 132 | + |
| 133 | +This repository expects code to be documented. |
| 134 | + |
| 135 | +- Add documentation comments to public classes, public functions, public headers, and reusable module entry points. |
| 136 | +- Document parameters, return values, ownership rules, side effects, failure modes, and hardware assumptions when they are not obvious from the signature. |
| 137 | +- Add brief intent comments above complex or safety-critical logic blocks where structure alone is insufficient. |
| 138 | +- Keep comments synchronized with the implementation. |
| 139 | +- Update repository documentation when changing developer workflows, build behavior, repository structure, or subsystem responsibilities. |
| 140 | + |
| 141 | +### Style |
| 142 | + |
| 143 | +- Follow the existing naming and file layout conventions. |
| 144 | +- Prefer clear control flow over compact but opaque code. |
| 145 | +- Avoid unrelated formatting churn. |
| 146 | +- Keep headers and source files aligned: declarations, ownership, and invariants should be easy to trace. |
| 147 | + |
| 148 | +## Validation Before Opening A Pull Request |
| 149 | + |
| 150 | +At minimum, contributors should validate that the firmware still builds with the repository's supported configuration. |
| 151 | + |
| 152 | +### Required |
| 153 | + |
| 154 | +Run a clean FOTA build equivalent to CI: |
| 155 | + |
| 156 | +```bash |
| 157 | +west build --board openearable_v2/nrf5340/cpuapp --pristine=always . -- -DFILE_SUFFIX="fota" |
| 158 | +``` |
| 159 | + |
| 160 | +### Recommended When Relevant |
| 161 | + |
| 162 | +- Rebuild any additional configuration affected by the change. |
| 163 | +- Flash hardware and smoke-test the changed behavior when the work touches sensors, Bluetooth, power management, storage, or audio paths. |
| 164 | +- Verify any developer tooling changes with the corresponding script in `tools/`. |
| 165 | + |
| 166 | +If a change cannot be validated locally, explain the gap in the pull request. |
| 167 | + |
| 168 | +## Pull Request Guidelines |
| 169 | + |
| 170 | +- Use a clear title that matches the final change. |
| 171 | +- Describe the problem, the chosen solution, and relevant tradeoffs. |
| 172 | +- Call out hardware dependencies, risky paths, and follow-up work explicitly. |
| 173 | +- Include logs, screenshots, or recordings when they help review tooling or workflow changes. |
| 174 | +- Keep each pull request scoped tightly enough for a focused review. |
| 175 | + |
| 176 | +Before requesting review, confirm that: |
| 177 | + |
| 178 | +- your branch is rebased onto the latest `main` |
| 179 | +- commits follow conventional commit rules |
| 180 | +- public APIs and changed behavior are documented |
| 181 | +- the relevant firmware build succeeds |
| 182 | +- repository documentation is updated where needed |
| 183 | + |
| 184 | +## What To Avoid |
| 185 | + |
| 186 | +- Merging `main` into feature branches |
| 187 | +- Force-pushing with `--force` |
| 188 | +- Bundling unrelated cleanup into functional changes |
| 189 | +- Adding undocumented public APIs or hardware assumptions |
| 190 | +- Changing build or flash behavior without updating the docs and scripts together |
| 191 | +- Opening a pull request without validating the affected configuration |
| 192 | + |
| 193 | +## Questions And Ambiguity |
| 194 | + |
| 195 | +When the correct approach is unclear: |
| 196 | + |
| 197 | +- prefer the simpler design |
| 198 | +- document assumptions in the pull request |
| 199 | +- ask for clarification before making a large or irreversible change |
| 200 | + |
| 201 | +Clean history, accurate documentation, and maintainable firmware structure are part of the contribution, not optional follow-up work. |
0 commit comments