diff --git a/include/sta/hal/spi.hpp b/include/sta/hal/spi.hpp index a342f12..dcc6280 100644 --- a/include/sta/hal/spi.hpp +++ b/include/sta/hal/spi.hpp @@ -45,6 +45,7 @@ namespace sta void receive(uint8_t * buffer, size_t size) override; + private: SPI_HandleTypeDef * handle_; /**< SPI handle */ }; diff --git a/include/sta/spi_device.hpp b/include/sta/spi_device.hpp index 377beae..336e123 100644 --- a/include/sta/spi_device.hpp +++ b/include/sta/spi_device.hpp @@ -87,6 +87,15 @@ namespace sta */ void receive(uint8_t * buffer, size_t size); + + /** + * @brief Get SPI interface settings. + * + * @return SPI settings + */ + const SpiSettings & settings() const; + + /** * @brief Activate device via CS pin. */ diff --git a/include/sta/spi_interface.hpp b/include/sta/spi_interface.hpp index 5708b89..fea5ddd 100644 --- a/include/sta/spi_interface.hpp +++ b/include/sta/spi_interface.hpp @@ -5,6 +5,7 @@ #define STA_SPI_INTERFACE_HPP #include +#include #include #include @@ -19,9 +20,10 @@ namespace sta { public: /** + * @param settings SPI interface settings * @param mutex Mutex object for managing shared access. Pass nullptr for no access control */ - SpiInterface(Mutex * mutex = nullptr); + SpiInterface(const SpiSettings & settings, Mutex * mutex = nullptr); /** @@ -76,6 +78,15 @@ namespace sta */ virtual void receive(uint8_t * buffer, size_t size) = 0; + + /** + * @brief Get SPI interface settings. + * + * @return SPI settings + */ + const SpiSettings & settings() const; + + /** * @brief Acquire usage rights to use the interface. * @@ -90,7 +101,8 @@ namespace sta virtual void release(); private: - Mutex * mutex_; /**< Mutex object */ + SpiSettings settings_; /** SPI settings */ + Mutex * mutex_; /**< Mutex object */ }; } // namespace sta diff --git a/src/hal/spi.cpp b/src/hal/spi.cpp index 69a428e..45b2b88 100644 --- a/src/hal/spi.cpp +++ b/src/hal/spi.cpp @@ -3,12 +3,71 @@ #ifdef STA_HAL_SPI_ENABLE #include +#include namespace sta { + static SpiSettings getHalSpiSettings(SPI_HandleTypeDef * handle) + { + SpiSettings settings; + + settings.mode = getSpiMode( + (handle->Init.CLKPolarity == SPI_POLARITY_LOW) ? SpiClkPolarity::LOW : SpiClkPolarity::HIGH, + (handle->Init.CLKPhase == SPI_PHASE_1EDGE) ? SpiClkPhase::EDGE_1 : SpiClkPhase::EDGE_2 + ); + settings.dataSize = (handle->Init.DataSize == SPI_DATASIZE_8BIT) ? SpiDataSize::BIT_8 : SpiDataSize::BIT_16; + settings.bitOrder = (handle->Init.FirstBit == SPI_FIRSTBIT_MSB) ? SpiBitOrder::MSB : SpiBitOrder::LSB; + + uint32_t prescaler = 1; + switch (handle->Init.BaudRatePrescaler) + { + case SPI_BAUDRATEPRESCALER_2: + settings.baudRatePrescaler = SpiBaudRatePrescaler::BRP_2; + prescaler = 2; + break; + case SPI_BAUDRATEPRESCALER_4: + settings.baudRatePrescaler = SpiBaudRatePrescaler::BRP_4; + prescaler = 2; + break; + case SPI_BAUDRATEPRESCALER_8: + settings.baudRatePrescaler = SpiBaudRatePrescaler::BRP_8; + prescaler = 2; + break; + case SPI_BAUDRATEPRESCALER_16: + settings.baudRatePrescaler = SpiBaudRatePrescaler::BRP_16; + prescaler = 2; + break; + case SPI_BAUDRATEPRESCALER_32: + settings.baudRatePrescaler = SpiBaudRatePrescaler::BRP_32; + prescaler = 2; + break; + case SPI_BAUDRATEPRESCALER_64: + settings.baudRatePrescaler = SpiBaudRatePrescaler::BRP_64; + prescaler = 2; + break; + case SPI_BAUDRATEPRESCALER_128: + settings.baudRatePrescaler = SpiBaudRatePrescaler::BRP_128; + prescaler = 2; + break; + case SPI_BAUDRATEPRESCALER_256: + settings.baudRatePrescaler = SpiBaudRatePrescaler::BRP_256; + prescaler = 2; + break; + default: + // Unreachable case + STA_ASSERT_MSG(false, "Case for SPI_BAUDRATEPRESCALER not handled"); + STA_UNREACHABLE(); + } + + settings.clkSpeed = HAL_RCC_GetSysClockFreq() / prescaler; + + return settings; + } + + HalSpiInterface::HalSpiInterface(SPI_HandleTypeDef * handle, Mutex * mutex /* = nullptr */) - : SpiInterface(mutex), handle_{handle} + : SpiInterface(getHalSpiSettings(handle), mutex), handle_{handle} { STA_ASSERT(handle != nullptr); } @@ -38,7 +97,7 @@ namespace sta void HalSpiInterface::transfer16(uint16_t value) { - static_assert(sizeof(uint16_t) == 2); + static_assert(sizeof(uint16_t) == 2, "Unexpected uint16_t size"); HAL_SPI_Transmit(handle_, reinterpret_cast(&value), 2, HAL_MAX_DELAY); } @@ -56,7 +115,7 @@ namespace sta void HalSpiInterface::fill32(uint32_t value, size_t count) { - static_assert(sizeof(uint32_t) == 4); + static_assert(sizeof(uint32_t) == 4, "Unexpected uint32_t size"); STA_ASSERT(count != 0); for (size_t i = 0; i < count; ++i) diff --git a/src/spi_device.cpp b/src/spi_device.cpp index 701d0e3..d3130e9 100644 --- a/src/spi_device.cpp +++ b/src/spi_device.cpp @@ -74,4 +74,9 @@ namespace sta intf_->receive(buffer, size); } + + const SpiSettings & SpiDevice::settings() const + { + return intf_->settings(); + } } // namespace sta diff --git a/src/spi_interface.cpp b/src/spi_interface.cpp index 26a141e..3abcca7 100644 --- a/src/spi_interface.cpp +++ b/src/spi_interface.cpp @@ -3,10 +3,15 @@ namespace sta { - SpiInterface::SpiInterface(Mutex * mutex /* = nullptr */) - : mutex_{mutex} + SpiInterface::SpiInterface(const SpiSettings & settings, Mutex * mutex /* = nullptr */) + : settings_{settings}, mutex_{mutex} {} + const SpiSettings & SpiInterface::settings() const + { + return settings_; + } + void SpiInterface::acquire() { if (mutex_ != nullptr)