diff --git a/CMakeLists.txt b/CMakeLists.txt index a23b510..ea01580 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,8 +33,6 @@ add_executable(skl_tunnel hpl/gclk/hpl_gclk.c hal/src/hal_init.c - main.cpp - samd21a/gcc/system_samd21.c examples/driver_examples.c driver_init.c @@ -50,6 +48,9 @@ add_executable(skl_tunnel radio/src/radio_spi.c radio/src/radio_gpio.c radio/src/radio_hw_instance.cpp + + app/src/app_logging.cpp + main.cpp ) target_include_directories(skl_tunnel @@ -74,6 +75,7 @@ target_include_directories(skl_tunnel CMSIS/Core/Include samd21a/include radio/include + app/include ) target_link_libraries(skl_tunnel diff --git a/app/include/app_logging.hpp b/app/include/app_logging.hpp new file mode 100644 index 0000000..f65a993 --- /dev/null +++ b/app/include/app_logging.hpp @@ -0,0 +1,15 @@ +// +// 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 diff --git a/app/include/skullc_samd21_hal.hpp b/app/include/skullc_samd21_hal.hpp new file mode 100644 index 0000000..3963f3e --- /dev/null +++ b/app/include/skullc_samd21_hal.hpp @@ -0,0 +1,162 @@ +// +// Created by erki on 26.06.22. +// + +#ifndef SKL_TUNNEL_SKULLC_SAMD21_HAL_HPP +#define SKL_TUNNEL_SKULLC_SAMD21_HAL_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace Peripherals +{ +namespace Hal +{ +namespace Samd +{ + +struct StaticHal +{ + static void initialize() + { } + + static void delay(const std::uint32_t milliseconds) + { + delay_ms(milliseconds); + } + + static void delayUs(const std::uint32_t microseconds) + { + delay_us(microseconds); + } + + static void enableInterrupts() + { + __enable_irq(); + } + + static void disableInterrupts() + { + __disable_irq(); + } +}; + +namespace Detail +{ + +template +using async_io_callback = void (*)(const original_handler* const io_descriptor); + +struct AsyncUsartWrapper +{ + static void getIo(usart_async_descriptor* usart, io_descriptor** io) + { + usart_async_get_io_descriptor(usart, io); + } + + static void enable(usart_async_descriptor* usart) + { + usart_async_enable(usart); + } + + static void registerRxCallback(usart_async_descriptor* usart, async_io_callback callback) + { + usart_async_register_callback(usart, USART_ASYNC_RXC_CB, callback); + } + + static void registerTxCallback(usart_async_descriptor* usart, async_io_callback callback) + { + usart_async_register_callback(usart, USART_ASYNC_TXC_CB, callback); + } +}; + +template +struct SerialPeripheralToWrapper +{ }; + +template<> +struct SerialPeripheralToWrapper : AsyncUsartWrapper +{ }; + +} + +template +struct SerialInterfaceAsync +{ + using original_handler = T; + original_handler* handle = nullptr; + io_descriptor* io = nullptr; + + using handle_wrapper = Detail::SerialPeripheralToWrapper; + + explicit SerialInterfaceAsync(original_handler* handle) + : handle(handle) + { + handle_wrapper::getIo(handle, &io); + handle_wrapper::enable(handle); + } + + void registerRxCallback(Utility::IFunction* rx_cb) + { + assert(rx_cb); + + handle_wrapper::registerRxCallback(handle, rx_cb->template toStaticFunction()); + } + + void registerRxCallback(Detail::async_io_callback rx_cb) + { + handle_wrapper::registerRxCallback(handle, rx_cb); + } + + void registerTxCallback(Utility::IFunction* tx_cb) + { + assert(tx_cb); + + handle_wrapper::registerTxCallback(handle, tx_cb->template toStaticFunction()); + } + + void registerTxCallback(Detail::async_io_callback tx_cb) + { + handle_wrapper::registerTxCallback(handle, tx_cb); + } + + bool transmit(std::uint8_t* data, const std::uint32_t data_len) + { + return io_write(io, data, data_len) == ERR_NONE; + } + + template + bool transmit(std::array& array) + { + static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large."); + + return transmit(reinterpret_cast(array.data()), std::uint32_t(N)); + } + + bool receive(std::uint8_t* data, const std::uint32_t data_len) + { + return io_read(handle, data, data_len) == ERR_NONE; + } + + template + bool receive(std::array& array) + { + static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large."); + + return receive(reinterpret_cast(array.data()), std::uint32_t(N)); + } +}; + +} +} +} + +#endif //SKL_TUNNEL_SKULLC_SAMD21_HAL_HPP diff --git a/app/src/app_logging.cpp b/app/src/app_logging.cpp new file mode 100644 index 0000000..09257a1 --- /dev/null +++ b/app/src/app_logging.cpp @@ -0,0 +1,43 @@ +// +// Created by erki on 28.06.22. +// + +#include "app_logging.hpp" + +#include "driver_init.h" + +#include +#include +#include + +#include "skullc_samd21_hal.hpp" + +namespace Hal = Peripherals::Hal::Samd; + +using Logger = Utility::AsyncLogger, Hal::StaticHal, 5, 255>; + +namespace +{ + +Utility::StaticPointer m_logger; + +void m_txCompleteCb(const usart_async_descriptor* const) +{ + m_logger->txCompleteCallback(); +} + +} + +namespace App::Logging +{ + +void setup() +{ + Hal::SerialInterfaceAsync usart0{&USART_0}; + usart0.registerTxCallback(m_txCompleteCb); + + m_logger.setup(usart0); + Utility::setLogger(*m_logger); +} + +} diff --git a/main.cpp b/main.cpp index aaffd51..3857541 100644 --- a/main.cpp +++ b/main.cpp @@ -1,14 +1,16 @@ #include -#include +#include #include "radio_hw_instance.hpp" +#include "app_logging.hpp" +#include "skullc_samd21_hal.hpp" -static volatile bool can_send_uart = true; +namespace Hal = Peripherals::Hal::Samd; -static void tx_cb_USART_0(const struct usart_async_descriptor* const io_descr) +namespace { - can_send_uart = true; + } int main(void) @@ -18,11 +20,7 @@ int main(void) gpio_set_pin_level(OUT_LED_TX, false); - struct io_descriptor* usart_io = NULL; - - usart_async_register_callback(&USART_0, USART_ASYNC_TXC_CB, tx_cb_USART_0); - usart_async_get_io_descriptor(&USART_0, &usart_io); - usart_async_enable(&USART_0); + App::Logging::setup(); radio::HwInstance* radio_hw = radio::HwInstance::create_instance(); @@ -31,17 +29,11 @@ int main(void) { gpio_toggle_pin_level(OUT_LED_RX); - uint8_t uart_data[12] = { 0 }; + const int16_t radio_num = radio_hw->register_read(0x1C); - if (can_send_uart) - { - can_send_uart = false; - const int16_t radio_num = radio_hw->register_read(0x1C); + SKULLC_LOG_INFO("Reg 0x1C: %d", radio_num); - std::sprintf((char*)uart_data, "%d\n\r", radio_num); - io_write(usart_io, uart_data, 12); - gpio_toggle_pin_level(OUT_LED_TX); - } + gpio_toggle_pin_level(OUT_LED_TX); delay_ms(1000); }