@@ -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
591591static 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