mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-15 20:35:33 +03:00
commit
d5c858e5b1
9 changed files with 421 additions and 435 deletions
|
@ -37,12 +37,62 @@
|
||||||
#include "common/utils.h"
|
#include "common/utils.h"
|
||||||
|
|
||||||
#include "drivers/dma.h"
|
#include "drivers/dma.h"
|
||||||
|
#include "drivers/dma_reqmap.h"
|
||||||
#include "drivers/rcc.h"
|
#include "drivers/rcc.h"
|
||||||
|
|
||||||
#include "drivers/serial.h"
|
#include "drivers/serial.h"
|
||||||
#include "drivers/serial_uart.h"
|
#include "drivers/serial_uart.h"
|
||||||
#include "drivers/serial_uart_impl.h"
|
#include "drivers/serial_uart_impl.h"
|
||||||
|
|
||||||
|
#include "pg/serial_uart.h"
|
||||||
|
|
||||||
|
#if defined(STM32H7)
|
||||||
|
#define UART_BUFFER_ATTRIBUTE DMA_RAM // D2 SRAM
|
||||||
|
#elif defined(STM32F7)
|
||||||
|
#define UART_BUFFER_ATTRIBUTE FAST_RAM_ZERO_INIT // DTCM RAM
|
||||||
|
#elif defined(STM32F4) || defined(STM32F3) || defined(STM32F1)
|
||||||
|
#define UART_BUFFER_ATTRIBUTE // NONE
|
||||||
|
#else
|
||||||
|
#error Undefined UART_BUFFER_ATTRIBUTE for this MCU
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UART_BUFFERS(n) \
|
||||||
|
UART_BUFFER(UART_BUFFER_ATTRIBUTE, n, R); \
|
||||||
|
UART_BUFFER(UART_BUFFER_ATTRIBUTE, n, T); struct dummy_s
|
||||||
|
|
||||||
|
#ifdef USE_UART1
|
||||||
|
UART_BUFFERS(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART2
|
||||||
|
UART_BUFFERS(2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART3
|
||||||
|
UART_BUFFERS(3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART4
|
||||||
|
UART_BUFFERS(4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART5
|
||||||
|
UART_BUFFERS(5);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART6
|
||||||
|
UART_BUFFERS(6);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART7
|
||||||
|
UART_BUFFERS(7);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART8
|
||||||
|
UART_BUFFERS(8);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef UART_BUFFERS
|
||||||
|
|
||||||
serialPort_t *uartOpen(UARTDevice_e device, serialReceiveCallbackPtr rxCallback, void *rxCallbackData, uint32_t baudRate, portMode_e mode, portOptions_e options)
|
serialPort_t *uartOpen(UARTDevice_e device, serialReceiveCallbackPtr rxCallback, void *rxCallbackData, uint32_t baudRate, portMode_e mode, portOptions_e options)
|
||||||
{
|
{
|
||||||
uartPort_t *s = serialUART(device, baudRate, mode, options);
|
uartPort_t *s = serialUART(device, baudRate, mode, options);
|
||||||
|
@ -232,6 +282,60 @@ const struct serialPortVTable uartVTable[] = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef USE_DMA
|
||||||
|
void uartConfigureDma(uartDevice_t *uartdev)
|
||||||
|
{
|
||||||
|
uartPort_t *s = &(uartdev->port);
|
||||||
|
const uartHardware_t *hardware = uartdev->hardware;
|
||||||
|
|
||||||
|
#ifdef USE_DMA_SPEC
|
||||||
|
UARTDevice_e device = hardware->device;
|
||||||
|
const dmaChannelSpec_t *dmaChannelSpec;
|
||||||
|
|
||||||
|
if (serialUartConfig(device)->txDmaopt != DMA_OPT_UNUSED) {
|
||||||
|
dmaChannelSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_UART_TX, device, serialUartConfig(device)->txDmaopt);
|
||||||
|
if (dmaChannelSpec) {
|
||||||
|
s->txDMAResource = dmaChannelSpec->ref;
|
||||||
|
s->txDMAChannel = dmaChannelSpec->channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serialUartConfig(device)->rxDmaopt != DMA_OPT_UNUSED) {
|
||||||
|
dmaChannelSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_UART_RX, device, serialUartConfig(device)->txDmaopt);
|
||||||
|
if (dmaChannelSpec) {
|
||||||
|
s->rxDMAResource = dmaChannelSpec->ref;
|
||||||
|
s->rxDMAChannel = dmaChannelSpec->channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Non USE_DMA_SPEC does not support configurable ON/OFF of UART DMA
|
||||||
|
|
||||||
|
if (hardware->rxDMAResource) {
|
||||||
|
s->rxDMAResource = hardware->rxDMAResource;
|
||||||
|
s->rxDMAChannel = hardware->rxDMAChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hardware->txDMAResource) {
|
||||||
|
s->txDMAResource = hardware->txDMAResource;
|
||||||
|
s->txDMAChannel = hardware->txDMAChannel;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (s->txDMAResource) {
|
||||||
|
dmaIdentifier_e identifier = dmaGetIdentifier(s->txDMAResource);
|
||||||
|
dmaInit(identifier, OWNER_SERIAL_TX, RESOURCE_INDEX(hardware->device));
|
||||||
|
dmaSetHandler(identifier, uartDmaIrqHandler, hardware->txPriority, (uint32_t)uartdev);
|
||||||
|
s->txDMAPeripheralBaseAddr = (uint32_t)&UART_REG_TXD(hardware->reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->rxDMAResource) {
|
||||||
|
dmaIdentifier_e identifier = dmaGetIdentifier(s->rxDMAResource);
|
||||||
|
dmaInit(identifier, OWNER_SERIAL_RX, RESOURCE_INDEX(hardware->device));
|
||||||
|
s->rxDMAPeripheralBaseAddr = (uint32_t)&UART_REG_RXD(hardware->reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#define UART_IRQHandler(type, dev) \
|
#define UART_IRQHandler(type, dev) \
|
||||||
void type ## dev ## _IRQHandler(void) \
|
void type ## dev ## _IRQHandler(void) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -44,9 +44,6 @@ typedef struct uartPort_s {
|
||||||
serialPort_t port;
|
serialPort_t port;
|
||||||
|
|
||||||
#ifdef USE_DMA
|
#ifdef USE_DMA
|
||||||
bool rxUseDma;
|
|
||||||
bool txUseDma;
|
|
||||||
|
|
||||||
#ifdef USE_HAL_DRIVER
|
#ifdef USE_HAL_DRIVER
|
||||||
DMA_HandleTypeDef rxDMAHandle;
|
DMA_HandleTypeDef rxDMAHandle;
|
||||||
DMA_HandleTypeDef txDMAHandle;
|
DMA_HandleTypeDef txDMAHandle;
|
||||||
|
@ -54,13 +51,8 @@ typedef struct uartPort_s {
|
||||||
|
|
||||||
dmaResource_t *rxDMAResource;
|
dmaResource_t *rxDMAResource;
|
||||||
dmaResource_t *txDMAResource;
|
dmaResource_t *txDMAResource;
|
||||||
#if defined(STM32F4) || defined(STM32F7)
|
|
||||||
uint32_t rxDMAChannel;
|
uint32_t rxDMAChannel;
|
||||||
uint32_t txDMAChannel;
|
uint32_t txDMAChannel;
|
||||||
#elif defined(STM32H7)
|
|
||||||
uint8_t rxDMARequest;
|
|
||||||
uint8_t txDMARequest;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t rxDMAIrq;
|
uint32_t rxDMAIrq;
|
||||||
uint32_t txDMAIrq;
|
uint32_t txDMAIrq;
|
||||||
|
|
|
@ -111,7 +111,7 @@ void uartReconfigure(uartPort_t *uartPort)
|
||||||
#if !defined(STM32H7)
|
#if !defined(STM32H7)
|
||||||
uartPort->rxDMAHandle.Init.Channel = uartPort->rxDMAChannel;
|
uartPort->rxDMAHandle.Init.Channel = uartPort->rxDMAChannel;
|
||||||
#else
|
#else
|
||||||
uartPort->txDMAHandle.Init.Request = uartPort->rxDMARequest;
|
uartPort->txDMAHandle.Init.Request = uartPort->rxDMAChannel;
|
||||||
#endif
|
#endif
|
||||||
uartPort->rxDMAHandle.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
uartPort->rxDMAHandle.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||||
uartPort->rxDMAHandle.Init.PeriphInc = DMA_PINC_DISABLE;
|
uartPort->rxDMAHandle.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||||
|
@ -159,7 +159,7 @@ void uartReconfigure(uartPort_t *uartPort)
|
||||||
#if !defined(STM32H7)
|
#if !defined(STM32H7)
|
||||||
uartPort->txDMAHandle.Init.Channel = uartPort->txDMAChannel;
|
uartPort->txDMAHandle.Init.Channel = uartPort->txDMAChannel;
|
||||||
#else
|
#else
|
||||||
uartPort->txDMAHandle.Init.Request = uartPort->txDMARequest;
|
uartPort->txDMAHandle.Init.Request = uartPort->txDMAChannel;
|
||||||
#endif
|
#endif
|
||||||
uartPort->txDMAHandle.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
uartPort->txDMAHandle.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||||
uartPort->txDMAHandle.Init.PeriphInc = DMA_PINC_DISABLE;
|
uartPort->txDMAHandle.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||||
|
@ -230,6 +230,100 @@ void uartTryStartTxDMA(uartPort_t *s)
|
||||||
HAL_UART_Transmit_DMA(&s->Handle, (uint8_t *)&s->port.txBuffer[fromwhere], size);
|
HAL_UART_Transmit_DMA(&s->Handle, (uint8_t *)&s->port.txBuffer[fromwhere], size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handleUsartTxDma(uartPort_t *s)
|
||||||
|
{
|
||||||
|
uartTryStartTxDMA(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uartDmaIrqHandler(dmaChannelDescriptor_t* descriptor)
|
||||||
|
{
|
||||||
|
uartPort_t *s = &(((uartDevice_t*)(descriptor->userParam))->port);
|
||||||
|
HAL_DMA_IRQHandler(&s->txDMAHandle);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void uartIrqHandler(uartPort_t *s)
|
||||||
|
{
|
||||||
|
UART_HandleTypeDef *huart = &s->Handle;
|
||||||
|
/* UART in mode Receiver ---------------------------------------------------*/
|
||||||
|
if ((__HAL_UART_GET_IT(huart, UART_IT_RXNE) != RESET)) {
|
||||||
|
uint8_t rbyte = (uint8_t)(huart->Instance->RDR & (uint8_t) 0xff);
|
||||||
|
|
||||||
|
if (s->port.rxCallback) {
|
||||||
|
s->port.rxCallback(rbyte, s->port.rxCallbackData);
|
||||||
|
} else {
|
||||||
|
s->port.rxBuffer[s->port.rxBufferHead] = rbyte;
|
||||||
|
s->port.rxBufferHead = (s->port.rxBufferHead + 1) % s->port.rxBufferSize;
|
||||||
|
}
|
||||||
|
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE));
|
||||||
|
|
||||||
|
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
|
||||||
|
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
||||||
|
|
||||||
|
__HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UART parity error interrupt occurred -------------------------------------*/
|
||||||
|
if ((__HAL_UART_GET_IT(huart, UART_IT_PE) != RESET)) {
|
||||||
|
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UART frame error interrupt occurred --------------------------------------*/
|
||||||
|
if ((__HAL_UART_GET_IT(huart, UART_IT_FE) != RESET)) {
|
||||||
|
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UART noise error interrupt occurred --------------------------------------*/
|
||||||
|
if ((__HAL_UART_GET_IT(huart, UART_IT_NE) != RESET)) {
|
||||||
|
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UART Over-Run interrupt occurred -----------------------------------------*/
|
||||||
|
if ((__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET)) {
|
||||||
|
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UART in mode Transmitter ------------------------------------------------*/
|
||||||
|
if (
|
||||||
|
#ifdef USE_DMA
|
||||||
|
!s->txDMAResource &&
|
||||||
|
#endif
|
||||||
|
(__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET)) {
|
||||||
|
/* Check that a Tx process is ongoing */
|
||||||
|
if (huart->gState != HAL_UART_STATE_BUSY_TX) {
|
||||||
|
if (s->port.txBufferTail == s->port.txBufferHead) {
|
||||||
|
huart->TxXferCount = 0;
|
||||||
|
/* Disable the UART Transmit Data Register Empty Interrupt */
|
||||||
|
CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
|
||||||
|
} else {
|
||||||
|
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) {
|
||||||
|
huart->Instance->TDR = (((uint16_t) s->port.txBuffer[s->port.txBufferTail]) & (uint16_t) 0x01FFU);
|
||||||
|
} else {
|
||||||
|
huart->Instance->TDR = (uint8_t)(s->port.txBuffer[s->port.txBufferTail]);
|
||||||
|
}
|
||||||
|
s->port.txBufferTail = (s->port.txBufferTail + 1) % s->port.txBufferSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UART in mode Transmitter (transmission end) -----------------------------*/
|
||||||
|
if ((__HAL_UART_GET_IT(huart, UART_IT_TC) != RESET)) {
|
||||||
|
HAL_UART_IRQHandler(huart);
|
||||||
|
#ifdef USE_DMA
|
||||||
|
if (s->txDMAResource) {
|
||||||
|
handleUsartTxDma(s);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__HAL_UART_GET_IT(huart, UART_IT_IDLE)) {
|
||||||
|
if (s->port.idleCallback) {
|
||||||
|
s->port.idleCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
__HAL_UART_CLEAR_IDLEFLAG(huart);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
#endif // USE_UART
|
#endif // USE_UART
|
||||||
|
|
|
@ -137,13 +137,10 @@ typedef struct uartHardware_s {
|
||||||
#ifdef USE_DMA
|
#ifdef USE_DMA
|
||||||
dmaResource_t *txDMAResource;
|
dmaResource_t *txDMAResource;
|
||||||
dmaResource_t *rxDMAResource;
|
dmaResource_t *rxDMAResource;
|
||||||
#if defined(STM32F4) || defined(STM32F7)
|
// For H7, {tx|rx}DMAChannel are DMAMUX input index for peripherals (DMA_REQUEST_xxx); RM0433 Table 110.
|
||||||
uint32_t DMAChannel;
|
// For F4 and F7, these are 32-bit channel identifiers (DMA_CHANNEL_x).
|
||||||
#elif defined(STM32H7)
|
uint32_t txDMAChannel;
|
||||||
// DMAMUX input from peripherals (DMA_REQUEST_xxx); RM0433 Table 110.
|
uint32_t rxDMAChannel;
|
||||||
uint8_t txDMARequest;
|
|
||||||
uint8_t rxDMARequest;
|
|
||||||
#endif
|
|
||||||
#endif // USE_DMA
|
#endif // USE_DMA
|
||||||
|
|
||||||
uartPinDef_t rxPins[UARTHARDWARE_MAX_PINS];
|
uartPinDef_t rxPins[UARTHARDWARE_MAX_PINS];
|
||||||
|
@ -170,12 +167,10 @@ typedef struct uartHardware_s {
|
||||||
uint8_t txPriority;
|
uint8_t txPriority;
|
||||||
uint8_t rxPriority;
|
uint8_t rxPriority;
|
||||||
|
|
||||||
#if defined(STM32H7) || defined(STM32F4)
|
|
||||||
volatile uint8_t *txBuffer;
|
volatile uint8_t *txBuffer;
|
||||||
volatile uint8_t *rxBuffer;
|
volatile uint8_t *rxBuffer;
|
||||||
uint16_t txBufferSize;
|
uint16_t txBufferSize;
|
||||||
uint16_t rxBufferSize;
|
uint16_t rxBufferSize;
|
||||||
#endif
|
|
||||||
} uartHardware_t;
|
} uartHardware_t;
|
||||||
|
|
||||||
extern const uartHardware_t uartHardware[];
|
extern const uartHardware_t uartHardware[];
|
||||||
|
@ -188,15 +183,8 @@ typedef struct uartDevice_s {
|
||||||
const uartHardware_t *hardware;
|
const uartHardware_t *hardware;
|
||||||
uartPinDef_t rx;
|
uartPinDef_t rx;
|
||||||
uartPinDef_t tx;
|
uartPinDef_t tx;
|
||||||
#if defined(STM32H7) || defined(STM32F4)
|
|
||||||
// For H7, buffers with possible DMA access is placed in D2 SRAM.
|
|
||||||
// For F4, buffers should NOT be in CCM DATA RAM (uartDevice is).
|
|
||||||
volatile uint8_t *rxBuffer;
|
volatile uint8_t *rxBuffer;
|
||||||
volatile uint8_t *txBuffer;
|
volatile uint8_t *txBuffer;
|
||||||
#else
|
|
||||||
volatile uint8_t rxBuffer[UART_RX_BUFFER_SIZE];
|
|
||||||
volatile uint8_t txBuffer[UART_TX_BUFFER_SIZE];
|
|
||||||
#endif
|
|
||||||
} uartDevice_t;
|
} uartDevice_t;
|
||||||
|
|
||||||
extern uartDevice_t *uartDevmap[];
|
extern uartDevice_t *uartDevmap[];
|
||||||
|
@ -210,3 +198,55 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
void uartIrqHandler(uartPort_t *s);
|
void uartIrqHandler(uartPort_t *s);
|
||||||
|
|
||||||
void uartReconfigure(uartPort_t *uartPort);
|
void uartReconfigure(uartPort_t *uartPort);
|
||||||
|
|
||||||
|
void uartConfigureDma(uartDevice_t *uartdev);
|
||||||
|
|
||||||
|
void uartDmaIrqHandler(dmaChannelDescriptor_t* descriptor);
|
||||||
|
|
||||||
|
#if defined(STM32F3) || defined(STM32F7) || defined(STM32H7)
|
||||||
|
#define UART_REG_RXD(base) ((base)->RDR)
|
||||||
|
#define UART_REG_TXD(base) ((base)->TDR)
|
||||||
|
#elif defined(STM32F1) || defined(STM32F4)
|
||||||
|
#define UART_REG_RXD(base) ((base)->DR)
|
||||||
|
#define UART_REG_TXD(base) ((base)->DR)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UART_BUFFER(type, n, rxtx) type volatile uint8_t uart ## n ## rxtx ## xBuffer[UART_ ## rxtx ## X_BUFFER_SIZE]
|
||||||
|
|
||||||
|
#define UART_BUFFERS_EXTERN(n) \
|
||||||
|
UART_BUFFER(extern, n, R); \
|
||||||
|
UART_BUFFER(extern, n, T); struct dummy_s
|
||||||
|
|
||||||
|
#ifdef USE_UART1
|
||||||
|
UART_BUFFERS_EXTERN(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART2
|
||||||
|
UART_BUFFERS_EXTERN(2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART3
|
||||||
|
UART_BUFFERS_EXTERN(3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART4
|
||||||
|
UART_BUFFERS_EXTERN(4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART5
|
||||||
|
UART_BUFFERS_EXTERN(5);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART6
|
||||||
|
UART_BUFFERS_EXTERN(6);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART7
|
||||||
|
UART_BUFFERS_EXTERN(7);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART8
|
||||||
|
UART_BUFFERS_EXTERN(8);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef UART_BUFFERS_EXTERN
|
||||||
|
|
|
@ -73,7 +73,11 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.rcc = RCC_APB2(USART1),
|
.rcc = RCC_APB2(USART1),
|
||||||
.irqn = USART1_IRQn,
|
.irqn = USART1_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART1_TXDMA,
|
.txPriority = NVIC_PRIO_SERIALUART1_TXDMA,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART1
|
.rxPriority = NVIC_PRIO_SERIALUART1,
|
||||||
|
.txBuffer = uart1TxBuffer,
|
||||||
|
.rxBuffer = uart1RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart1TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart1RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_UART2
|
#ifdef USE_UART2
|
||||||
|
@ -88,7 +92,11 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.rcc = RCC_APB1(USART2),
|
.rcc = RCC_APB1(USART2),
|
||||||
.irqn = USART2_IRQn,
|
.irqn = USART2_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART2,
|
.txPriority = NVIC_PRIO_SERIALUART2,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART2
|
.rxPriority = NVIC_PRIO_SERIALUART2,
|
||||||
|
.txBuffer = uart2TxBuffer,
|
||||||
|
.rxBuffer = uart2RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart2TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart2RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_UART3
|
#ifdef USE_UART3
|
||||||
|
@ -103,12 +111,16 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.rcc = RCC_APB1(USART3),
|
.rcc = RCC_APB1(USART3),
|
||||||
.irqn = USART3_IRQn,
|
.irqn = USART3_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART3,
|
.txPriority = NVIC_PRIO_SERIALUART3,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART3
|
.rxPriority = NVIC_PRIO_SERIALUART3,
|
||||||
|
.txBuffer = uart3TxBuffer,
|
||||||
|
.rxBuffer = uart3RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart3TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart3RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void uart_tx_dma_IRQHandler(dmaChannelDescriptor_t* descriptor)
|
void uartDmaIrqHandler(dmaChannelDescriptor_t* descriptor)
|
||||||
{
|
{
|
||||||
uartPort_t *s = (uartPort_t*)(descriptor->userParam);
|
uartPort_t *s = (uartPort_t*)(descriptor->userParam);
|
||||||
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
|
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
|
||||||
|
@ -132,30 +144,18 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
|
|
||||||
s->port.baudRate = baudRate;
|
s->port.baudRate = baudRate;
|
||||||
|
|
||||||
s->port.rxBuffer = uartdev->rxBuffer;
|
|
||||||
s->port.txBuffer = uartdev->txBuffer;
|
|
||||||
s->port.rxBufferSize = ARRAYLEN(uartdev->rxBuffer);
|
|
||||||
s->port.txBufferSize = ARRAYLEN(uartdev->txBuffer);
|
|
||||||
|
|
||||||
const uartHardware_t *hardware = uartdev->hardware;
|
const uartHardware_t *hardware = uartdev->hardware;
|
||||||
|
|
||||||
s->USARTx = hardware->reg;
|
s->USARTx = hardware->reg;
|
||||||
|
|
||||||
|
s->port.rxBuffer = hardware->rxBuffer;
|
||||||
|
s->port.txBuffer = hardware->txBuffer;
|
||||||
|
s->port.rxBufferSize = hardware->rxBufferSize;
|
||||||
|
s->port.txBufferSize = hardware->txBufferSize;
|
||||||
|
|
||||||
RCC_ClockCmd(hardware->rcc, ENABLE);
|
RCC_ClockCmd(hardware->rcc, ENABLE);
|
||||||
|
|
||||||
if (hardware->rxDMAResource) {
|
uartConfigureDma(uartdev);
|
||||||
dmaInit(dmaGetIdentifier(hardware->rxDMAResource), OWNER_SERIAL_RX, RESOURCE_INDEX(device));
|
|
||||||
s->rxDMAResource = hardware->rxDMAResource;
|
|
||||||
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hardware->txDMAResource) {
|
|
||||||
const dmaIdentifier_e identifier = dmaGetIdentifier(hardware->txDMAResource);
|
|
||||||
dmaInit(identifier, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
|
||||||
dmaSetHandler(identifier, uart_tx_dma_IRQHandler, hardware->txPriority, (uint32_t)s);
|
|
||||||
s->txDMAResource = hardware->txDMAResource;
|
|
||||||
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
|
|
||||||
}
|
|
||||||
|
|
||||||
IO_t rxIO = IOGetByTag(uartdev->rx.pin);
|
IO_t rxIO = IOGetByTag(uartdev->rx.pin);
|
||||||
IO_t txIO = IOGetByTag(uartdev->tx.pin);
|
IO_t txIO = IOGetByTag(uartdev->tx.pin);
|
||||||
|
|
|
@ -83,6 +83,18 @@
|
||||||
# define UART3_TX_DMA 0
|
# define UART3_TX_DMA 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART4_RX_DMA
|
||||||
|
# define UART4_RX_DMA DMA2_Channel3
|
||||||
|
#else
|
||||||
|
# define UART4_RX_DMA 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UART4_TX_DMA
|
||||||
|
# define UART4_TX_DMA DMA2_Channel5
|
||||||
|
#else
|
||||||
|
# define UART4_TX_DMA 0
|
||||||
|
#endif
|
||||||
|
|
||||||
const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
#ifdef USE_UART1
|
#ifdef USE_UART1
|
||||||
{
|
{
|
||||||
|
@ -97,6 +109,10 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.irqn = USART1_IRQn,
|
.irqn = USART1_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART1_TXDMA,
|
.txPriority = NVIC_PRIO_SERIALUART1_TXDMA,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART1_RXDMA,
|
.rxPriority = NVIC_PRIO_SERIALUART1_RXDMA,
|
||||||
|
.txBuffer = uart1TxBuffer,
|
||||||
|
.rxBuffer = uart1RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart1TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart1RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -113,6 +129,10 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.irqn = USART2_IRQn,
|
.irqn = USART2_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART2_TXDMA,
|
.txPriority = NVIC_PRIO_SERIALUART2_TXDMA,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART2_RXDMA,
|
.rxPriority = NVIC_PRIO_SERIALUART2_RXDMA,
|
||||||
|
.txBuffer = uart2TxBuffer,
|
||||||
|
.rxBuffer = uart2RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart2TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart2RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -129,6 +149,10 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.irqn = USART3_IRQn,
|
.irqn = USART3_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART3_TXDMA,
|
.txPriority = NVIC_PRIO_SERIALUART3_TXDMA,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART3_RXDMA,
|
.rxPriority = NVIC_PRIO_SERIALUART3_RXDMA,
|
||||||
|
.txBuffer = uart3TxBuffer,
|
||||||
|
.rxBuffer = uart3RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart3TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart3RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -146,6 +170,10 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.irqn = UART4_IRQn,
|
.irqn = UART4_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART4_TXDMA,
|
.txPriority = NVIC_PRIO_SERIALUART4_TXDMA,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART4_RXDMA,
|
.rxPriority = NVIC_PRIO_SERIALUART4_RXDMA,
|
||||||
|
.txBuffer = uart4TxBuffer,
|
||||||
|
.rxBuffer = uart4RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart4TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart4RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -163,11 +191,15 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.irqn = UART5_IRQn,
|
.irqn = UART5_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART5,
|
.txPriority = NVIC_PRIO_SERIALUART5,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART5,
|
.rxPriority = NVIC_PRIO_SERIALUART5,
|
||||||
|
.txBuffer = uart5TxBuffer,
|
||||||
|
.rxBuffer = uart5RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart5TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart5RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static void handleUsartTxDma(dmaChannelDescriptor_t* descriptor)
|
void uartDmaIrqHandler(dmaChannelDescriptor_t* descriptor)
|
||||||
{
|
{
|
||||||
uartPort_t *s = (uartPort_t*)(descriptor->userParam);
|
uartPort_t *s = (uartPort_t*)(descriptor->userParam);
|
||||||
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
|
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
|
||||||
|
@ -217,30 +249,19 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
|
|
||||||
s->port.baudRate = baudRate;
|
s->port.baudRate = baudRate;
|
||||||
|
|
||||||
s->port.rxBuffer = uartDev->rxBuffer;
|
|
||||||
s->port.txBuffer = uartDev->txBuffer;
|
|
||||||
s->port.rxBufferSize = sizeof(uartDev->rxBuffer);
|
|
||||||
s->port.txBufferSize = sizeof(uartDev->txBuffer);
|
|
||||||
|
|
||||||
const uartHardware_t *hardware = uartDev->hardware;
|
const uartHardware_t *hardware = uartDev->hardware;
|
||||||
|
|
||||||
s->USARTx = hardware->reg;
|
s->USARTx = hardware->reg;
|
||||||
|
|
||||||
|
|
||||||
|
s->port.rxBuffer = hardware->rxBuffer;
|
||||||
|
s->port.txBuffer = hardware->txBuffer;
|
||||||
|
s->port.rxBufferSize = hardware->rxBufferSize;
|
||||||
|
s->port.txBufferSize = hardware->txBufferSize;
|
||||||
|
|
||||||
RCC_ClockCmd(hardware->rcc, ENABLE);
|
RCC_ClockCmd(hardware->rcc, ENABLE);
|
||||||
|
|
||||||
if (hardware->rxDMAResource) {
|
uartConfigureDma(uartDev);
|
||||||
dmaInit(dmaGetIdentifier(hardware->rxDMAResource), OWNER_SERIAL_RX, RESOURCE_INDEX(device));
|
|
||||||
s->rxDMAResource = hardware->rxDMAResource;
|
|
||||||
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hardware->txDMAResource) {
|
|
||||||
const dmaIdentifier_e identifier = dmaGetIdentifier(hardware->txDMAResource);
|
|
||||||
dmaInit(identifier, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
|
||||||
dmaSetHandler(identifier, handleUsartTxDma, hardware->txPriority, (uint32_t)s);
|
|
||||||
s->txDMAResource = hardware->txDMAResource;
|
|
||||||
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR;
|
|
||||||
}
|
|
||||||
|
|
||||||
serialUARTInitIO(IOGetByTag(uartDev->tx.pin), IOGetByTag(uartDev->rx.pin), mode, options, hardware->af, device);
|
serialUARTInitIO(IOGetByTag(uartDev->tx.pin), IOGetByTag(uartDev->rx.pin), mode, options, hardware->af, device);
|
||||||
|
|
||||||
|
|
|
@ -39,42 +39,13 @@
|
||||||
#include "drivers/serial_uart.h"
|
#include "drivers/serial_uart.h"
|
||||||
#include "drivers/serial_uart_impl.h"
|
#include "drivers/serial_uart_impl.h"
|
||||||
|
|
||||||
#define UART_BUFFERS(n) \
|
|
||||||
volatile uint8_t uart ## n ## RxBuffer[UART_RX_BUFFER_SIZE]; \
|
|
||||||
volatile uint8_t uart ## n ## TxBuffer[UART_TX_BUFFER_SIZE]; struct dummy_s
|
|
||||||
|
|
||||||
#ifdef USE_UART1
|
|
||||||
UART_BUFFERS(1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_UART2
|
|
||||||
UART_BUFFERS(2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_UART3
|
|
||||||
UART_BUFFERS(3);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_UART4
|
|
||||||
UART_BUFFERS(4);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_UART5
|
|
||||||
UART_BUFFERS(5);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_UART6
|
|
||||||
UART_BUFFERS(6);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef UART_BUFFERS
|
|
||||||
|
|
||||||
const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
#ifdef USE_UART1
|
#ifdef USE_UART1
|
||||||
{
|
{
|
||||||
.device = UARTDEV_1,
|
.device = UARTDEV_1,
|
||||||
.reg = USART1,
|
.reg = USART1,
|
||||||
.DMAChannel = DMA_Channel_4,
|
.rxDMAChannel = DMA_Channel_4,
|
||||||
|
.txDMAChannel = DMA_Channel_4,
|
||||||
#ifdef USE_UART1_RX_DMA
|
#ifdef USE_UART1_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA2_Stream5,
|
.rxDMAResource = (dmaResource_t *)DMA2_Stream5,
|
||||||
#endif
|
#endif
|
||||||
|
@ -107,7 +78,8 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
{
|
{
|
||||||
.device = UARTDEV_2,
|
.device = UARTDEV_2,
|
||||||
.reg = USART2,
|
.reg = USART2,
|
||||||
.DMAChannel = DMA_Channel_4,
|
.rxDMAChannel = DMA_Channel_4,
|
||||||
|
.txDMAChannel = DMA_Channel_4,
|
||||||
#ifdef USE_UART2_RX_DMA
|
#ifdef USE_UART2_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA1_Stream5,
|
.rxDMAResource = (dmaResource_t *)DMA1_Stream5,
|
||||||
#endif
|
#endif
|
||||||
|
@ -132,7 +104,8 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
{
|
{
|
||||||
.device = UARTDEV_3,
|
.device = UARTDEV_3,
|
||||||
.reg = USART3,
|
.reg = USART3,
|
||||||
.DMAChannel = DMA_Channel_4,
|
.rxDMAChannel = DMA_Channel_4,
|
||||||
|
.txDMAChannel = DMA_Channel_4,
|
||||||
#ifdef USE_UART3_RX_DMA
|
#ifdef USE_UART3_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA1_Stream1,
|
.rxDMAResource = (dmaResource_t *)DMA1_Stream1,
|
||||||
#endif
|
#endif
|
||||||
|
@ -157,7 +130,8 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
{
|
{
|
||||||
.device = UARTDEV_4,
|
.device = UARTDEV_4,
|
||||||
.reg = UART4,
|
.reg = UART4,
|
||||||
.DMAChannel = DMA_Channel_4,
|
.rxDMAChannel = DMA_Channel_4,
|
||||||
|
.txDMAChannel = DMA_Channel_4,
|
||||||
#ifdef USE_UART4_RX_DMA
|
#ifdef USE_UART4_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA1_Stream2,
|
.rxDMAResource = (dmaResource_t *)DMA1_Stream2,
|
||||||
#endif
|
#endif
|
||||||
|
@ -182,7 +156,8 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
{
|
{
|
||||||
.device = UARTDEV_5,
|
.device = UARTDEV_5,
|
||||||
.reg = UART5,
|
.reg = UART5,
|
||||||
.DMAChannel = DMA_Channel_4,
|
.rxDMAChannel = DMA_Channel_4,
|
||||||
|
.txDMAChannel = DMA_Channel_4,
|
||||||
#ifdef USE_UART5_RX_DMA
|
#ifdef USE_UART5_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA1_Stream0,
|
.rxDMAResource = (dmaResource_t *)DMA1_Stream0,
|
||||||
#endif
|
#endif
|
||||||
|
@ -207,7 +182,8 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
{
|
{
|
||||||
.device = UARTDEV_6,
|
.device = UARTDEV_6,
|
||||||
.reg = USART6,
|
.reg = USART6,
|
||||||
.DMAChannel = DMA_Channel_5,
|
.rxDMAChannel = DMA_Channel_5,
|
||||||
|
.txDMAChannel = DMA_Channel_5,
|
||||||
#ifdef USE_UART6_RX_DMA
|
#ifdef USE_UART6_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA2_Stream1,
|
.rxDMAResource = (dmaResource_t *)DMA2_Stream1,
|
||||||
#endif
|
#endif
|
||||||
|
@ -246,7 +222,7 @@ static void handleUsartTxDma(uartPort_t *s)
|
||||||
uartTryStartTxDMA(s);
|
uartTryStartTxDMA(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmaIRQHandler(dmaChannelDescriptor_t* descriptor)
|
void uartDmaIrqHandler(dmaChannelDescriptor_t* descriptor)
|
||||||
{
|
{
|
||||||
uartPort_t *s = &(((uartDevice_t*)(descriptor->userParam))->port);
|
uartPort_t *s = &(((uartDevice_t*)(descriptor->userParam))->port);
|
||||||
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF))
|
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF))
|
||||||
|
@ -292,21 +268,9 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
|
|
||||||
s->USARTx = hardware->reg;
|
s->USARTx = hardware->reg;
|
||||||
|
|
||||||
if (hardware->rxDMAResource) {
|
#ifdef USE_DMA
|
||||||
dmaInit(dmaGetIdentifier(hardware->rxDMAResource), OWNER_SERIAL_RX, RESOURCE_INDEX(device));
|
uartConfigureDma(uart);
|
||||||
s->rxDMAChannel = hardware->DMAChannel;
|
#endif
|
||||||
s->rxDMAResource = hardware->rxDMAResource;
|
|
||||||
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hardware->txDMAResource) {
|
|
||||||
const dmaIdentifier_e identifier = dmaGetIdentifier(hardware->txDMAResource);
|
|
||||||
dmaInit(identifier, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
|
||||||
dmaSetHandler(identifier, dmaIRQHandler, hardware->txPriority, (uint32_t)uart);
|
|
||||||
s->txDMAChannel = hardware->DMAChannel;
|
|
||||||
s->txDMAResource = hardware->txDMAResource;
|
|
||||||
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
|
|
||||||
}
|
|
||||||
|
|
||||||
IO_t txIO = IOGetByTag(uart->tx.pin);
|
IO_t txIO = IOGetByTag(uart->tx.pin);
|
||||||
IO_t rxIO = IOGetByTag(uart->rx.pin);
|
IO_t rxIO = IOGetByTag(uart->rx.pin);
|
||||||
|
@ -330,7 +294,8 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(s->rxDMAChannel)) {
|
#ifdef USE_DMA
|
||||||
|
if (!(s->rxDMAResource)) {
|
||||||
NVIC_InitTypeDef NVIC_InitStructure;
|
NVIC_InitTypeDef NVIC_InitStructure;
|
||||||
|
|
||||||
NVIC_InitStructure.NVIC_IRQChannel = hardware->irqn;
|
NVIC_InitStructure.NVIC_IRQChannel = hardware->irqn;
|
||||||
|
@ -339,6 +304,7 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||||
NVIC_Init(&NVIC_InitStructure);
|
NVIC_Init(&NVIC_InitStructure);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,14 +41,13 @@
|
||||||
|
|
||||||
#include "stm32f7xx_ll_usart.h"
|
#include "stm32f7xx_ll_usart.h"
|
||||||
|
|
||||||
static void handleUsartTxDma(uartPort_t *s);
|
|
||||||
|
|
||||||
const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
#ifdef USE_UART1
|
#ifdef USE_UART1
|
||||||
{
|
{
|
||||||
.device = UARTDEV_1,
|
.device = UARTDEV_1,
|
||||||
.reg = USART1,
|
.reg = USART1,
|
||||||
.DMAChannel = DMA_CHANNEL_4,
|
.rxDMAChannel = DMA_CHANNEL_4,
|
||||||
|
.txDMAChannel = DMA_CHANNEL_4,
|
||||||
#ifdef USE_UART1_RX_DMA
|
#ifdef USE_UART1_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA2_Stream5,
|
.rxDMAResource = (dmaResource_t *)DMA2_Stream5,
|
||||||
#endif
|
#endif
|
||||||
|
@ -75,7 +74,11 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.rcc_apb2 = RCC_APB2(USART1),
|
.rcc_apb2 = RCC_APB2(USART1),
|
||||||
.rxIrq = USART1_IRQn,
|
.rxIrq = USART1_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART1_TXDMA,
|
.txPriority = NVIC_PRIO_SERIALUART1_TXDMA,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART1
|
.rxPriority = NVIC_PRIO_SERIALUART1,
|
||||||
|
.txBuffer = uart1TxBuffer,
|
||||||
|
.rxBuffer = uart1RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart1TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart1RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -83,7 +86,8 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
{
|
{
|
||||||
.device = UARTDEV_2,
|
.device = UARTDEV_2,
|
||||||
.reg = USART2,
|
.reg = USART2,
|
||||||
.DMAChannel = DMA_CHANNEL_4,
|
.rxDMAChannel = DMA_CHANNEL_4,
|
||||||
|
.txDMAChannel = DMA_CHANNEL_4,
|
||||||
#ifdef USE_UART2_RX_DMA
|
#ifdef USE_UART2_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA1_Stream5,
|
.rxDMAResource = (dmaResource_t *)DMA1_Stream5,
|
||||||
#endif
|
#endif
|
||||||
|
@ -104,7 +108,11 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.rcc_apb1 = RCC_APB1(USART2),
|
.rcc_apb1 = RCC_APB1(USART2),
|
||||||
.rxIrq = USART2_IRQn,
|
.rxIrq = USART2_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART2_TXDMA,
|
.txPriority = NVIC_PRIO_SERIALUART2_TXDMA,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART2
|
.rxPriority = NVIC_PRIO_SERIALUART2,
|
||||||
|
.txBuffer = uart2TxBuffer,
|
||||||
|
.rxBuffer = uart2RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart2TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart2RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -112,7 +120,8 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
{
|
{
|
||||||
.device = UARTDEV_3,
|
.device = UARTDEV_3,
|
||||||
.reg = USART3,
|
.reg = USART3,
|
||||||
.DMAChannel = DMA_CHANNEL_4,
|
.rxDMAChannel = DMA_CHANNEL_4,
|
||||||
|
.txDMAChannel = DMA_CHANNEL_4,
|
||||||
#ifdef USE_UART3_RX_DMA
|
#ifdef USE_UART3_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA1_Stream1,
|
.rxDMAResource = (dmaResource_t *)DMA1_Stream1,
|
||||||
#endif
|
#endif
|
||||||
|
@ -135,7 +144,11 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.rcc_apb1 = RCC_APB1(USART3),
|
.rcc_apb1 = RCC_APB1(USART3),
|
||||||
.rxIrq = USART3_IRQn,
|
.rxIrq = USART3_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART3_TXDMA,
|
.txPriority = NVIC_PRIO_SERIALUART3_TXDMA,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART3
|
.rxPriority = NVIC_PRIO_SERIALUART3,
|
||||||
|
.txBuffer = uart3TxBuffer,
|
||||||
|
.rxBuffer = uart3RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart3TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart3RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -143,7 +156,8 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
{
|
{
|
||||||
.device = UARTDEV_4,
|
.device = UARTDEV_4,
|
||||||
.reg = UART4,
|
.reg = UART4,
|
||||||
.DMAChannel = DMA_CHANNEL_4,
|
.rxDMAChannel = DMA_CHANNEL_4,
|
||||||
|
.txDMAChannel = DMA_CHANNEL_4,
|
||||||
#ifdef USE_UART4_RX_DMA
|
#ifdef USE_UART4_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA1_Stream2,
|
.rxDMAResource = (dmaResource_t *)DMA1_Stream2,
|
||||||
#endif
|
#endif
|
||||||
|
@ -172,7 +186,11 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.rcc_apb1 = RCC_APB1(UART4),
|
.rcc_apb1 = RCC_APB1(UART4),
|
||||||
.rxIrq = UART4_IRQn,
|
.rxIrq = UART4_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART4_TXDMA,
|
.txPriority = NVIC_PRIO_SERIALUART4_TXDMA,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART4
|
.rxPriority = NVIC_PRIO_SERIALUART4,
|
||||||
|
.txBuffer = uart4TxBuffer,
|
||||||
|
.rxBuffer = uart4RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart4TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart4RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -180,7 +198,8 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
{
|
{
|
||||||
.device = UARTDEV_5,
|
.device = UARTDEV_5,
|
||||||
.reg = UART5,
|
.reg = UART5,
|
||||||
.DMAChannel = DMA_CHANNEL_4,
|
.rxDMAChannel = DMA_CHANNEL_4,
|
||||||
|
.txDMAChannel = DMA_CHANNEL_4,
|
||||||
#ifdef USE_UART5_RX_DMA
|
#ifdef USE_UART5_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA1_Stream0,
|
.rxDMAResource = (dmaResource_t *)DMA1_Stream0,
|
||||||
#endif
|
#endif
|
||||||
|
@ -209,7 +228,11 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.rcc_apb1 = RCC_APB1(UART5),
|
.rcc_apb1 = RCC_APB1(UART5),
|
||||||
.rxIrq = UART5_IRQn,
|
.rxIrq = UART5_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART5_TXDMA,
|
.txPriority = NVIC_PRIO_SERIALUART5_TXDMA,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART5
|
.rxPriority = NVIC_PRIO_SERIALUART5,
|
||||||
|
.txBuffer = uart5TxBuffer,
|
||||||
|
.rxBuffer = uart5RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart5TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart5RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -217,7 +240,8 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
{
|
{
|
||||||
.device = UARTDEV_6,
|
.device = UARTDEV_6,
|
||||||
.reg = USART6,
|
.reg = USART6,
|
||||||
.DMAChannel = DMA_CHANNEL_5,
|
.rxDMAChannel = DMA_CHANNEL_5,
|
||||||
|
.txDMAChannel = DMA_CHANNEL_5,
|
||||||
#ifdef USE_UART6_RX_DMA
|
#ifdef USE_UART6_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA2_Stream1,
|
.rxDMAResource = (dmaResource_t *)DMA2_Stream1,
|
||||||
#endif
|
#endif
|
||||||
|
@ -238,7 +262,11 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.rcc_apb2 = RCC_APB2(USART6),
|
.rcc_apb2 = RCC_APB2(USART6),
|
||||||
.rxIrq = USART6_IRQn,
|
.rxIrq = USART6_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART6_TXDMA,
|
.txPriority = NVIC_PRIO_SERIALUART6_TXDMA,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART6
|
.rxPriority = NVIC_PRIO_SERIALUART6,
|
||||||
|
.txBuffer = uart6TxBuffer,
|
||||||
|
.rxBuffer = uart6RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart6TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart6RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -246,7 +274,8 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
{
|
{
|
||||||
.device = UARTDEV_7,
|
.device = UARTDEV_7,
|
||||||
.reg = UART7,
|
.reg = UART7,
|
||||||
.DMAChannel = DMA_CHANNEL_5,
|
.rxDMAChannel = DMA_CHANNEL_5,
|
||||||
|
.txDMAChannel = DMA_CHANNEL_5,
|
||||||
#ifdef USE_UART7_RX_DMA
|
#ifdef USE_UART7_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA1_Stream3,
|
.rxDMAResource = (dmaResource_t *)DMA1_Stream3,
|
||||||
#endif
|
#endif
|
||||||
|
@ -275,7 +304,11 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.rcc_apb1 = RCC_APB1(UART7),
|
.rcc_apb1 = RCC_APB1(UART7),
|
||||||
.rxIrq = UART7_IRQn,
|
.rxIrq = UART7_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART7_TXDMA,
|
.txPriority = NVIC_PRIO_SERIALUART7_TXDMA,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART7
|
.rxPriority = NVIC_PRIO_SERIALUART7,
|
||||||
|
.txBuffer = uart7TxBuffer,
|
||||||
|
.rxBuffer = uart7RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart7TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart7RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -283,7 +316,8 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
{
|
{
|
||||||
.device = UARTDEV_8,
|
.device = UARTDEV_8,
|
||||||
.reg = UART8,
|
.reg = UART8,
|
||||||
.DMAChannel = DMA_CHANNEL_5,
|
.rxDMAChannel = DMA_CHANNEL_5,
|
||||||
|
.txDMAChannel = DMA_CHANNEL_5,
|
||||||
#ifdef USE_UART8_RX_DMA
|
#ifdef USE_UART8_RX_DMA
|
||||||
.rxDMAResource = (dmaResource_t *)DMA1_Stream6,
|
.rxDMAResource = (dmaResource_t *)DMA1_Stream6,
|
||||||
#endif
|
#endif
|
||||||
|
@ -302,99 +336,15 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.rcc_apb1 = RCC_APB1(UART8),
|
.rcc_apb1 = RCC_APB1(UART8),
|
||||||
.rxIrq = UART8_IRQn,
|
.rxIrq = UART8_IRQn,
|
||||||
.txPriority = NVIC_PRIO_SERIALUART8_TXDMA,
|
.txPriority = NVIC_PRIO_SERIALUART8_TXDMA,
|
||||||
.rxPriority = NVIC_PRIO_SERIALUART8
|
.rxPriority = NVIC_PRIO_SERIALUART8,
|
||||||
|
.txBuffer = uart8TxBuffer,
|
||||||
|
.rxBuffer = uart8RxBuffer,
|
||||||
|
.txBufferSize = sizeof(uart8TxBuffer),
|
||||||
|
.rxBufferSize = sizeof(uart8RxBuffer),
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void uartIrqHandler(uartPort_t *s)
|
|
||||||
{
|
|
||||||
UART_HandleTypeDef *huart = &s->Handle;
|
|
||||||
/* UART in mode Receiver ---------------------------------------------------*/
|
|
||||||
if ((__HAL_UART_GET_IT(huart, UART_IT_RXNE) != RESET)) {
|
|
||||||
uint8_t rbyte = (uint8_t)(huart->Instance->RDR & (uint8_t) 0xff);
|
|
||||||
|
|
||||||
if (s->port.rxCallback) {
|
|
||||||
s->port.rxCallback(rbyte, s->port.rxCallbackData);
|
|
||||||
} else {
|
|
||||||
s->port.rxBuffer[s->port.rxBufferHead] = rbyte;
|
|
||||||
s->port.rxBufferHead = (s->port.rxBufferHead + 1) % s->port.rxBufferSize;
|
|
||||||
}
|
|
||||||
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE));
|
|
||||||
|
|
||||||
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
|
|
||||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
|
||||||
|
|
||||||
__HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UART parity error interrupt occurred -------------------------------------*/
|
|
||||||
if ((__HAL_UART_GET_IT(huart, UART_IT_PE) != RESET)) {
|
|
||||||
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UART frame error interrupt occurred --------------------------------------*/
|
|
||||||
if ((__HAL_UART_GET_IT(huart, UART_IT_FE) != RESET)) {
|
|
||||||
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UART noise error interrupt occurred --------------------------------------*/
|
|
||||||
if ((__HAL_UART_GET_IT(huart, UART_IT_NE) != RESET)) {
|
|
||||||
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UART Over-Run interrupt occurred -----------------------------------------*/
|
|
||||||
if ((__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET)) {
|
|
||||||
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UART in mode Transmitter ------------------------------------------------*/
|
|
||||||
if (!s->txDMAResource && (__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET)) {
|
|
||||||
/* Check that a Tx process is ongoing */
|
|
||||||
if (huart->gState != HAL_UART_STATE_BUSY_TX) {
|
|
||||||
if (s->port.txBufferTail == s->port.txBufferHead) {
|
|
||||||
huart->TxXferCount = 0;
|
|
||||||
/* Disable the UART Transmit Data Register Empty Interrupt */
|
|
||||||
CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
|
|
||||||
} else {
|
|
||||||
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) {
|
|
||||||
huart->Instance->TDR = (((uint16_t) s->port.txBuffer[s->port.txBufferTail]) & (uint16_t) 0x01FFU);
|
|
||||||
} else {
|
|
||||||
huart->Instance->TDR = (uint8_t)(s->port.txBuffer[s->port.txBufferTail]);
|
|
||||||
}
|
|
||||||
s->port.txBufferTail = (s->port.txBufferTail + 1) % s->port.txBufferSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UART in mode Transmitter (transmission end) -----------------------------*/
|
|
||||||
if ((__HAL_UART_GET_IT(huart, UART_IT_TC) != RESET)) {
|
|
||||||
HAL_UART_IRQHandler(huart);
|
|
||||||
if (s->txDMAResource) {
|
|
||||||
handleUsartTxDma(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (__HAL_UART_GET_IT(huart, UART_IT_IDLE)) {
|
|
||||||
if (s->port.idleCallback) {
|
|
||||||
s->port.idleCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
__HAL_UART_CLEAR_IDLEFLAG(huart);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handleUsartTxDma(uartPort_t *s)
|
|
||||||
{
|
|
||||||
uartTryStartTxDMA(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dmaIRQHandler(dmaChannelDescriptor_t* descriptor)
|
|
||||||
{
|
|
||||||
uartPort_t *s = &(((uartDevice_t*)(descriptor->userParam))->port);
|
|
||||||
HAL_DMA_IRQHandler(&s->txDMAHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX Should serialUART be consolidated?
|
// XXX Should serialUART be consolidated?
|
||||||
|
|
||||||
uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode, portOptions_e options)
|
uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode, portOptions_e options)
|
||||||
|
@ -410,32 +360,18 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
|
|
||||||
s->port.baudRate = baudRate;
|
s->port.baudRate = baudRate;
|
||||||
|
|
||||||
s->port.rxBuffer = uartdev->rxBuffer;
|
|
||||||
s->port.txBuffer = uartdev->txBuffer;
|
|
||||||
s->port.rxBufferSize = ARRAYLEN(uartdev->rxBuffer);
|
|
||||||
s->port.txBufferSize = ARRAYLEN(uartdev->txBuffer);
|
|
||||||
|
|
||||||
const uartHardware_t *hardware = uartdev->hardware;
|
const uartHardware_t *hardware = uartdev->hardware;
|
||||||
|
|
||||||
s->USARTx = hardware->reg;
|
s->USARTx = hardware->reg;
|
||||||
|
|
||||||
if (hardware->rxDMAResource) {
|
s->port.rxBuffer = hardware->rxBuffer;
|
||||||
s->rxDMAChannel = hardware->DMAChannel;
|
s->port.txBuffer = hardware->txBuffer;
|
||||||
s->rxDMAResource = hardware->rxDMAResource;
|
s->port.rxBufferSize = hardware->rxBufferSize;
|
||||||
}
|
s->port.txBufferSize = hardware->txBufferSize;
|
||||||
|
|
||||||
if (hardware->txDMAResource) {
|
#ifdef USE_DMA
|
||||||
s->txDMAChannel = hardware->DMAChannel;
|
uartConfigureDma(uartdev);
|
||||||
s->txDMAResource = hardware->txDMAResource;
|
#endif
|
||||||
|
|
||||||
// DMA TX Interrupt
|
|
||||||
dmaIdentifier_e identifier = dmaGetIdentifier(hardware->txDMAResource);
|
|
||||||
dmaInit(identifier, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
|
||||||
dmaSetHandler(identifier, dmaIRQHandler, hardware->txPriority, (uint32_t)uartdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR;
|
|
||||||
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR;
|
|
||||||
|
|
||||||
s->Handle.Instance = hardware->reg;
|
s->Handle.Instance = hardware->reg;
|
||||||
|
|
||||||
|
@ -464,10 +400,12 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s->rxDMAChannel) {
|
#ifdef USE_DMA
|
||||||
|
if (!s->rxDMAResource) {
|
||||||
HAL_NVIC_SetPriority(hardware->rxIrq, NVIC_PRIORITY_BASE(hardware->rxPriority), NVIC_PRIORITY_SUB(hardware->rxPriority));
|
HAL_NVIC_SetPriority(hardware->rxIrq, NVIC_PRIORITY_BASE(hardware->rxPriority), NVIC_PRIORITY_SUB(hardware->rxPriority));
|
||||||
HAL_NVIC_EnableIRQ(hardware->rxIrq);
|
HAL_NVIC_EnableIRQ(hardware->rxIrq);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,53 +88,15 @@
|
||||||
#define UART8_RX_DMA_STREAM NULL
|
#define UART8_RX_DMA_STREAM NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UART_BUFFERS(n) \
|
|
||||||
DMA_RAM volatile uint8_t uart ## n ## RxBuffer[UART_RX_BUFFER_SIZE]; \
|
|
||||||
DMA_RAM volatile uint8_t uart ## n ## TxBuffer[UART_TX_BUFFER_SIZE]; struct dummy_s
|
|
||||||
|
|
||||||
#ifdef USE_UART1
|
|
||||||
UART_BUFFERS(1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_UART2
|
|
||||||
UART_BUFFERS(2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_UART3
|
|
||||||
UART_BUFFERS(3);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_UART4
|
|
||||||
UART_BUFFERS(4);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_UART5
|
|
||||||
UART_BUFFERS(5);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_UART6
|
|
||||||
UART_BUFFERS(6);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_UART7
|
|
||||||
UART_BUFFERS(7);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_UART8
|
|
||||||
UART_BUFFERS(8);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef UART_BUFFERS
|
|
||||||
|
|
||||||
const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
#ifdef USE_UART1
|
#ifdef USE_UART1
|
||||||
{
|
{
|
||||||
.device = UARTDEV_1,
|
.device = UARTDEV_1,
|
||||||
.reg = USART1,
|
.reg = USART1,
|
||||||
#ifdef USE_DMA
|
#ifdef USE_DMA
|
||||||
.rxDMARequest = DMA_REQUEST_USART1_RX,
|
.rxDMAChannel = DMA_REQUEST_USART1_RX,
|
||||||
.rxDMAResource = (dmaResource_t *)UART1_RX_DMA_STREAM,
|
.rxDMAResource = (dmaResource_t *)UART1_RX_DMA_STREAM,
|
||||||
.txDMARequest = DMA_REQUEST_USART1_TX,
|
.txDMAChannel = DMA_REQUEST_USART1_TX,
|
||||||
.txDMAResource = (dmaResource_t *)UART1_TX_DMA_STREAM,
|
.txDMAResource = (dmaResource_t *)UART1_TX_DMA_STREAM,
|
||||||
#endif
|
#endif
|
||||||
.rxPins = {
|
.rxPins = {
|
||||||
|
@ -163,9 +125,9 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.device = UARTDEV_2,
|
.device = UARTDEV_2,
|
||||||
.reg = USART2,
|
.reg = USART2,
|
||||||
#ifdef USE_DMA
|
#ifdef USE_DMA
|
||||||
.rxDMARequest = DMA_REQUEST_USART2_RX,
|
.rxDMAChannel = DMA_REQUEST_USART2_RX,
|
||||||
.rxDMAResource = (dmaResource_t *)UART2_RX_DMA_STREAM,
|
.rxDMAResource = (dmaResource_t *)UART2_RX_DMA_STREAM,
|
||||||
.txDMARequest = DMA_REQUEST_USART2_TX,
|
.txDMAChannel = DMA_REQUEST_USART2_TX,
|
||||||
.txDMAResource = (dmaResource_t *)UART2_TX_DMA_STREAM,
|
.txDMAResource = (dmaResource_t *)UART2_TX_DMA_STREAM,
|
||||||
#endif
|
#endif
|
||||||
.rxPins = {
|
.rxPins = {
|
||||||
|
@ -192,9 +154,9 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.device = UARTDEV_3,
|
.device = UARTDEV_3,
|
||||||
.reg = USART3,
|
.reg = USART3,
|
||||||
#ifdef USE_DMA
|
#ifdef USE_DMA
|
||||||
.rxDMARequest = DMA_REQUEST_USART3_RX,
|
.rxDMAChannel = DMA_REQUEST_USART3_RX,
|
||||||
.rxDMAResource = (dmaResource_t *)UART3_RX_DMA_STREAM,
|
.rxDMAResource = (dmaResource_t *)UART3_RX_DMA_STREAM,
|
||||||
.txDMARequest = DMA_REQUEST_USART3_TX,
|
.txDMAChannel = DMA_REQUEST_USART3_TX,
|
||||||
.txDMAResource = (dmaResource_t *)UART3_TX_DMA_STREAM,
|
.txDMAResource = (dmaResource_t *)UART3_TX_DMA_STREAM,
|
||||||
#endif
|
#endif
|
||||||
.rxPins = {
|
.rxPins = {
|
||||||
|
@ -223,9 +185,9 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.device = UARTDEV_4,
|
.device = UARTDEV_4,
|
||||||
.reg = UART4,
|
.reg = UART4,
|
||||||
#ifdef USE_DMA
|
#ifdef USE_DMA
|
||||||
.rxDMARequest = DMA_REQUEST_UART4_RX,
|
.rxDMAChannel = DMA_REQUEST_UART4_RX,
|
||||||
.rxDMAResource = (dmaResource_t *)UART4_RX_DMA_STREAM,
|
.rxDMAResource = (dmaResource_t *)UART4_RX_DMA_STREAM,
|
||||||
.txDMARequest = DMA_REQUEST_UART4_TX,
|
.txDMAChannel = DMA_REQUEST_UART4_TX,
|
||||||
.txDMAResource = (dmaResource_t *)UART4_TX_DMA_STREAM,
|
.txDMAResource = (dmaResource_t *)UART4_TX_DMA_STREAM,
|
||||||
#endif
|
#endif
|
||||||
.rxPins = {
|
.rxPins = {
|
||||||
|
@ -258,9 +220,9 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.device = UARTDEV_5,
|
.device = UARTDEV_5,
|
||||||
.reg = UART5,
|
.reg = UART5,
|
||||||
#ifdef USE_DMA
|
#ifdef USE_DMA
|
||||||
.rxDMARequest = DMA_REQUEST_UART5_RX,
|
.rxDMAChannel = DMA_REQUEST_UART5_RX,
|
||||||
.rxDMAResource = (dmaResource_t *)UART5_RX_DMA_STREAM,
|
.rxDMAResource = (dmaResource_t *)UART5_RX_DMA_STREAM,
|
||||||
.txDMARequest = DMA_REQUEST_UART5_TX,
|
.txDMAChannel = DMA_REQUEST_UART5_TX,
|
||||||
.txDMAResource = (dmaResource_t *)UART5_TX_DMA_STREAM,
|
.txDMAResource = (dmaResource_t *)UART5_TX_DMA_STREAM,
|
||||||
#endif
|
#endif
|
||||||
.rxPins = {
|
.rxPins = {
|
||||||
|
@ -289,9 +251,9 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.device = UARTDEV_6,
|
.device = UARTDEV_6,
|
||||||
.reg = USART6,
|
.reg = USART6,
|
||||||
#ifdef USE_DMA
|
#ifdef USE_DMA
|
||||||
.rxDMARequest = DMA_REQUEST_USART6_RX,
|
.rxDMAChannel = DMA_REQUEST_USART6_RX,
|
||||||
.rxDMAResource = (dmaResource_t *)UART6_RX_DMA_STREAM,
|
.rxDMAResource = (dmaResource_t *)UART6_RX_DMA_STREAM,
|
||||||
.txDMARequest = DMA_REQUEST_USART6_TX,
|
.txDMAChannel = DMA_REQUEST_USART6_TX,
|
||||||
.txDMAResource = (dmaResource_t *)UART6_TX_DMA_STREAM,
|
.txDMAResource = (dmaResource_t *)UART6_TX_DMA_STREAM,
|
||||||
#endif
|
#endif
|
||||||
.rxPins = {
|
.rxPins = {
|
||||||
|
@ -318,9 +280,9 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.device = UARTDEV_7,
|
.device = UARTDEV_7,
|
||||||
.reg = UART7,
|
.reg = UART7,
|
||||||
#ifdef USE_DMA
|
#ifdef USE_DMA
|
||||||
.rxDMARequest = DMA_REQUEST_UART7_RX,
|
.rxDMAChannel = DMA_REQUEST_UART7_RX,
|
||||||
.rxDMAResource = (dmaResource_t *)UART7_RX_DMA_STREAM,
|
.rxDMAResource = (dmaResource_t *)UART7_RX_DMA_STREAM,
|
||||||
.txDMARequest = DMA_REQUEST_UART7_TX,
|
.txDMAChannel = DMA_REQUEST_UART7_TX,
|
||||||
.txDMAResource = (dmaResource_t *)UART7_TX_DMA_STREAM,
|
.txDMAResource = (dmaResource_t *)UART7_TX_DMA_STREAM,
|
||||||
#endif
|
#endif
|
||||||
.rxPins = {
|
.rxPins = {
|
||||||
|
@ -351,9 +313,9 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
.device = UARTDEV_8,
|
.device = UARTDEV_8,
|
||||||
.reg = UART8,
|
.reg = UART8,
|
||||||
#ifdef USE_DMA
|
#ifdef USE_DMA
|
||||||
.rxDMARequest = DMA_REQUEST_UART8_RX,
|
.rxDMAChannel = DMA_REQUEST_UART8_RX,
|
||||||
.rxDMAResource = (dmaResource_t *)UART8_RX_DMA_STREAM,
|
.rxDMAResource = (dmaResource_t *)UART8_RX_DMA_STREAM,
|
||||||
.txDMARequest = DMA_REQUEST_UART8_TX,
|
.txDMAChannel = DMA_REQUEST_UART8_TX,
|
||||||
.txDMAResource = (dmaResource_t *)UART8_TX_DMA_STREAM,
|
.txDMAResource = (dmaResource_t *)UART8_TX_DMA_STREAM,
|
||||||
#endif
|
#endif
|
||||||
.rxPins = {
|
.rxPins = {
|
||||||
|
@ -374,107 +336,6 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef USE_DMA
|
|
||||||
static void handleUsartTxDma(uartPort_t *s);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void uartIrqHandler(uartPort_t *s)
|
|
||||||
{
|
|
||||||
UART_HandleTypeDef *huart = &s->Handle;
|
|
||||||
/* UART in mode Receiver ---------------------------------------------------*/
|
|
||||||
if ((__HAL_UART_GET_IT(huart, UART_IT_RXNE) != RESET)) {
|
|
||||||
uint8_t rbyte = (uint8_t)(huart->Instance->RDR & (uint8_t) 0xff);
|
|
||||||
|
|
||||||
if (s->port.rxCallback) {
|
|
||||||
s->port.rxCallback(rbyte, s->port.rxCallbackData);
|
|
||||||
} else {
|
|
||||||
s->port.rxBuffer[s->port.rxBufferHead] = rbyte;
|
|
||||||
s->port.rxBufferHead = (s->port.rxBufferHead + 1) % s->port.rxBufferSize;
|
|
||||||
}
|
|
||||||
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE));
|
|
||||||
|
|
||||||
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
|
|
||||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
|
||||||
|
|
||||||
__HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UART parity error interrupt occurred -------------------------------------*/
|
|
||||||
if ((__HAL_UART_GET_IT(huart, UART_IT_PE) != RESET)) {
|
|
||||||
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UART frame error interrupt occurred --------------------------------------*/
|
|
||||||
if ((__HAL_UART_GET_IT(huart, UART_IT_FE) != RESET)) {
|
|
||||||
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UART noise error interrupt occurred --------------------------------------*/
|
|
||||||
if ((__HAL_UART_GET_IT(huart, UART_IT_NE) != RESET)) {
|
|
||||||
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UART Over-Run interrupt occurred -----------------------------------------*/
|
|
||||||
if ((__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET)) {
|
|
||||||
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UART in mode Transmitter ------------------------------------------------*/
|
|
||||||
if (
|
|
||||||
#ifdef USE_DMA
|
|
||||||
!s->txDMAResource &&
|
|
||||||
#endif
|
|
||||||
(__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET)) {
|
|
||||||
/* Check that a Tx process is ongoing */
|
|
||||||
if (huart->gState != HAL_UART_STATE_BUSY_TX) {
|
|
||||||
if (s->port.txBufferTail == s->port.txBufferHead) {
|
|
||||||
huart->TxXferCount = 0;
|
|
||||||
/* Disable the UART Transmit Data Register Empty Interrupt */
|
|
||||||
CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
|
|
||||||
} else {
|
|
||||||
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) {
|
|
||||||
huart->Instance->TDR = (((uint16_t) s->port.txBuffer[s->port.txBufferTail]) & (uint16_t) 0x01FFU);
|
|
||||||
} else {
|
|
||||||
huart->Instance->TDR = (uint8_t)(s->port.txBuffer[s->port.txBufferTail]);
|
|
||||||
}
|
|
||||||
s->port.txBufferTail = (s->port.txBufferTail + 1) % s->port.txBufferSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UART in mode Transmitter (transmission end) -----------------------------*/
|
|
||||||
if ((__HAL_UART_GET_IT(huart, UART_IT_TC) != RESET)) {
|
|
||||||
HAL_UART_IRQHandler(huart);
|
|
||||||
#ifdef USE_DMA
|
|
||||||
if (s->txDMAResource) {
|
|
||||||
handleUsartTxDma(s);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (__HAL_UART_GET_IT(huart, UART_IT_IDLE)) {
|
|
||||||
if (s->port.idleCallback) {
|
|
||||||
s->port.idleCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
__HAL_UART_CLEAR_IDLEFLAG(huart);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_DMA
|
|
||||||
static void handleUsartTxDma(uartPort_t *s)
|
|
||||||
{
|
|
||||||
uartTryStartTxDMA(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dmaIRQHandler(dmaChannelDescriptor_t* descriptor)
|
|
||||||
{
|
|
||||||
uartPort_t *s = &(((uartDevice_t*)(descriptor->userParam))->port);
|
|
||||||
HAL_DMA_IRQHandler(&s->txDMAHandle);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// XXX Should serialUART be consolidated?
|
// XXX Should serialUART be consolidated?
|
||||||
|
|
||||||
uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode, portOptions_e options)
|
uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode, portOptions_e options)
|
||||||
|
@ -494,39 +355,13 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
|
|
||||||
s->USARTx = hardware->reg;
|
s->USARTx = hardware->reg;
|
||||||
|
|
||||||
#ifdef STM32H7
|
|
||||||
s->port.rxBuffer = hardware->rxBuffer;
|
s->port.rxBuffer = hardware->rxBuffer;
|
||||||
s->port.txBuffer = hardware->txBuffer;
|
s->port.txBuffer = hardware->txBuffer;
|
||||||
s->port.rxBufferSize = hardware->rxBufferSize;
|
s->port.rxBufferSize = hardware->rxBufferSize;
|
||||||
s->port.txBufferSize = hardware->txBufferSize;
|
s->port.txBufferSize = hardware->txBufferSize;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_DMA
|
#ifdef USE_DMA
|
||||||
if (hardware->rxDMAResource) {
|
uartConfigureDma(uartdev);
|
||||||
s->rxDMAResource = hardware->rxDMAResource;
|
|
||||||
#if defined(STM32H7)
|
|
||||||
s->rxDMARequest = hardware->rxDMARequest;
|
|
||||||
#else // F4 & F7
|
|
||||||
s->rxDMAChannel = hardware->DMAChannel;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hardware->txDMAResource) {
|
|
||||||
s->txDMAResource = hardware->txDMAResource;
|
|
||||||
#if defined(STM32H7)
|
|
||||||
s->txDMARequest = hardware->txDMARequest;
|
|
||||||
#else // F4 & F7
|
|
||||||
s->txDMAChannel = hardware->DMAChannel;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// DMA TX Interrupt
|
|
||||||
dmaIdentifier_e identifier = dmaGetIdentifier(hardware->txDMAResource);
|
|
||||||
dmaInit(identifier, OWNER_SERIAL_TX, RESOURCE_INDEX(device));
|
|
||||||
dmaSetHandler(identifier, dmaIRQHandler, hardware->txPriority, (uint32_t)uartdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR;
|
|
||||||
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s->Handle.Instance = hardware->reg;
|
s->Handle.Instance = hardware->reg;
|
||||||
|
@ -556,11 +391,7 @@ uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_e mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_DMA
|
#ifdef USE_DMA
|
||||||
#if defined(STM32H7)
|
|
||||||
if (!s->rxDMAResource)
|
if (!s->rxDMAResource)
|
||||||
#else
|
|
||||||
if (!s->rxDMAChannel)
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
HAL_NVIC_SetPriority(hardware->rxIrq, NVIC_PRIORITY_BASE(hardware->rxPriority), NVIC_PRIORITY_SUB(hardware->rxPriority));
|
HAL_NVIC_SetPriority(hardware->rxIrq, NVIC_PRIORITY_BASE(hardware->rxPriority), NVIC_PRIORITY_SUB(hardware->rxPriority));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue