Merge branch 'feature/skullc_hal'

This commit is contained in:
Erki 2022-06-29 00:30:59 +03:00
commit 798d529b20
5 changed files with 234 additions and 20 deletions

View File

@ -33,8 +33,6 @@ add_executable(skl_tunnel
hpl/gclk/hpl_gclk.c hpl/gclk/hpl_gclk.c
hal/src/hal_init.c hal/src/hal_init.c
main.cpp
samd21a/gcc/system_samd21.c samd21a/gcc/system_samd21.c
examples/driver_examples.c examples/driver_examples.c
driver_init.c driver_init.c
@ -50,6 +48,9 @@ add_executable(skl_tunnel
radio/src/radio_spi.c radio/src/radio_spi.c
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
main.cpp
) )
target_include_directories(skl_tunnel target_include_directories(skl_tunnel
@ -74,6 +75,7 @@ target_include_directories(skl_tunnel
CMSIS/Core/Include CMSIS/Core/Include
samd21a/include samd21a/include
radio/include radio/include
app/include
) )
target_link_libraries(skl_tunnel target_link_libraries(skl_tunnel

View File

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

View File

@ -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 <array>
#include <cstdint>
#include <cassert>
#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>
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<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

43
app/src/app_logging.cpp Normal file
View File

@ -0,0 +1,43 @@
//
// 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);
}
}

View File

@ -1,14 +1,16 @@
#include <atmel_start.h> #include <atmel_start.h>
#include <cstdio> #include <utility_logging.hpp>
#include "radio_hw_instance.hpp" #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) int main(void)
@ -18,11 +20,7 @@ int main(void)
gpio_set_pin_level(OUT_LED_TX, false); gpio_set_pin_level(OUT_LED_TX, false);
struct io_descriptor* usart_io = NULL; App::Logging::setup();
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);
radio::HwInstance* radio_hw = radio::HwInstance::create_instance(); radio::HwInstance* radio_hw = radio::HwInstance::create_instance();
@ -31,17 +29,11 @@ int main(void)
{ {
gpio_toggle_pin_level(OUT_LED_RX); 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) SKULLC_LOG_INFO("Reg 0x1C: %d", radio_num);
{
can_send_uart = false;
const int16_t radio_num = radio_hw->register_read(0x1C);
std::sprintf((char*)uart_data, "%d\n\r", radio_num); gpio_toggle_pin_level(OUT_LED_TX);
io_write(usart_io, uart_data, 12);
gpio_toggle_pin_level(OUT_LED_TX);
}
delay_ms(1000); delay_ms(1000);
} }