Skip to content

Commit 8a0be63

Browse files
committed
fix: uart driver
1 parent 5708a6f commit 8a0be63

1 file changed

Lines changed: 24 additions & 15 deletions

File tree

src/fw/drivers/sf32lb/uart.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ static void prv_init(UARTDevice *dev, UARTInitMode_t mode) {
163163
default:
164164
break;
165165
}
166-
dev->state->initialized = true;
166+
dev->state->initialized = true;
167167
if (dev->rx_dma) {
168168
// initialize the DMA request
169169
__HAL_LINKDMA(dev->periph, hdmarx, *dev->rx_dma);
@@ -293,25 +293,29 @@ void uart_irq_handler(UARTDevice *dev) {
293293
.overrun_error = uart_has_rx_overrun(dev),
294294
.framing_error = uart_has_rx_framing_error(dev),
295295
};
296+
// DMA
296297
if (dev->state->rx_dma_buffer) {
297298
// process bytes from the DMA buffer
298299
const uint32_t dma_length = dev->state->rx_dma_length;
299-
const uint32_t next_idx = dma_length - __HAL_DMA_GET_COUNTER(dev->rx_dma);
300-
// make sure we didn't underflow the index
301-
PBL_ASSERTN(next_idx < dma_length);
302-
while (dev->state->rx_dma_index != next_idx) {
303-
const uint8_t data = dev->state->rx_dma_buffer[dev->state->rx_dma_index];
300+
const uint32_t recv_total_index = dma_length - __HAL_DMA_GET_COUNTER(dev->rx_dma);
301+
int32_t recv_len = recv_total_index - dev->state->rx_dma_index;
302+
if (recv_len < 0) {
303+
recv_len += dma_length;
304+
}
305+
306+
for (uint32_t i = 0; i < recv_len; i++) {
307+
const uint8_t data = dev->state->rx_dma_buffer[dev->state->rx_dma_index + i];
304308
if (dev->state->rx_irq_handler(dev, data, &err_flags)) {
305309
should_context_switch = true;
306310
}
307-
if (++dev->state->rx_dma_index == dma_length) {
308-
dev->state->rx_dma_index = 0;
309-
}
310311
}
311-
// explicitly clear error flags since we're not reading from the data register
312+
dev->state->rx_dma_index = recv_total_index;
313+
if (dev->state->rx_dma_index >= dma_length) {
314+
dev->state->rx_dma_index = 0;
315+
HAL_UART_DmaTransmit(dev->periph, dev->state->rx_dma_buffer, dma_length, DMA_PERIPH_TO_MEMORY);
316+
}
312317
uart_clear_all_interrupt_flags(dev);
313-
314-
__HAL_UART_CLEAR_IDLEFLAG(dev->periph); // IDLEFLAG needs to be cleaned manually
318+
__HAL_UART_CLEAR_IDLEFLAG(dev->periph);
315319
} else {
316320
const bool has_byte = uart_is_rx_ready(dev);
317321
// read the data register regardless to clear the error flags
@@ -332,21 +336,26 @@ void uart_irq_handler(UARTDevice *dev) {
332336
}
333337

334338
void uart_clear_all_interrupt_flags(UARTDevice *dev) {
335-
dev->periph->Instance->ISR &= ~(USART_ISR_TXE | USART_ISR_RXNE | USART_ISR_ORE);
339+
// dev->periph->Instance->ISR &= ~(USART_ISR_TXE | USART_ISR_RXNE | USART_ISR_ORE);
340+
__HAL_UART_CLEAR_OREFLAG(dev->periph);
336341
}
337342

338343
// DMA
339344
////////////////////////////////////////////////////////////////////////////////
340345

341346
void uart_start_rx_dma(UARTDevice *dev, void *buffer, uint32_t length) {
347+
dev->state->rx_dma_buffer = buffer;
348+
dev->state->rx_dma_length = length;
349+
dev->state->rx_dma_index = 0;
342350
HAL_UART_DmaTransmit(dev->periph, buffer, length, DMA_PERIPH_TO_MEMORY);
343351
}
344352

345353
void uart_stop_rx_dma(UARTDevice *dev) {
354+
dev->state->rx_dma_buffer = NULL;
355+
dev->state->rx_dma_length = 0;
346356
HAL_UART_DMAPause(dev->periph);
347357
}
348358

349359
void uart_clear_rx_dma_buffer(UARTDevice *dev) {
350-
dev->state->rx_dma_index =
351-
dev->state->rx_dma_length - __HAL_DMA_GET_COUNTER(dev->rx_dma);
360+
dev->state->rx_dma_index = dev->state->rx_dma_length - __HAL_DMA_GET_COUNTER(dev->rx_dma);
352361
}

0 commit comments

Comments
 (0)