139 lines
3.7 KiB
C++
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 = "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 */
|