Skip to content

Conversation

@Tejasgarg
Copy link
Contributor

@Tejasgarg Tejasgarg commented Oct 12, 2025

This is a work in progress.

Currently, I have implemented the basic low-level driver for SPI bus, that implements two SPI buses (SPI1 and SPI2)

I will continue working on this to implement the complete working of the SPI bus module

Summary by Sourcery

Add basic SPI bus driver support by providing hardware abstraction, system-level APIs, platform configuration, and example usage in main

New Features:

  • Implement low-level SPI driver (spi_ll) for STM32H563xx
  • Introduce high-level SPI system API for init, deinit, transmit, receive, and transmit_receive
  • Integrate SPI support into main application with example transmit/receive workflow

Enhancements:

  • Update platform clock configuration to enable SPI3 with PLL2P and adjust prescalers

Build:

  • Enable HAL SPI module, add spi_ll.c to CMakeLists, and link HAL SPIEx library

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @Tejasgarg, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@Tejasgarg Tejasgarg changed the base branch from main to prototype_1 October 31, 2025 23:01
@Tejasgarg Tejasgarg requested a review from bessman November 2, 2025 15:31
@Tejasgarg Tejasgarg marked this pull request as ready for review November 2, 2025 17:11
@sourcery-ai
Copy link

sourcery-ai bot commented Nov 2, 2025

Reviewer's Guide

This PR introduces a basic SPI bus driver by adding low-level STM32H5 SPI code, exposing a high-level SPI_Handle API, configuring clocks and build files, and integrating an example usage in the application.

Sequence diagram for SPI transmit and receive in main application

sequenceDiagram
    participant App as Application
    participant SPI as SPI_Handle
    participant LL as SPI_LL
    participant HW as STM32 SPI Peripheral
    App->>SPI: SPI_init(0)
    SPI->>LL: SPI_LL_init(bus)
    LL->>HW: Configure SPI peripheral
    App->>SPI: SPI_transmit_receive(spi_handle, &tx_data, rx_data, size)
    SPI->>LL: SPI_LL_transmit_receive(bus, tx_data, rx_data, size)
    LL->>HW: HAL_SPI_TransmitReceive(...)
    HW-->>LL: Data received
    LL-->>SPI: Return received data
    SPI-->>App: Return received data
Loading

Class diagram for new SPI bus driver API

classDiagram
    class SPI_Handle {
        +SPI_Bus bus_id
        +bool initialized
    }
    class SPI_Bus {
    }
    SPI_Handle -- SPI_Bus
    SPI_Handle <|.. SPI_init
    SPI_Handle <|.. SPI_deinit
    SPI_Handle <|.. SPI_transmit
    SPI_Handle <|.. SPI_receive
    SPI_Handle <|.. SPI_transmit_receive
    class SPI_init {
        +SPI_Handle *SPI_init(size_t bus)
    }
    class SPI_deinit {
        +void SPI_deinit(SPI_Handle *handle)
    }
    class SPI_transmit {
        +void SPI_transmit(SPI_Handle *handle, uint8_t const *txbuf, size_t sz)
    }
    class SPI_receive {
        +void SPI_receive(SPI_Handle *handle, uint8_t *rxbuf, size_t sz)
    }
    class SPI_transmit_receive {
        +void SPI_transmit_receive(SPI_Handle *handle, uint8_t const *tx_data, uint8_t *rx_data, size_t size)
    }
Loading

Class diagram for SPI low-level hardware interface

classDiagram
    class SPIInstance {
        +SPI_HandleTypeDef *hspi
        +bool initialized
    }
    class SPI_Bus {
    }
    SPIInstance -- SPI_Bus
    SPIInstance <|.. SPI_LL_init
    SPIInstance <|.. SPI_LL_deinit
    SPIInstance <|.. SPI_LL_transmit
    SPIInstance <|.. SPI_LL_receive
    SPIInstance <|.. SPI_LL_transmit_receive
    class SPI_LL_init {
        +void SPI_LL_init(SPI_Bus bus)
    }
    class SPI_LL_deinit {
        +void SPI_LL_deinit(SPI_Bus bus)
    }
    class SPI_LL_transmit {
        +void SPI_LL_transmit(SPI_Bus bus, uint8_t const *txdata, size_t size)
    }
    class SPI_LL_receive {
        +void SPI_LL_receive(SPI_Bus bus, uint8_t *rxdata, size_t size)
    }
    class SPI_LL_transmit_receive {
        +void SPI_LL_transmit_receive(SPI_Bus bus, uint8_t const *tx_data, uint8_t *rx_data, size_t size)
    }
Loading

File-Level Changes

Change Details Files
Added high-level SPI interface and system integration
  • Created spi.h and spi.c for SPI_Handle API
  • Implemented allocation, init, deinit, transmit, receive and transceive functions
  • Integrated calls to SPI_init, SPI_transmit_receive, and SPI_deinit
src/system/bus/spi.h
src/system/bus/spi.c
src/application/main.c
Implemented low-level HAL-based SPI hardware module
  • Created spi_ll.h defining SPI_Bus enum and prototypes
  • Developed spi_ll.c with HAL_SPI MSP init, init, deinit, transmit, receive, and transceive
  • Configured instance structure and error handling
src/platform/h563xx/spi_ll.c
src/platform/spi_ll.h
Updated clock configuration for SPI3
  • Enabled SPI3 peripheral clock selection in RCC config
  • Adjusted PLL2P prescaler for SPI3 clock
  • Enabled PLL2P output alongside PLL2R
src/platform/h563xx/platform.c
Modified build and HAL configuration to include SPI
  • Enabled HAL_SPI_MODULE_ENABLED in hal_conf.h
  • Added spi_ll.c to CMakeLists sources
  • Linked HAL::STM32::H5::SPIEx library
src/platform/h563xx/stm32h5xx_hal_conf.h
src/platform/h563xx/CMakeLists.txt
src/system/bus/CMakeLists.target.txt
Integrated SPI example in main application
  • Imported system/bus/spi.h and defined TX/RX buffer constants
  • Initialized SPI in main and handled init failure
  • Added SPI_transmit_receive example with logging
src/application/main.c

Assessment against linked issues

Issue Objective Addressed Explanation
#126 Implement a basic SPI bus driver, including initialization, transmit, receive, and transmit-receive functions.
#126 Expose the SPI bus functionality via a public API (header and implementation) for use in application code.
#126 Integrate the SPI bus driver into the build system and enable required hardware support.

Possibly linked issues

  • Develop basic SPI bus #126: The PR implements the basic low-level driver for an SPI bus, which directly addresses the issue of developing a basic SPI bus.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • In SPI_init you dereference g_spi_instances[bus_id] without checking for NULL (it starts out as nullptr), so the first init will crash—update the logic to check the pointer before deref and reset the slot on deinit.
  • The bus enum and HAL_SPI_MspInit comment refer to SPI1, but the code enables/configures SPI3—align the instance mapping, names, and comments to the same peripheral to avoid confusion.
  • It looks like src/system/bus/spi.c isn’t added to your CMakeLists.target.txt, so the new high-level SPI module won’t be built—please include it in the build configuration.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In SPI_init you dereference g_spi_instances[bus_id] without checking for NULL (it starts out as nullptr), so the first init will crash—update the logic to check the pointer before deref and reset the slot on deinit.
- The bus enum and HAL_SPI_MspInit comment refer to SPI1, but the code enables/configures SPI3—align the instance mapping, names, and comments to the same peripheral to avoid confusion.
- It looks like src/system/bus/spi.c isn’t added to your CMakeLists.target.txt, so the new high-level SPI module won’t be built—please include it in the build configuration.

## Individual Comments

### Comment 1
<location> `src/system/bus/spi.c:25` </location>
<code_context>
+    bool initialized;
+};
+
+static SPI_Handle *g_spi_instances[SPI_BUS_COUNT] = { nullptr };
+
+/**
</code_context>

<issue_to_address>
**issue (bug_risk):** Potential null pointer dereference in SPI_init.

g_spi_instances[bus_id] may be nullptr on first use, leading to a crash when accessing its members. Add a nullptr check before referencing g_spi_instances[bus_id]->initialized.
</issue_to_address>

### Comment 2
<location> `src/platform/h563xx/spi_ll.c:35` </location>
<code_context>
+} SPIInstance;
+
+/* HAL SPI handle */
+static SPI_HandleTypeDef g_hspi1 = { nullptr };
+
+/* SPI instance configuration */
</code_context>

<issue_to_address>
**issue (bug_risk):** Use of 'nullptr' in C source file.

Replace 'nullptr' with 'NULL' to ensure compatibility with C compilers.
</issue_to_address>

### Comment 3
<location> `src/platform/h563xx/spi_ll.c:53` </location>
<code_context>
+{
+    GPIO_InitTypeDef gpio_init = { 0 };
+
+    if (hspi->Instance == SPI3) {
+        /* SPI3 clock enable */
+        __HAL_RCC_SPI3_CLK_ENABLE();
</code_context>

<issue_to_address>
**nitpick (typo):** GPIO configuration comment refers to SPI1 instead of SPI3.

Please change the comment to 'SPI3 GPIO Configuration' to match the code.

```suggestion
        /* SPI3 GPIO Configuration: PC10=SCK, PC11=MISO, PC12=MOSI */
```
</issue_to_address>

### Comment 4
<location> `src/application/main.c:22-19` </location>
<code_context>
     }

+    // Initialize the SPI bus
+    SPI_Handle *spi_handle = SPI_init(0);
+    if (spi_handle == NULL) {
+        LOG_ERROR("Failed to initialize SPI bus");
+    }
+
     // Main application loop
</code_context>

<issue_to_address>
**issue (bug_risk):** SPI bus initialization error is logged but not handled.

Please ensure the function exits or handles the error when SPI_init returns NULL to prevent invalid SPI operations.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

if (!protocol_init()) {
LOG_ERROR("Failed to initialize protocol");
return -1;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): SPI bus initialization error is logged but not handled.

Please ensure the function exits or handles the error when SPI_init returns NULL to prevent invalid SPI operations.

@Tejasgarg Tejasgarg changed the title WIP: SPI bus driver SPI bus driver Nov 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Develop basic SPI bus

2 participants