/** * @brief Implementations for `SpiInterface` and `SpiDevice` using HAL. * * Configuration: * STA_HAL_SPI_ENABLE: Enable module * * Requires **HAL_GPIO** module. */ #ifndef STA_HAL_SPI_HPP #define STA_HAL_SPI_HPP #include #ifdef STA_HAL_SPI_ENABLE #ifndef STA_HAL_GPIO_ENABLE #error "HAL GPIO required" #endif // !STA_HAL_GPIO_ENABLE #include #include #include #include namespace sta { /** * @brief Get peripheral clock frequency. * * @return Clock frequency */ using HalSpiPCLKFreqFn = uint32_t (*)(); /** * @brief Info related to HAL SPI interface. */ struct HalSpiInterfaceInfo { SPI_HandleTypeDef * handle; /**< Interface handle */ HalSpiPCLKFreqFn getPCLKFreq; /**< Getter for peripheral clock used by interface */ }; /** * @brief Implementation of `SpiInterface` interface using HAL. */ class HalSpiInterface : public SpiInterface { public: /** * @param info SPI interface info * @param mutex Mutex object for managing access. Pass nullptr for no access control */ HalSpiInterface(const HalSpiInterfaceInfo & info, Mutex * mutex = nullptr); void transfer(uint8_t value) override; void transfer16(uint16_t value) override; void transfer(const uint8_t * buffer, size_t size) override; void transfer(const uint8_t * txBuffer, uint8_t * rxBuffer, size_t size) override; void receive(uint8_t * buffer, size_t size) override; void fill(uint8_t value, size_t count) override; const SpiSettings & settings() const override; private: HalSpiInterfaceInfo info_; /**< SPI interface info */ }; /** * @brief Implementation of `SpiDevice` interface using HAL. */ class HalSpiDevice : public SpiDevice { public: /** * @param intf SPI interface * @param csPin Device CS pin */ HalSpiDevice(SpiInterface * intf, HalGpioPin csPin); void select() override; void deselect() override; private: HalGpioPin csPin_; /**< Device CS pin */ }; } // namespace sta /** * @brief Get SPI interface info struct for HAL handle. * * Requires STA_HAL__PCLK_IDX to be defined for the MCU. * MCU mappings are found in `core` -> sta/mcu/.hpp files. * * Check the MCUs Reference Manual RCC register documentation to see which * peripheral clock is used. * * @param handle SPI interface handle */ #define STA_HAL_SPI_INFO(handle) sta::HalSpiInterfaceInfo{&handle, STA_HAL_GET_HANDLE_PCLK_FREQ_FN(handle)} #endif // STA_HAL_SPI_ENABLE #endif // STA_HAL_SPI_HPP