Skip to content
Merged
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::cortex::*` — Reset, SystemTick, SystemTickTimerService, TimeKeeper, InterruptTable/InterruptHandler, DataWatchpointAndTrace, EventDispatcher — all from EMIL, not this repo
- `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
7 changes: 7 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"permissions": {
"allow": [
"Bash(*)"
]
}
Comment thread
gabrielfrasantos marked this conversation as resolved.
}
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::cortex::*` — Reset, SystemTick, SystemTickTimerService, TimeKeeper, InterruptTable/InterruptHandler, DataWatchpointAndTrace, EventDispatcher — all from EMIL, not this repo
- `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
9 changes: 5 additions & 4 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::cortex::***: Reset, SystemTick, SystemTickTimerService, TimeKeeper, InterruptTable/InterruptHandler, DataWatchpointAndTrace, EventDispatcher — all from EMIL's `hal/cortex_m/`, not this repo
- **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 @@ -148,10 +149,10 @@ The `+1` is required by `QueueForOneReaderOneIrqWriter` which uses one slot as a
### CMake Targets

- `hal_tiva.tiva` — Peripheral drivers
- `hal_tiva.cortex` — Cortex-M core
- `hal.cortex_m` — Cortex-M core (from EMIL)
- `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/instantiations/`, `tiva/CMSIS/`, or EMIL's `hal::cortex::*`), 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
82 changes: 82 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# 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::cortex::*` — Reset, SystemTick, SystemTickTimerService, TimeKeeper, InterruptTable/InterruptHandler, DataWatchpointAndTrace, EventDispatcher all come from EMIL's `hal/cortex_m/`, not from this repo — hal_tiva/ has no local copies
- `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, Reset, SystemTick, SystemTickTimerService) 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. Note EMIL has no `TimeKeeper` explicitly injecting a `SystemTickTimerService&`; `hal::TimeKeeperGeneric` (`hal/generic/`, built on the ambient `infra::Now()`) is the closest equivalent if a concrete `hal::TimeKeeper` is ever needed here.

`hal_ti_target_bringup()` (in `hal_tiva/bringup/CMakeLists.txt`) must explicitly list `$<TARGET_OBJECTS:hal.cortex_m.runtime>` on any target it's applied to — `hal.cortex_m.runtime` is an EMIL `OBJECT` library, and its object files do **not** propagate through the intermediate `hal.cortex_m` `STATIC` library automatically; omitting it produces link errors for `_sbrk`/`_read`/`_write`/etc. only at the final executable-link step (the host preset can't catch this — `hal.cortex_m` doesn't build there, it needs ARM instructions the host assembler rejects).

## 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