Skip to content

Commit 209cb81

Browse files
Raymond0225mmahadevan108
authored andcommitted
drivers: serial: lpuart: Enable SG mode of LPUART
New implemented eDMA loop SG mode can be used to lpuart driver to fix the conflict of "Done" bit issue which cause uart_async_api test failed when SG mode is enabled. Also, this loop SG mode works well even with a high bandrate(test done on 2000000bps). Fixes: #78291 Signed-off-by: Raymond Lei <[email protected]>
1 parent 7145295 commit 209cb81

File tree

1 file changed

+15
-23
lines changed

1 file changed

+15
-23
lines changed

drivers/serial/uart_mcux_lpuart.c

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ static void prepare_rx_dma_block_config(const struct device *dev)
585585
head_block_config->dest_address = (uint32_t)rx_dma_params->buf;
586586
head_block_config->source_address = LPUART_GetDataRegisterAddress(lpuart);
587587
head_block_config->block_size = rx_dma_params->buf_len;
588-
head_block_config->dest_scatter_en = false;
588+
head_block_config->dest_scatter_en = true;
589589
}
590590

591591
static int configure_and_start_rx_dma(
@@ -616,37 +616,20 @@ static int uart_mcux_lpuart_dma_replace_rx_buffer(const struct device *dev)
616616
struct mcux_lpuart_data *data = (struct mcux_lpuart_data *)dev->data;
617617
const struct mcux_lpuart_config *config = dev->config;
618618
LPUART_Type *lpuart = config->base;
619-
struct mcux_lpuart_rx_dma_params *rx_dma_params = &data->async.rx_dma_params;
620619

621620
LOG_DBG("Replacing RX buffer, new length: %d", data->async.next_rx_buffer_len);
622-
623621
/* There must be a buffer to replace this one with */
624622
assert(data->async.next_rx_buffer != NULL);
625623
assert(data->async.next_rx_buffer_len != 0U);
626-
rx_dma_params->buf = data->async.next_rx_buffer;
627-
rx_dma_params->buf_len = data->async.next_rx_buffer_len;
628-
rx_dma_params->offset = 0;
629-
rx_dma_params->counter = 0;
630-
data->async.next_rx_buffer = NULL;
631-
data->async.next_rx_buffer_len = 0U;
632624

633625
const int success =
634626
dma_reload(config->rx_dma_config.dma_dev, config->rx_dma_config.dma_channel,
635-
LPUART_GetDataRegisterAddress(lpuart), (uint32_t)rx_dma_params->buf,
636-
rx_dma_params->buf_len);
627+
LPUART_GetDataRegisterAddress(lpuart),
628+
(uint32_t)data->async.next_rx_buffer, data->async.next_rx_buffer_len);
637629

638630
if (success != 0) {
639631
LOG_ERR("Error %d reloading DMA with next RX buffer", success);
640632
}
641-
/* Request next buffer */
642-
async_evt_rx_buf_request(dev);
643-
644-
int ret = dma_start(config->rx_dma_config.dma_dev, config->rx_dma_config.dma_channel);
645-
646-
if (ret < 0) {
647-
LOG_ERR("Failed to start DMA(Rx) Ch %d(%d)", config->rx_dma_config.dma_channel,
648-
ret);
649-
}
650633

651634
return success;
652635
}
@@ -692,9 +675,16 @@ static void dma_callback(const struct device *dma_dev, void *callback_arg, uint3
692675
async_evt_rx_rdy(dev);
693676
async_evt_rx_buf_release(dev);
694677

695-
if (data->async.next_rx_buffer != NULL && data->async.next_rx_buffer_len > 0) {
678+
/* Remember the buf so it can be released after it is done. */
679+
rx_dma_params->buf = data->async.next_rx_buffer;
680+
rx_dma_params->buf_len = data->async.next_rx_buffer_len;
681+
data->async.next_rx_buffer = NULL;
682+
data->async.next_rx_buffer_len = 0U;
683+
684+
/* A new buffer was available (and already loaded into the DMA engine) */
685+
if (rx_dma_params->buf != NULL && rx_dma_params->buf_len > 0) {
696686
/* Request the next buffer */
697-
uart_mcux_lpuart_dma_replace_rx_buffer(dev);
687+
async_evt_rx_buf_request(dev);
698688
} else {
699689
/* Buffer full without valid next buffer, disable RX DMA */
700690
LOG_INF("Disabled RX DMA, no valid next buffer ");
@@ -873,6 +863,7 @@ static int mcux_lpuart_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t
873863
assert(data->async.next_rx_buffer_len == 0);
874864
data->async.next_rx_buffer = buf;
875865
data->async.next_rx_buffer_len = len;
866+
uart_mcux_lpuart_dma_replace_rx_buffer(dev);
876867
irq_unlock(key);
877868
return 0;
878869
}
@@ -1347,7 +1338,8 @@ static const struct uart_driver_api mcux_lpuart_driver_api = {
13471338
.dma_slot = DT_INST_DMAS_CELL_BY_NAME( \
13481339
id, rx, source), \
13491340
.dma_callback = dma_callback, \
1350-
.user_data = (void *)DEVICE_DT_INST_GET(id) \
1341+
.user_data = (void *)DEVICE_DT_INST_GET(id), \
1342+
.cyclic = 1, \
13511343
}, \
13521344
},
13531345
#else

0 commit comments

Comments
 (0)