diff --git a/.claude/agents/orchestrator.md b/.claude/agents/orchestrator.md index 7949ca6..095640f 100644 --- a/.claude/agents/orchestrator.md +++ b/.claude/agents/orchestrator.md @@ -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)? diff --git a/.claude/agents/reviewer.md b/.claude/agents/reviewer.md index eee39d1..9243c33 100644 --- a/.claude/agents/reviewer.md +++ b/.claude/agents/reviewer.md @@ -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 diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..90c1b37 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,7 @@ +{ + "permissions": { + "allow": [ + "Bash(*)" + ] + } +} diff --git a/.github/agents/orchestrator.agent.md b/.github/agents/orchestrator.agent.md index 2dd423b..a3621b1 100644 --- a/.github/agents/orchestrator.agent.md +++ b/.github/agents/orchestrator.agent.md @@ -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)? @@ -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/) diff --git a/.github/agents/reviewer.agent.md b/.github/agents/reviewer.agent.md index d2f779b..87f2690 100644 --- a/.github/agents/reviewer.agent.md +++ b/.github/agents/reviewer.agent.md @@ -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 diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 705edbd..5817b37 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -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) @@ -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 diff --git a/.github/prompts/orchestrate.prompt.md b/.github/prompts/orchestrate.prompt.md index cc7660a..1bb00ec 100644 --- a/.github/prompts/orchestrate.prompt.md +++ b/.github/prompts/orchestrate.prompt.md @@ -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 diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..ce8328e --- /dev/null +++ b/AGENTS.md @@ -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`, `infra::BoundedString`, `infra::WithStorage`, `std::array`, `std::optional`. + +## ISR safety — critical + +- Nothing inside an ISR allocates, blocks, or locks a mutex +- ISR-to-main data transfer: `infra::QueueForOneReaderOneIrqWriter` 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 (`$<$:...>`), 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` 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 `$` 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 diff --git a/CLAUDE.md b/CLAUDE.md index 1015f68..4582955 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,92 +1,13 @@ -# hal-ti +# hal-ti — Claude Instructions -Hardware Abstraction Layer for TI ARM Cortex-M microcontrollers (TM4C123 and TM4C129 families), implementing `embedded-infra-lib` HAL interfaces over TI Tiva C peripherals for real-time motor control and similar embedded applications. +Canonical rules: [AGENTS.md](AGENTS.md) (shared with Copilot and sub-agents). C++ coding detail: [.github/instructions/hal-ti-cpp.instructions.md](.github/instructions/hal-ti-cpp.instructions.md). Full pattern reference: [.github/copilot-instructions.md](.github/copilot-instructions.md). Copilot agents: [.github/agents/](.github/agents/). Build presets: [CMakePresets.json](CMakePresets.json). -## Detailed Guidelines +Essentials (full detail in AGENTS.md): -- Coding rules (applies to all `*.hpp`/`*.cpp`): [.github/instructions/hal-ti-cpp.instructions.md](.github/instructions/hal-ti-cpp.instructions.md) -- Full reference with patterns and common pitfalls: [.github/copilot-instructions.md](.github/copilot-instructions.md) - -## Repository Structure - -| Path | Contents | -|------------------------------|-----------------------------------------------------------------------------| -| `hal_tiva/cortex/` | ARM Cortex-M core (InterruptTable, SystemTick, EventDispatcher, Reset, DWT) | -| `hal_tiva/tiva/` | TM4C peripheral drivers (Gpio, Uart, Can, Adc, SpiMaster, Dma, Clock) | -| `hal_tiva/synchronous_tiva/` | Blocking/polling driver variants | -| `hal_tiva/instantiations/` | Board Support Packages (LaunchPadBsp, EventInfrastructure) | -| `hal_tiva/default_init/` | Startup code, atomics shim, hardware init hooks | -| `tiva/CMSIS/Device/TI/` | CMSIS device headers, startup vector tables, linker scripts | -| `integration_test/` | Host-side integration tests (GoogleTest) | -| `examples/` | Reference applications (blink, terminal, FreeRTOS) | -| `doc/` | Board-specific documentation | - -## Critical Constraints - -### No Heap Allocation - -Never use `new`, `delete`, `malloc`, `free`, `std::make_unique`, `std::make_shared`, `std::vector`, `std::string`, `std::deque`, or `std::list`. Use `infra::BoundedVector`, `infra::BoundedString`, `std::array`, and `infra::WithStorage`. No recursion — stack usage must be predictable. - -### ISR Safety - -- Never allocate, block, or lock a mutex inside an ISR -- ISR-to-main transfer: `QueueForOneReaderOneIrqWriter` only — `T` must be `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 accessed from both ISR and main must be `volatile` (or `std::atomic`) -- Always `NVIC_ClearPendingIRQ` before `NVIC_EnableIRQ` -- Clear all interrupt status bits before returning from an ISR - -### Peripheral Lifecycle (Order is Mandatory) - -**Constructor body order:** -1. `EnableClock()` first — sets `SYSCTL->RCGCxxx |= bit`, then polls `SYSCTL->PRxxx` until the peripheral-ready bit is set. Do NOT use `__asm("nop")` delays. -2. Configure peripheral registers -3. `NVIC_ClearPendingIRQ` + `NVIC_EnableIRQ` last - -`PeripheralPin` members are initialized in the C++ initializer list, before the constructor body runs. - -**Destructor body order:** -1. `NVIC_DisableIRQ` first — always before clock disable -2. `DisableClock()` — clears `SYSCTL->RCGCxxx &= ~bit` -3. `PeripheralPin` / `ImmediateInterruptHandler` destructors run automatically - -### Vector Table — Both Startup Files - -Every new ISR handler requires all three steps: -1. `extern "C" void HandlerName()` in driver `.cpp` inside an anonymous namespace, calling `InterruptTable::Instance().Invoke(IRQn)` -2. Weak alias + vector table entry in `tiva/CMSIS/.../startup_TM4C123.c` -3. Weak alias + vector table entry in `tiva/CMSIS/.../startup_TM4C129.c` - -Missing any step → interrupt silently falls through to `Default_Handler` (infinite loop) on hardware. - -## Naming and Style - -- Classes/Methods: `PascalCase`; member variables: `camelCase` -- Namespaces: `hal::tiva`, `hal::cortex`, `instantiations` -- Register bit constants: `constexpr uint32_t` in anonymous namespace -- Allman braces (opening brace on new line), 4-space indent, functions ≤ 50 lines -- `const` on all non-mutating methods; `constexpr` for compile-time constants -- Use fixed-size types: `uint8_t`, `uint32_t`, etc. - -## MCU Family Conditionals - -Use CMake generator expressions for family-specific sources — never `#ifdef` in C++: -```cmake -$<$:ClockTm4c123.cpp> -$<$:ClockTm4c129.cpp> -``` - -## Build Commands - -hal-ti cannot be built standalone; it is consumed as a dependency by a larger project (e.g., e-foc): -```bash -cmake --preset host -cmake --build --preset host-Debug -ctest --preset host-Debug -``` - -## Known Code Inconsistencies - -- `.github/agents/executor.agent.md` previously used a 3-NOP delay (`__asm("nop")`) after `SYSCTL->RCGCxxx |=`. Corrected to `SYSCTL->PRxxx` polling — consistent with the instructions file, planner/reviewer agents, and the actual driver implementations (`UartBase.cpp`, `Can.cpp`). -- `.github/agents/reviewer.agent.md` previously had `model: "GPT-5.4"`. Corrected to `claude-sonnet-4-6`. -- `.github/agents/planner.agent.md` previously had `model: "Claude Opus 4.6"` (non-existent model ID). Corrected to `claude-opus-4-8`. +- No heap — bounded containers / `std::array` / `std::optional`; no recursion in driver code. Applies repo-wide (this is an MCU HAL library for realtime motor control). +- TI Tiva C — `SYSCTL->RCGCxxx` clock-enable then poll `SYSCTL->PRxxx` (never a NOP delay), `NVIC_ClearPendingIRQ` before `NVIC_EnableIRQ`, `hal::cortex::ImmediateInterruptHandler`/`DispatchedInterruptHandler` (from EMIL, not local) for ISRs, both `startup_TM4C123.c` and `startup_TM4C129.c` updated for every new vector. +- EMIL (`embedded-infra-lib`) provides `hal::cortex::*` core services and the generic runtime shim — don't reintroduce local copies of what EMIL already provides. +- Style — Allman braces, 4-space, PascalCase types/methods, camelCase members. No comments except non-obvious why. +- Testing — `integration_test/` GoogleTest runs on the host build; no on-target test suite. Don't add unit tests for driver changes that only real hardware can verify. +- No exceptions — `std::optional`/status enums; interfaces `virtual ~I() = default`. +- Be terse — minimal prose; report file paths + build pass/fail. diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d5631a..cf61a51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ endif() option(CMAKE_COMPILE_WARNING_AS_ERROR "Enable warnings-as-error" ON) option(HAL_TI_BUILD_TESTS "Enable building the tests" Off) -option(HAL_TI_INCLUDE_DEFAULT_INIT "Include default initialization code; turn off when providing custom initialization" ON) +option(HAL_TI_INCLUDE_BRINGUP "Include default bringup code; turn off when providing custom initialization" ON) option(HAL_TI_BUILD_EXAMPLES "Enable build of the examples" OFF) option(HAL_TI_BUILD_EXAMPLES_FREERTOS "Enable build of the FreeRTOS example" OFF) @@ -24,7 +24,7 @@ if (HAL_TI_STANDALONE) FetchContent_Declare( emil GIT_REPOSITORY https://github.com/embedded-pro/embedded-infra-lib.git - GIT_TAG 9c3d4c32bba0123abdc0013b8b9d5aea26e1f103 # Unreleased + GIT_TAG b2ac7ed7f6121f9aa1b1e15a68986af0cfca63de # Unreleased ) add_definitions(-DEMIL_ENABLE_TRACING=1) diff --git a/README.md b/README.md index 1df9b24..4d8780b 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ target_link_libraries(myprogram PUBLIC ) hal_ti_target_default_linker_scripts(myprogram) -hal_ti_target_default_init(myprogram) +hal_ti_target_bringup(myprogram) ``` diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt index b9bfaf1..f102b49 100644 --- a/examples/blink/CMakeLists.txt +++ b/examples/blink/CMakeLists.txt @@ -9,6 +9,6 @@ target_link_libraries(hal_tiva.blink PRIVATE ) hal_ti_target_default_linker_scripts(hal_tiva.blink) -hal_ti_target_default_init(hal_tiva.blink) +hal_ti_target_bringup(hal_tiva.blink) emil_generate_artifacts(TARGET hal_tiva.blink LST MAP BIN HEX) diff --git a/examples/freertos/CMakeLists.txt b/examples/freertos/CMakeLists.txt index a979c20..14822c6 100644 --- a/examples/freertos/CMakeLists.txt +++ b/examples/freertos/CMakeLists.txt @@ -9,6 +9,6 @@ target_link_libraries(hal_tiva.freertos PRIVATE ) hal_ti_target_default_linker_scripts(hal_tiva.freertos) -hal_ti_target_default_init(hal_tiva.freertos) +hal_ti_target_bringup(hal_tiva.freertos) emil_generate_artifacts(TARGET hal_tiva.freertos LST MAP BIN HEX) diff --git a/examples/terminal_and_peripherals/CMakeLists.txt b/examples/terminal_and_peripherals/CMakeLists.txt index da2641c..93634c4 100644 --- a/examples/terminal_and_peripherals/CMakeLists.txt +++ b/examples/terminal_and_peripherals/CMakeLists.txt @@ -9,6 +9,6 @@ target_link_libraries(hal_tiva.terminal_and_peripherals PRIVATE ) hal_ti_target_default_linker_scripts(hal_tiva.terminal_and_peripherals) -hal_ti_target_default_init(hal_tiva.terminal_and_peripherals) +hal_ti_target_bringup(hal_tiva.terminal_and_peripherals) emil_generate_artifacts(TARGET hal_tiva.terminal_and_peripherals LST MAP BIN HEX) diff --git a/examples/terminal_uart_with_dma/CMakeLists.txt b/examples/terminal_uart_with_dma/CMakeLists.txt index f7c28d6..84c8a41 100644 --- a/examples/terminal_uart_with_dma/CMakeLists.txt +++ b/examples/terminal_uart_with_dma/CMakeLists.txt @@ -9,6 +9,6 @@ target_link_libraries(hal_tiva.terminal_uart_with_dma PRIVATE ) hal_ti_target_default_linker_scripts(hal_tiva.terminal_uart_with_dma) -hal_ti_target_default_init(hal_tiva.terminal_uart_with_dma) +hal_ti_target_bringup(hal_tiva.terminal_uart_with_dma) emil_generate_artifacts(TARGET hal_tiva.terminal_uart_with_dma LST MAP BIN HEX) diff --git a/hal_tiva/CMakeLists.txt b/hal_tiva/CMakeLists.txt index bfdd9b8..5363603 100644 --- a/hal_tiva/CMakeLists.txt +++ b/hal_tiva/CMakeLists.txt @@ -1,5 +1,7 @@ -add_subdirectory(cortex) -add_subdirectory(synchronous_tiva) -add_subdirectory(tiva) -add_subdirectory(instantiations) -add_subdirectory(default_init) +add_subdirectory(synchronous_tiva) +add_subdirectory(tiva) +add_subdirectory(instantiations) + +if (HAL_TI_INCLUDE_BRINGUP) + add_subdirectory(bringup) +endif() diff --git a/hal_tiva/bringup/Bringup.cpp b/hal_tiva/bringup/Bringup.cpp new file mode 100644 index 0000000..674db64 --- /dev/null +++ b/hal_tiva/bringup/Bringup.cpp @@ -0,0 +1,24 @@ +#include DEVICE_HEADER +#include "hal/cortex_m/InterruptCortex.hpp" +#include "hal_tiva/tiva/Gpio.hpp" +#if defined(TM4C123) +#include "hal_tiva/tiva/PinoutTableDefaultTm4c123.hpp" +#elif defined(TM4C129) +#include "hal_tiva/tiva/PinoutTableDefaultTm4c129.hpp" +#else +#error "MCU family not defined or invalid [TM4C123 | TM4C129]!" +#endif + +extern "C" +{ + [[gnu::weak]] void Default_Handler_Forwarded() + { + hal::cortex::InterruptTable::Instance().Invoke(hal::cortex::ActiveInterrupt()); + } + + void HardwareInitialization() + { + static hal::cortex::InterruptTable::WithStorage<128> interruptTable; + static hal::tiva::Gpio gpio{ hal::tiva::pinoutTableDefault, hal::tiva::analogTableDefault }; + } +} diff --git a/hal_tiva/bringup/CMakeLists.txt b/hal_tiva/bringup/CMakeLists.txt new file mode 100644 index 0000000..93f7cc1 --- /dev/null +++ b/hal_tiva/bringup/CMakeLists.txt @@ -0,0 +1,38 @@ +add_library(hal_tiva.bringup OBJECT) +emil_build_for(hal_tiva.bringup TARGET_MCU_VENDOR ti PREREQUISITE_BOOL HAL_TI_STANDALONE) + +target_include_directories(hal_tiva.bringup PUBLIC + "$" + "$" +) + +target_link_libraries(hal_tiva.bringup PUBLIC + hal.cortex_m + hal_tiva.tiva + ti.hal_driver +) + +# Assembler does not understand -Werror +set_target_properties(hal_tiva.bringup PROPERTIES COMPILE_WARNING_AS_ERROR Off) + +target_sources(hal_tiva.bringup PRIVATE + Bringup.cpp +) + +if (TARGET_MCU_VENDOR STREQUAL ti) + get_target_property(startup_source ti.hal_driver_${TARGET_MCU_FAMILY} HAL_TI_STARTUP_SOURCE) + + target_sources(hal_tiva.bringup PRIVATE + ${startup_source} + ) +endif() + +function(hal_ti_target_bringup target) + target_link_libraries(${target} PUBLIC + $ + $ + hal.cortex_m + hal_tiva.tiva + ti.hal_driver + ) +endfunction() diff --git a/hal_tiva/cortex/CMakeLists.txt b/hal_tiva/cortex/CMakeLists.txt deleted file mode 100644 index 0e212dc..0000000 --- a/hal_tiva/cortex/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -add_library(hal_tiva.cortex STATIC) -emil_build_for(hal_tiva.cortex TARGET_MCU_VENDOR ti PREREQUISITE_BOOL HAL_TI_STANDALONE) - -target_include_directories(hal_tiva.cortex PUBLIC - "$" - "$" -) - -target_link_libraries(hal_tiva.cortex PUBLIC - hal.interfaces - ti.hal_driver - infra.event -) - -target_sources(hal_tiva.cortex PRIVATE - DataWatchpointAndTrace.hpp - DataWatchpointAndTrace.cpp - EventDispatcherCortex.cpp - EventDispatcherCortex.hpp - InterruptCortex.cpp - InterruptCortex.hpp - Reset.cpp - Reset.hpp - SystemTick.cpp - SystemTick.hpp - SystemTickTimerService.cpp - SystemTickTimerService.hpp - TimeKeeper.cpp - TimeKeeper.hpp -) diff --git a/hal_tiva/cortex/DataWatchpointAndTrace.cpp b/hal_tiva/cortex/DataWatchpointAndTrace.cpp deleted file mode 100644 index 1f101e4..0000000 --- a/hal_tiva/cortex/DataWatchpointAndTrace.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "hal_tiva/cortex/DataWatchpointAndTrace.hpp" - -namespace hal -{ - DataWatchPointAndTrace::DataWatchPointAndTrace() - { - CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - DWT->CYCCNT = 0; - } - - DataWatchPointAndTrace::~DataWatchPointAndTrace() - { - CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; - } - - void DataWatchPointAndTrace::Start() const - { - DWT->CYCCNT = 0; - DWT->CTRL |= DWT_CTRL_CYCEVTENA_Msk; - } - - uint32_t DataWatchPointAndTrace::Stop() const - { - uint32_t cycles = DWT->CYCCNT; - DWT->CTRL &= ~DWT_CTRL_CYCEVTENA_Msk; - return cycles; - } -} diff --git a/hal_tiva/cortex/DataWatchpointAndTrace.hpp b/hal_tiva/cortex/DataWatchpointAndTrace.hpp deleted file mode 100644 index 7061a4c..0000000 --- a/hal_tiva/cortex/DataWatchpointAndTrace.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include DEVICE_HEADER -#include "infra/util/InterfaceConnector.hpp" - -namespace hal -{ - class DataWatchPointAndTrace - : public infra::InterfaceConnector - { - public: - DataWatchPointAndTrace(); - ~DataWatchPointAndTrace(); - - void Start() const; - uint32_t Stop() const; - }; -} diff --git a/hal_tiva/cortex/EventDispatcherCortex.cpp b/hal_tiva/cortex/EventDispatcherCortex.cpp deleted file mode 100644 index 391b3f8..0000000 --- a/hal_tiva/cortex/EventDispatcherCortex.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "hal_tiva/cortex/EventDispatcherCortex.hpp" -#include DEVICE_HEADER - -namespace hal -{ - EventDispatcherCortexWorker::EventDispatcherCortexWorker(infra::MemoryRange, std::atomic>> scheduledActionsStorage) - : infra::EventDispatcherWorkerImpl(scheduledActionsStorage) - {} - - void EventDispatcherCortexWorker::Idle() - { - __DSB(); - __WFE(); - } - - void EventDispatcherCortexWorker::RequestExecution() - { - __DSB(); - __SEV(); - } -} diff --git a/hal_tiva/cortex/EventDispatcherCortex.hpp b/hal_tiva/cortex/EventDispatcherCortex.hpp deleted file mode 100644 index 57abec7..0000000 --- a/hal_tiva/cortex/EventDispatcherCortex.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef HAL_EVENT_DISPATCHER_CORTEX_HPP -#define HAL_EVENT_DISPATCHER_CORTEX_HPP - -#include "infra/event/EventDispatcher.hpp" - -namespace hal -{ - class EventDispatcherCortexWorker - : public infra::EventDispatcherWorkerImpl - { - public: - template - using WithSize = infra::WithStorage, std::atomic>, StorageSize>>; - - EventDispatcherCortexWorker(infra::MemoryRange, std::atomic>> scheduledActionsStorage); - - protected: - virtual void Idle() override; - virtual void RequestExecution() override; - }; - - using EventDispatcherCortex = infra::EventDispatcherConnector; -} - -#endif diff --git a/hal_tiva/cortex/InterruptCortex.cpp b/hal_tiva/cortex/InterruptCortex.cpp deleted file mode 100644 index 60e7fe8..0000000 --- a/hal_tiva/cortex/InterruptCortex.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#include "hal_tiva/cortex/InterruptCortex.hpp" -#include "infra/event/EventDispatcher.hpp" -#include - -namespace hal -{ - namespace - { - constexpr auto invalidIrq = static_cast(-128); - - void EnableInterrupt(IRQn_Type irq, InterruptPriority priority) - { - if (irq >= 0) - { - NVIC_SetPriority(irq, static_cast(priority)); - NVIC_ClearPendingIRQ(irq); - NVIC_EnableIRQ(irq); - } - else if (irq == -13 /*HardFault_IRQn*/) - ; - else if (irq == PendSV_IRQn) - ; - else if (irq == SysTick_IRQn) - { - NVIC_SetPriority(irq, static_cast(InterruptPriority::Normal)); - SysTick->CTRL |= 1 << 1; - } - else - std::abort(); - } - - void DisableInterrupt(IRQn_Type irq) - { - if (irq >= 0) - { - NVIC_DisableIRQ(irq); - } - else if (irq == -13 /*HardFault_IRQn*/) - ; - else if (irq == PendSV_IRQn) - ; - else if (irq == SysTick_IRQn) - { - SysTick->CTRL &= ~(1 << 1); - SCB->ICSR |= 1 << 25; - } - else - std::abort(); - } - } - - IRQn_Type ActiveInterrupt() - { - return static_cast(((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) >> SCB_ICSR_VECTACTIVE_Pos) - 16); - } - - InterruptHandler::InterruptHandler() - {} - - InterruptHandler::InterruptHandler(InterruptHandler&& other) - : irq(other.irq) - { - InterruptTable::Instance().TakeOverHandler(irq, *this, other); - other.irq = invalidIrq; - } - - InterruptHandler& InterruptHandler::operator=(InterruptHandler&& other) - { - if (irq != invalidIrq) - InterruptTable::Instance().DeregisterHandler(irq, *this); - - irq = other.irq; - - InterruptTable::Instance().TakeOverHandler(irq, *this, other); - other.irq = invalidIrq; - - return *this; - } - - InterruptHandler::~InterruptHandler() - { - if (irq != invalidIrq) - InterruptTable::Instance().DeregisterHandler(irq, *this); - } - - void InterruptHandler::Register(IRQn_Type irq, InterruptPriority priority) - { - this->irq = irq; - InterruptTable::Instance().RegisterHandler(this->irq, *this, priority); - } - - void InterruptHandler::Unregister() - { - InterruptTable::Instance().DeregisterHandler(irq, *this); - irq = invalidIrq; - } - - IRQn_Type InterruptHandler::Irq() const - { - return irq; - } - - void InterruptHandler::ClearPending() - { - NVIC_ClearPendingIRQ(irq); - } - - InterruptTable::InterruptTable(infra::MemoryRange table) - : table(table) - { - std::fill(table.begin(), table.end(), nullptr); - } - - void InterruptTable::Invoke(IRQn_Type irq) - { - __DMB(); - if (!table[irq + 16]) - std::abort(); - - table[irq + 16]->Invoke(); - } - - InterruptHandler* InterruptTable::Handler(IRQn_Type irq) - { - return table[irq + 16]; - } - - void InterruptTable::RegisterHandler(IRQn_Type irq, InterruptHandler& handler, InterruptPriority priority) - { - assert(irq + 16 < table.size()); - assert(table[irq + 16] == nullptr); - table[irq + 16] = &handler; - __DSB(); - EnableInterrupt(irq, priority); - } - - void InterruptTable::DeregisterHandler(IRQn_Type irq, InterruptHandler& handler) - { - assert(table[irq + 16] == &handler); - DisableInterrupt(irq); - __DSB(); - table[irq + 16] = nullptr; - } - - void InterruptTable::TakeOverHandler(IRQn_Type irq, InterruptHandler& handler, const InterruptHandler& previous) - { - assert(table[irq + 16] == &previous); - table[irq + 16] = &handler; - __DSB(); - } - - DispatchedInterruptHandler::DispatchedInterruptHandler(IRQn_Type irq, const infra::Function& onInvoke) - : InterruptHandler() - , onInvoke(onInvoke) - { - Register(irq); - } - - DispatchedInterruptHandler::DispatchedInterruptHandler(DispatchedInterruptHandler&& other, const infra::Function& onInvoke) - : InterruptHandler(std::move(other)) - , onInvoke(onInvoke) - {} - - DispatchedInterruptHandler& DispatchedInterruptHandler::Assign(DispatchedInterruptHandler&& other, const infra::Function& onInvoke) - { - InterruptHandler::operator=(std::move(other)); - this->onInvoke = onInvoke; - return *this; - } - - void DispatchedInterruptHandler::Invoke() - { - DisableInterrupt(Irq()); - assert(!pending); - pending = true; - - IRQn_Type irq = Irq(); - DispatchedInterruptHandler& handler = *this; - infra::EventDispatcher::Instance().Schedule([irq, &handler]() - { - InvokeScheduled(irq, handler); - }); - } - - void DispatchedInterruptHandler::SetInvoke(const infra::Function& onInvoke) - { - this->onInvoke = onInvoke; - } - - void DispatchedInterruptHandler::InvokeScheduled(IRQn_Type irq, DispatchedInterruptHandler& handler) - { - if (InterruptTable::Instance().Handler(irq) == &handler) - { - infra::Function invoke = handler.onInvoke; - invoke(); - - if (InterruptTable::Instance().Handler(irq) == &handler) - { - handler.pending = false; - if (handler.onInvoke) - EnableInterrupt(irq, InterruptPriority::Normal); - } - } - } - - ImmediateInterruptHandler::ImmediateInterruptHandler(IRQn_Type irq, const infra::Function& onInvoke) - : InterruptHandler() - , onInvoke(onInvoke) - { - Register(irq); - } - - ImmediateInterruptHandler::ImmediateInterruptHandler(IRQn_Type irq, InterruptPriority priority, const infra::Function& onInvoke) - : InterruptHandler() - , onInvoke(onInvoke) - { - Register(irq, priority); - } - - ImmediateInterruptHandler::ImmediateInterruptHandler(ImmediateInterruptHandler&& other, const infra::Function& onInvoke) - : InterruptHandler(std::move(other)) - , onInvoke(onInvoke) - {} - - ImmediateInterruptHandler& ImmediateInterruptHandler::Assign(ImmediateInterruptHandler&& other, const infra::Function& onInvoke) - { - InterruptHandler::operator=(std::move(other)); - this->onInvoke = onInvoke; - return *this; - } - - void ImmediateInterruptHandler::Invoke() - { - auto expect = false; - - if (processingInterrupt.compare_exchange_strong(expect, true, std::memory_order_acquire)) - { - __DSB(); - onInvoke(); - __DSB(); - - processingInterrupt.store(false, std::memory_order_release); - } - else - NVIC_SetPendingIRQ(Irq()); - } -} diff --git a/hal_tiva/cortex/InterruptCortex.hpp b/hal_tiva/cortex/InterruptCortex.hpp deleted file mode 100644 index 5772c03..0000000 --- a/hal_tiva/cortex/InterruptCortex.hpp +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef HAL_INTERRUPT_CORTEX_HPP -#define HAL_INTERRUPT_CORTEX_HPP - -#include DEVICE_HEADER -#include "infra/util/Function.hpp" -#include "infra/util/InterfaceConnector.hpp" -#include "infra/util/MemoryRange.hpp" -#include "infra/util/WithStorage.hpp" -#include -#include - -namespace hal -{ - enum class InterruptPriority : uint8_t - { - // Critical system priorities - Highest = 0, // Highest priority, use sparingly for critical real-time tasks - VeryHigh = 1, // Very high priority for urgent time-critical tasks - High = 2, // High priority for important but not critical tasks - - // Normal application priorities - AboveNormal = 3, // Above normal priority - Normal = 4, // Default priority for most interrupts - BelowNormal = 5, // Below normal priority - - // Background task priorities - Low = 6, // Low priority for non-urgent interrupts - VeryLow = 7, // Very low priority for background processing - Lowest = 15, // Lowest possible priority - - // Aliases for backward compatibility - Default = Normal, - Background = Low - }; - - IRQn_Type ActiveInterrupt(); - - class InterruptHandler - { - protected: - InterruptHandler(); - InterruptHandler(const InterruptHandler& other) = delete; - InterruptHandler(InterruptHandler&& other); - InterruptHandler& operator=(const InterruptHandler& other) = delete; - InterruptHandler& operator=(InterruptHandler&& other); - ~InterruptHandler(); - - public: - void Register(IRQn_Type irq, InterruptPriority priority = InterruptPriority::Normal); - void Unregister(); - virtual void Invoke() = 0; - - IRQn_Type Irq() const; - - void ClearPending(); - - private: - IRQn_Type irq; - }; - - class InterruptTable - : public infra::InterfaceConnector - { - public: - template - using WithStorage = infra::WithStorage>; - - InterruptTable(infra::MemoryRange table); - - void Invoke(IRQn_Type irq); - InterruptHandler* Handler(IRQn_Type irq); - - private: - friend class InterruptHandler; - - void RegisterHandler(IRQn_Type irq, InterruptHandler& handler, InterruptPriority priority); - void DeregisterHandler(IRQn_Type irq, InterruptHandler& handler); - void TakeOverHandler(IRQn_Type irq, InterruptHandler& handler, const InterruptHandler& previous); - - private: - infra::MemoryRange table; - }; - - class DispatchedInterruptHandler - : public InterruptHandler - { - public: - DispatchedInterruptHandler(IRQn_Type irq, const infra::Function& onInvoke); - DispatchedInterruptHandler(const DispatchedInterruptHandler& other) = delete; - DispatchedInterruptHandler(DispatchedInterruptHandler&& other) = delete; - DispatchedInterruptHandler(DispatchedInterruptHandler&& other, const infra::Function& onInvoke); - DispatchedInterruptHandler& operator=(const DispatchedInterruptHandler& other) = delete; - DispatchedInterruptHandler& operator=(DispatchedInterruptHandler&& other) = delete; - DispatchedInterruptHandler& Assign(DispatchedInterruptHandler&& other, const infra::Function& onInvoke); - - virtual void Invoke() final; - void SetInvoke(const infra::Function& onInvoke); - - private: - static void InvokeScheduled(IRQn_Type irq, DispatchedInterruptHandler& handler); - - private: - infra::Function onInvoke; - bool pending = false; - }; - - class ImmediateInterruptHandler - : public InterruptHandler - { - public: - ImmediateInterruptHandler(IRQn_Type irq, const infra::Function& onInvoke); - ImmediateInterruptHandler(IRQn_Type irq, InterruptPriority priority, const infra::Function& onInvoke); - ImmediateInterruptHandler(const ImmediateInterruptHandler& other) = delete; - ImmediateInterruptHandler(ImmediateInterruptHandler&& other) = delete; - ImmediateInterruptHandler(ImmediateInterruptHandler&& other, const infra::Function& onInvoke); - ImmediateInterruptHandler& operator=(const ImmediateInterruptHandler& other) = delete; - ImmediateInterruptHandler& operator=(ImmediateInterruptHandler&& other) = delete; - ImmediateInterruptHandler& Assign(ImmediateInterruptHandler&& other, const infra::Function& onInvoke); - - virtual void Invoke() final; - - private: - infra::Function onInvoke; - // Indicates whether an interrupt is currently being processed. - // Used to prevent reentrant interrupt handling by ensuring that - // an interrupt is not processed again while it is already being handled. - std::atomic processingInterrupt{ false }; - }; -} - -#endif diff --git a/hal_tiva/cortex/Reset.cpp b/hal_tiva/cortex/Reset.cpp deleted file mode 100644 index b1e31ef..0000000 --- a/hal_tiva/cortex/Reset.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "hal_tiva/cortex/Reset.hpp" -#include DEVICE_HEADER - -namespace hal::cortex -{ - void Reset::ResetModule(const char* resetReason) - { - NVIC_SystemReset(); - } -} diff --git a/hal_tiva/cortex/Reset.hpp b/hal_tiva/cortex/Reset.hpp deleted file mode 100644 index c4c07b4..0000000 --- a/hal_tiva/cortex/Reset.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef HAL_RESET_TIVA_HPP -#define HAL_RESET_TIVA_HPP - -#include "hal/interfaces/Reset.hpp" - -namespace hal::cortex -{ - class Reset - : public hal::Reset - { - public: - virtual void ResetModule(const char* resetReason) override; - }; -} - -#endif diff --git a/hal_tiva/cortex/SystemTick.cpp b/hal_tiva/cortex/SystemTick.cpp deleted file mode 100644 index 395d288..0000000 --- a/hal_tiva/cortex/SystemTick.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "hal_tiva/cortex/SystemTick.hpp" -#include DEVICE_HEADER - -namespace hal::cortex -{ - SystemTick::SystemTick(const infra::Function& callback, infra::Duration tickDuration) - : callback(callback) - { - Register(SysTick_IRQn); - SysTick->LOAD = SystemCoreClock / (1000000000 / std::chrono::duration_cast(tickDuration).count()) - 1ul; - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; - SysTick->VAL = 0; - } - - void SystemTick::Invoke() - { - callback(); - } -} diff --git a/hal_tiva/cortex/SystemTick.hpp b/hal_tiva/cortex/SystemTick.hpp deleted file mode 100644 index e12e1e1..0000000 --- a/hal_tiva/cortex/SystemTick.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef HAL_TI_SYSTEM_TICK_TIVA_HPP -#define HAL_TI_SYSTEM_TICK_TIVA_HPP - -#include "hal_tiva/cortex/InterruptCortex.hpp" -#include "infra/timer/Timer.hpp" - -namespace hal::cortex -{ - class SystemTick - : private InterruptHandler - { - public: - SystemTick(const infra::Function& callback, infra::Duration tickDuration = std::chrono::milliseconds(1)); - - private: - void Invoke() override; - - private: - infra::Function callback; - }; -} - -#endif diff --git a/hal_tiva/cortex/SystemTickTimerService.cpp b/hal_tiva/cortex/SystemTickTimerService.cpp deleted file mode 100644 index d0174ac..0000000 --- a/hal_tiva/cortex/SystemTickTimerService.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "hal_tiva/cortex/SystemTickTimerService.hpp" -#include DEVICE_HEADER -#include "hal/interfaces/Gpio.hpp" - -extern uint32_t SystemCoreClock; - -namespace hal::cortex -{ - SystemTickTimerService::SystemTickTimerService(infra::Duration tickDuration, uint32_t id) - : infra::TickOnInterruptTimerService(id, tickDuration) - { - Register(SysTick_IRQn); - SysTick->LOAD = SystemCoreClock / (1000000000 / std::chrono::duration_cast(tickDuration).count()) - 1ul; - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; - SysTick->VAL = 0; - } - - infra::TimePoint SystemTickTimerService::Now() const - { - infra::TimePoint now; - uint32_t adjust; - - do - { - static_cast(SysTick->CTRL); - now = infra::TickOnInterruptTimerService::Now(); - adjust = SysTick->LOAD - SysTick->VAL; - } while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == SysTick_CTRL_COUNTFLAG_Msk); - - return now + std::chrono::nanoseconds(static_cast(adjust) * 1000000000 / SystemCoreClock); - } - - void SystemTickTimerService::Invoke() - { - SystemTickInterrupt(); - } -} - -extern "C" uint32_t HAL_GetTick() -{ - if (hal::cortex::SystemTickTimerService::InstanceSet()) - return std::chrono::duration_cast(hal::cortex::SystemTickTimerService::Instance().Now().time_since_epoch()).count(); - else - return 0; -} diff --git a/hal_tiva/cortex/SystemTickTimerService.hpp b/hal_tiva/cortex/SystemTickTimerService.hpp deleted file mode 100644 index 4ed7bba..0000000 --- a/hal_tiva/cortex/SystemTickTimerService.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef HAL_TI_SYSTEM_TICK_TIMER_SERVICE_HPP -#define HAL_TI_SYSTEM_TICK_TIMER_SERVICE_HPP - -#include "hal_tiva/cortex/InterruptCortex.hpp" -#include "infra/timer/TickOnInterruptTimerService.hpp" -#include "infra/util/InterfaceConnector.hpp" -#include - -extern "C" uint32_t HAL_GetTick(); - -namespace hal::cortex -{ - class SystemTickTimerService - : public infra::InterfaceConnector - , public infra::TickOnInterruptTimerService - , private InterruptHandler - { - public: - SystemTickTimerService(infra::Duration tickDuration = std::chrono::milliseconds(1), uint32_t id = infra::systemTimerServiceId); - - infra::TimePoint Now() const override; - - private: - friend uint32_t HAL_GetTick(); - - void Invoke() override; - }; -} - -#endif diff --git a/hal_tiva/cortex/TimeKeeper.cpp b/hal_tiva/cortex/TimeKeeper.cpp deleted file mode 100644 index b8efd08..0000000 --- a/hal_tiva/cortex/TimeKeeper.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "hal_tiva/cortex/TimeKeeper.hpp" - -namespace hal::cortex -{ - TimeKeeper::TimeKeeper(infra::Duration duration, SystemTickTimerService& timeService) - : duration(duration) - , timeService(timeService) - { - Reset(); - } - - bool TimeKeeper::Timeout() - { - return timeService.Now() > endTime; - } - - void TimeKeeper::Reset() - { - endTime = timeService.Now() + duration; - } -} diff --git a/hal_tiva/cortex/TimeKeeper.hpp b/hal_tiva/cortex/TimeKeeper.hpp deleted file mode 100644 index e4cd2ce..0000000 --- a/hal_tiva/cortex/TimeKeeper.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef CORTEX_TIME_KEEPER_HPP -#define CORTEX_TIME_KEEPER_HPP - -#include "hal/synchronous_interfaces/TimeKeeper.hpp" -#include "hal/synchronous_interfaces/TimeService.hpp" -#include "hal_tiva/cortex/SystemTickTimerService.hpp" - -namespace hal::cortex -{ - class TimeKeeper - : public hal::TimeKeeper - { - public: - explicit TimeKeeper(infra::Duration duration, SystemTickTimerService& timeService); - - virtual bool Timeout() override; - virtual void Reset() override; - - private: - const infra::Duration duration; - SystemTickTimerService& timeService; - infra::TimePoint endTime; - }; -} - -#endif diff --git a/hal_tiva/default_init/Atomic.cpp b/hal_tiva/default_init/Atomic.cpp deleted file mode 100644 index d1c2d57..0000000 --- a/hal_tiva/default_init/Atomic.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include DEVICE_HEADER - -extern "C" -{ - unsigned char __attribute__((used)) __atomic_exchange_1(volatile void* mem, unsigned char val, int model) - { - __disable_irq(); - __DSB(); - - unsigned char result = *reinterpret_cast(mem); - *reinterpret_cast(mem) = val; - - __DSB(); - __enable_irq(); - - return result; - } - - unsigned int __attribute__((used)) __atomic_exchange_4(volatile void* mem, unsigned int val, int model) - { - __disable_irq(); - __DSB(); - - unsigned int result = *reinterpret_cast(mem); - *reinterpret_cast(mem) = val; - - __DSB(); - __enable_irq(); - - return result; - } - - bool __attribute__((used)) __atomic_compare_exchange_4(volatile void* mem, void* expected, unsigned int desired, bool weak, int success, int failure) - { - __disable_irq(); - __DSB(); - - if (*reinterpret_cast(mem) == *reinterpret_cast(expected)) - { - *reinterpret_cast(mem) = desired; - __DSB(); - __enable_irq(); - return true; - } - else - { - *reinterpret_cast(expected) = *reinterpret_cast(mem); - __enable_irq(); - return false; - } - } - - unsigned int __attribute__((used)) __atomic_fetch_add_4(volatile void* mem, unsigned int val, int model) - { - __disable_irq(); - __DSB(); - - uint32_t previous = *reinterpret_cast(mem); - *reinterpret_cast(mem) += val; - - __DSB(); - __enable_irq(); - - return previous; - } -} diff --git a/hal_tiva/default_init/CMakeLists.txt b/hal_tiva/default_init/CMakeLists.txt deleted file mode 100644 index 246bfc1..0000000 --- a/hal_tiva/default_init/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -add_library(hal_tiva.default_init STATIC) -emil_build_for(hal_tiva.default_init TARGET_MCU_VENDOR ti PREREQUISITE_BOOL HAL_TI_STANDALONE) - -target_include_directories(hal_tiva.default_init PUBLIC - "$" - "$" -) - -target_link_libraries(hal_tiva.default_init PUBLIC - hal_tiva.cortex - hal_tiva.tiva - ti.hal_driver -) - -# Assembler does not understand -Werror -set_target_properties(hal_tiva.default_init PROPERTIES COMPILE_WARNING_AS_ERROR Off) - -target_sources(hal_tiva.default_init PRIVATE - DefaultInit.cpp -) - -if (TARGET_MCU_VENDOR STREQUAL ti) - get_target_property(startup_source ti.hal_driver_${TARGET_MCU_FAMILY} HAL_TI_STARTUP_SOURCE) - - target_sources(hal_tiva.default_init PRIVATE - ${startup_source} - ) -endif() - -function(hal_ti_target_default_init target) - target_link_libraries(${target} PUBLIC - $ - hal_tiva.cortex - hal_tiva.tiva - ti.hal_driver - ) -endfunction() diff --git a/hal_tiva/default_init/DefaultInit.cpp b/hal_tiva/default_init/DefaultInit.cpp deleted file mode 100644 index f359b94..0000000 --- a/hal_tiva/default_init/DefaultInit.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#include DEVICE_HEADER -#include "hal_tiva/cortex/InterruptCortex.hpp" -#include "hal_tiva/tiva/Gpio.hpp" -#if defined(TM4C123) -#include "hal_tiva/tiva/PinoutTableDefaultTm4c123.hpp" -#elif defined(TM4C129) -#include "hal_tiva/tiva/PinoutTableDefaultTm4c129.hpp" -#else -#error "MCU family not defined or invalid [TM4C123 | TM4C129]!" -#endif -#include -#include -#include - -extern "C" -{ - extern char _Heap_Begin; - extern char _Heap_Limit; - - caddr_t _sbrk(int incr) - { - static char* current_heap_end = &_Heap_Begin; - - char* current_block_address = current_heap_end; - - incr = (incr + 3) & (~3); - if (current_heap_end + incr > &_Heap_Limit) - { - errno = ENOMEM; - return reinterpret_cast(-1); - } - - current_heap_end += incr; - - return static_cast(current_block_address); - } - - [[gnu::weak]] void Default_Handler_Forwarded() - { - hal::InterruptTable::Instance().Invoke(hal::ActiveInterrupt()); - } - - void abort() - { - __BKPT(); - NVIC_SystemReset(); - __builtin_unreachable(); - } - - int _close(int /* fd */) - { - errno = ENOSYS; - return -1; - } - - int _fstat(int /* fd */, struct stat* st) - { - st->st_mode = S_IFCHR; - return 0; - } - - int _isatty(int /* fd */) - { - return 1; - } - - int _lseek(int /* fd */, int /* ptr */, int /* dir */) - { - errno = ENOSYS; - return -1; - } - - int _read(int /* fd */, char* /* ptr */, int /* len */) - { - errno = ENOSYS; - return -1; - } - - int _write(int /* fd */, char* /* ptr */, int /* len */) - { - errno = ENOSYS; - return -1; - } - - void _init() - {} - - void __assert_func(const char*, int, const char*, const char*) - { - std::abort(); - } - - void assert_failed(uint8_t* file, uint32_t line) - { - std::abort(); - } - - void HardwareInitialization() - { - static hal::InterruptTable::WithStorage<128> interruptTable; - static hal::tiva::Gpio gpio{ hal::tiva::pinoutTableDefault, hal::tiva::analogTableDefault }; - } -} diff --git a/hal_tiva/instantiations/CMakeLists.txt b/hal_tiva/instantiations/CMakeLists.txt index 3d266ed..e8e7587 100644 --- a/hal_tiva/instantiations/CMakeLists.txt +++ b/hal_tiva/instantiations/CMakeLists.txt @@ -11,7 +11,7 @@ target_include_directories(hal_tiva.instantiations PUBLIC ) target_link_libraries(hal_tiva.instantiations PUBLIC - hal_tiva.cortex + hal.cortex_m hal_tiva.tiva hal_tiva.synchronous_tiva infra.event diff --git a/hal_tiva/instantiations/EventInfrastructure.cpp b/hal_tiva/instantiations/EventInfrastructure.cpp index c0d69fd..fcbb8ac 100644 --- a/hal_tiva/instantiations/EventInfrastructure.cpp +++ b/hal_tiva/instantiations/EventInfrastructure.cpp @@ -2,9 +2,11 @@ namespace instantiations { - EventInfrastructure::EventInfrastructure(infra::Duration tickDuration) - : systemTick(tickDuration) - {} + EventInfrastructure::EventInfrastructure(infra::Duration tickDuration, uint32_t coreClockHz) + : systemTick(coreClockHz, tickDuration) + { + systemTick.Start(); + } void EventInfrastructure::Run() { diff --git a/hal_tiva/instantiations/EventInfrastructure.hpp b/hal_tiva/instantiations/EventInfrastructure.hpp index 4cdf5ae..aa6ebf0 100644 --- a/hal_tiva/instantiations/EventInfrastructure.hpp +++ b/hal_tiva/instantiations/EventInfrastructure.hpp @@ -1,14 +1,16 @@ #ifndef HAL_TI_EVENT_INFRASTRUCTURE_HPP #define HAL_TI_EVENT_INFRASTRUCTURE_HPP -#include "hal_tiva/cortex/SystemTickTimerService.hpp" +#include "hal/cortex_m/SystemTickTimerService.hpp" #include "infra/event/EventDispatcherWithWeakPtr.hpp" +extern "C" uint32_t SystemCoreClock; + namespace instantiations { struct EventInfrastructure { - explicit EventInfrastructure(infra::Duration tickDuration = std::chrono::milliseconds(1)); + explicit EventInfrastructure(infra::Duration tickDuration = std::chrono::milliseconds(1), uint32_t coreClockHz = SystemCoreClock); void Run(); diff --git a/hal_tiva/instantiations/TracingReset.hpp b/hal_tiva/instantiations/TracingReset.hpp index bbc1733..c0ccaca 100644 --- a/hal_tiva/instantiations/TracingReset.hpp +++ b/hal_tiva/instantiations/TracingReset.hpp @@ -1,7 +1,7 @@ #ifndef HAL_TI_TRACING_RESET_HPP #define HAL_TI_TRACING_RESET_HPP -#include "hal_tiva/cortex/Reset.hpp" +#include "hal/cortex_m/Reset.hpp" #include "services/tracer/TracingReset.hpp" namespace instatiations diff --git a/hal_tiva/instantiations/lwip/CMakeLists.txt b/hal_tiva/instantiations/lwip/CMakeLists.txt index 7b0604e..6308d68 100644 --- a/hal_tiva/instantiations/lwip/CMakeLists.txt +++ b/hal_tiva/instantiations/lwip/CMakeLists.txt @@ -7,7 +7,7 @@ target_include_directories(hal_tiva.instantiations.lwip PUBLIC ) target_link_libraries(hal_tiva.instantiations.lwip PUBLIC - hal_tiva.cortex + hal.cortex_m hal_tiva.tiva hal_tiva.synchronous_tiva infra.event diff --git a/hal_tiva/synchronous_tiva/SynchronousQuadratureEncoder.cpp b/hal_tiva/synchronous_tiva/SynchronousQuadratureEncoder.cpp index 1bebf8b..56c05ec 100644 --- a/hal_tiva/synchronous_tiva/SynchronousQuadratureEncoder.cpp +++ b/hal_tiva/synchronous_tiva/SynchronousQuadratureEncoder.cpp @@ -77,7 +77,7 @@ namespace hal::tiva #endif } }; - constexpr std::array peripheralIrqQeiArray = { { + constexpr std::array peripheralIrqQeiArray = { { QEI0_IRQn, #if defined(TM4C123) QEI1_IRQn, diff --git a/hal_tiva/synchronous_tiva/SynchronousQuadratureEncoder.hpp b/hal_tiva/synchronous_tiva/SynchronousQuadratureEncoder.hpp index 8c78a18..62e9da5 100644 --- a/hal_tiva/synchronous_tiva/SynchronousQuadratureEncoder.hpp +++ b/hal_tiva/synchronous_tiva/SynchronousQuadratureEncoder.hpp @@ -2,7 +2,7 @@ #define HAL_QUADRATURE_ENCODER_TIVA_HPP #include "hal/synchronous_interfaces/SynchronousQuadratureEncoder.hpp" -#include "hal_tiva/cortex/InterruptCortex.hpp" +#include "hal/cortex_m/InterruptCortex.hpp" #include "hal_tiva/tiva/Gpio.hpp" #include "infra/util/Function.hpp" #include @@ -76,10 +76,10 @@ namespace hal::tiva PeripheralPin index; infra::MemoryRange qeiArray; - infra::MemoryRange irqArray; + infra::MemoryRange irqArray; infra::Function onDirectionChange; - std::optional qeiInterruptRegistration; + std::optional qeiInterruptRegistration; }; } diff --git a/hal_tiva/synchronous_tiva/SynchronousUart.hpp b/hal_tiva/synchronous_tiva/SynchronousUart.hpp index aeb480c..a5063f6 100644 --- a/hal_tiva/synchronous_tiva/SynchronousUart.hpp +++ b/hal_tiva/synchronous_tiva/SynchronousUart.hpp @@ -3,7 +3,7 @@ #include "hal/synchronous_interfaces/SynchronousSerialCommunication.hpp" #include "hal/synchronous_interfaces/TimeKeeper.hpp" -#include "hal_tiva/cortex/InterruptCortex.hpp" +#include "hal/cortex_m/InterruptCortex.hpp" #include "hal_tiva/tiva/Gpio.hpp" #include "infra/util/WithStorage.hpp" #include @@ -13,7 +13,7 @@ namespace hal::tiva { class SynchronousUart : public SynchronousSerialCommunication - , private InterruptHandler + , private hal::cortex::InterruptHandler { public: struct HwFlowControl diff --git a/hal_tiva/tiva/Adc.cpp b/hal_tiva/tiva/Adc.cpp index 3315f9b..59745ee 100644 --- a/hal_tiva/tiva/Adc.cpp +++ b/hal_tiva/tiva/Adc.cpp @@ -7,42 +7,42 @@ namespace { extern "C" void Adc0Sequence0_Handler() { - hal::InterruptTable::Instance().Invoke(ADC0SS0_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(ADC0SS0_IRQn); } extern "C" void Adc0Sequence1_Handler() { - hal::InterruptTable::Instance().Invoke(ADC0SS1_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(ADC0SS1_IRQn); } extern "C" void Adc0Sequence2_Handler() { - hal::InterruptTable::Instance().Invoke(ADC0SS2_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(ADC0SS2_IRQn); } extern "C" void Adc0Sequence3_Handler() { - hal::InterruptTable::Instance().Invoke(ADC0SS3_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(ADC0SS3_IRQn); } extern "C" void Adc1Sequence0_Handler() { - hal::InterruptTable::Instance().Invoke(ADC1SS0_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(ADC1SS0_IRQn); } extern "C" void Adc1Sequence1_Handler() { - hal::InterruptTable::Instance().Invoke(ADC1SS1_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(ADC1SS1_IRQn); } extern "C" void Adc1Sequence2_Handler() { - hal::InterruptTable::Instance().Invoke(ADC1SS2_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(ADC1SS2_IRQn); } extern "C" void Adc1Sequence3_Handler() { - hal::InterruptTable::Instance().Invoke(ADC1SS3_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(ADC1SS3_IRQn); } constexpr static size_t sequencerOffset = 8; @@ -96,7 +96,7 @@ namespace ADC1_BASE, } }; - constexpr std::array peripheralIrqAdcArray = { { + constexpr std::array peripheralIrqAdcArray = { { ADC0SS0_IRQn, ADC0SS1_IRQn, ADC0SS2_IRQn, diff --git a/hal_tiva/tiva/Adc.hpp b/hal_tiva/tiva/Adc.hpp index 21a0274..f44b6d9 100644 --- a/hal_tiva/tiva/Adc.hpp +++ b/hal_tiva/tiva/Adc.hpp @@ -4,7 +4,7 @@ #include #include DEVICE_HEADER #include "hal/interfaces/AdcMultiChannel.hpp" -#include "hal_tiva/cortex/InterruptCortex.hpp" +#include "hal/cortex_m/InterruptCortex.hpp" #include "hal_tiva/tiva/Gpio.hpp" #include @@ -12,7 +12,7 @@ namespace hal::tiva { class Adc : public hal::AdcMultiChannel - , private hal::ImmediateInterruptHandler + , private hal::cortex::ImmediateInterruptHandler { public: enum class Trigger : uint8_t @@ -97,7 +97,7 @@ namespace hal::tiva std::optional oversampling; std::optional samplingDelay; infra::MemoryRange digitalComparators; - hal::InterruptPriority interruptPriority = hal::InterruptPriority::Normal; + hal::cortex::InterruptPriority interruptPriority = hal::cortex::InterruptPriority::normal; }; Adc(uint8_t adcIndex, uint8_t adcSequencer, infra::MemoryRange inputs, const Config& config); diff --git a/hal_tiva/tiva/AnalogComparator.cpp b/hal_tiva/tiva/AnalogComparator.cpp index fa660f7..277b049 100644 --- a/hal_tiva/tiva/AnalogComparator.cpp +++ b/hal_tiva/tiva/AnalogComparator.cpp @@ -5,29 +5,29 @@ namespace { extern "C" void Comp0_Handler() { - hal::InterruptTable::Instance().Invoke(COMP0_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(COMP0_IRQn); } extern "C" void Comp1_Handler() { - hal::InterruptTable::Instance().Invoke(COMP1_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(COMP1_IRQn); } #if defined(TM4C129) extern "C" void Comp2_Handler() { - hal::InterruptTable::Instance().Invoke(COMP2_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(COMP2_IRQn); } #endif #if defined(TM4C129) - constexpr std::array peripheralIrqComp = { { + constexpr std::array peripheralIrqComp = { { COMP0_IRQn, COMP1_IRQn, COMP2_IRQn, } }; #else - constexpr std::array peripheralIrqComp = { { + constexpr std::array peripheralIrqComp = { { COMP0_IRQn, COMP1_IRQn, } }; diff --git a/hal_tiva/tiva/AnalogComparator.hpp b/hal_tiva/tiva/AnalogComparator.hpp index c17d4fb..f81e593 100644 --- a/hal_tiva/tiva/AnalogComparator.hpp +++ b/hal_tiva/tiva/AnalogComparator.hpp @@ -1,7 +1,7 @@ #pragma once #include "hal/interfaces/AnalogComparator.hpp" -#include "hal_tiva/cortex/InterruptCortex.hpp" +#include "hal/cortex_m/InterruptCortex.hpp" #include "hal_tiva/tiva/Gpio.hpp" #include "infra/util/Function.hpp" #include @@ -66,7 +66,7 @@ namespace hal::tiva std::optional routeToPwmFault; InterruptSense interruptSense = InterruptSense::both; bool interruptLevelHigh = true; - InterruptPriority priority = InterruptPriority::Normal; + hal::cortex::InterruptPriority priority = hal::cortex::InterruptPriority::normal; }; AnalogComparator(uint8_t index, GpioPin& vinPositive, GpioPin& vinNegative, GpioPin& outputPin, const Config& config); @@ -92,7 +92,7 @@ namespace hal::tiva std::optional vinPositivePin; std::optional vinNegativePin; std::optional outputPeripheralPin; - std::optional irqHandler; + std::optional irqHandler; infra::Function onOutputChanged; }; } diff --git a/hal_tiva/tiva/CMakeLists.txt b/hal_tiva/tiva/CMakeLists.txt index 885a165..55c0e76 100644 --- a/hal_tiva/tiva/CMakeLists.txt +++ b/hal_tiva/tiva/CMakeLists.txt @@ -11,7 +11,7 @@ target_link_libraries(hal_tiva.tiva PUBLIC hal.interfaces infra.timer ti.hal_driver - hal_tiva.cortex + hal.cortex_m ) target_sources(hal_tiva.tiva PRIVATE diff --git a/hal_tiva/tiva/Can.cpp b/hal_tiva/tiva/Can.cpp index 7d7f5ec..20ed0ca 100644 --- a/hal_tiva/tiva/Can.cpp +++ b/hal_tiva/tiva/Can.cpp @@ -6,12 +6,12 @@ namespace { extern "C" void Can0_Handler() { - hal::InterruptTable::Instance().Invoke(CAN0_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(CAN0_IRQn); } extern "C" void Can1_Handler() { - hal::InterruptTable::Instance().Invoke(CAN1_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(CAN1_IRQn); } const std::array peripheralCan = { { @@ -19,7 +19,7 @@ namespace reinterpret_cast(CAN1_BASE), } }; - constexpr std::array peripheralIrqCan = { { + constexpr std::array peripheralIrqCan = { { CAN0_IRQn, CAN1_IRQn, } }; @@ -539,7 +539,7 @@ namespace hal::tiva EnterInitMode(can); DisableInterrupts(can); - const auto irq = peripheralIrqCan[canIndex]; + const auto irq = static_cast(peripheralIrqCan[canIndex]); NVIC_DisableIRQ(irq); NVIC_ClearPendingIRQ(irq); diff --git a/hal_tiva/tiva/Can.hpp b/hal_tiva/tiva/Can.hpp index e6545ad..09cb0cb 100644 --- a/hal_tiva/tiva/Can.hpp +++ b/hal_tiva/tiva/Can.hpp @@ -1,7 +1,7 @@ #pragma once #include "hal/interfaces/Can.hpp" -#include "hal_tiva/cortex/InterruptCortex.hpp" +#include "hal/cortex_m/InterruptCortex.hpp" #include "hal_tiva/tiva/Gpio.hpp" #include "infra/event/QueueForOneReaderOneIrqWriter.hpp" #include @@ -22,7 +22,7 @@ namespace hal::tiva class Can : public hal::Can - , private hal::ImmediateInterruptHandler + , private hal::cortex::ImmediateInterruptHandler { public: template @@ -69,7 +69,7 @@ namespace hal::tiva bool autoBusOffRecovery = true; std::variant timing = BitRate{ 1000000 }; std::optional filter; - hal::InterruptPriority interruptPriority = hal::InterruptPriority::Normal; + hal::cortex::InterruptPriority interruptPriority = hal::cortex::InterruptPriority::normal; }; Can(infra::MemoryRange rxStorage, uint8_t canIndex, GpioPin& rxPin, GpioPin& txPin, const Config& config, const infra::Function& onError); diff --git a/hal_tiva/tiva/ClockTm4c123.hpp b/hal_tiva/tiva/ClockTm4c123.hpp index b9a9447..336da50 100644 --- a/hal_tiva/tiva/ClockTm4c123.hpp +++ b/hal_tiva/tiva/ClockTm4c123.hpp @@ -4,11 +4,6 @@ #include DEVICE_HEADER #include -extern "C" -{ - uint32_t HAL_GetTick(void); -} - namespace hal::tiva { enum class crystalFrequency : uint32_t diff --git a/hal_tiva/tiva/ClockTm4c129.hpp b/hal_tiva/tiva/ClockTm4c129.hpp index 3c42873..c6ab24b 100644 --- a/hal_tiva/tiva/ClockTm4c129.hpp +++ b/hal_tiva/tiva/ClockTm4c129.hpp @@ -4,11 +4,6 @@ #include DEVICE_HEADER #include -extern "C" -{ - uint32_t HAL_GetTick(void); -} - namespace hal::tiva { enum class crystalFrequency : uint32_t diff --git a/hal_tiva/tiva/Dma.cpp b/hal_tiva/tiva/Dma.cpp index 5c8b462..fd1fece 100644 --- a/hal_tiva/tiva/Dma.cpp +++ b/hal_tiva/tiva/Dma.cpp @@ -5,7 +5,7 @@ namespace { extern "C" void UdmaError_Handler() { - hal::InterruptTable::Instance().Invoke(UDMAERR_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(UDMAERR_IRQn); } } diff --git a/hal_tiva/tiva/Dma.hpp b/hal_tiva/tiva/Dma.hpp index 90320be..3881bf1 100644 --- a/hal_tiva/tiva/Dma.hpp +++ b/hal_tiva/tiva/Dma.hpp @@ -4,13 +4,13 @@ #include "infra/util/InterfaceConnector.hpp" #include #include DEVICE_HEADER -#include "hal_tiva/cortex/InterruptCortex.hpp" +#include "hal/cortex_m/InterruptCortex.hpp" namespace hal::tiva { class Dma : public infra::InterfaceConnector - , private InterruptHandler + , private hal::cortex::InterruptHandler { public: explicit Dma(const infra::Function& onError); diff --git a/hal_tiva/tiva/Eeprom.cpp b/hal_tiva/tiva/Eeprom.cpp index 231977f..caf321c 100644 --- a/hal_tiva/tiva/Eeprom.cpp +++ b/hal_tiva/tiva/Eeprom.cpp @@ -1,10 +1,9 @@ #include "hal_tiva/tiva/Eeprom.hpp" -#include "hal_tiva/cortex/InterruptCortex.hpp" #include "infra/util/ReallyAssert.hpp" extern "C" void Eeprom_Handler() { - hal::InterruptTable::Instance().Invoke(FLASH_CTRL_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(FLASH_CTRL_IRQn); } namespace diff --git a/hal_tiva/tiva/Eeprom.hpp b/hal_tiva/tiva/Eeprom.hpp index 972fe6b..e89ab4e 100644 --- a/hal_tiva/tiva/Eeprom.hpp +++ b/hal_tiva/tiva/Eeprom.hpp @@ -1,7 +1,8 @@ #pragma once +#include DEVICE_HEADER #include "hal/interfaces/Eeprom.hpp" -#include "hal_tiva/cortex/InterruptCortex.hpp" +#include "hal/cortex_m/InterruptCortex.hpp" #include "infra/timer/Timer.hpp" #include "infra/util/AutoResetFunction.hpp" #include "infra/util/Function.hpp" @@ -11,7 +12,7 @@ namespace hal::tiva { class Eeprom : public hal::Eeprom - , private hal::ImmediateInterruptHandler + , private hal::cortex::ImmediateInterruptHandler { public: Eeprom(); diff --git a/hal_tiva/tiva/Ethernet.hpp b/hal_tiva/tiva/Ethernet.hpp index 087cf5f..dfce37e 100644 --- a/hal_tiva/tiva/Ethernet.hpp +++ b/hal_tiva/tiva/Ethernet.hpp @@ -4,7 +4,7 @@ #include DEVICE_HEADER #include "hal/interfaces/Ethernet.hpp" #include "hal/interfaces/MacAddress.hpp" -#include "hal_tiva/cortex/InterruptCortex.hpp" +#include "hal/cortex_m/InterruptCortex.hpp" #include "hal_tiva/tiva/Gpio.hpp" #include @@ -138,7 +138,7 @@ namespace hal::tiva hal::MacAddress macAddress; uint8_t phyId = 0; volatile bool EEELinkActive = false; - DispatchedInterruptHandler interrupt; + hal::cortex::DispatchedInterruptHandler interrupt; std::optional receiveDescriptors; std::optional sendDescriptors; }; diff --git a/hal_tiva/tiva/Gpio.hpp b/hal_tiva/tiva/Gpio.hpp index 7845ae6..8d84424 100644 --- a/hal_tiva/tiva/Gpio.hpp +++ b/hal_tiva/tiva/Gpio.hpp @@ -3,7 +3,7 @@ #include DEVICE_HEADER #include "hal/interfaces/Gpio.hpp" -#include "hal_tiva/cortex/InterruptCortex.hpp" +#include "hal/cortex_m/InterruptCortex.hpp" #include "infra/util/MemoryRange.hpp" #include @@ -244,12 +244,12 @@ namespace hal::tiva std::array, 8 * 6> handlers; std::array assignedPins; - DispatchedInterruptHandler interruptDispatcherA; - DispatchedInterruptHandler interruptDispatcherB; - DispatchedInterruptHandler interruptDispatcherC; - DispatchedInterruptHandler interruptDispatcherD; - DispatchedInterruptHandler interruptDispatcherE; - DispatchedInterruptHandler interruptDispatcherF; + hal::cortex::DispatchedInterruptHandler interruptDispatcherA; + hal::cortex::DispatchedInterruptHandler interruptDispatcherB; + hal::cortex::DispatchedInterruptHandler interruptDispatcherC; + hal::cortex::DispatchedInterruptHandler interruptDispatcherD; + hal::cortex::DispatchedInterruptHandler interruptDispatcherE; + hal::cortex::DispatchedInterruptHandler interruptDispatcherF; }; } diff --git a/hal_tiva/tiva/Pwm.cpp b/hal_tiva/tiva/Pwm.cpp index ecdfa5d..ca59055 100644 --- a/hal_tiva/tiva/Pwm.cpp +++ b/hal_tiva/tiva/Pwm.cpp @@ -9,53 +9,53 @@ namespace { extern "C" void Pwm0Generator0_Handler() { - hal::InterruptTable::Instance().Invoke(PWM0_0_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(PWM0_0_IRQn); } extern "C" void Pwm0Generator1_Handler() { - hal::InterruptTable::Instance().Invoke(PWM0_1_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(PWM0_1_IRQn); } extern "C" void Pwm0Generator2_Handler() { - hal::InterruptTable::Instance().Invoke(PWM0_2_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(PWM0_2_IRQn); } extern "C" void Pwm0Generator3_Handler() { - hal::InterruptTable::Instance().Invoke(PWM0_3_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(PWM0_3_IRQn); } extern "C" void Pwm0Fault_Handler() { - hal::InterruptTable::Instance().Invoke(PWM0_FAULT_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(PWM0_FAULT_IRQn); } #if defined(TM4C123) extern "C" void Pwm1Generator0_Handler() { - hal::InterruptTable::Instance().Invoke(PWM1_0_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(PWM1_0_IRQn); } extern "C" void Pwm1Generator1_Handler() { - hal::InterruptTable::Instance().Invoke(PWM1_1_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(PWM1_1_IRQn); } extern "C" void Pwm1Generator2_Handler() { - hal::InterruptTable::Instance().Invoke(PWM1_2_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(PWM1_2_IRQn); } extern "C" void Pwm1Generator3_Handler() { - hal::InterruptTable::Instance().Invoke(PWM1_3_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(PWM1_3_IRQn); } extern "C" void Pwm1Fault_Handler() { - hal::InterruptTable::Instance().Invoke(PWM1_FAULT_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(PWM1_FAULT_IRQn); } #endif @@ -78,8 +78,8 @@ namespace struct PwmIrqInfo { - std::array generatorIrqs; - IRQn_Type faultIrq; + std::array generatorIrqs; + int32_t faultIrq; }; constexpr std::array peripheralPwmIrqs = { { @@ -265,7 +265,7 @@ namespace hal::tiva return value & 0x7fffe; } - Pwm::GeneratorInterruptSlot::GeneratorInterruptSlot(Pwm& owner, IRQn_Type irq, hal::InterruptPriority priority, GeneratorIndex gen) + Pwm::GeneratorInterruptSlot::GeneratorInterruptSlot(Pwm& owner, int32_t irq, hal::cortex::InterruptPriority priority, GeneratorIndex gen) : owner(owner) , gen(gen) , handler(irq, priority, [this]() @@ -274,7 +274,7 @@ namespace hal::tiva }) {} - Pwm::FaultInterruptSlot::FaultInterruptSlot(Pwm& owner, IRQn_Type irq, hal::InterruptPriority priority) + Pwm::FaultInterruptSlot::FaultInterruptSlot(Pwm& owner, int32_t irq, hal::cortex::InterruptPriority priority) : owner(owner) , handler(irq, priority, [this]() { diff --git a/hal_tiva/tiva/Pwm.hpp b/hal_tiva/tiva/Pwm.hpp index 7939419..33eec88 100644 --- a/hal_tiva/tiva/Pwm.hpp +++ b/hal_tiva/tiva/Pwm.hpp @@ -1,7 +1,7 @@ #pragma once #include "hal/interfaces/Pwm.hpp" -#include "hal_tiva/cortex/InterruptCortex.hpp" +#include "hal/cortex_m/InterruptCortex.hpp" #include "hal_tiva/tiva/Gpio.hpp" #include "infra/util/BoundedVector.hpp" #include "infra/util/EnumCast.hpp" @@ -97,7 +97,7 @@ namespace hal::tiva infra::BoundedVector::WithMaxSize<4> normalSources; infra::BoundedVector::WithMaxSize<4> faultConfigs; - InterruptPriority priority = InterruptPriority::Normal; + hal::cortex::InterruptPriority priority = hal::cortex::InterruptPriority::normal; }; bool channelAInverted = false; @@ -235,19 +235,19 @@ namespace hal::tiva struct GeneratorInterruptSlot { - GeneratorInterruptSlot(Pwm& owner, IRQn_Type irq, hal::InterruptPriority priority, GeneratorIndex gen); + GeneratorInterruptSlot(Pwm& owner, int32_t irq, hal::cortex::InterruptPriority priority, GeneratorIndex gen); Pwm& owner; GeneratorIndex gen; - hal::ImmediateInterruptHandler handler; + hal::cortex::ImmediateInterruptHandler handler; }; struct FaultInterruptSlot { - FaultInterruptSlot(Pwm& owner, IRQn_Type irq, hal::InterruptPriority priority); + FaultInterruptSlot(Pwm& owner, int32_t irq, hal::cortex::InterruptPriority priority); Pwm& owner; - hal::ImmediateInterruptHandler handler; + hal::cortex::ImmediateInterruptHandler handler; }; uint8_t pwmIndex; diff --git a/hal_tiva/tiva/SpiMaster.cpp b/hal_tiva/tiva/SpiMaster.cpp index 39f2c6a..24dfa3d 100644 --- a/hal_tiva/tiva/SpiMaster.cpp +++ b/hal_tiva/tiva/SpiMaster.cpp @@ -119,7 +119,7 @@ namespace hal::tiva SSI3_BASE, } }; - constexpr std::array peripheralIrqSsiArray = { { + constexpr std::array peripheralIrqSsiArray = { { SSI0_IRQn, SSI1_IRQn, SSI2_IRQn, diff --git a/hal_tiva/tiva/SpiMaster.hpp b/hal_tiva/tiva/SpiMaster.hpp index 6e6da1a..edb39d6 100644 --- a/hal_tiva/tiva/SpiMaster.hpp +++ b/hal_tiva/tiva/SpiMaster.hpp @@ -2,7 +2,7 @@ #define HAL_SPI_MASTER_TIVA_HPP #include "hal/interfaces/Spi.hpp" -#include "hal_tiva/cortex/InterruptCortex.hpp" +#include "hal/cortex_m/InterruptCortex.hpp" #include "hal_tiva/tiva/Gpio.hpp" #include "infra/util/AutoResetFunction.hpp" #include @@ -44,12 +44,12 @@ namespace hal::tiva PeripheralPin slaveSelect; infra::MemoryRange ssiArray; - infra::MemoryRange irqArray; + infra::MemoryRange irqArray; infra::AutoResetFunction onDone; ChipSelectConfigurator* chipSelectConfigurator = nullptr; CommunicationConfigurator* communicationConfigurator = nullptr; - std::optional spiInterruptRegistration; + std::optional spiInterruptRegistration; infra::ConstByteRange sendData; infra::ByteRange receiveData; bool sending; diff --git a/hal_tiva/tiva/UartBase.cpp b/hal_tiva/tiva/UartBase.cpp index 7a5f22b..a08c671 100644 --- a/hal_tiva/tiva/UartBase.cpp +++ b/hal_tiva/tiva/UartBase.cpp @@ -9,42 +9,42 @@ namespace { extern "C" void Uart0_Handler() { - hal::InterruptTable::Instance().Invoke(UART0_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(UART0_IRQn); } extern "C" void Uart1_Handler() { - hal::InterruptTable::Instance().Invoke(UART1_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(UART1_IRQn); } extern "C" void Uart2_Handler() { - hal::InterruptTable::Instance().Invoke(UART2_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(UART2_IRQn); } extern "C" void Uart3_Handler() { - hal::InterruptTable::Instance().Invoke(UART3_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(UART3_IRQn); } extern "C" void Uart4_Handler() { - hal::InterruptTable::Instance().Invoke(UART4_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(UART4_IRQn); } extern "C" void Uart5_Handler() { - hal::InterruptTable::Instance().Invoke(UART5_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(UART5_IRQn); } extern "C" void Uart6_Handler() { - hal::InterruptTable::Instance().Invoke(UART6_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(UART6_IRQn); } extern "C" void Uart7_Handler() { - hal::InterruptTable::Instance().Invoke(UART7_IRQn); + hal::cortex::InterruptTable::Instance().Invoke(UART7_IRQn); } } @@ -126,7 +126,7 @@ namespace hal::tiva UART7_BASE, } }; - constexpr std::array peripheralIrqUartArray{ { + constexpr std::array peripheralIrqUartArray{ { UART0_IRQn, UART1_IRQn, UART2_IRQn, diff --git a/hal_tiva/tiva/UartBase.hpp b/hal_tiva/tiva/UartBase.hpp index a7fd3a1..f4991ca 100644 --- a/hal_tiva/tiva/UartBase.hpp +++ b/hal_tiva/tiva/UartBase.hpp @@ -3,7 +3,7 @@ #include DEVICE_HEADER #include "hal/interfaces/SerialCommunication.hpp" -#include "hal_tiva/cortex/InterruptCortex.hpp" +#include "hal/cortex_m/InterruptCortex.hpp" #include "hal_tiva/tiva/Gpio.hpp" #include @@ -11,7 +11,7 @@ namespace hal::tiva { class UartBase : public hal::SerialCommunication - , protected hal::InterruptHandler + , protected hal::cortex::InterruptHandler { public: enum class Baudrate : uint32_t @@ -64,7 +64,7 @@ namespace hal::tiva , enableRx(enableRx) {} - Config(bool enableTx, bool enableRx, Baudrate baudrate, FlowControl hwFlowControl, Parity parity, StopBits stopbits, NumberOfBytes numberOfBytes, std::optional priority) + Config(bool enableTx, bool enableRx, Baudrate baudrate, FlowControl hwFlowControl, Parity parity, StopBits stopbits, NumberOfBytes numberOfBytes, std::optional priority) : enableTx(enableTx) , enableRx(enableRx) , baudrate(baudrate) @@ -82,7 +82,7 @@ namespace hal::tiva Parity parity = Parity::none; StopBits stopbits = StopBits::one; NumberOfBytes numberOfBytes = NumberOfBytes::_8_bytes; - std::optional priority; + std::optional priority; }; protected: @@ -131,7 +131,7 @@ namespace hal::tiva bool sending = false; infra::MemoryRange uartArray; - infra::MemoryRange irqArray; + infra::MemoryRange irqArray; }; }