How to set the DMA UART receive size dynamically RT1020

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

How to set the DMA UART receive size dynamically RT1020

5,971件の閲覧回数
hanmant
Contributor III

Hi,

Board: Custom Board based on RT1020

I'm using "evkmimxrt1020_lpuart_edma_transfer" , i can able to receive and transmit data successfully with Fixed Size of rx data buff.

I'm executing some operations based on received ID like 

if(rxBuff[0] == 0x24)

{

//receiveXfer.dataSize size will be 11

}

if(rxBuff[0] == 0x22)

{

//receiveXfer.dataSize size will be 32

}

Currently, im not able to do that.

Can anyone please help with this 

ラベル(1)
タグ(2)
0 件の賞賛
返信
11 返答(返信)

5,933件の閲覧回数
Gavin_Jia
NXP TechSupport
NXP TechSupport

Hi @hanmant ,

Thanks for your interest in NXP MIMXRT series!

According to the scenario you describe, using the UART's idle interrupt + DMA to receive an array of indeterminate length should be the more efficient and correct way. After receiving, then post-process the data.

Best regards,
Gavin

0 件の賞賛
返信

5,930件の閲覧回数
hanmant
Contributor III
Hi @Gavin_Jia
Thanks for reply.
Can you did not get you.
My code is like
' /*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_lpuart_edma.h"
#include "fsl_debug_console.h"
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT
#include "fsl_dmamux.h"
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
#define DEMO_LPUART LPUART3
#define DEMO_LPUART_CLK_FREQ BOARD_DebugConsoleSrcFreq()

#define LPUART_TX_DMA_CHANNEL 0U
#define LPUART_RX_DMA_CHANNEL 1U
#define LPI2C_TRANSMIT_DMA_CHANNEL 2U
#define LPI2C_RECEIVE_DMA_CHANNEL 3U


#define LPUART_TX_DMA_REQUEST kDmaRequestMuxLPUART3Tx
#define LPUART_RX_DMA_REQUEST kDmaRequestMuxLPUART3Rx
#define EXAMPLE_LPUART_DMAMUX_BASEADDR DMAMUX
#define EXAMPLE_LPUART_DMA_BASEADDR DMA0
#define ECHO_BUFFER_LENGTH 8

/*******************************************************************************
* Prototypes
******************************************************************************/

/* LPUART user callback */
void LPUART_UserCallback(LPUART_Type *base, lpuart_edma_handle_t *handle, status_t status, void *userData);

/*******************************************************************************
* Variables
******************************************************************************/

lpuart_edma_handle_t g_lpuartEdmaHandle;
edma_handle_t g_lpuartTxEdmaHandle;
edma_handle_t g_lpuartRxEdmaHandle;
AT_NONCACHEABLE_SECTION_INIT(uint8_t g_tipString[]) =
"LPUART EDMA example\r\nSend back received data\r\nEcho every 8 characters\r\n";
SDK_L1DCACHE_ALIGN(uint8_t g_txBuffer[1000]) = {0x23,00,00,00,0x28,00,00,00,0x01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,0x3B,0xF7,0xF8,0x5D};
AT_NONCACHEABLE_SECTION_INIT(uint8_t g_rxBuffer[32]) = {0};
volatile bool rxBufferEmpty = true;
volatile bool txBufferFull = false;
volatile bool txOnGoing = false;
volatile bool rxOnGoing = false;
lpuart_transfer_t sendXfer;
lpuart_transfer_t receiveXfer;
uint32_t rx_count;
/*******************************************************************************
* Code
******************************************************************************/
/* LPUART user callback */
void LPUART_UserCallback(LPUART_Type *base, lpuart_edma_handle_t *handle, status_t status, void *userData)
{

userData = userData;

if (kStatus_LPUART_TxIdle == status)
{
txBufferFull = false;
txOnGoing = false;
}

if (kStatus_LPUART_RxIdle == status)
{
rxBufferEmpty = false;
rxOnGoing = false;
}

// /*if TC interrupt is enabled*/
// if(LPUART_GetEnabledInterrupts(DEMO_LPUART) & kLPUART_TransmissionCompleteFlag)
// {
// if((kLPUART_TransmissionCompleteFlag)&stat)/*TC interrupt flag is set*/
// {
// /*Since TC occurs, disable TC interrupt now*/
// LPUART_DisableInterrupts(DEMO_LPUART, kLPUART_TransmissionCompleteInterruptEnable);
// /*Enable RS485 receive again*/
//
// LPUART_TransferAbortReceiveEDMA(DEMO_LPUART, &g_lpuartEdmaHandle);
// LPUART_ReceiveEDMA(DEMO_LPUART, &g_lpuartEdmaHandle, &receiveXfer);
//
// }
// }
/*Fetch Data from DMA RX buffer*/
if (kStatus_NoTransferInProgress ==
LPUART_TransferGetReceiveCountEDMA(DEMO_LPUART, &g_lpuartEdmaHandle, &rx_count))
{
rx_count = 0;
}
if(rx_count > 32)
{
rx_count = 0;
// memcpy(g_txBuffer,g_rxBuffer,rx_count);/*save received data*/
// send_size = rx_count;
// reciveFrame = true;/*Assume receive entire frame*/
}

}

/*!
* @brief Main function
*/
int main(void)
{
lpuart_config_t lpuartConfig;


edma_config_t userConfig = {0};
uint32_t uiCnt = 0;


BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_InitBootClocks();

/* Initialize the LPUART. */
/*
* lpuartConfig.baudRate_Bps = 115200U;
* lpuartConfig.parityMode = kLPUART_ParityDisabled;
* lpuartConfig.stopBitCount = kLPUART_OneStopBit;
* lpuartConfig.txFifoWatermark = 0;
* lpuartConfig.rxFifoWatermark = 0;
* lpuartConfig.enableTx = false;
* lpuartConfig.enableRx = false;
*/
LPUART_GetDefaultConfig(&lpuartConfig);
lpuartConfig.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;
lpuartConfig.enableTx = true;
lpuartConfig.enableRx = true;

/*set RX IDLE parameters*/
lpuartConfig.rxIdleType = kLPUART_IdleTypeStopBit;
lpuartConfig.rxIdleConfig = kLPUART_IdleCharacter32;

/*set LPUART tx rx fifo, receive doesn't use FIFO*/
lpuartConfig.rxFifoWatermark = 0;
/*
If doesn't use tramsmit fifo, set txFifoWatermark=0
Must be care, the maximum fifo depth doesn't exceed allowed
*/
lpuartConfig.txFifoWatermark = FSL_FEATURE_LPUART_FIFO_SIZEn(DEMO_LPUART) - 1;

LPUART_Init(DEMO_LPUART, &lpuartConfig, DEMO_LPUART_CLK_FREQ);

#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT
/* Init DMAMUX */
DMAMUX_Init(EXAMPLE_LPUART_DMAMUX_BASEADDR);
/* Set channel for LPUART */
DMAMUX_SetSource(EXAMPLE_LPUART_DMAMUX_BASEADDR, LPUART_TX_DMA_CHANNEL, LPUART_TX_DMA_REQUEST);
DMAMUX_SetSource(EXAMPLE_LPUART_DMAMUX_BASEADDR, LPUART_RX_DMA_CHANNEL, LPUART_RX_DMA_REQUEST);
DMAMUX_EnableChannel(EXAMPLE_LPUART_DMAMUX_BASEADDR, LPUART_TX_DMA_CHANNEL);
DMAMUX_EnableChannel(EXAMPLE_LPUART_DMAMUX_BASEADDR, LPUART_RX_DMA_CHANNEL);
#endif
/* Init the EDMA module */
EDMA_GetDefaultConfig(&userConfig);
#if defined(BOARD_GetEDMAConfig)
BOARD_GetEDMAConfig(userConfig);
#endif
EDMA_Init(EXAMPLE_LPUART_DMA_BASEADDR, &userConfig);
EDMA_CreateHandle(&g_lpuartTxEdmaHandle, EXAMPLE_LPUART_DMA_BASEADDR, LPUART_TX_DMA_CHANNEL);
EDMA_CreateHandle(&g_lpuartRxEdmaHandle, EXAMPLE_LPUART_DMA_BASEADDR, LPUART_RX_DMA_CHANNEL);
#if defined(FSL_FEATURE_EDMA_HAS_CHANNEL_MUX) && FSL_FEATURE_EDMA_HAS_CHANNEL_MUX
EDMA_SetChannelMux(EXAMPLE_LPUART_DMA_BASEADDR, LPUART_TX_DMA_CHANNEL, DEMO_LPUART_TX_EDMA_CHANNEL);
EDMA_SetChannelMux(EXAMPLE_LPUART_DMA_BASEADDR, LPUART_RX_DMA_CHANNEL, DEMO_LPUART_RX_EDMA_CHANNEL);
#endif

/* Create LPUART DMA handle. */
LPUART_TransferCreateHandleEDMA(DEMO_LPUART, &g_lpuartEdmaHandle, LPUART_UserCallback, NULL, &g_lpuartTxEdmaHandle,
&g_lpuartRxEdmaHandle);

/* Start to echo. */
char buff[100];
// LPUART_SendEDMA(DEMO_LPUART, &g_lpuartEdmaHandle, &sendXfer);
//
// /* Wait send finished */
// while (txOnGoing)
// {
// }

/* Start to echo. */

sendXfer.dataSize = 52;
receiveXfer.data = g_rxBuffer;
receiveXfer.dataSize = 32;


while (1)
{
//PRINTF("\r\n%d",rx_count);
/* If RX is idle and g_rxBuffer is empty, start to read data to g_rxBuffer. */
if ((!rxOnGoing) && (rxBufferEmpty))
{
// memset(buff,0x00,100);
// memset(g_rxBuffer,0x00,32);
rxOnGoing = true;
LPUART_ReceiveEDMA(DEMO_LPUART, &g_lpuartEdmaHandle, &receiveXfer);

}
// sendXfer.data[0] = uiCnt++;

if ((!txOnGoing) && (txBufferFull))
{
memset(buff,0x00,sizeof(buff));
memcpy(buff,g_txBuffer,52);
sendXfer.data = buff;
txOnGoing = true;
LPUART_SendEDMA(DEMO_LPUART, &g_lpuartEdmaHandle, &sendXfer);

// while(txOnGoing)
// {
//
// }
//SDK_DelayAtLeastUs(1000, CLOCK_GetFreq(kCLOCK_CpuClk));


}
/* If g_txBuffer is empty and g_rxBuffer is full, copy g_rxBuffer to g_txBuffer. */
if ((!rxBufferEmpty) && (!txBufferFull))
{
//memcpy(g_txBuffer, g_rxBuffer, ECHO_BUFFER_LENGTH);
rxBufferEmpty = true;
txBufferFull = true;
}



}
}'
Please give code example what you trying to explain because I'm new into dma uart
0 件の賞賛
返信

5,889件の閲覧回数
hanmant
Contributor III
Hi @Gavin_Jia,

Any update on this?
0 件の賞賛
返信

5,888件の閲覧回数
Gavin_Jia
NXP TechSupport
NXP TechSupport

Hi @hanmant ,

Here is a complete AN for your reference which uses DMA + UART IDEL interrupts.

It provides a software at the same time, and I believe this project will inspire you enough.

Gavin_Jia_0-1733307965664.png

 

Best regards,
Gavin

0 件の賞賛
返信

5,881件の閲覧回数
hanmant
Contributor III
Hi @Gavin_Jia
Can you please recheck link that you provide because I'm not able to brows it.
0 件の賞賛
返信

5,860件の閲覧回数
Gavin_Jia
NXP TechSupport
NXP TechSupport

Hi @hanmant ,

Please kindly check this AN & ANSW. It is under the page of RT1060.

Link: https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/i-mx-rt-crossover-...

Gavin_Jia_0-1733379180286.png

 

0 件の賞賛
返信

5,804件の閲覧回数
hanmant
Contributor III

Hi @Gavin_Jia I have tried that RS_485 example from AN software which you mentioned but in this case DMA or ISR not triggering.

Control is not come in below code:

'if(reciveFrame)//接收到完整的数据包了,echo数据

{

 

PRINTF("\r\n%",send_size);

sendXfer.data = g_txBuffer;

sendXfer.dataSize = send_size;

LPUART_SendEDMA(DEMO_LPUART, &g_lpuartEdmaHandle, &sendXfer);

 

reciveFrame = false;

}'

I have attached whole code for your reference ,also can you please tell

how to set priority for Uart DMA channel by using the DCHPRIn register

0 件の賞賛
返信

5,609件の閲覧回数
hanmant
Contributor III

HI @Gavin_Jia  ,

Have you tried at your end.

0 件の賞賛
返信

5,485件の閲覧回数
Gavin_Jia
NXP TechSupport
NXP TechSupport

Hi @hanmant ,

Sorry for the backlog lately. I'll be testing it on my end today and when I get the results we can sync it.

0 件の賞賛
返信

5,473件の閲覧回数
hanmant
Contributor III
Hi @Gavin_Jia ,
Yes, I'm waiting

0 件の賞賛
返信

5,452件の閲覧回数
Gavin_Jia
NXP TechSupport
NXP TechSupport

Hi @hanmant ,

Here is a simple demo for using uart idle interrupt. Since the policy does not allow direct code releases, it is only for testing. Thank you in advance for your understanding and cooperation.

0 件の賞賛
返信