// // 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 = "app_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; 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); error_t status_ok = [](llcc68::CommandStatus st) { switch (st) { case llcc68::CommandStatus::COMMAND_TIMEOUT: return error::RADIO_TRANS_TIMEOUT; case llcc68::CommandStatus::FAILURE_TO_EXECUTE_COMMAND: return error::RADIO_TRANS_FAIL_TO_EXE; case llcc68::CommandStatus::COMMAND_PROCESSING_ERROR: #ifdef APP_SPI_DISABLE_INVALID_STATUS_CHECK return error::OK; #else return error::RADIO_TRANS_CMD_PROC_ERR; #endif default: return error::OK; } }(st.command_status); if (status_ok != error::OK) { return status_ok; } error_t chip_mode_usual = [](llcc68::ChipMode mode) { switch (mode) { case llcc68::ChipMode::TX: case llcc68::ChipMode::RX: case llcc68::ChipMode::STBY_RC: return error::OK; default: return error::RADIO_TRANS_INVALID_RADIO_STATE; } }(st.chip_mode); return chip_mode_usual; } /*! 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 */