Add UART Half-DMA transfer mode (#2)
This commit is contained in:
parent
313ea78044
commit
9ab37526f8
|
@ -298,6 +298,26 @@ typedef enum {
|
||||||
_uart_wakeup_rx_complete_isr(uartp); \
|
_uart_wakeup_rx_complete_isr(uartp); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Common ISR code for RX half-transfer data.
|
||||||
|
* @details This code handles the portable part of the ISR code:
|
||||||
|
* - Callback invocation.
|
||||||
|
* - Waiting thread wakeup, if any.
|
||||||
|
* - Driver state transitions.
|
||||||
|
* .
|
||||||
|
* @note This macro is meant to be used in the low level drivers
|
||||||
|
* implementation only.
|
||||||
|
*
|
||||||
|
* @param[in] uartp pointer to the @p UARTDriver object
|
||||||
|
* @param[in] full flag set to 1 for the second half, and 0 for the first half
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define _uart_rx_half_isr_code(uartp, full) { \
|
||||||
|
if ((uartp)->config->rxhalf_cb != NULL) \
|
||||||
|
(uartp)->config->rxhalf_cb(uartp, full); \
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Common ISR code for RX error.
|
* @brief Common ISR code for RX error.
|
||||||
* @details This code handles the portable part of the ISR code:
|
* @details This code handles the portable part of the ISR code:
|
||||||
|
|
|
@ -262,6 +262,11 @@ static void usart_start(UARTDriver *uartp) {
|
||||||
/* Mustn't ever set TCIE here - if done, it causes an immediate
|
/* Mustn't ever set TCIE here - if done, it causes an immediate
|
||||||
interrupt.*/
|
interrupt.*/
|
||||||
cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE;
|
cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE;
|
||||||
|
|
||||||
|
/* Add Idle interrupt if needed */
|
||||||
|
if (uartp->config->timeout_cb != NULL)
|
||||||
|
cr1 |= USART_CR1_IDLEIE;
|
||||||
|
|
||||||
u->CR1 = uartp->config->cr1 | cr1;
|
u->CR1 = uartp->config->cr1 | cr1;
|
||||||
|
|
||||||
/* Starting the receiver idle loop.*/
|
/* Starting the receiver idle loop.*/
|
||||||
|
@ -290,6 +295,15 @@ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) {
|
||||||
received character and then the driver stays in the same state.*/
|
received character and then the driver stays in the same state.*/
|
||||||
_uart_rx_idle_code(uartp);
|
_uart_rx_idle_code(uartp);
|
||||||
}
|
}
|
||||||
|
/* DMA half-transter interrupt handling - for the 1st/2nd half transfers. */
|
||||||
|
else if (uartp->config->rxhalf_cb != NULL) {
|
||||||
|
if ((flags & STM32_DMA_ISR_HTIF) != 0) {
|
||||||
|
_uart_rx_half_isr_code(uartp, 0);
|
||||||
|
}
|
||||||
|
else if ((flags & STM32_DMA_ISR_TCIF) != 0) {
|
||||||
|
_uart_rx_half_isr_code(uartp, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
/* Receiver in active state, a callback is generated, if enabled, after
|
/* Receiver in active state, a callback is generated, if enabled, after
|
||||||
a completed transfer.*/
|
a completed transfer.*/
|
||||||
|
@ -975,8 +989,14 @@ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
|
||||||
/* RX DMA channel preparation.*/
|
/* RX DMA channel preparation.*/
|
||||||
dmaStreamSetMemory0(uartp->dmarx, rxbuf);
|
dmaStreamSetMemory0(uartp->dmarx, rxbuf);
|
||||||
dmaStreamSetTransactionSize(uartp->dmarx, n);
|
dmaStreamSetTransactionSize(uartp->dmarx, n);
|
||||||
dmaStreamSetMode(uartp->dmarx, uartp->dmarxmode | STM32_DMA_CR_DIR_P2M |
|
|
||||||
STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE);
|
uint32_t mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE;
|
||||||
|
|
||||||
|
/* DMA half-transfer interrupt & circular mode, if needed */
|
||||||
|
if (uartp->config->rxhalf_cb != NULL)
|
||||||
|
mode |= STM32_DMA_CR_HTIE | STM32_DMA_CR_CIRC;
|
||||||
|
|
||||||
|
dmaStreamSetMode(uartp->dmarx, uartp->dmarxmode | mode);
|
||||||
|
|
||||||
/* Starting transfer.*/
|
/* Starting transfer.*/
|
||||||
dmaStreamEnable(uartp->dmarx);
|
dmaStreamEnable(uartp->dmarx);
|
||||||
|
|
|
@ -577,6 +577,14 @@ typedef void (*uartccb_t)(UARTDriver *uartp, uint16_t c);
|
||||||
*/
|
*/
|
||||||
typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e);
|
typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Receive Half-transfer UART notification callback type.
|
||||||
|
*
|
||||||
|
* @param[in] uartp pointer to the @p UARTDriver object
|
||||||
|
* @param[in] full flag set to 1 for the second half, and 0 for the first half
|
||||||
|
*/
|
||||||
|
typedef void (*uarthcb_t)(UARTDriver *uartp, uartflags_t full);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Driver configuration structure.
|
* @brief Driver configuration structure.
|
||||||
* @note It could be empty on some architectures.
|
* @note It could be empty on some architectures.
|
||||||
|
@ -625,6 +633,11 @@ typedef struct {
|
||||||
* @brief Initialization value for the CR3 register.
|
* @brief Initialization value for the CR3 register.
|
||||||
*/
|
*/
|
||||||
uint16_t cr3;
|
uint16_t cr3;
|
||||||
|
/* Additional (optional) handlers. Placed here for the struct compatibility.*/
|
||||||
|
/**
|
||||||
|
* @brief Half-transfer receive buffer callback.
|
||||||
|
*/
|
||||||
|
uarthcb_t rxhalf_cb;
|
||||||
} UARTConfig;
|
} UARTConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue