172 lines
3.7 KiB
C++
172 lines
3.7 KiB
C++
//
|
|
// Created by erki on 26.06.22.
|
|
//
|
|
|
|
#ifndef SKL_TUNNEL_SKULLC_SAMD21_HAL_HPP
|
|
#define SKL_TUNNEL_SKULLC_SAMD21_HAL_HPP
|
|
|
|
#include <hal_delay.h>
|
|
#include <hal_io.h>
|
|
#include <hal_usart_async.h>
|
|
#include <cmsis_gcc.h>
|
|
#include <utility_function.hpp>
|
|
#include <utility_tag.hpp>
|
|
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <cassert>
|
|
|
|
#include "app_board.hpp"
|
|
|
|
namespace Peripherals
|
|
{
|
|
namespace Hal
|
|
{
|
|
namespace Samd
|
|
{
|
|
|
|
struct StaticHal
|
|
{
|
|
static void initialize()
|
|
{
|
|
App::Board::setup();
|
|
}
|
|
|
|
static std::uint32_t getMillis()
|
|
{
|
|
return App::Board::systickGet();
|
|
}
|
|
|
|
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<typename original_handler>
|
|
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<usart_async_descriptor> callback)
|
|
{
|
|
usart_async_register_callback(usart, USART_ASYNC_RXC_CB, callback);
|
|
}
|
|
|
|
static void registerTxCallback(usart_async_descriptor* usart, async_io_callback<usart_async_descriptor> callback)
|
|
{
|
|
usart_async_register_callback(usart, USART_ASYNC_TXC_CB, callback);
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
struct SerialPeripheralToWrapper
|
|
{ };
|
|
|
|
template<>
|
|
struct SerialPeripheralToWrapper<usart_async_descriptor> : AsyncUsartWrapper
|
|
{ };
|
|
|
|
}
|
|
|
|
template<typename T>
|
|
struct SerialInterfaceAsync
|
|
{
|
|
using original_handler = T;
|
|
original_handler* handle = nullptr;
|
|
io_descriptor* io = nullptr;
|
|
|
|
using handle_wrapper = Detail::SerialPeripheralToWrapper<T>;
|
|
|
|
explicit SerialInterfaceAsync(original_handler* handle)
|
|
: handle(handle)
|
|
{
|
|
handle_wrapper::getIo(handle, &io);
|
|
handle_wrapper::enable(handle);
|
|
}
|
|
|
|
void registerRxCallback(Utility::IFunction<void (const original_handler* const)>* rx_cb)
|
|
{
|
|
assert(rx_cb);
|
|
|
|
handle_wrapper::registerRxCallback(handle, rx_cb->template toStaticFunction<SKULLC_TAG>());
|
|
}
|
|
|
|
void registerRxCallback(Detail::async_io_callback<original_handler> rx_cb)
|
|
{
|
|
handle_wrapper::registerRxCallback(handle, rx_cb);
|
|
}
|
|
|
|
void registerTxCallback(Utility::IFunction<void (const original_handler* const)>* tx_cb)
|
|
{
|
|
assert(tx_cb);
|
|
|
|
handle_wrapper::registerTxCallback(handle, tx_cb->template toStaticFunction<SKULLC_TAG>());
|
|
}
|
|
|
|
void registerTxCallback(Detail::async_io_callback<original_handler> 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<typename Td, std::size_t N>
|
|
bool transmit(std::array<Td, N>& array)
|
|
{
|
|
static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large.");
|
|
|
|
return transmit(reinterpret_cast<std::uint8_t*>(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<typename Td, std::size_t N>
|
|
bool receive(std::array<Td, N>& array)
|
|
{
|
|
static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large.");
|
|
|
|
return receive(reinterpret_cast<std::uint8_t*>(array.data()), std::uint32_t(N));
|
|
}
|
|
};
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif //SKL_TUNNEL_SKULLC_SAMD21_HAL_HPP
|