// // Created by Kurosu Chan on 2024/1/17. // #ifndef B7431E31_4075_4B09_B4B3_EAD0234EFB40 #define B7431E31_4075_4B09_B4B3_EAD0234EFB40 #include #include #include "hal/spi_types.h" #include "radiolib_definitions.hpp" #include "llcc68_definitions.hpp" #include "utils/app_result.hpp" #include "hal_error.hpp" #include "app_const_llcc68.hpp" namespace app::driver::hal::spi { template using Result = app::utils::Result; using Unit = app::utils::Unit; constexpr auto TAG = "spi"; constexpr auto MOSI_PIN = llcc68::MOSI_PIN; constexpr auto MISO_PIN = llcc68::MISO_PIN; constexpr auto SCLK_PIN = llcc68::SCLK_PIN; constexpr auto BUSY_PIN = llcc68::BUSY_PIN; constexpr auto CS_PIN = llcc68::CS_PIN; using error_t = error::t; using ue_t = app::utils::unexpected; constexpr uint8_t SPI_READ_COMMAND = RADIOLIB_SX126X_CMD_READ_REGISTER; constexpr uint8_t SPI_WRITE_COMMAND = RADIOLIB_SX126X_CMD_WRITE_REGISTER; constexpr uint8_t SPI_NOP_COMMAND = RADIOLIB_SX126X_CMD_NOP; constexpr uint8_t SPI_WRITE_BUFFER_CMD = RADIOLIB_SX126X_CMD_WRITE_BUFFER; constexpr uint8_t SPI_READ_BUFFER_CMD = RADIOLIB_SX126X_CMD_READ_BUFFER; constexpr size_t DEFAULT_TIMEOUT_MS = 1000; std::span mut_shared_buffer(); struct spi_config_t { spi_host_device_t host_id; int clock_speed_hz; }; /*! \brief Initialize the SPI interface. */ void init(spi_config_t config = {SPI2_HOST, 4'000'000}); inline error_t status_to_err(const uint8_t status) { const auto st = *reinterpret_cast(&status); switch (st.command_status) { case llcc68::CommandStatus::COMMAND_TIMEOUT: return error::SPI_TIMEOUT; case llcc68::CommandStatus::FAILURE_TO_EXECUTE_COMMAND: return error::SPI_CMD_FAILED; case llcc68::CommandStatus::COMMAND_PROCESSING_ERROR: #ifdef APP_SPI_DISABLE_INVALID_STATUS_CHECK return error::OK; #else return error::SPI_CMD_INVALID; #endif default: return error::OK; } } /*! See also LLCC68 chapter 10 Host Controller Interface */ /*! Common API patterns */ /*! READ (no parameters, only OPCODE, but has data and status) OPCODE() -> (status, data) */ Result read_stream(uint8_t cmd, std::span data, const size_t timeout_ms = DEFAULT_TIMEOUT_MS); /*! WRITE (having parameters, no excessive return values but status) OPCODE(parameters) -> status */ Result write_stream(uint8_t cmd, std::span data, const size_t timeout_ms = DEFAULT_TIMEOUT_MS); /*! READ REGISTER READ_REGISTER(register, offset) -> (status, data) */ Result read_register(uint16_t reg, std::span data, const size_t timeout_ms = DEFAULT_TIMEOUT_MS); /*! WRITE REGISTER WRITE_REGISTER(register, offset, data) -> status */ Result write_register(uint16_t offset, std::span data, const size_t timeout_ms = DEFAULT_TIMEOUT_MS); /*! WRITE BUFFER WRITE_BUFFER(offset, data) -> status */ Result write_buffer(uint8_t offset, std::span data_from_host, const size_t timeout_ms = DEFAULT_TIMEOUT_MS); /*! READ BUFFER READ_BUFFER(offset) -> (status, data) */ Result, error_t> read_buffer(uint8_t offset, uint8_t size, const size_t timeout_ms = DEFAULT_TIMEOUT_MS); } #endif /* B7431E31_4075_4B09_B4B3_EAD0234EFB40 */