// // 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