Fix and implement RF interrupt handling

This commit is contained in:
Erki 2022-07-15 13:52:34 +03:00
parent 671abd2f7f
commit c67c41f166
6 changed files with 80 additions and 29 deletions

View File

@ -13,6 +13,8 @@ TransparentClient::TransparentClient(const RadioSettings& initial_settings)
: m_radio(radio::HwInstance::instance()) : m_radio(radio::HwInstance::instance())
{ {
apply_settings(initial_settings); apply_settings(initial_settings);
m_radio->set_current_state(radio::HwInstance::States::PLL_ON);
} }
void TransparentClient::apply_settings(const RadioSettings& settings) void TransparentClient::apply_settings(const RadioSettings& settings)

View File

@ -3,6 +3,8 @@
#include <utility_logging.hpp> #include <utility_logging.hpp>
#include <utility_assert.hpp> #include <utility_assert.hpp>
#include <utility_staticpointer.hpp> #include <utility_staticpointer.hpp>
#include <cassert>
#include <utility_function.hpp>
#include "radio_hw_instance.hpp" #include "radio_hw_instance.hpp"
#include "app_logging.hpp" #include "app_logging.hpp"
@ -25,6 +27,13 @@ Utility::StaticPointer<App::TransparentClient> m_app;
while (true); while (true);
} }
volatile bool irq_seen = false;
void m_irqHandler(radio::HwInstance*)
{
irq_seen = true;
}
} }
int main() int main()
@ -41,18 +50,17 @@ int main()
SKULLC_LOG_DEBUG("Begin."); SKULLC_LOG_DEBUG("Begin.");
const App::RadioSettings settings; const App::RadioSettings settings;
Utility::Function<void (radio::HwInstance*)> irq_handler{m_irqHandler};
m_app.setup(settings); m_app.setup(settings);
radio::HwInstance* radio_hw = radio::HwInstance::instance(); radio::HwInstance* radio_hw = radio::HwInstance::instance();
radio_hw->set_irq_handler(&irq_handler);
/* Replace with your application code */ /* Replace with your application code */
while (true) while (true)
{ {
gpio_toggle_pin_level(OUT_LED_RX); gpio_toggle_pin_level(OUT_LED_RX);
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); gpio_toggle_pin_level(OUT_LED_TX);
int16_t radio_status = radio_hw->register_read(radio::Registers::TRX_STATUS); int16_t radio_status = radio_hw->register_read(radio::Registers::TRX_STATUS);
@ -60,24 +68,11 @@ int main()
SKULLC_LOG_INFO("Status: %d", radio_status); SKULLC_LOG_INFO("Status: %d", radio_status);
static int transitioned = 0; if (irq_seen)
if (radio_status == 0x08 && transitioned == 0)
{ {
SKULLC_LOG_DEBUG("Transitioning..."); irq_seen = false;
radio_hw->set_current_state(radio::HwInstance::States::PLL_ON); const radio::Interrupts irqs = radio_hw->get_pending_irq();
transitioned = 1; SKULLC_LOG_INFO("IRQ received. %X", std::uint8_t(irqs));
}
else if (radio_status == 0x09 && transitioned == 1)
{
SKULLC_LOG_DEBUG("Transitioning 2...");
radio_hw->set_current_state(radio::HwInstance::States::RX_ON);
transitioned = 2;
}
else if (radio_status == 0x09 && transitioned == 1)
{
SKULLC_LOG_DEBUG("Transitioning 2...");
radio_hw->set_current_state(radio::HwInstance::States::RX_ON);
transitioned = 2;
} }
delay_ms(1000); delay_ms(1000);

View File

@ -11,7 +11,10 @@
#include <cstring> #include <cstring>
#include <optional> #include <optional>
#include <utility_function.hpp>
#include "radio_hw_registers.hpp" #include "radio_hw_registers.hpp"
#include "radio_interrupts.hpp"
namespace radio namespace radio
{ {
@ -43,7 +46,8 @@ struct HwInstance
HwInstance& operator=(const HwInstance&) = delete; HwInstance& operator=(const HwInstance&) = delete;
HwInstance& operator=(HwInstance&&) = delete; HwInstance& operator=(HwInstance&&) = delete;
void irq_handler(); void set_irq_handler(Utility::IFunction<void (HwInstance*)>* cb);
Interrupts get_pending_irq();
uint8_t register_read(const Registers& address); uint8_t register_read(const Registers& address);
void register_write(const Registers& address, const uint8_t value); void register_write(const Registers& address, const uint8_t value);

View File

@ -0,0 +1,39 @@
//
// Created by erki on 15.07.22.
//
#ifndef SKL_TUNNEL_RADIO_INTERRUPTS_HPP
#define SKL_TUNNEL_RADIO_INTERRUPTS_HPP
#include <cstdint>
namespace radio
{
enum class Interrupts : std::uint8_t
{
PLL_LOCK = (1 << 0),
PLL_UNLOCK = (1 << 1),
RX_START = (1 << 2),
TRX_END = (1 << 3),
CCA_ED_DONE = (1 << 4),
AMI = (1 << 5),
TRX_UR = (1 << 6),
BAT_LOW = (1 << 7)
};
inline Interrupts operator|(const Interrupts& lhs, const Interrupts& rhs)
{
using T = std::underlying_type_t<Interrupts>;
return static_cast<Interrupts>(static_cast<T>(lhs) | static_cast<T>(rhs));
}
inline Interrupts operator&(const Interrupts& lhs, const Interrupts& rhs)
{
using T = std::underlying_type_t<Interrupts>;
return static_cast<Interrupts>(static_cast<T>(lhs) & static_cast<T>(rhs));
}
}
#endif //SKL_TUNNEL_RADIO_INTERRUPTS_HPP

View File

@ -23,6 +23,11 @@ void radio_gpio_init()
gpio_set_pin_direction(IN_RADIO_IRQ, GPIO_DIRECTION_IN); gpio_set_pin_direction(IN_RADIO_IRQ, GPIO_DIRECTION_IN);
gpio_set_pin_pull_mode(IN_RADIO_IRQ, GPIO_PULL_OFF); gpio_set_pin_pull_mode(IN_RADIO_IRQ, GPIO_PULL_OFF);
EIC->CONFIG[0].reg |= (1 << 0);
EIC->INTENSET.reg |= (1 << 0);
EIC->CTRL.reg |= (1 << 1);
gpio_set_pin_function(IN_RADIO_IRQ, PINMUX_PB00A_EXTINT0); gpio_set_pin_function(IN_RADIO_IRQ, PINMUX_PB00A_EXTINT0);
#undef PINMUX_PB00A_EXTINT0 #undef PINMUX_PB00A_EXTINT0

View File

@ -7,12 +7,12 @@
#include "radio_hardware_instance.h" #include "radio_hardware_instance.h"
#include "radio_gpio.h" #include "radio_gpio.h"
#include "radio_spi.h" #include "radio_spi.h"
#include "utility_logging.hpp"
#include <hal_delay.h> #include <hal_delay.h>
#include <hal_ext_irq.h> #include <hal_ext_irq.h>
#include <utility_assert.hpp> #include <utility_assert.hpp>
#include <utility_staticpointer.hpp> #include <utility_staticpointer.hpp>
#include <utility_logging.hpp>
#include <optional> #include <optional>
#include <algorithm> #include <algorithm>
@ -20,11 +20,14 @@ namespace
{ {
Utility::StaticPointer<radio::HwInstance> _INSTANCE; Utility::StaticPointer<radio::HwInstance> _INSTANCE;
Utility::IFunction<void (radio::HwInstance*)>* _CALLBACK;
void _irq_handler() void _irq_handler()
{ {
SKULLC_ASSERT_DEBUG(_INSTANCE.isInitialized()); SKULLC_ASSERT_DEBUG(_INSTANCE);
_INSTANCE->irq_handler();
if (_CALLBACK)
(*_CALLBACK)(_INSTANCE.get());
} }
} }
@ -54,9 +57,7 @@ HwInstance::HwInstance()
gpio_set_pin_level(OUT_RADIO_SLP_TR, false); gpio_set_pin_level(OUT_RADIO_SLP_TR, false);
delay_ms(10); delay_ms(10);
ext_irq_enable(IN_RADIO_IRQ);
ext_irq_register(IN_RADIO_IRQ, _irq_handler); ext_irq_register(IN_RADIO_IRQ, _irq_handler);
ext_irq_register(0, _irq_handler);
gpio_set_pin_level(OUT_RADIO_RST, true); gpio_set_pin_level(OUT_RADIO_RST, true);
delay_ms(10); delay_ms(10);
@ -71,7 +72,7 @@ HwInstance::HwInstance()
register_write(Registers::TRX_CTRL_0, trx_ctrl); register_write(Registers::TRX_CTRL_0, trx_ctrl);
// Enable interrupts. // Enable interrupts.
register_write(Registers::IRQ_MASK, 0x08); register_write(Registers::IRQ_MASK, 0xFF);
// clear interrupts. // clear interrupts.
register_read(Registers::IRQ_STATUS); register_read(Registers::IRQ_STATUS);
@ -79,9 +80,14 @@ HwInstance::HwInstance()
set_current_state(States::TRX_OFF); set_current_state(States::TRX_OFF);
} }
void HwInstance::irq_handler() void HwInstance::set_irq_handler(Utility::IFunction<void (HwInstance*)>* cb)
{ {
SKULLC_LOG_DEBUG("IRQ set."); _CALLBACK = cb;
}
Interrupts HwInstance::get_pending_irq()
{
return Interrupts(register_read(Registers::IRQ_STATUS));
} }
uint8_t HwInstance::register_read(const Registers& address) uint8_t HwInstance::register_read(const Registers& address)