/** * @brief Implementations for `SpiInterface` and `SpiDevice` using HAL. * * Define **STA_HAL_SPI_ENABLE** in `` to enable module. * * Requires **STA_HAL_GPIO_ENABLE**. */ #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 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 function returning PCLK frequency. * * @param n Index of peripheral clock */ #define STA_HAL_GET_PCLK_FREQ_FN(n) HAL_RCC_GetPCLK ## n ## Freq /** * @brief Get SPI interface info struct. * * Check the MCUs Reference Manual RCC register documentation to see which * peripheral clock is used. * * @param n Index of SPI interface (e.g. 2 for SPI2) * @param pclk Index of peripheral clock used by SPI interface */ #define STA_HAL_SPI_INFO_MANUAL(n, pclk) sta::HalSpiInterfaceInfo{&hspi ## n, STA_HAL_GET_PCLK_FREQ_FN(pclk)} /** * @brief Get SPI interface info struct. * * Requires STA_HAL_SPI_n_PCLK_IDX set to idx of PCLK used by the interface. * * Check the MCUs Reference Manual RCC register documentation to see which * peripheral clock is used. * * @param n Index of SPI interface (e.g. 2 for SPI2) */ #define STA_HAL_SPI_INFO(n) STA_HAL_SPI_INFO_MANUAL(n, STA_HAL_SPI_ ## n ## _PCLK_IDX) #endif // STA_HAL_SPI_ENABLE #endif // STA_HAL_SPI_HPP