Best Way to use UART Interrupt Implementation for send and receive functions

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Best Way to use UART Interrupt Implementation for send and receive functions

ソリューションへジャンプ
3,061件の閲覧回数
VolcanicCheese
Contributor III

In a project, I am currently working on. I am trying to use LPUART for three UART ports. Most of the code are based from UART interrupt example project provided in the MCUXPRESSO IDE. The goal was to implement three UART port for three different tasks. Trouble understanding what is the best way to get data received from the interrupt. Currently, this is what I have done so far for one of the task. I removed all the other codes that are within the task, but this is the layout I am trying to use to make UART work. Currently, the issue is that the message received from UART does not get copied properly to the recv_buffer. Below the code there is a our debug console message. I used teraterm to send messages to UART. Thank you for the help!

/**********************CODE*************************************/
uint8_t UART1RingBuffer[UART1_RING_BUFFER_SIZE];
volatile uint16_t txIndex; /* Index of the data to send out. */
volatile uint16_t rxIndex; /* Index of the memory to save new arrived data. */
uint8_t g_tipString[] =
"UART 1 initialized \r\n";

void UART1_IRQHandler(void)
{
     uint8_t data;
     uint16_t tmprxIndex = rxIndex;
     uint16_t tmptxIndex = txIndex;

     /* If new data arrived. */
     if ((kLPUART_RxDataRegFullFlag)&LPUART_GetStatusFlags(LPUART_1))
     {
          data = LPUART_ReadByte(LPUART_1);

          /* If ring buffer is not full, add data to ring buffer. */
          if (((tmprxIndex + 1) % UART1_RING_BUFFER_SIZE) != tmptxIndex)
               {
                    UART1RingBuffer[rxIndex] = data;
                    rxIndex++;
                    rxIndex %= UART1_RING_BUFFER_SIZE;
               }
     }

     SDK_ISR_EXIT_BARRIER;

     // Printing out received data:
     PRINTF("Printing out received data:");
     for (int i = 0; i < UART1_RING_BUFFER_SIZE; i++)

     {
          PRINTF("UART RING BUFFER ITEM: %u\n:", UART1RingBuffer[i]);
     }
}

void com_task(void *pvParameters)
{
     /*initiate UART 1*/
     lpuart_config_t config;
     uint16_t tmprxIndex = rxIndex;
     uint16_t tmptxIndex = txIndex;

     LPUART_GetDefaultConfig(&config);
     config.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;
     config.enableTx = true;
     config.enableRx = true;

     LPUART_Init(LPUART_1, &config, LPUART1_CLK_FREQ);

     /* Send g_tipString out. */
     if(kStatus_Success == LPUART_WriteBlocking(LPUART_1, g_tipString, sizeof(g_tipString) /                                sizeof(g_tipString[0]))) {
     PRINTF("UART1 succeed write blocking\r\n");
     } else {
          PRINTF("UART1 failed write blocking\r\n");
     }

     /* Enable RX interrupt. */
     LPUART_EnableInterrupts(LPUART_1, kLPUART_RxDataRegFullInterruptEnable);
     EnableIRQ(UART1_IRQn);
     /*UART 1 initialization done */

     uint8_t recv_buffer[UART1_RING_BUFFER_SIZE];
     static QueueHandle_t uartRxQueue; //handle by which the queue can be referenced
     uartRxQueue = xQueueCreate(sizeof(g_tipString)/sizeof(char), sizeof(char));
     configASSERT(uartRxQueue);

     LPUART_DisableInterrupts(LPUART_1, kLPUART_RxDataRegFullInterruptEnable);

     for(;;)

     {

          xLastWakeTime = xTaskGetTickCount();          

          LPUART_EnableInterrupts(LPUART_1, kLPUART_RxDataRegFullInterruptEnable);
          xQueueSendToBack(uartRxQueue, &UART1RingBuffer, ( TickType_t ) 1000);
          xQueueReceive(uartRxQueue, &recv_buffer, ( TickType_t ) 1000); //instead of uart_receive
          PRINTF("UART Receive: %c\n", recv_buffer);
          for(int i = 0; i < UART1_RING_BUFFER_SIZE; i++) {
               PRINTF("%c", recv_buffer[i]);
          }
          PRINTF("\n");
          LPUART_DisableInterrupts(LPUART_1, kLPUART_RxDataRegFullInterruptEnable);
          vTaskDelayUntil(&xLastWakeTime, xDelayms);

     }

}

/**********************CODE*************************************/

/**********************DEBUG CONSOLE****************************/

UART1 succeed write blocking
UART Receive: ,

Printing out received data:UART RING BUFFER ITEM: 97
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:Printing out received data:UART RING BUFFER ITEM: 97
:UART RING BUFFER ITEM: 115
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:Printing out received data:UART RING BUFFER ITEM: 97
:UART RING BUFFER ITEM: 115
:UART RING BUFFER ITEM: 100
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:Printing out received data:UART RING BUFFER ITEM: 97
:UART RING BUFFER ITEM: 115
:UART RING BUFFER ITEM: 100
:UART RING BUFFER ITEM: 102
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART RING BUFFER ITEM: 0
:UART Receive: ,
a¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥

0 件の賞賛
返信
1 解決策
3,048件の閲覧回数
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @VolcanicCheese 

Your code is not good, you add the printf in the interrupt code, as you know, to the MCU, interrupt ISR code should be as short as possible.

 You can save the data to the buffer, then in the main to print it.

If you use more UART and all use the interrupt, and your communication is frequently, your interrupt service will be heavy, I suggest you try the DMA method.

SDK_2_10_0_EVK-MIMXRT1060\boards\evkmimxrt1060\driver_examples\lpuart\edma_transfer

Wish it helps you!

Best Regards,

Kerry

元の投稿で解決策を見る

0 件の賞賛
返信
3 返答(返信)
3,049件の閲覧回数
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @VolcanicCheese 

Your code is not good, you add the printf in the interrupt code, as you know, to the MCU, interrupt ISR code should be as short as possible.

 You can save the data to the buffer, then in the main to print it.

If you use more UART and all use the interrupt, and your communication is frequently, your interrupt service will be heavy, I suggest you try the DMA method.

SDK_2_10_0_EVK-MIMXRT1060\boards\evkmimxrt1060\driver_examples\lpuart\edma_transfer

Wish it helps you!

Best Regards,

Kerry

0 件の賞賛
返信
3,032件の閲覧回数
VolcanicCheese
Contributor III

Thanks for the help. 

If I want to initialize three LPUARTS ports, I was not sure how the DMA channels were selected. I was not able to find any documentation and understand how the value are being selected for TX and RX DMA channel. Also, how do I make sure that the channel I set for UART corresponds to the pins that I want to use on the DEV board for UART communication. This is the part of the example code I am not sure about. How to set the LPUART_TX_DMA_CHANNEL? I am assuming that all the LPUART would be set under one DMAMUX and is that a safe assumption.

/* Set channel for LPUART */
DMAMUX_SetSource(DMAMUX, LPUART_TX_DMA_CHANNEL, kDmaRequestMuxLPUART1Tx);
DMAMUX_SetSource(DMAMUX, LPUART_RX_DMA_CHANNEL, kDmaRequestMuxLPUART1Rx);
DMAMUX_SetSource(DMAMUX, LPUART_TX_DMA_CHANNEL, kDmaRequestMuxLPUART2Tx);
DMAMUX_SetSource(DMAMUX, LPUART_RX_DMA_CHANNEL, kDmaRequestMuxLPUART2Rx);
DMAMUX_SetSource(DMAMUX, LPUART_TX_DMA_CHANNEL, kDmaRequestMuxLPUART3Tx);
DMAMUX_SetSource(DMAMUX, LPUART_RX_DMA_CHANNEL, kDmaRequestMuxLPUART3Rx);

I was wondering if there is any guide to transferring demo project like the UART edma to different project. Recently, I was trying to use lpI2C to a project that uses a powermode driver. It seems like the problem derives from not understanding different FreeRTOS setting/configuration needed to run the project.

 

0 件の賞賛
返信
3,005件の閲覧回数
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @VolcanicCheese ,

Different UART interface need to use different DMA channel:

#define LPUART_TX_DMA_CHANNEL 0U
#define LPUART_RX_DMA_CHANNEL 1U

The above is used for LPUART1, if other, you need to use other DMA channel number, you can't use the same.

Wish it helps you!

Best Regards.

Kerry

0 件の賞賛
返信