skl-tunnel/radio/include/radio_hw_instance.hpp

89 lines
2.2 KiB
C++

//
// Created by erki on 4.06.22.
//
#ifndef SKL_TUNNEL_RADIO_HW_INSTANCE_HPP
#define SKL_TUNNEL_RADIO_HW_INSTANCE_HPP
#include <hal_spi_m_sync.h>
#include <type_traits>
#include <array>
#include <cstring>
#include <optional>
#include "radio_hw_registers.hpp"
namespace radio
{
struct HwInstance
{
enum class States : std::uint8_t
{
P_ON = 0,
BUSY_RX = 0x1,
BUSY_TX = 0x2,
RX_ON = 0x06,
TRX_OFF = 0x08,
PLL_ON = 0x09,
SLEEP = 0x0F,
PREP_DEEP_SLEEP = 0x10,
BUSY_RX_AACK = 0x11,
BUSY_TX_ARET = 0x12,
RX_AACK_ON = 0x16,
TX_ARET_ON = 0x19,
TRANSITION_IN_PROGRESS = 0x1F
};
static HwInstance* instance();
HwInstance();
HwInstance(const HwInstance&) = delete;
HwInstance(HwInstance&&) = delete;
HwInstance& operator=(const HwInstance&) = delete;
HwInstance& operator=(HwInstance&&) = delete;
void irq_handler();
uint8_t register_read(const Registers& address);
void register_write(const Registers& address, const uint8_t value);
template<typename T>
void register_write(const Registers& initial_address, const T value)
{
static_assert(std::is_integral_v<T>, "T must be an integral type.");
std::array<std::uint8_t, sizeof(T)> data_array;
std::memcpy(data_array.data(), &value, sizeof(T));
for (std::uint8_t i = 0; i < sizeof(T); i++)
{
const std::uint8_t address = std::uint8_t(initial_address) + i;
register_write(Registers(address), std::uint8_t(data_array[i]));
}
}
States current_state() const;
bool set_current_state(const States& new_state);
void set_address_short(const std::uint16_t address);
void set_address_long(const std::uint64_t address);
void set_channel(const std::uint8_t channel);
void set_pan_id(const std::uint16_t pan_id);
void set_tx_power(std::int16_t power);
void set_max_retries(std::uint8_t retries);
void set_csma_max_retries(const std::optional<std::uint8_t>& retries);
void set_csma_backoff_exponential(std::uint8_t max, std::uint8_t min);
void set_csma_seed(const std::uint16_t entropy);
private:
spi_m_sync_descriptor* m_spi = nullptr;
io_descriptor* m_spi_io = nullptr;
States m_current_state = States::P_ON;
void m_wait_can_transition();
};
}
#endif //SKL_TUNNEL_RADIO_HW_INSTANCE_HPP