Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .claude/agents/orchestrator.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ You triage incoming development requests and route them to the right specialist
## Context to Gather Before Routing

- Which layer is affected?
- `hal_tiva/cortex/` — ARM Cortex-M core (SystemTick, EventDispatcher, InterruptTable, Reset, DWT)
- `hal_tiva/{Reset,SystemTick,SystemTickTimerService,TimeKeeper}` — generic ARM Cortex-M core services (local until EMIL hosts family-agnostic versions); `InterruptTable`/`InterruptHandler`/`DataWatchpointAndTrace`/`EventDispatcher` come from EMIL's `hal::cortex::*`
- `hal_tiva/tiva/` — TM4C peripheral drivers (Gpio, Uart, Can, Adc, SpiMaster, Dma, Clock)
- `hal_tiva/synchronous_tiva/` — Blocking driver variants (SynchronousAdc, SynchronousPwm, SynchronousQuadratureEncoder)
- `hal_tiva/instantiations/` — Board Support Packages (LaunchPadBsp, EventInfrastructure)
- `hal_tiva/default_init/` — Startup, atomics shim, hardware init hooks
- `hal_tiva/bringup/` — Startup, atomics shim, hardware init hooks
- `tiva/CMSIS/` — Device headers, startup vector tables, linker scripts
- Which MCU family? TM4C123 / TM4C129 / both
- Is this asynchronous (event-driven) or synchronous (blocking/polling)?
Expand Down
2 changes: 1 addition & 1 deletion .claude/agents/reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,4 @@ Applies if any new `extern "C"` ISR handler was introduced:
- [ ] New source files added to the correct `CMakeLists.txt` target (`hal_tiva.tiva`, `hal_tiva.synchronous_tiva`, etc.)
- [ ] MCU-family conditional compilation uses CMake generator expressions
- [ ] No circular dependencies between targets
- [ ] `hal_tiva.default_init` linked as object files (not static library) — check if startup changes require this
- [ ] `hal_tiva.bringup` linked as object files (not static library) — check if startup changes require this
6 changes: 3 additions & 3 deletions .github/agents/orchestrator.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ You triage incoming development requests and route them to the right specialist
## Context to Gather Before Routing

- Which layer is affected?
- `hal_tiva/cortex/` — ARM Cortex-M core (SystemTick, EventDispatcher, InterruptTable, Reset, DWT)
- `hal_tiva/{Reset,SystemTick,SystemTickTimerService,TimeKeeper}` — generic ARM Cortex-M core services (local until EMIL hosts family-agnostic versions); `InterruptTable`/`InterruptHandler`/`DataWatchpointAndTrace`/`EventDispatcher` come from EMIL's `hal::cortex::*`
- `hal_tiva/tiva/` — TM4C peripheral drivers (Gpio, Uart, Can, Adc, SpiMaster, Dma, Clock)
- `hal_tiva/synchronous_tiva/` — Blocking driver variants (SynchronousAdc, SynchronousPwm, SynchronousQuadratureEncoder)
- `hal_tiva/instantiations/` — Board Support Packages (LaunchPadBsp, EventInfrastructure)
- `hal_tiva/default_init/` — Startup, atomics shim, hardware init hooks
- `hal_tiva/bringup/` — Startup, atomics shim, hardware init hooks
- `tiva/CMSIS/` — Device headers, startup vector tables, linker scripts
- Which MCU family? TM4C123 / TM4C129 / both
- Is this asynchronous (event-driven) or synchronous (blocking/polling)?
Expand All @@ -51,5 +51,5 @@ You triage incoming development requests and route them to the right specialist
- Project guidelines: [copilot-instructions.md](../../.github/copilot-instructions.md)
- Board documentation: [`doc/`](../../doc/)
- Existing peripheral drivers: [`hal_tiva/tiva/`](../../hal_tiva/tiva/)
- Cortex-M core: [`hal_tiva/cortex/`](../../hal_tiva/cortex/)
- Cortex-M core services: [`hal_tiva/`](../../hal_tiva/) (top level) and EMIL's `hal::cortex::*`
- Startup files: [`tiva/CMSIS/`](../../tiva/CMSIS/)
2 changes: 1 addition & 1 deletion .github/agents/reviewer.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,4 @@ Applies if any new `extern "C"` ISR handler was introduced:
- [ ] New source files added to the correct `CMakeLists.txt` target (`hal_tiva.tiva`, `hal_tiva.synchronous_tiva`, etc.)
- [ ] MCU-family conditional compilation uses CMake generator expressions
- [ ] No circular dependencies between targets
- [ ] `hal_tiva.default_init` linked as object files (not static library) — check if startup changes require this
- [ ] `hal_tiva.bringup` linked as object files (not static library) — check if startup changes require this
7 changes: 4 additions & 3 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ This is a Hardware Abstraction Layer (HAL) for TI ARM Cortex-M based microcontro

## Repository Structure

- **hal_tiva/cortex/**: ARM Cortex-M core abstractions (InterruptTable, SystemTick, EventDispatcher, Reset, DWT)
- **hal_tiva/{Reset,SystemTick,SystemTickTimerService,TimeKeeper}**: Generic ARM Cortex-M core services, kept local until EMIL hosts family-agnostic equivalents under `hal/cortex_m/`
- **hal_tiva/tiva/**: TM4C-specific peripheral drivers (Gpio, Uart, Can, Adc, SpiMaster, Dma, Clock)
- **hal_tiva/synchronous_tiva/**: Blocking/polling driver variants (SynchronousAdc, SynchronousUart)
- **hal_tiva/instantiations/**: Board Support Packages and infrastructure (LaunchPadBsp, EventInfrastructure)
- **hal_tiva/default_init/**: Startup code, atomic operations shim, hardware initialization hooks
- **hal_tiva/bringup/**: Startup glue (`HardwareInitialization()`, weak `Default_Handler_Forwarded()`) — generic runtime (atomics shim, syscall stubs, `abort`/`__assert_func`) comes from EMIL's `hal.cortex_m.runtime`
- **InterruptTable/InterruptHandler/DataWatchpointAndTrace/EventDispatcher**: `hal::cortex::*` from EMIL (`embedded-infra-lib`), not this repo
- **tiva/CMSIS/Device/TI/**: CMSIS device headers, register structs, startup vector tables, linker scripts
- **integration_test/**: Host-side integration tests (GoogleTest)
- **examples/**: Reference applications (blink, terminal, FreeRTOS)
Expand Down Expand Up @@ -151,7 +152,7 @@ The `+1` is required by `QueueForOneReaderOneIrqWriter` which uses one slot as a
- `hal_tiva.cortex` — Cortex-M core
- `hal_tiva.synchronous_tiva` — Blocking drivers
- `hal_tiva.instantiations` — BSP
- `hal_tiva.default_init` — Startup (linked as object files, not static library)
- `hal_tiva.bringup` — Startup (linked as object files, not static library)
- `ti.hal_driver` — CMSIS device headers and linker scripts

### MCU Family Conditionals
Expand Down
2 changes: 1 addition & 1 deletion .github/prompts/orchestrate.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ argument-hint: "Describe the peripheral driver, ISR, board support, or HAL chang
model: "Claude Sonnet 4.6"
---

Analyze the following task for the **hal-ti** project — a Hardware Abstraction Layer for TI ARM Cortex-M microcontrollers (TM4C123 and TM4C129). Gather relevant context from the codebase — identify the affected layer (`hal_tiva/tiva/`, `hal_tiva/synchronous_tiva/`, `hal_tiva/cortex/`, `hal_tiva/instantiations/`, `tiva/CMSIS/`), the MCU family (TM4C123 / TM4C129 / both), whether ISR handling is involved (vector table hygiene, ISR-safe data transfer), and any documentation requirements. Then provide a brief scope summary and use the handoff buttons to route to the appropriate specialist:
Analyze the following task for the **hal-ti** project — a Hardware Abstraction Layer for TI ARM Cortex-M microcontrollers (TM4C123 and TM4C129). Gather relevant context from the codebase — identify the affected layer (`hal_tiva/tiva/`, `hal_tiva/synchronous_tiva/`, `hal_tiva/{Reset,SystemTick,SystemTickTimerService,TimeKeeper}`, `hal_tiva/instantiations/`, `tiva/CMSIS/`), the MCU family (TM4C123 / TM4C129 / both), whether ISR handling is involved (vector table hygiene, ISR-safe data transfer), and any documentation requirements. Then provide a brief scope summary and use the handoff buttons to route to the appropriate specialist:

- **Plan Implementation**: For new peripheral drivers, new interrupt handlers, new BSP targets, or multi-file changes needing careful register-sequence design
- **Execute Directly**: For straightforward bug fixes, register corrections, or small changes with a clear path
Expand Down
80 changes: 80 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# hal-ti — Agent Rules (canonical)

Single source of truth for **Claude, Copilot, and sub-agents**. `CLAUDE.md` points here. Detailed C++ coding rules: `.github/instructions/hal-ti-cpp.instructions.md` (binding for all `*.hpp/*.cpp` changes). Full pattern reference with common pitfalls: `.github/copilot-instructions.md`. Copilot custom agents: `.github/agents/`. Build presets: `CMakePresets.json`.

hal-ti is a Hardware Abstraction Layer for TI ARM Cortex-M microcontrollers (TM4C123 and TM4C129 families), implementing [embedded-infra-lib](https://github.com/embedded-pro/embedded-infra-lib) (EMIL) HAL interfaces over TI Tiva C peripherals, for strict realtime/memory-constrained applications (BLDC/PMSM motor control and similar).

## Architecture

- `hal_tiva/{Reset,SystemTick,SystemTickTimerService,TimeKeeper}.{hpp,cpp}` — generic ARM Cortex-M core services, kept local only until EMIL hosts family-agnostic equivalents under `hal/cortex_m/` (tracked upstream; `hal::cortex::InterruptTable`/`InterruptHandler`/`DataWatchpointAndTrace`/`EventDispatcher` already come from EMIL directly, not from this repo)
- `hal_tiva/tiva/` — TM4C peripheral drivers (Gpio, Uart, Can, Adc, SpiMaster, Pwm, Dma, Eeprom, Ethernet, AnalogComparator, Clock), namespace `hal::tiva`
- `hal_tiva/synchronous_tiva/` — Blocking/polling driver variants (`SynchronousUart`, `SynchronousQuadratureEncoder`, …)
- `hal_tiva/instantiations/` — Board support packages and event infrastructure (`LaunchPadBsp`, `EventInfrastructure`, `TracingReset`)
- `hal_tiva/bringup/` — Startup glue: `HardwareInitialization()` (constructs the interrupt table + default GPIO pinout) and the weak `Default_Handler_Forwarded()`. Generic runtime (atomics shim, `abort`/`__assert_func`, libc syscall stubs) comes from EMIL's `hal.cortex_m.runtime`, not from this repo.
- `tiva/CMSIS/Device/TI/` — CMSIS device headers, startup vector tables (`startup_TM4C123.c`, `startup_TM4C129.c`), linker scripts
- `integration_test/` — Host-side integration tests (GoogleTest)
- `examples/` — Reference applications (`blink`, `terminal_and_peripherals`, `terminal_uart_with_dma`, `freertos`)
- `doc/` — Board-specific documentation

## Memory — no heap

This is a driver library for constrained MCUs running realtime motor control. Forbidden everywhere: `new`/`delete`/`malloc`/`free`, `make_unique`/`make_shared`, `std::vector`/`string`/`deque`/`list`/`map`/`set`. No recursion in driver code — stack depth must be statically bounded.

Use: `infra::BoundedVector<T>`, `infra::BoundedString`, `infra::WithStorage<Base, StorageType>`, `std::array<T,N>`, `std::optional<T>`.

## ISR safety — critical

- Nothing inside an ISR allocates, blocks, or locks a mutex
- ISR-to-main data transfer: `infra::QueueForOneReaderOneIrqWriter<T>` only — `T` must satisfy `std::is_trivial` (plain POD struct with fixed-size array members; no `BoundedVector`, no user-declared constructors)
- `infra::BoundedDeque` is **not** ISR-safe across the ISR/main boundary
- Shared flags written in ISR and read in main must be `volatile` (or `std::atomic`)
- Always `NVIC_ClearPendingIRQ` before `NVIC_EnableIRQ`; clear interrupt status bits before returning from an ISR

## Peripheral driver conventions

Full detail lives in `.github/instructions/hal-ti-cpp.instructions.md` and `.github/copilot-instructions.md` — read them before touching driver code. Key points:

- Constructor body: `EnableClock()` first (`SYSCTL->RCGCxxx |= bit`, then poll `SYSCTL->PRxxx` until ready — never a fixed NOP delay), then register configuration, then `NVIC_ClearPendingIRQ` + `NVIC_EnableIRQ` last
- Destructor body (reverse order): `NVIC_DisableIRQ` before `DisableClock()`
- `PeripheralPin` members are constructed in the initializer list, before the constructor body runs
- Interrupt handlers: inherit `hal::cortex::ImmediateInterruptHandler` (single-vector, ISR-context processing) or `hal::cortex::DispatchedInterruptHandler` (deferred to main); never call `NVIC_EnableIRQ` directly — use `Register()`
- Vector table hygiene: every new ISR handler needs an `extern "C"` handler in the driver `.cpp`, a weak alias in **both** `startup_TM4C123.c` and `startup_TM4C129.c`, and the corresponding vector table slot updated in both files — missing any step means the interrupt silently falls through to `Default_Handler` on real hardware
- MCU family conditionals: use CMake generator expressions (`$<$<STREQUAL:${TARGET_MCU_FAMILY},TM4C123>:...>`), never `#ifdef TM4C123`/`#ifdef TM4C129` in C++

## Style

- Allman braces, 4-space indent, `.clang-format` authoritative
- PascalCase types/methods, camelCase members/locals; `const`-correct on all observer/query methods; `constexpr` for compile-time constants
- Fixed-size types (`uint8_t`, `uint32_t`, …) over `int`
- **No comments** except non-obvious *why*. No `TODO`/`FIXME`/`HACK`, no commented-out code
- No C-style casts — `static_cast<>`; `reinterpret_cast<>` only where raw register/void-pointer access requires it

## Interfaces & errors

- Interfaces = pure virtual; `virtual ~I() = default` — never `= 0` destructors
- No exceptions. `std::optional<T>` or status enums for fallible operations
- No global mutable state — driver state lives in class members

## Testing

`integration_test/` runs GoogleTest on the host build (`HAL_TI_BUILD_TESTS`) — this is host-side interface/logic testing, not hardware-in-the-loop. There is no on-target test suite; hardware validation is manual (LaunchPad boards, logic analyser/scope). Don't add new unit tests for driver register-sequence changes that can only be verified on real hardware.

## Build

hal-ti cannot be built standalone as a deployable target; it's consumed as a dependency by a larger project (e.g. a motor-control application), but the host preset builds and tests it directly:

```bash
cmake --preset host
cmake --build --preset host-Debug
ctest --preset host
```

## Dependency: EMIL (embedded-infra-lib)

Pulled via `FetchContent` in the top-level `CMakeLists.txt`, pinned to a specific commit (`GIT_TAG`), auto-bumped by `.github/workflows/update-emil-git-tag.yml`. `hal::cortex::*` (InterruptTable, InterruptHandler, DataWatchpointAndTrace, FaultTracer) and the generic runtime (`hal.cortex_m.runtime`: atomics shim, syscall stubs, `abort`/`__assert_func`) come from EMIL, not from this repo — don't reintroduce local copies of these.

## Assistant behavior — be terse

- Minimal prose. No preamble/postamble, no restating the plan, no summaries unless asked
- Report results as file paths + build pass/fail
- Don't re-read files already read; batch reads; prefer targeted edits
Loading
Loading