Hi everyone:
I have a question about lpuart and dma for RT1064. Now I have to use two lpuart,lpuart1 and lpuart2. and lpuart1 and lpuart2 send or receive data by edma. Now, if I only use lpuart1 send or receive data, the lpuart1 is normally. If I only use lpuart2 send or receive data, the lpuart2 is normally too.
But when I use lpuart1 and lpuart2 both. if I Initiaize lpuart1 first, the lpuart1 can't enter functiong DrvUartUserCallback but can enter LPUART1_IRQHandler and lpuart1 received data in error. The lpuart2 work normally. if I Initiaize lpuart2 first, the lpuart2 can't enter functiong DrvWIFIUartUserCallback but can enter LPUART2_IRQHandler and lpuart2 received data in error. The lpuart1 work normally.
Now , I put my code as follow:
1. about lpuart1
#define HW_GPIO_UART_PRIORITY 5
#define HW_GPIO_UART LPUART1
#define HW_GPIO_TX_PIN_MUX IOMUXC_GPIO_AD_B0_12_LPUART1_TX
#define HW_GPIO_RX_PIN_MUX IOMUXC_GPIO_AD_B0_13_LPUART1_RX
//#define HW_GPIO_UART_IRQ LPUART1_IRQn
//#define HW_GPIO_UART_IRQ_HANDLER LPUART1_IRQHandler
#define HW_GPIO_UART_DMA_REQUEST_TX kDmaRequestMuxLPUART1Tx
#define HW_GPIO_UART_DMA_REQUEST_RX kDmaRequestMuxLPUART1Rx
#define CONFIG_DMA_UART_DMAMUX DMAMUX
#define CONFIG_DMA_UART_DMA DMA0
#define CONFIG_DMA_UART_TX_CHANNEL 0
#define CONFIG_DMA_UART_RX_CHANNEL 1
#define CONFIG_DMA_UART_TX_IRQ DMA0_DMA16_IRQn
#define CONFIG_DMA_UART_TX_PRIORITY 5
#define CONFIG_DMA_UART_RX_IRQ DMA1_DMA17_IRQn
#define CONFIG_DMA_UART_RX_PRIORITY 5
static void DrvUartUserCallback(LPUART_Type *base, lpuart_edma_handle_t *handle, status_t status, void *userData)
{
BaseType_t reschedule = pdFALSE;
BaseType_t xResult;
userData = userData;
if (kStatus_LPUART_TxIdle == status)
{
xResult=xEventGroupSetBitsFromISR(gg_event_uart, UART_EVENT_SEND_DATA_COMPLETE, &reschedule);
if (xResult != pdFAIL)
{
portYIELD_FROM_ISR(reschedule);
}
}
else if (kStatus_LPUART_RxIdle == status)
{
xResult=xEventGroupSetBitsFromISR(gg_event_uart, UART_EVENT_RECV_DATA_COMPLETE, &reschedule);
if (xResult != pdFAIL)
{
portYIELD_FROM_ISR(reschedule);
}
}
}
static void DrvUartConfigGPIO(void)
{
CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
IOMUXC_SetPinMux(HW_GPIO_TX_PIN_MUX, 0U);
IOMUXC_SetPinMux(HW_GPIO_RX_PIN_MUX, 0U);
IOMUXC_SetPinConfig(HW_GPIO_TX_PIN_MUX, 0x10B0u);
IOMUXC_SetPinConfig(HW_GPIO_RX_PIN_MUX, 0x10B0u);
}
static void DrvUartConfigParameter(T_U32 baudrate)
{
T_U32 uiFreq;
lpuart_config_t uart;
edma_config_t uart_dma;
uart.baudRate_Bps = baudrate;
uart.parityMode = kLPUART_ParityDisabled;
uart.dataBitsCount = kLPUART_EightDataBits;
uart.isMsb = false;
uart.stopBitCount = kLPUART_OneStopBit;
uart.txFifoWatermark = 0;
uart.rxFifoWatermark = 0;
uart.enableRxRTS = false;
uart.enableTxCTS = false;
uart.txCtsConfig = kLPUART_CtsSampleAtStart;
uart.txCtsSource = kLPUART_CtsSourcePin;
uart.rxIdleType = kLPUART_IdleTypeStartBit;
uart.rxIdleConfig = kLPUART_IdleCharacter1;
uart.enableTx = true;
uart.enableRx = true;
if (CLOCK_GetMux(kCLOCK_UartMux) == 0) /* PLL3 div6 80M */
uiFreq = (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
else
uiFreq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
LPUART_Init(HW_GPIO_UART, &uart, uiFreq);
/* Init DMAMUX */
DMAMUX_Init(CONFIG_DMA_UART_DMAMUX);
/* Set channel for LPUART */
DMAMUX_SetSource(CONFIG_DMA_UART_DMAMUX, CONFIG_DMA_UART_TX_CHANNEL, HW_GPIO_UART_DMA_REQUEST_TX);
DMAMUX_SetSource(CONFIG_DMA_UART_DMAMUX, CONFIG_DMA_UART_RX_CHANNEL, HW_GPIO_UART_DMA_REQUEST_RX);
DMAMUX_EnableChannel(CONFIG_DMA_UART_DMAMUX, CONFIG_DMA_UART_TX_CHANNEL);
DMAMUX_EnableChannel(CONFIG_DMA_UART_DMAMUX, CONFIG_DMA_UART_RX_CHANNEL);
/* Init the EDMA module */
EDMA_GetDefaultConfig(&uart_dma);
EDMA_Init(CONFIG_DMA_UART_DMA, &uart_dma);
NVIC_SetPriority(CONFIG_DMA_UART_TX_IRQ, CONFIG_DMA_UART_TX_PRIORITY);
EDMA_CreateHandle(&g_UartTxEdmaHandle, CONFIG_DMA_UART_DMA, CONFIG_DMA_UART_TX_CHANNEL);
NVIC_SetPriority(CONFIG_DMA_UART_RX_IRQ, CONFIG_DMA_UART_RX_PRIORITY);
EDMA_CreateHandle(&g_UartRxEdmaHandle, CONFIG_DMA_UART_DMA, CONFIG_DMA_UART_RX_CHANNEL);
/* Create LPUART DMA handle. */
LPUART_TransferCreateHandleEDMA(HW_GPIO_UART, &gg_uart_EdmaHandle, DrvUartUserCallback, NULL, &g_UartTxEdmaHandle, &g_UartRxEdmaHandle);
g_UartRecv.data = g_uart_recv_buff;
g_UartRecv.dataSize = M_UART_RECV_DATA_LEN;
LPUART_ReceiveEDMA(HW_GPIO_UART,&gg_uart_EdmaHandle,&g_UartRecv);
LPUART_EnableInterrupts(HW_GPIO_UART, kLPUART_IdleLineInterruptEnable);
NVIC_SetPriority(HW_GPIO_UART_IRQ, HW_GPIO_UART_PRIORITY);
EnableIRQ(HW_GPIO_UART_IRQ);
}
void DrvUartInit(T_U32 baudrate)
{
DrvUartConfigGPIO();
DrvUartConfigParameter(baudrate);
}
2.about lpuart2
#define HW_GPIO_WIFI_UART_PRIORITY 5
#define HW_GPIO_WIFI_UART LPUART2
#define HW_GPIO_WIFI_TX_PIN_MUX IOMUXC_GPIO_SD_B1_11_LPUART2_TX
#define HW_GPIO_WIFI_RX_PIN_MUX IOMUXC_GPIO_SD_B1_10_LPUART2_RX
//#define HW_GPIO_WIFI_UART_IRQ LPUART2_IRQn
//#define HW_GPIO_WIFI_UART_IRQ_HANDLER LPUART2_IRQHandler
#define HW_GPIO_WIFI_UART_DMA_REQUEST_TX kDmaRequestMuxLPUART2Tx
#define HW_GPIO_WIFI_UART_DMA_REQUEST_RX kDmaRequestMuxLPUART2Rx
#define CONFIG_DMA_WIFI_UART_DMAMUX DMAMUX
#define CONFIG_DMA_WIFI_UART_DMA DMA0
#define CONFIG_DMA_WIFI_UART_TX_CHANNEL 2
#define CONFIG_DMA_WIFI_UART_RX_CHANNEL 3
#define CONFIG_DMA_WIFI_UART_TX_IRQ DMA2_DMA18_IRQn
#define CONFIG_DMA_WIFI_UART_TX_PRIORITY 5
#define CONFIG_DMA_WIFI_UART_RX_IRQ DMA3_DMA19_IRQn
#define CONFIG_DMA_WIFI_UART_RX_PRIORITY 5
static void DrvWIFIUartUserCallback(LPUART_Type *base, lpuart_edma_handle_t *handle, status_t status, void *userData)
{
BaseType_t xResult;
BaseType_t reschedule = pdFALSE;
userData = userData;
if (kStatus_LPUART_TxIdle == status)
{
xResult = xEventGroupSetBitsFromISR(gg_event_wifi, WIFI_EVENT_SEND_DATA_COMPLETE, &reschedule);
if (xResult != pdFAIL)
{
portYIELD_FROM_ISR(reschedule);
}
}
else if (kStatus_LPUART_RxIdle == status)
{
xResult=xEventGroupSetBitsFromISR(gg_event_wifi, WIFI_EVENT_RECV_DATA_COMPLETE, &reschedule);
if (xResult != pdFAIL)
{
portYIELD_FROM_ISR(reschedule);
}
}
}
static void DrvWIFIUartConfigGPIO(void)
{
CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
IOMUXC_SetPinMux(HW_GPIO_WIFI_TX_PIN_MUX, 0U);
IOMUXC_SetPinMux(HW_GPIO_WIFI_RX_PIN_MUX, 0U);
IOMUXC_SetPinConfig(HW_GPIO_WIFI_TX_PIN_MUX, 0x10B0u);
IOMUXC_SetPinConfig(HW_GPIO_WIFI_RX_PIN_MUX, 0x10B0u);
}
static void DrvWIFIUartConfigParameter(T_U32 baudrate)
{
unsigned int uiFreq;
lpuart_config_t uart;
edma_config_t uart_dma;
T_U8 recv_buff[M_WIFI_RECV_DATA_LEN];
// LPUART_GetDefaultConfig(&uart);
// uart.baudRate_Bps = baudrate;
// uart.enableTx = true;
// uart.enableRx = true;
uart.baudRate_Bps = baudrate;
uart.parityMode = kLPUART_ParityDisabled;
uart.dataBitsCount = kLPUART_EightDataBits;
uart.isMsb = false;
uart.stopBitCount = kLPUART_OneStopBit;
uart.txFifoWatermark = 0;
uart.rxFifoWatermark = 0;
uart.enableRxRTS = false;
uart.enableTxCTS = false;
uart.txCtsConfig = kLPUART_CtsSampleAtStart;
uart.txCtsSource = kLPUART_CtsSourcePin;
uart.rxIdleType = kLPUART_IdleTypeStartBit;
uart.rxIdleConfig = kLPUART_IdleCharacter1;
uart.enableTx = true;
uart.enableRx = true;
if (CLOCK_GetMux(kCLOCK_UartMux) == 0) /* PLL3 div6 80M */
{
uiFreq = (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
}
else
{
uiFreq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
}
LPUART_Init(HW_GPIO_WIFI_UART, &uart, uiFreq);
/* Init DMAMUX */
DMAMUX_Init(CONFIG_DMA_WIFI_UART_DMAMUX);
/* Set channel for LPUART */
DMAMUX_SetSource(CONFIG_DMA_WIFI_UART_DMAMUX, CONFIG_DMA_WIFI_UART_TX_CHANNEL, HW_GPIO_WIFI_UART_DMA_REQUEST_TX);
DMAMUX_SetSource(CONFIG_DMA_WIFI_UART_DMAMUX, CONFIG_DMA_WIFI_UART_RX_CHANNEL, HW_GPIO_WIFI_UART_DMA_REQUEST_RX);
DMAMUX_EnableChannel(CONFIG_DMA_WIFI_UART_DMAMUX, CONFIG_DMA_WIFI_UART_TX_CHANNEL);
DMAMUX_EnableChannel(CONFIG_DMA_WIFI_UART_DMAMUX, CONFIG_DMA_WIFI_UART_RX_CHANNEL);
/* Init the EDMA module */
EDMA_GetDefaultConfig(&uart_dma);
EDMA_Init(CONFIG_DMA_WIFI_UART_DMA, &uart_dma);
NVIC_SetPriority(CONFIG_DMA_WIFI_UART_TX_IRQ, CONFIG_DMA_WIFI_UART_TX_PRIORITY);
EDMA_CreateHandle(&g_WIFIUartTxEdmaHandle, CONFIG_DMA_WIFI_UART_DMA, CONFIG_DMA_WIFI_UART_TX_CHANNEL);
NVIC_SetPriority(CONFIG_DMA_WIFI_UART_RX_IRQ, CONFIG_DMA_WIFI_UART_RX_PRIORITY);
EDMA_CreateHandle(&g_WIFIUartRxEdmaHandle, CONFIG_DMA_WIFI_UART_DMA, CONFIG_DMA_WIFI_UART_RX_CHANNEL);
/* Create LPUART DMA handle. */
LPUART_TransferCreateHandleEDMA(HW_GPIO_WIFI_UART, &gg_wifi_EdmaHandle, DrvWIFIUartUserCallback, NULL, &g_WIFIUartTxEdmaHandle, &g_WIFIUartRxEdmaHandle);
g_WifiRecv.data = g_wifi_recv_buff;
g_WifiRecv.dataSize = M_WIFI_RECV_DATA_LEN;
LPUART_ReceiveEDMA(HW_GPIO_WIFI_UART,&gg_wifi_EdmaHandle,&g_WifiRecv);
LPUART_EnableInterrupts(HW_GPIO_WIFI_UART, kLPUART_IdleLineInterruptEnable);
NVIC_SetPriority(HW_GPIO_WIFI_UART_IRQ, HW_GPIO_WIFI_UART_PRIORITY);
EnableIRQ(HW_GPIO_WIFI_UART_IRQ);
}
void DrvWIFIUartInit(T_U32 baudrate)
{
DrvWIFIUartConfigGPIO();
DrvWIFIUartConfigParameter(baudrate);
}
3. function main (Initiaze lpuart2 first)
int main(void)
{
BOARD_ConfigMPU();
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_USDHCClockConfiguration();
DrvWIFIUartInit(921600);
DrvUartInit(921600);
//DrvUartInit(115200);
//DrvWIFIUartInit(921600);
NVIC_SetPriorityGrouping(0x03);
NVIC_SetPriority(BOARD_SD_HOST_IRQ, 5U);
gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
/* Init output LED GPIO. */
GPIO_PinInit(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, &led_config);
InitSoftware();
CtlAds129xInit();
CtlAds129xTimeInit();
xEventGroupSetBits(gg_event_uart, UART_EVENT_SEND_DATA_START);
taskENTER_CRITICAL();
CardDetectTaskCreate();
CardWriteTaskCreate();
CardReadTaskCreate();
AlgorithmTaskCreate();
SampleTaskCreate();
//BleUartTaskCreate();
WifiUartTaskCreate();
UartTaskCreate();
taskEXIT_CRITICAL();
/* Start the tasks and timer running. */
vTaskStartScheduler();
/* Scheduler should never reach this point. */
while (true)
{
}
}
4. function main (Initiaze lpuart1 first)
int main(void)
{
BOARD_ConfigMPU();
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_USDHCClockConfiguration();
//DrvWIFIUartInit(921600);
DrvUartInit(921600);
//DrvUartInit(115200);
DrvWIFIUartInit(921600);
NVIC_SetPriorityGrouping(0x03);
NVIC_SetPriority(BOARD_SD_HOST_IRQ, 5U);
gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
/* Init output LED GPIO. */
GPIO_PinInit(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, &led_config);
InitSoftware();
CtlAds129xInit();
CtlAds129xTimeInit();
xEventGroupSetBits(gg_event_uart, UART_EVENT_SEND_DATA_START);
taskENTER_CRITICAL();
CardDetectTaskCreate();
CardWriteTaskCreate();
CardReadTaskCreate();
AlgorithmTaskCreate();
SampleTaskCreate();
//BleUartTaskCreate();
WifiUartTaskCreate();
UartTaskCreate();
taskEXIT_CRITICAL();
/* Start the tasks and timer running. */
vTaskStartScheduler();
/* Scheduler should never reach this point. */
while (true)
{
}
}
5.
void LPUART1_IRQHandler(void)
{
unsigned int count;
if ((kLPUART_IdleLineFlag) & LPUART_GetStatusFlags(HW_GPIO_UART))
{
HW_GPIO_UART->STAT |= LPUART_STAT_IDLE_MASK;
LPUART_TransferGetReceiveCountEDMA(HW_GPIO_UART,&gg_uart_EdmaHandle,&count);
LPUART_TransferAbortReceiveEDMA(HW_GPIO_UART, &gg_uart_EdmaHandle);
LPUART_ReceiveEDMA(HW_GPIO_UART,&gg_uart_EdmaHandle,&g_UartRecv);
memcpy(uart1_rx_buffer, g_UartRecv.data,8);
}
}
void LPUART2_IRQHandler(void)
{
unsigned int count;
if ((kLPUART_IdleLineFlag) & LPUART_GetStatusFlags(HW_GPIO_WIFI_UART))
{
HW_GPIO_WIFI_UART->STAT |= LPUART_STAT_IDLE_MASK;
LPUART_TransferGetReceiveCountEDMA(HW_GPIO_WIFI_UART,&gg_wifi_EdmaHandle,&count);
LPUART_TransferAbortReceiveEDMA(HW_GPIO_WIFI_UART, &gg_wifi_EdmaHandle);
LPUART_ReceiveEDMA(HW_GPIO_WIFI_UART,&gg_wifi_EdmaHandle,&g_WifiRecv);
memcpy(uart1_rx_buffer, g_WifiRecv.data,8);
}
}
Because DrvUartInit() and DrvWIFIUartInit() have the common part about edma. so I think the error is about it .Could some can point out my error? Thanks very much.
Regards
Chris Song
Hi Chris Song ,
Thank you for your interest in NXP Semiconductor products and
for the opportunity to serve you.
After having a brief review of the attachment, I've not found out anything wrong.
So I'd like to suggest you try to add another UART module to lpuart_edma_transfer demo project in the SDK library to replicate this phenomenon, as it's easier to find out the cause in a simple demo project.
Please give a try.
Have a great day,
TIC
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Hi Chris Song ,
Thanks for your reply.
Whether you can add the Freertos to the lpuart_edma_transfer demo project to replicate the issue, then I can do some testing on my site.
Have a great day,
TIC
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Hi Jeremy
The attachment is my lpuart edma project with freertos .I use IAR to debug it. And the picture is the location for my project.
Thanks a lot.
Regards
Chris Song
HiChris Song ,
Thanks for your reply.
I didn't see the attachment and picture you mentioned, please check them.
Have a great day,
TIC
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Hi Jeremy
I have updated two version software for lpuart using edma. One is interrupt by uart.Another is interrupt by Edma
The version interrupt by uart work normally now. Because I found a error in my code on initiaization part.
The version interrupt by edma work unnormally.Because of xSemaphoreGiveFromISR couldn't work in interrupt function. I konw that is the priority of dma is not fit for software. So can you give me saome advise on how to set priority of dma?
The attachment is two version and the picture is location. The two project is set up by IAR.