From 9f5365f4629bf8ebea647e36873e6abb72b5834e Mon Sep 17 00:00:00 2001 From: Erki Date: Tue, 28 Jun 2022 00:20:32 +0300 Subject: [PATCH] starting HAL adaptions --- CMakeLists.txt | 5 +- main.cpp | 22 +++- skullc_interface/include/samd21_hal.hpp | 158 ++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 4 deletions(-) create mode 100644 skullc_interface/include/samd21_hal.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a23b510..261b1d4 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,8 @@ add_executable(skl_tunnel radio/src/radio_spi.c radio/src/radio_gpio.c radio/src/radio_hw_instance.cpp + + main.cpp ) target_include_directories(skl_tunnel @@ -74,6 +74,7 @@ target_include_directories(skl_tunnel CMSIS/Core/Include samd21a/include radio/include + skullc_interface/include ) target_link_libraries(skl_tunnel diff --git a/main.cpp b/main.cpp index aaffd51..2799dab 100644 --- a/main.cpp +++ b/main.cpp @@ -2,15 +2,23 @@ #include +#include +#include + #include "radio_hw_instance.hpp" -static volatile bool can_send_uart = true; +namespace +{ -static void tx_cb_USART_0(const struct usart_async_descriptor* const io_descr) +volatile bool can_send_uart = true; + +void tx_cb_USART_0(const struct usart_async_descriptor* const io_descr) { can_send_uart = true; } +} + int main(void) { /* Initializes MCU, drivers and middleware */ @@ -20,9 +28,16 @@ int main(void) struct io_descriptor* usart_io = NULL; + Utility::Function callback{tx_cb_USART_0}; + Peripherals::Hal::Samd::SerialInterfaceAsync usart0{&USART_0}; + + usart0.registerTxCallback(&callback); + +#if 0 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); +#endif radio::HwInstance* radio_hw = radio::HwInstance::create_instance(); @@ -39,7 +54,10 @@ int main(void) const int16_t radio_num = radio_hw->register_read(0x1C); std::sprintf((char*)uart_data, "%d\n\r", radio_num); + usart0.transmit(uart_data, 12); +#if 0 io_write(usart_io, uart_data, 12); +#endif gpio_toggle_pin_level(OUT_LED_TX); } diff --git a/skullc_interface/include/samd21_hal.hpp b/skullc_interface/include/samd21_hal.hpp new file mode 100644 index 0000000..dfce182 --- /dev/null +++ b/skullc_interface/include/samd21_hal.hpp @@ -0,0 +1,158 @@ +// +// Created by erki on 26.06.22. +// + +#ifndef SKL_TUNNEL_SAMD21_HAL_HPP +#define SKL_TUNNEL_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); + m_rx_cb = rx_cb; + + handle_wrapper::registerRxCallback(handle, m_rx_cb->template toStaticFunction()); + } + + void registerTxCallback(Utility::IFunction* tx_cb) + { + assert(tx_cb); + m_tx_cb = tx_cb; + + handle_wrapper::registerRxCallback(handle, m_tx_cb->template toStaticFunction()); + } + + 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)); + } + +private: + Utility::IFunction* m_rx_cb = nullptr; + Utility::IFunction* m_tx_cb = nullptr; +}; + +} +} +} + +#endif //SKL_TUNNEL_SAMD21_HAL_HPP