95 lines
2.5 KiB
C++
95 lines
2.5 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 <utility_function.hpp>
|
|
|
|
#include "radio_hw_registers.hpp"
|
|
#include "radio_interrupts.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 set_irq_handler(Utility::IFunction<void (HwInstance*)>* cb);
|
|
Interrupts get_pending_irq();
|
|
|
|
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]));
|
|
}
|
|
}
|
|
|
|
void sram_write(const std::uint8_t* data, const std::size_t length, const std::uint8_t offset = 0);
|
|
|
|
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
|