Files
esp_llcc68_driver/inc/hal_spi.hpp

139 lines
3.7 KiB
C++

//
// Created by Kurosu Chan on 2024/1/17.
//
#ifndef B7431E31_4075_4B09_B4B3_EAD0234EFB40
#define B7431E31_4075_4B09_B4B3_EAD0234EFB40
#include <cstdint>
#include <span>
#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 <typename T, typename E>
using Result = app::utils::Result<T, E>;
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<error_t>;
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<const llcc68::status_t *>(&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<Unit, error_t>
read_stream(uint8_t cmd, std::span<uint8_t> data, const size_t timeout_ms = DEFAULT_TIMEOUT_MS);
/*!
WRITE (having parameters, no excessive return values but status)
OPCODE(parameters) -> status
*/
Result<Unit, error_t>
write_stream(uint8_t cmd, std::span<const uint8_t> data, const size_t timeout_ms = DEFAULT_TIMEOUT_MS);
/*!
READ REGISTER
READ_REGISTER(register, offset) -> (status, data)
*/
Result<Unit, error_t>
read_register(uint16_t reg, std::span<uint8_t> data, const size_t timeout_ms = DEFAULT_TIMEOUT_MS);
/*!
WRITE REGISTER
WRITE_REGISTER(register, offset, data) -> status
*/
Result<Unit, error_t>
write_register(uint16_t offset, std::span<const uint8_t> data, const size_t timeout_ms = DEFAULT_TIMEOUT_MS);
/*!
WRITE BUFFER
WRITE_BUFFER(offset, data) -> status
*/
Result<Unit, error_t>
write_buffer(uint8_t offset, std::span<const uint8_t> data_from_host, const size_t timeout_ms = DEFAULT_TIMEOUT_MS);
/*!
READ BUFFER
READ_BUFFER(offset) -> (status, data)
*/
Result<std::span<const uint8_t>, error_t>
read_buffer(uint8_t offset, uint8_t size, const size_t timeout_ms = DEFAULT_TIMEOUT_MS);
}
#endif /* B7431E31_4075_4B09_B4B3_EAD0234EFB40 */