feat(spi): SPI (MibSPI host mode) driver implementation and host unit tests #84

Merged
hoogv merged 1 commit from feat/83-spi-driver into dev 2026-07-23 12:58:03 +00:00
Owner

Description

Adds hal/mss/spi_host/hal_spi_host.c/.h — the SPI driver: MibSPI classic (non-buffered, non-DMA) polling master-mode init (mode 0-3 CPOL/CPHA, prescale clamp), blocking byte-shift write/read via SPIDAT1/SPIBUF, software chip-select via hal_gpio_write(), and the IRQ handler decoding SPIFLG to a weak, application-overridable hal_spi_host_irq_handler() hook. Depends on the already-landed GPIO driver (#75) for chip-select, but only via a FFF fake in the test suite — no real hal_gpio.c linked.

Why

Continues the driver-implementation phase started by GPIO (#75/#76), ESM (#77/#78), UART (#79/#80), and I2C (#81/#82).

Closes #83

Type of Change

  • New feature

Impact Assessment

  • Functional impact: None — self-contained addition alongside the already-landed GPIO/ESM/UART/I2C drivers.
  • Regulatory impact: None.
  • QMS impact: None.
  • Risk impact: No — existing risk coverage sufficient.

Testing

  • CI pipeline passes (compile, unit tests, integration tests, static analysis)
  • Manually tested: built and ran testing/mss/unit/hal_functionality/test_spi_host locally (17 test cases, 87 assertions, all passing) alongside the full existing ctest suite (222/222 passing, no regressions); ran a full MISRA C:2025 pass (0 unsuppressed findings, -DENABLE_SPI_HOST_MODULE added); reformatted and re-verified against the exact clang-format 18.1.3 the CI runner uses; sanity-checked by dropping the - 1U from the PRESCALE field write, confirming the test suite fails (6 assertions), then reverting.
  • No regressions observed in related areas

PR Size

  • XL (> 300 lines) — justification required below

Size justification / exemption (if L or XL):

765 raw lines across 6 files, all hand-reviewed (no mechanically-generated content). Not split further — the driver (hal_spi_host.c/.h, 397 lines) and its comprehensive Catch2 spec (test_spi_host.c, 359 lines, covering all four SPI modes, prescale clamping, and the FFF-faked GPIO chip-select calls) don't decompose into independently-reviewable sub-PRs, same rationale as prior driver PRs (#78, #80, #82).

Checklist

  • Commit messages follow type(scope): description convention with Relates to #<issue> footer
  • PR template filled in completely
  • No unverified external binaries introduced (see QMS-GITFLOW-001 Binary Security section)
  • All commits leave the codebase in a compilable, passing-tests state (Commit Integrity Rule)

Summary

  • hal/mss/spi_host/hal_spi_host.c/.h: SPI driver (mode/prescale init, blocking write/read, software chip-select, IRQ handler) — ported from AWR6xxx_Toolchain's Universal_hal spi_host_iwr68xx.c (itself from the mmWave SDK's MIBSPI_initMaster())
  • Cross-checked the mode-to-PHASE/POLARITY bit mapping against the standard SPI mode table — correct; the prescale formula matches the TRM's SPICLK = VCLK/(PRESCALE+1) relationship, same derivation pattern as UART's baud divisor and I2C's clock divisor
  • testing/mss/unit/hal_functionality/test_spi_host.c (+ CMakeLists.txt): Catch2 functional test suite, using an FFF fake for hal_gpio_write()
  • tools/misra/run_misra.sh: -DENABLE_SPI_HOST_MODULE added
## Description Adds `hal/mss/spi_host/hal_spi_host.c`/`.h` — the SPI driver: MibSPI classic (non-buffered, non-DMA) polling master-mode init (mode 0-3 CPOL/CPHA, prescale clamp), blocking byte-shift write/read via `SPIDAT1`/`SPIBUF`, software chip-select via `hal_gpio_write()`, and the IRQ handler decoding `SPIFLG` to a weak, application-overridable `hal_spi_host_irq_handler()` hook. Depends on the already-landed GPIO driver (#75) for chip-select, but only via a FFF fake in the test suite — no real `hal_gpio.c` linked. ## Why Continues the driver-implementation phase started by GPIO (#75/#76), ESM (#77/#78), UART (#79/#80), and I2C (#81/#82). ## Related Issue Closes #83 ## Type of Change - [x] New feature ## Impact Assessment - **Functional impact:** None — self-contained addition alongside the already-landed GPIO/ESM/UART/I2C drivers. - **Regulatory impact:** None. - **QMS impact:** None. - **Risk impact:** No — existing risk coverage sufficient. ## Testing - [x] CI pipeline passes (compile, unit tests, integration tests, static analysis) - [x] Manually tested: built and ran `testing/mss/unit/hal_functionality/test_spi_host` locally (17 test cases, 87 assertions, all passing) alongside the full existing `ctest` suite (222/222 passing, no regressions); ran a full MISRA C:2025 pass (0 unsuppressed findings, `-DENABLE_SPI_HOST_MODULE` added); reformatted and re-verified against the exact clang-format 18.1.3 the CI runner uses; sanity-checked by dropping the `- 1U` from the `PRESCALE` field write, confirming the test suite fails (6 assertions), then reverting. - [x] No regressions observed in related areas ## PR Size - [x] XL (> 300 lines) — justification required below **Size justification / exemption (if L or XL):** 765 raw lines across 6 files, all hand-reviewed (no mechanically-generated content). Not split further — the driver (`hal_spi_host.c`/`.h`, 397 lines) and its comprehensive Catch2 spec (`test_spi_host.c`, 359 lines, covering all four SPI modes, prescale clamping, and the FFF-faked GPIO chip-select calls) don't decompose into independently-reviewable sub-PRs, same rationale as prior driver PRs (#78, #80, #82). ## Checklist - [x] Commit messages follow `type(scope): description` convention with `Relates to #<issue>` footer - [x] PR template filled in completely - [x] No unverified external binaries introduced (see QMS-GITFLOW-001 Binary Security section) - [x] All commits leave the codebase in a compilable, passing-tests state (Commit Integrity Rule) ## Summary - `hal/mss/spi_host/hal_spi_host.c`/`.h`: SPI driver (mode/prescale init, blocking write/read, software chip-select, IRQ handler) — ported from `AWR6xxx_Toolchain`'s `Universal_hal spi_host_iwr68xx.c` (itself from the mmWave SDK's `MIBSPI_initMaster()`) - Cross-checked the mode-to-`PHASE`/`POLARITY` bit mapping against the standard SPI mode table — correct; the prescale formula matches the TRM's `SPICLK = VCLK/(PRESCALE+1)` relationship, same derivation pattern as UART's baud divisor and I2C's clock divisor - `testing/mss/unit/hal_functionality/test_spi_host.c` (+ `CMakeLists.txt`): Catch2 functional test suite, using an FFF fake for `hal_gpio_write()` - `tools/misra/run_misra.sh`: `-DENABLE_SPI_HOST_MODULE` added
feat(spi): SPI (MibSPI host mode) driver implementation and host unit tests
All checks were successful
lint / clang-format (pull_request) Successful in 9s
lint / misra (pull_request) Successful in 25s
tests / host-tests (pull_request) Successful in 37s
lint / clang-format (push) Successful in 10s
lint / misra (push) Successful in 25s
tests / host-tests (push) Successful in 39s
4b1b88f4e0
Adds hal/mss/spi_host/hal_spi_host.c/.h -- MibSPI classic (non-
multibuffered, non-DMA) polling master-mode init (mode 0-3 CPOL/CPHA
via PHASE/POLARITY, prescale derived from peripheral/bus clock and
clamped to 1), blocking byte-shift write/read via SPIDAT1/SPIBUF
(full-duplex: every write also reads back, even for a write-only or
read-only caller), software chip-select via hal_gpio_write() (MibSPI's
own hardware CS lines are left unused, CSNR=0xFF on every transfer),
and the IRQ handler decoding SPIFLG to a weak, application-overridable
hal_spi_host_irq_handler() hook. Ported from AWR6xxx_Toolchain's
Universal_hal spi_host_iwr68xx.c (itself from the mmWave SDK's
MIBSPI_initMaster()), per the driver's own top-of-file comment --
unlike ESM/I2C, this one has real prior-art to port from rather than
being derived fresh from the TRM.

Depends on the already-landed GPIO driver (#75) for chip-select, but
only via an FFF fake in the test suite (RESET_FAKE(hal_gpio_write)) --
hal_gpio.c itself is not linked into this test binary, matching this
suite's established pattern for cross-module dependencies (see ESM's
VIM calls).

Reformatted and verified against the exact clang-format 18.1.3 the CI
runner uses. Cross-checked the mode-to-PHASE/POLARITY bit mapping
against the standard SPI mode table (mode 1/3 -> CPHA=1, mode 2/3 ->
CPOL=1) -- correct. The prescale formula (PRESCALE = peripheral_clock/
bus_clock - 1, clamped to a minimum of 1 before the -1) matches the
TRM's SPICLK = VCLK/(PRESCALE+1) relationship, same derivation pattern
as UART's baud divisor and I2C's clock divisor.

Verified clean under testing/mss/unit/hal_functionality/test_spi_host.c
(17 test cases, 87 assertions) plus the full existing suite (222/222),
and a MISRA C:2025 pass (0 findings, -DENABLE_SPI_HOST_MODULE added).

Sanity-checked by dropping the "- 1U" from hal_spi_host_init()'s
PRESCALE field write, confirming test_spi_host fails (6 assertions),
then reverting.

Closes #83

Signed-off-by: Victor Hogeweij <hogeweyv@gmail.com>
hoogv added this to the Development project 2026-07-23 13:35:25 +00:00
hoogv self-assigned this 2026-07-23 13:36:15 +00:00
Sign in to join this conversation.
No reviewers
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
opendutchsolutions.public/hal_awr6843!84
No description provided.