Skip to content

Commit 8f3c3a5

Browse files
committed
fix: uart driver dma
1 parent e82f613 commit 8f3c3a5

1 file changed

Lines changed: 56 additions & 3 deletions

File tree

src/fw/drivers/sf32lb/uart.c

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
#include "system/passert.h"
2525
#include "uart_definitions.h"
2626

27+
#define container_of(ptr, type, member) \
28+
((type *)((char *)(ptr) - offsetof(type, member)))
29+
2730
typedef enum {
2831
UART_FullDuplex = 0,
2932
UART_TxOnly,
@@ -294,7 +297,9 @@ void uart_irq_handler(UARTDevice *dev) {
294297
.framing_error = uart_has_rx_framing_error(dev),
295298
};
296299
// DMA
297-
if (dev->state->rx_dma_buffer) {
300+
if (dev->state->rx_dma_buffer &&
301+
(__HAL_UART_GET_FLAG(dev->periph, UART_FLAG_IDLE) != RESET) &&
302+
(__HAL_UART_GET_IT_SOURCE(dev->periph, UART_IT_IDLE) != RESET)) {
298303
// process bytes from the DMA buffer
299304
const uint32_t dma_length = dev->state->rx_dma_length;
300305
const uint32_t recv_total_index = dma_length - __HAL_DMA_GET_COUNTER(dev->rx_dma);
@@ -303,7 +308,7 @@ void uart_irq_handler(UARTDevice *dev) {
303308
recv_len += dma_length;
304309
}
305310

306-
for (int32_t i = 0; i < recv_len; i++) {
311+
for (uint32_t i = 0; i < recv_len; i++) {
307312
const uint8_t data = dev->state->rx_dma_buffer[dev->state->rx_dma_index + i];
308313
if (dev->state->rx_irq_handler(dev, data, &err_flags)) {
309314
should_context_switch = true;
@@ -337,9 +342,57 @@ void uart_irq_handler(UARTDevice *dev) {
337342

338343
void uart_clear_all_interrupt_flags(UARTDevice *dev) {
339344
// dev->periph->Instance->ISR &= ~(USART_ISR_TXE | USART_ISR_RXNE | USART_ISR_ORE);
340-
__HAL_UART_CLEAR_OREFLAG(dev->periph);
345+
UART_HandleTypeDef *uart = dev->periph;
346+
if (__HAL_UART_GET_FLAG(uart, UART_FLAG_ORE) != RESET) {
347+
__HAL_UART_CLEAR_OREFLAG(uart);
348+
}
349+
if (__HAL_UART_GET_FLAG(uart, UART_FLAG_NE) != RESET) {
350+
__HAL_UART_CLEAR_NEFLAG(uart);
351+
}
352+
if (__HAL_UART_GET_FLAG(uart, UART_FLAG_FE) != RESET) {
353+
__HAL_UART_CLEAR_FEFLAG(uart);
354+
}
355+
if (__HAL_UART_GET_FLAG(uart, UART_FLAG_PE) != RESET) {
356+
__HAL_UART_CLEAR_PEFLAG(uart);
357+
}
358+
// if (__HAL_UART_GET_FLAG(uart, UART_FLAG_CTS) != RESET) {
359+
// UART_INSTANCE_CLEAR_FUNCTION(uart, UART_FLAG_CTS);
360+
// }
361+
// if (__HAL_UART_GET_FLAG(uart, UART_FLAG_TXE) != RESET) {
362+
// UART_INSTANCE_CLEAR_FUNCTION(uart, UART_FLAG_TXE);
363+
// }
364+
// if (__HAL_UART_GET_FLAG(uart, UART_FLAG_TC) != RESET) {
365+
// UART_INSTANCE_CLEAR_FUNCTION(uart, UART_FLAG_TC);
366+
// }
367+
// if (__HAL_UART_GET_FLAG(uart, UART_FLAG_RXNE) != RESET) {
368+
// UART_INSTANCE_CLEAR_FUNCTION(uart, UART_FLAG_RXNE);
369+
// }
341370
}
342371

372+
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) {
373+
size_t recv_len;
374+
size_t recv_total_index;
375+
UARTDevice *dev = container_of(huart, UARTDevice, periph);
376+
377+
recv_total_index = dev->state->rx_dma_length - __HAL_DMA_GET_COUNTER(dev->rx_dma);
378+
if (recv_total_index < dev->state->rx_dma_index)
379+
recv_len = dev->state->rx_dma_length + recv_total_index - dev->state->rx_dma_index;
380+
else
381+
recv_len = recv_total_index - dev->state->rx_dma_index;
382+
dev->state->rx_dma_index = recv_total_index;
383+
384+
if (recv_len) {
385+
for (size_t i = 0; i < recv_len; i++) {
386+
const uint8_t data = dev->state->rx_dma_buffer[dev->state->rx_dma_index + i];
387+
if (dev->state->rx_irq_handler(dev, data, NULL)) {
388+
// context switch
389+
}
390+
}
391+
}
392+
}
393+
394+
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { HAL_UART_RxHalfCpltCallback(huart); }
395+
343396
// DMA
344397
////////////////////////////////////////////////////////////////////////////////
345398

0 commit comments

Comments
 (0)