Basic radio boot-up code + initial state transition

This commit is contained in:
Erki 2022-06-30 19:35:05 +03:00
parent 94368b458a
commit bb1a446f77
4 changed files with 133 additions and 25 deletions

View File

@ -41,12 +41,16 @@ int main()
{
gpio_toggle_pin_level(OUT_LED_RX);
const int16_t radio_num = radio_hw.register_read(0x1C);
const int16_t radio_num = radio_hw.register_read(radio::Registers::PART_NUM);
SKULLC_LOG_INFO("Reg 0x1C: %d", radio_num);
gpio_toggle_pin_level(OUT_LED_TX);
int16_t radio_status = radio_hw.register_read(radio::Registers::TRX_STATUS);
radio_status &= 0x1F;
SKULLC_LOG_INFO("Status: %d", radio_status);
delay_ms(1000);
}
}

View File

@ -7,11 +7,15 @@
#include <hal_spi_m_sync.h>
#include "radio_hw_registers.hpp"
namespace radio
{
struct HwInstance
{
static HwInstance* instance();
HwInstance();
HwInstance(const HwInstance&) = delete;
HwInstance(HwInstance&&) = delete;
@ -20,11 +24,13 @@ struct HwInstance
void irq_handler();
uint8_t register_read(uint8_t address);
void register_write(uint8_t address, const uint8_t value);
uint8_t register_read(const Registers& address);
void register_write(const Registers& address, const uint8_t value);
private:
spi_m_sync_descriptor* m_spi = nullptr;
io_descriptor* m_spi_io = nullptr;
void m_wait_transition_complete();
};
}

View File

@ -0,0 +1,64 @@
//
// Created by erki on 30.06.22.
//
#ifndef SKL_TUNNEL_RADIO_HW_REGISTERS_HPP
#define SKL_TUNNEL_RADIO_HW_REGISTERS_HPP
#include <cstdint>
namespace radio
{
enum class Registers : std::uint8_t
{
TRX_STATUS = (0x01),
TRX_STATE = (0x02),
TRX_CTRL_0 = (0x03),
TRX_CTRL_1 = (0x04),
PHY_TX_PWR = (0x05),
PHY_RSSI = (0x06),
PHY_ED_LEVEL = (0x07),
PHY_CC_CCA = (0x08),
CCA_THRES = (0x09),
RX_CTRL = (0x0A),
SFD_VALUE = (0x0B),
TRX_CTRL_2 = (0x0C),
ANT_DIV = (0x0D),
IRQ_MASK = (0x0E),
IRQ_STATUS = (0x0F),
VREG_CTRL = (0x10),
BATMON = (0x11),
XOSC_CTRL = (0x12),
CC_CTRL_1 = (0x14),
RX_SYN = (0x15),
XAH_CTRL_1 = (0x17),
FTN_CTRL = (0x18),
PLL_CF = (0x1A),
PLL_DCU = (0x1B),
PART_NUM = (0x1C),
VERSION_NUM = (0x1D),
MAN_ID_0 = (0x1E),
MAN_ID_1 = (0x1F),
SHORT_ADDR_0 = (0x20),
SHORT_ADDR_1 = (0x21),
PAN_ID_0 = (0x22),
PAN_ID_1 = (0x23),
IEEE_ADDR_0 = (0x24),
IEEE_ADDR_1 = (0x25),
IEEE_ADDR_2 = (0x26),
IEEE_ADDR_3 = (0x27),
IEEE_ADDR_4 = (0x28),
IEEE_ADDR_5 = (0x29),
IEEE_ADDR_6 = (0x2A),
IEEE_ADDR_7 = (0x2B),
XAH_CTRL_0 = (0x2C),
CSMA_SEED_0 = (0x2D),
CSMA_SEED_1 = (0x2E),
CSMA_BE = (0x2F),
TST_CTRL_DIGI = (0x36)
};
}
#endif //SKL_TUNNEL_RADIO_HW_REGISTERS_HPP

View File

@ -11,19 +11,42 @@
#include <hal_delay.h>
#include <hal_ext_irq.h>
#include <utility_assert.hpp>
#include <utility_staticpointer.hpp>
namespace
{
radio::HwInstance* _INSTANCE = nullptr;
Utility::StaticPointer<radio::HwInstance> _INSTANCE;
void _irq_handler()
{
SKULLC_ASSERT_DEBUG(_INSTANCE.isInitialized());
_INSTANCE->irq_handler();
}
void _startup()
}
namespace radio
{
HwInstance* HwInstance::instance()
{
if (!_INSTANCE.isInitialized())
{
_INSTANCE.setup();
}
return &(*_INSTANCE);
}
HwInstance::HwInstance()
{
radio_gpio_init();
m_spi = radio_spi_init();
spi_m_sync_get_io_descriptor(m_spi, &m_spi_io);
spi_m_sync_enable(m_spi);
gpio_set_pin_level(OUT_RADIO_RST, false);
gpio_set_pin_level(OUT_RADIO_SLP_TR, false);
delay_ms(10);
@ -33,40 +56,39 @@ void _startup()
gpio_set_pin_level(OUT_RADIO_RST, true);
delay_ms(10);
}
}
// Enable safe mode for TX.
register_write(Registers::TRX_CTRL_2, 0x80);
namespace radio
{
// Disable external clock output.
std::uint8_t trx_ctrl = register_read(Registers::TRX_CTRL_0);
trx_ctrl &= ~(0x07);
trx_ctrl &= ~(0x08);
register_write(Registers::TRX_CTRL_0, trx_ctrl);
HwInstance::HwInstance()
{
SKULLC_ASSERT_SAFE(!_INSTANCE);
// Enable interrupts.
register_write(Registers::IRQ_MASK, 0x08);
radio_gpio_init();
// clear interrupts.
register_read(Registers::IRQ_STATUS);
m_spi = radio_spi_init();
spi_m_sync_get_io_descriptor(m_spi, &m_spi_io);
spi_m_sync_enable(m_spi);
m_wait_transition_complete();
_INSTANCE = this;
_startup();
register_write(Registers::TRX_STATE, 0x08);
}
void HwInstance::irq_handler()
{
}
uint8_t HwInstance::register_read(uint8_t address)
uint8_t HwInstance::register_read(const Registers& address)
{
address = (address & 0x3F) | (1 << 7);
const uint8_t address_to_write = (uint8_t(address) & 0x3F) | (1 << 7);
gpio_set_pin_level(OUT_RADIO_CS, false);
delay_us(1);
io_write(m_spi_io, &address, 1);
io_write(m_spi_io, &address_to_write, 1);
delay_us(1);
uint8_t data = 0xFF;
io_read(m_spi_io, &data, 1);
@ -76,10 +98,10 @@ uint8_t HwInstance::register_read(uint8_t address)
return data;
}
void HwInstance::register_write(const uint8_t address, const uint8_t value)
void HwInstance::register_write(const Registers& address, const uint8_t value)
{
uint8_t data[2] = {
uint8_t((address & 0x3F) | (1 << 7) | (1 << 6)),
uint8_t((uint8_t(address) & 0x3F) | (1 << 7) | (1 << 6)),
uint8_t(value & 0xEF)
};
@ -89,4 +111,16 @@ void HwInstance::register_write(const uint8_t address, const uint8_t value)
gpio_set_pin_level(OUT_RADIO_CS, true);
}
void HwInstance::m_wait_transition_complete()
{
while (true)
{
int16_t radio_status = register_read(radio::Registers::TRX_STATUS);
radio_status &= 0x1F;
if (radio_status != 0x1F)
return;
}
}
}