WIP working buffer copy with simple locking

This commit is contained in:
2023-02-27 23:17:11 +01:00
parent c3d62bba08
commit 9b22bc6acf
8 changed files with 322 additions and 53 deletions

View File

@@ -2,6 +2,7 @@
#include <stm32f1xx_hal.h>
#include <array>
#include <string_view>
#include "stm32f1xx_it.h"
@@ -22,11 +23,22 @@ constexpr auto UART2_PORT = GPIOA_BASE;
* small uart wrapper
* assumes USART1 with default pins/port
*/
template <uint16_t PinTX, uint16_t PinRX, uint32_t Port, uint32_t UsartBase>
enum class UartMode : uint8_t {
Blocking = 0,
Interrupt,
DMA,
};
template <uint16_t PinTX, uint16_t PinRX, uint32_t Port, uint32_t UsartBase,
UartMode M = UartMode::Interrupt, uint16_t Size = 1>
struct uart_handler {
static void enable_clocks() {
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_USART2_CLK_ENABLE();
if constexpr (UsartBase == USART1_BASE) {
__HAL_RCC_USART1_CLK_ENABLE();
} else if constexpr (UsartBase == USART2_BASE) {
__HAL_RCC_USART2_CLK_ENABLE();
}
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_AFIO_CLK_ENABLE();
}
@@ -46,13 +58,83 @@ struct uart_handler {
HAL_GPIO_Init(reinterpret_cast<GPIO_TypeDef*>(port), &ua_tx);
HAL_GPIO_Init(reinterpret_cast<GPIO_TypeDef*>(port), &ua_rx);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
// if constexpr (UsartBase == USART1_BASE) {
// /* USART1 interrupt Init */
// HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(USART1_IRQn);
// }
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
///* USART2 interrupt Init */
// HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(USART2_IRQn);
}
static void init_mode() {
if (M == UartMode::Blocking) {
return; // nothing to od
}
if constexpr (M == UartMode::Interrupt) {
constexpr auto GlobalInterrupt = [](auto Base) {
if (Base == USART1_BASE) {
return USART1_IRQn;
}
if (Base == USART2_BASE) {
return USART2_IRQn;
}
}(UsartBase);
HAL_NVIC_SetPriority(GlobalInterrupt, 0, 0);
HAL_NVIC_EnableIRQ(GlobalInterrupt);
HAL_UART_Receive_IT(&s_UARTHandle, &rx_buff, rx_buff_size);
return;
}
if constexpr (M == UartMode::DMA) {
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
__HAL_RCC_AFIO_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
/* System interrupt init*/
/** NOJTAG: JTAG-DP Disabled and SW-DP Enabled
*/
__HAL_AFIO_REMAP_SWJ_NOJTAG();
/* DMA interrupt init */
/* DMA1_Channel6_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
s_DMAHandle.Instance = DMA1_Channel6;
s_DMAHandle.Init.Direction = DMA_PERIPH_TO_MEMORY;
s_DMAHandle.Init.PeriphInc = DMA_PINC_DISABLE;
s_DMAHandle.Init.MemInc = DMA_MINC_ENABLE;
s_DMAHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
s_DMAHandle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
s_DMAHandle.Init.Mode = DMA_NORMAL;
s_DMAHandle.Init.Priority = DMA_PRIORITY_LOW;
write("TRY DMA INIT");
if (HAL_DMA_Init(&s_DMAHandle) != HAL_OK) {
write("FAILED");
// Error_Handler();
}
__HAL_LINKDMA(&s_UARTHandle, hdmarx, s_DMAHandle);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
HAL_DMA_Start_IT(
&s_DMAHandle, reinterpret_cast<uint32_t>(&s_UARTHandle.Instance->DR),
reinterpret_cast<uint32_t>(new_rx_buf.data()), new_rx_buf.size());
HAL_UARTEx_ReceiveToIdle_DMA(&s_UARTHandle, new_rx_buf.data(),
new_rx_buf.size());
__HAL_DMA_DISABLE_IT(&s_DMAHandle, DMA_IT_HT);
}
}
static bool enable_oscillators() {
@@ -101,32 +183,25 @@ struct uart_handler {
return false;
}
result = HAL_UART_Receive_IT(&s_UARTHandle, &rx_buff, rx_buff_size);
return result == HAL_OK;
}
static bool init() {
enable_clocks();
init_gpio();
if (!enable_oscillators()) {
return false;
}
return init_uart_handle();
auto result = init_uart_handle();
init_mode();
return result;
}
static HAL_StatusTypeDef write(const std::string_view& message,
uint32_t timeout = HAL_MAX_DELAY) {
// constexpr std::string_view carriage_return{"\r\n"};
return write(reinterpret_cast<uint8_t*>(const_cast<char*>(message.data())),
message.size(), timeout);
// return write(
// reinterpret_cast<uint8_t*>(const_cast<char*>(carriage_return.data())),
// carriage_return.size(), timeout);
}
static HAL_StatusTypeDef write(uint8_t* buf, uint16_t size,
@@ -135,9 +210,11 @@ struct uart_handler {
}
static UART_HandleTypeDef s_UARTHandle;
static DMA_HandleTypeDef s_DMAHandle;
static uint8_t* get_buf() { return &rx_buff; }
static const uint8_t* get_buf_c() { return &rx_buff; }
static std::array<uint8_t, Size> new_rx_buf;
private:
static constexpr auto pin_tx = PinTX;
@@ -148,12 +225,18 @@ struct uart_handler {
static uint8_t rx_buff;
};
template <uint16_t PinTX, uint16_t PinRX, uint32_t Port, uint32_t UsartBase>
UART_HandleTypeDef uart_handler<PinTX, PinRX, Port, UsartBase>::s_UARTHandle =
UART_HandleTypeDef();
template <uint16_t PinTX, uint16_t PinRX, uint32_t Port, uint32_t UsartBase,
UartMode M, uint16_t Size>
DMA_HandleTypeDef uart_handler<PinTX, PinRX, Port, UsartBase, M,
Size>::s_DMAHandle = DMA_HandleTypeDef();
using uart_interface =
uart_handler<UARTTX_PIN, UARTRX_PIN, UART_PORT, USART1_BASE>;
template <uint16_t PinTX, uint16_t PinRX, uint32_t Port, uint32_t UsartBase,
UartMode M, uint16_t Size>
UART_HandleTypeDef uart_handler<PinTX, PinRX, Port, UsartBase, M,
Size>::s_UARTHandle = UART_HandleTypeDef();
using gps_interface =
uart_handler<UART2TX_PIN, UART2RX_PIN, UART2_PORT, USART2_BASE>;
using uart_interface = uart_handler<UARTTX_PIN, UARTRX_PIN, UART_PORT,
USART1_BASE, UartMode::Interrupt>;
using gps_interface = uart_handler<UART2TX_PIN, UART2RX_PIN, UART2_PORT,
USART2_BASE, UartMode::DMA, 64>;