Compare commits
2 Commits
00810009ec
...
c994e63478
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c994e63478 | ||
|
|
1c695fbaa8 |
@ -49,7 +49,7 @@ add_executable(skl_tunnel
|
|||||||
radio/src/radio_gpio.c
|
radio/src/radio_gpio.c
|
||||||
radio/src/radio_hw_instance.cpp
|
radio/src/radio_hw_instance.cpp
|
||||||
|
|
||||||
app/src/app_logging.cpp
|
app/src/app_board.cpp
|
||||||
app/src/app_transparent_client.cpp
|
app/src/app_transparent_client.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
syscalls.c
|
syscalls.c
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by erki on 28.06.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef SKL_TUNNEL_APP_LOGGING_HPP
|
|
||||||
#define SKL_TUNNEL_APP_LOGGING_HPP
|
|
||||||
|
|
||||||
namespace App::Logging
|
|
||||||
{
|
|
||||||
|
|
||||||
void setup();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //SKL_TUNNEL_APP_LOGGING_HPP
|
|
||||||
@ -36,8 +36,23 @@ private:
|
|||||||
Utility::FunctionOwned<TransparentClient, void (radio::HwInstance*)> m_isr_cb_pointer;
|
Utility::FunctionOwned<TransparentClient, void (radio::HwInstance*)> m_isr_cb_pointer;
|
||||||
std::optional<radio::Interrupts> m_pending_irqs = std::nullopt;
|
std::optional<radio::Interrupts> m_pending_irqs = std::nullopt;
|
||||||
|
|
||||||
|
enum class AppState
|
||||||
|
{
|
||||||
|
STARTUP,
|
||||||
|
PASSIVE,
|
||||||
|
ACTIVE_RX,
|
||||||
|
ACTIVE_TX,
|
||||||
|
RX_FRAME_READY
|
||||||
|
};
|
||||||
|
|
||||||
|
AppState m_state = AppState::STARTUP;
|
||||||
|
|
||||||
void m_cbRadioIrqHandler(radio::HwInstance*);
|
void m_cbRadioIrqHandler(radio::HwInstance*);
|
||||||
void m_processInterrupts();
|
std::optional<AppState> m_hwInterruptToNewState();
|
||||||
|
void m_transitionToState(const AppState& new_state);
|
||||||
|
void m_processState();
|
||||||
|
void m_initiateTx();
|
||||||
|
bool m_txBufferIsReady();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,10 +5,6 @@
|
|||||||
#ifndef SKL_TUNNEL_SKULLC_SAMD21_HAL_HPP
|
#ifndef SKL_TUNNEL_SKULLC_SAMD21_HAL_HPP
|
||||||
#define SKL_TUNNEL_SKULLC_SAMD21_HAL_HPP
|
#define SKL_TUNNEL_SKULLC_SAMD21_HAL_HPP
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include <hal_delay.h>
|
#include <hal_delay.h>
|
||||||
#include <hal_io.h>
|
#include <hal_io.h>
|
||||||
#include <hal_usart_async.h>
|
#include <hal_usart_async.h>
|
||||||
@ -16,6 +12,12 @@
|
|||||||
#include <utility_function.hpp>
|
#include <utility_function.hpp>
|
||||||
#include <utility_tag.hpp>
|
#include <utility_tag.hpp>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "app_board.hpp"
|
||||||
|
|
||||||
namespace Peripherals
|
namespace Peripherals
|
||||||
{
|
{
|
||||||
namespace Hal
|
namespace Hal
|
||||||
@ -26,7 +28,14 @@ namespace Samd
|
|||||||
struct StaticHal
|
struct StaticHal
|
||||||
{
|
{
|
||||||
static void initialize()
|
static void initialize()
|
||||||
{ }
|
{
|
||||||
|
App::Board::setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::uint32_t getMillis()
|
||||||
|
{
|
||||||
|
return App::Board::systickGet();
|
||||||
|
}
|
||||||
|
|
||||||
static void delay(const std::uint32_t milliseconds)
|
static void delay(const std::uint32_t milliseconds)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,15 +2,16 @@
|
|||||||
// Created by erki on 15.07.22.
|
// Created by erki on 15.07.22.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "driver_init.h"
|
||||||
|
|
||||||
#include "app_board.hpp"
|
#include "app_board.hpp"
|
||||||
|
|
||||||
#include "driver_init.h"
|
#include "skullc_samd21_hal.hpp"
|
||||||
|
|
||||||
#include <utility_logging.hpp>
|
#include <utility_logging.hpp>
|
||||||
#include <utility_asynclogger.hpp>
|
#include <utility_asynclogger.hpp>
|
||||||
#include <utility_staticpointer.hpp>
|
#include <utility_staticpointer.hpp>
|
||||||
|
|
||||||
#include "skullc_samd21_hal.hpp"
|
|
||||||
|
|
||||||
namespace Hal = Peripherals::Hal::Samd;
|
namespace Hal = Peripherals::Hal::Samd;
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ void setup()
|
|||||||
m_logger.setup(usart0);
|
m_logger.setup(usart0);
|
||||||
Utility::setLogger(*m_logger);
|
Utility::setLogger(*m_logger);
|
||||||
|
|
||||||
SysTick_Config(1000);
|
SysTick_Config(F_CPU / 1000u);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t systickGet()
|
std::uint32_t systickGet()
|
||||||
|
|||||||
@ -1,43 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by erki on 28.06.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "app_logging.hpp"
|
|
||||||
|
|
||||||
#include "driver_init.h"
|
|
||||||
|
|
||||||
#include <utility_logging.hpp>
|
|
||||||
#include <utility_asynclogger.hpp>
|
|
||||||
#include <utility_staticpointer.hpp>
|
|
||||||
|
|
||||||
#include "skullc_samd21_hal.hpp"
|
|
||||||
|
|
||||||
namespace Hal = Peripherals::Hal::Samd;
|
|
||||||
|
|
||||||
using Logger = Utility::AsyncLogger<Hal::SerialInterfaceAsync<usart_async_descriptor>, Hal::StaticHal, 5, 255>;
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
Utility::StaticPointer<Logger> m_logger;
|
|
||||||
|
|
||||||
void m_txCompleteCb(const usart_async_descriptor* const)
|
|
||||||
{
|
|
||||||
m_logger->txCompleteCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace App::Logging
|
|
||||||
{
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Hal::SerialInterfaceAsync<usart_async_descriptor> usart0{&USART_0};
|
|
||||||
usart0.registerTxCallback(m_txCompleteCb);
|
|
||||||
|
|
||||||
m_logger.setup(usart0);
|
|
||||||
Utility::setLogger(*m_logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -5,6 +5,10 @@
|
|||||||
#include "radio_hw_instance.hpp"
|
#include "radio_hw_instance.hpp"
|
||||||
|
|
||||||
#include "app_transparent_client.hpp"
|
#include "app_transparent_client.hpp"
|
||||||
|
#include "skullc_samd21_hal.hpp"
|
||||||
|
#include "utility_logging.hpp"
|
||||||
|
|
||||||
|
#include <utility_atomicscopeguard.hpp>
|
||||||
|
|
||||||
namespace App
|
namespace App
|
||||||
{
|
{
|
||||||
@ -14,7 +18,7 @@ TransparentClient::TransparentClient(const RadioSettings& initial_settings)
|
|||||||
, m_isr_cb_pointer(*this, &TransparentClient::m_cbRadioIrqHandler)
|
, m_isr_cb_pointer(*this, &TransparentClient::m_cbRadioIrqHandler)
|
||||||
{
|
{
|
||||||
apply_settings(initial_settings);
|
apply_settings(initial_settings);
|
||||||
|
m_radio->set_irq_handler(&m_isr_cb_pointer);
|
||||||
m_radio->set_current_state(radio::HwInstance::States::PLL_ON);
|
m_radio->set_current_state(radio::HwInstance::States::PLL_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,8 +34,21 @@ void TransparentClient::apply_settings(const RadioSettings& settings)
|
|||||||
|
|
||||||
void TransparentClient::process()
|
void TransparentClient::process()
|
||||||
{
|
{
|
||||||
if (m_pending_irqs)
|
std::optional<AppState> new_state_request = std::nullopt;
|
||||||
m_processInterrupts();
|
|
||||||
|
{
|
||||||
|
Utility::AtomicScopeGuard<Peripherals::Hal::Samd::StaticHal> irq_guard;
|
||||||
|
if (m_pending_irqs)
|
||||||
|
new_state_request = m_hwInterruptToNewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!new_state_request && m_txBufferIsReady())
|
||||||
|
new_state_request = AppState::ACTIVE_TX;
|
||||||
|
|
||||||
|
if (new_state_request)
|
||||||
|
m_transitionToState(*new_state_request);
|
||||||
|
|
||||||
|
m_processState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransparentClient::m_cbRadioIrqHandler(radio::HwInstance*)
|
void TransparentClient::m_cbRadioIrqHandler(radio::HwInstance*)
|
||||||
@ -43,9 +60,86 @@ void TransparentClient::m_cbRadioIrqHandler(radio::HwInstance*)
|
|||||||
m_pending_irqs = new_irqs;
|
m_pending_irqs = new_irqs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransparentClient::m_processInterrupts()
|
std::optional<TransparentClient::AppState> TransparentClient::m_hwInterruptToNewState()
|
||||||
{
|
{
|
||||||
|
const radio::Interrupts current_irqs = *m_pending_irqs;
|
||||||
m_pending_irqs = std::nullopt;
|
m_pending_irqs = std::nullopt;
|
||||||
|
|
||||||
|
SKULLC_LOG_DEBUG("APP: Processing IRQs: %d.", current_irqs);
|
||||||
|
|
||||||
|
const auto flag_is_set = [current_irqs](const radio::Interrupts& flag) -> bool
|
||||||
|
{
|
||||||
|
return std::underlying_type_t<radio::Interrupts>(current_irqs & flag);
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (m_state)
|
||||||
|
{
|
||||||
|
case AppState::STARTUP:
|
||||||
|
if (flag_is_set(radio::Interrupts::PLL_LOCK))
|
||||||
|
return AppState::PASSIVE;
|
||||||
|
break;
|
||||||
|
case AppState::PASSIVE:
|
||||||
|
if (flag_is_set(radio::Interrupts::RX_START))
|
||||||
|
return AppState::ACTIVE_RX;
|
||||||
|
else if (flag_is_set(radio::Interrupts::AMI))
|
||||||
|
return AppState::RX_FRAME_READY;
|
||||||
|
break;
|
||||||
|
case AppState::ACTIVE_RX:
|
||||||
|
[[fallthrough]];
|
||||||
|
case AppState::ACTIVE_TX:
|
||||||
|
if (flag_is_set(radio::Interrupts::TRX_END))
|
||||||
|
return AppState::PASSIVE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransparentClient::m_transitionToState(const AppState& new_state)
|
||||||
|
{
|
||||||
|
SKULLC_LOG_DEBUG("APP: Trans. to state. %d -> %d.", m_state, new_state);
|
||||||
|
|
||||||
|
switch (m_state)
|
||||||
|
{
|
||||||
|
case AppState::STARTUP:
|
||||||
|
if (new_state == AppState::PASSIVE)
|
||||||
|
m_radio->set_current_state(radio::HwInstance::States::RX_ON);
|
||||||
|
break;
|
||||||
|
case AppState::PASSIVE:
|
||||||
|
// new_state == AppState::ACTIVE_RX is a HW transition. State machine simply locks itself.
|
||||||
|
// new_state == AppState::RX_FRAME_READY is handled in process state.
|
||||||
|
if (new_state == AppState::ACTIVE_TX)
|
||||||
|
m_initiateTx();
|
||||||
|
break;
|
||||||
|
case AppState::ACTIVE_RX:
|
||||||
|
// new_state == AppState::PASSIVE is a HW transition. State machine simply unlocks itself.
|
||||||
|
break;
|
||||||
|
case AppState::ACTIVE_TX:
|
||||||
|
if (new_state == AppState::PASSIVE)
|
||||||
|
m_radio->set_current_state(radio::HwInstance::States::RX_ON);
|
||||||
|
break;
|
||||||
|
case AppState::RX_FRAME_READY:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_state = new_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransparentClient::m_processState()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransparentClient::m_initiateTx()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TransparentClient::m_txBufferIsReady()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
23
main.cpp
23
main.cpp
@ -6,7 +6,6 @@
|
|||||||
#include <utility_function.hpp>
|
#include <utility_function.hpp>
|
||||||
|
|
||||||
#include "radio_hw_instance.hpp"
|
#include "radio_hw_instance.hpp"
|
||||||
#include "app_logging.hpp"
|
|
||||||
#include "skullc_samd21_hal.hpp"
|
#include "skullc_samd21_hal.hpp"
|
||||||
#include "app_transparent_client.hpp"
|
#include "app_transparent_client.hpp"
|
||||||
|
|
||||||
@ -34,30 +33,28 @@ int main()
|
|||||||
atmel_start_init();
|
atmel_start_init();
|
||||||
|
|
||||||
Utility::Assert::setHandler(m_faultHandler);
|
Utility::Assert::setHandler(m_faultHandler);
|
||||||
|
Hal::StaticHal::initialize();
|
||||||
|
|
||||||
gpio_set_pin_level(OUT_LED_TX, false);
|
gpio_set_pin_level(OUT_LED_TX, false);
|
||||||
|
|
||||||
App::Logging::setup();
|
|
||||||
|
|
||||||
SKULLC_LOG_DEBUG("Begin.");
|
SKULLC_LOG_DEBUG("Begin.");
|
||||||
|
|
||||||
const App::RadioSettings settings;
|
const App::RadioSettings settings;
|
||||||
|
|
||||||
m_app.setup(settings);
|
m_app.setup(settings);
|
||||||
radio::HwInstance* radio_hw = radio::HwInstance::instance();
|
|
||||||
|
std::uint32_t counter = 0;
|
||||||
|
|
||||||
/* Replace with your application code */
|
/* Replace with your application code */
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
gpio_toggle_pin_level(OUT_LED_RX);
|
if (counter++ == 1000)
|
||||||
|
{
|
||||||
|
gpio_toggle_pin_level(OUT_LED_TX);
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
gpio_toggle_pin_level(OUT_LED_TX);
|
m_app->process();
|
||||||
|
Hal::StaticHal::delay(1);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -150,6 +150,7 @@ bool HwInstance::set_current_state(const States& new_state)
|
|||||||
|
|
||||||
register_write(Registers::TRX_STATE, std::uint8_t(new_state));
|
register_write(Registers::TRX_STATE, std::uint8_t(new_state));
|
||||||
m_wait_can_transition();
|
m_wait_can_transition();
|
||||||
|
SKULLC_LOG_DEBUG("HW: New state. %d -> %d.", m_current_state, new_state);
|
||||||
m_current_state = new_state;
|
m_current_state = new_state;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user