2022-05-02 13:37:44 +02:00

109 lines
2.5 KiB
C++

/**
* @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 <sta/config.hpp>
#ifdef STA_HAL_SPI_ENABLE
#ifndef STA_HAL_GPIO_ENABLE
#error "HAL GPIO required"
#endif // !STA_HAL_GPIO_ENABLE
#include <sta/hal.hpp>
#include <sta/hal/clocks.hpp>
#include <sta/hal/gpio_pin.hpp>
#include <sta/intf/spi_device.hpp>
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_<handle>_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