IMXRT1024 LPUART EDMA Multi Channel Usage and tcdMemoryPoolPtr

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IMXRT1024 LPUART EDMA Multi Channel Usage and tcdMemoryPoolPtr

Jump to solution
1,786 Views
Lukas_Frank
Senior Contributor I

Hi all,

I am just trying to use multiple LPUART with DMA. I am using lpuart_edma_rb_transfer SDK example as reference. 

 

.
..
...
/* Allocate TCD memory poll with ring buffer used. */
AT_NONCACHEABLE_SECTION_ALIGN(static edma_tcd_t tcdMemoryPoolPtr[1], sizeof(edma_tcd_t));
...
..
.

 

 

/* Start ring buffer. */
static void EXAMPLE_StartRingBufferEDMA(void)
{
    edma_transfer_config_t xferConfig;

    /* Install TCD memory for using only one TCD queue. */
    EDMA_InstallTCDMemory(&g_lpuartRxEdmaHandle, (edma_tcd_t *)&tcdMemoryPoolPtr[0], 1U);

    /* Prepare transfer to receive data to ring buffer. */
    EDMA_PrepareTransfer(&xferConfig, (void *)(uint32_t *)LPUART_GetDataRegisterAddress(EXAMPLE_LPUART),
                         sizeof(uint8_t), g_ringBuffer, sizeof(uint8_t), sizeof(uint8_t), EXAMPLE_RING_BUFFER_SIZE,
                         kEDMA_PeripheralToMemory);

    /* Submit transfer. */
    g_lpuartRxEdmaHandle.tcdUsed = 1U;
    g_lpuartRxEdmaHandle.tail    = 0U;
    EDMA_TcdReset(&g_lpuartRxEdmaHandle.tcdPool[0U]);
    EDMA_TcdSetTransferConfig(&g_lpuartRxEdmaHandle.tcdPool[0U], &xferConfig, tcdMemoryPoolPtr);

    /* Enable major interrupt for counting received bytes. */
    g_lpuartRxEdmaHandle.tcdPool[0U].CSR |= DMA_CSR_INTMAJOR_MASK;

    /* There is no live chain, TCD block need to be installed in TCD registers. */
    EDMA_InstallTCD(g_lpuartRxEdmaHandle.base, g_lpuartRxEdmaHandle.channel, &g_lpuartRxEdmaHandle.tcdPool[0U]);

    /* Setup call back function. */
    EDMA_SetCallback(&g_lpuartRxEdmaHandle, EXAMPLE_RxEDMACallback, NULL);

    /* Start EDMA transfer. */
    EDMA_StartTransfer(&g_lpuartRxEdmaHandle);

    /* Enable LPUART RX EDMA. */
    LPUART_EnableRxDMA(EXAMPLE_LPUART, true);

    /* Enable RX interrupt for detecting the IDLE line interrupt. */
    LPUART_EnableInterrupts(EXAMPLE_LPUART, kLPUART_IdleLineInterruptEnable);
    EnableIRQ(EXAMPLE_LPUART_IRQn);
}

 

Is it enough to change below parameters to use multiple EDMA for multiple LPUART

tcdMemoryPoolPtr[manipulated_size]

g_lpuartRxEdmaHandle.tcdUsed = 1U;

g_lpuartRxEdmaHandle.tail = 0U;

EDMA_TcdReset(&g_lpuartRxEdmaHandle.tcdPool[manipulated_index]);

EDMA_TcdSetTransferConfig(&g_lpuartRxEdmaHandle.tcdPool[manipulated_index], &xferConfig, tcdMemoryPoolPtr);

 

Thanks and Regards.

0 Kudos
1 Solution
1,718 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Q1 : Should I use separate lpuart_edma_handle_t for each UARTx object?
-- Yes.
Q2: Should I align tcdMemoryPoolPtr like below ?
-- Yes.
Q3: Should I use seperate edma_handle_t for each RX(like g_lpuartRxEdmaHandle, g_lpuartRxEdmaHandle2, so on)
-- Yes.
Q4: Could you please check that?
-- Yes.

static void EXAMPLE_StartRingBufferEDMA2(void)
{
    edma_transfer_config_t xferConfig;

    EDMA_InstallTCDMemory(&g_lpuartRxEdmaHandle2, (edma_tcd_t *)&tcdMemoryPoolPtr[1], 1U); //NOT SURE
    EDMA_PrepareTransfer(&xferConfig, (void *)(uint32_t *)LPUART_GetDataRegisterAddress(EXAMPLE_LPUART2),
                         sizeof(uint8_t), g_ringBuffer2, sizeof(uint8_t), sizeof(uint8_t), EXAMPLE_RING_BUFFER_SIZE,
                         kEDMA_PeripheralToMemory);

    g_lpuartRxEdmaHandle2.tcdUsed = 1U; //NOT SURE 1U or 2U
    g_lpuartRxEdmaHandle2.tail    = 0U; //NOT SURE What?
    EDMA_TcdReset(&g_lpuartRxEdmaHandle2.tcdPool[0U]);
    EDMA_TcdSetTransferConfig(&g_lpuartRxEdmaHandle2.tcdPool[0U], &xferConfig, tcdMemoryPoolPtr[1]);


    g_lpuartRxEdmaHandle2.tcdPool[1U].CSR |= DMA_CSR_INTMAJOR_MASK;
    EDMA_InstallTCD(g_lpuartRxEdmaHandle2.base, g_lpuartRxEdmaHandle2.channel, &g_lpuartRxEdmaHandle2.tcdPool[0]);
    EDMA_SetCallback(&g_lpuartRxEdmaHandle2, EXAMPLE_RxEDMACallback2, NULL);
    EDMA_StartTransfer(&g_lpuartRxEdmaHandle2);
    LPUART_EnableRxDMA(EXAMPLE_LPUART2, true);
    LPUART_EnableInterrupts(EXAMPLE_LPUART2, kLPUART_IdleLineInterruptEnable);
    EnableIRQ(EXAMPLE_LPUART_IRQn2);
}

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.
-------------------------------------------------------------------------------

View solution in original post

0 Kudos
7 Replies
1,719 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Q1 : Should I use separate lpuart_edma_handle_t for each UARTx object?
-- Yes.
Q2: Should I align tcdMemoryPoolPtr like below ?
-- Yes.
Q3: Should I use seperate edma_handle_t for each RX(like g_lpuartRxEdmaHandle, g_lpuartRxEdmaHandle2, so on)
-- Yes.
Q4: Could you please check that?
-- Yes.

static void EXAMPLE_StartRingBufferEDMA2(void)
{
    edma_transfer_config_t xferConfig;

    EDMA_InstallTCDMemory(&g_lpuartRxEdmaHandle2, (edma_tcd_t *)&tcdMemoryPoolPtr[1], 1U); //NOT SURE
    EDMA_PrepareTransfer(&xferConfig, (void *)(uint32_t *)LPUART_GetDataRegisterAddress(EXAMPLE_LPUART2),
                         sizeof(uint8_t), g_ringBuffer2, sizeof(uint8_t), sizeof(uint8_t), EXAMPLE_RING_BUFFER_SIZE,
                         kEDMA_PeripheralToMemory);

    g_lpuartRxEdmaHandle2.tcdUsed = 1U; //NOT SURE 1U or 2U
    g_lpuartRxEdmaHandle2.tail    = 0U; //NOT SURE What?
    EDMA_TcdReset(&g_lpuartRxEdmaHandle2.tcdPool[0U]);
    EDMA_TcdSetTransferConfig(&g_lpuartRxEdmaHandle2.tcdPool[0U], &xferConfig, tcdMemoryPoolPtr[1]);


    g_lpuartRxEdmaHandle2.tcdPool[1U].CSR |= DMA_CSR_INTMAJOR_MASK;
    EDMA_InstallTCD(g_lpuartRxEdmaHandle2.base, g_lpuartRxEdmaHandle2.channel, &g_lpuartRxEdmaHandle2.tcdPool[0]);
    EDMA_SetCallback(&g_lpuartRxEdmaHandle2, EXAMPLE_RxEDMACallback2, NULL);
    EDMA_StartTransfer(&g_lpuartRxEdmaHandle2);
    LPUART_EnableRxDMA(EXAMPLE_LPUART2, true);
    LPUART_EnableInterrupts(EXAMPLE_LPUART2, kLPUART_IdleLineInterruptEnable);
    EnableIRQ(EXAMPLE_LPUART_IRQn2);
}

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.
-------------------------------------------------------------------------------

0 Kudos
1,711 Views
Lukas_Frank
Senior Contributor I

Thank you Dear @jeremyzhou.

Best wishes

0 Kudos
1,764 Views
Lukas_Frank
Senior Contributor I

Hi Dear @jeremyzhou,

 

Could you please help me about the topic?

Thanks and Regards.

0 Kudos
1,751 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
1) Is it enough to change below parameters to use multiple EDMA for multiple LPUART
--- No, I'm afraid not.
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.
-------------------------------------------------------------------------------

0 Kudos
1,745 Views
Lukas_Frank
Senior Contributor I

Hi Dear @jeremyzhou,

 

Thanks for your feedback. Could you please help me about the implementation? Do you have any directive or example code for multiple LPUART with EDMA. It has really high importance for the project.

 

Best regards. 

0 Kudos
1,741 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Thanks for your reply.
1) Could you please help me about the implementation? Do you have any directive or example code for multiple LPUART with EDMA?
-- In the lpuart_edma_rb_transfer demo, it uses the LUART1 for example, if you want to use the multiple LPUART, for instance, the LPUART2, LPUART3, etc, it's easy to do that via copy the original demo code, then adjust the code a bit.
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.
-------------------------------------------------------------------------------

0 Kudos
1,736 Views
Lukas_Frank
Senior Contributor I

Hi Dear @jeremyzhou ,

 

Thanks for your feedback. I just get confused a little bit when you said "--- No, I'm afraid not.". Could you please confirm my code about the way I go ? I will be shairing below. Could you check that please? (lpuart_edma_rb_transfer.c attached)

I have some highlited questions here:

Q1 : Should I use separate lpuart_edma_handle_t for each UARTx object?

Q2: Should I align tcdMemoryPoolPtr like below ? 

 

//Increased tcdMemoryPoolPtr[1] to tcdMemoryPoolPtr[2]
AT_NONCACHEABLE_SECTION_ALIGN(static edma_tcd_t tcdMemoryPoolPtr[2], sizeof(edma_tcd_t)); 

 

Q3: Should I use seperate edma_handle_t for each RX(like g_lpuartRxEdmaHandle, g_lpuartRxEdmaHandle2, so on)  or Can I use one g_lpuartRxEdmaHandle for all and only change tcdUsed? For the time being, I used like below. There are some missing point for me in comment lines for tcdUsed, tail, tcdMemoryPoolPtr[indexValue=?and tcdPool[indexValue=?]. Could you please check that?

 

static void EXAMPLE_StartRingBufferEDMA2(void)
{
    edma_transfer_config_t xferConfig;

    EDMA_InstallTCDMemory(&g_lpuartRxEdmaHandle2, (edma_tcd_t *)&tcdMemoryPoolPtr[1], 1U); //NOT SURE
    EDMA_PrepareTransfer(&xferConfig, (void *)(uint32_t *)LPUART_GetDataRegisterAddress(EXAMPLE_LPUART2),
                         sizeof(uint8_t), g_ringBuffer2, sizeof(uint8_t), sizeof(uint8_t), EXAMPLE_RING_BUFFER_SIZE,
                         kEDMA_PeripheralToMemory);

    g_lpuartRxEdmaHandle2.tcdUsed = 2U; //NOT SURE 1U or 2U
    g_lpuartRxEdmaHandle2.tail    = 0U; //NOT SURE What?
    EDMA_TcdReset(&g_lpuartRxEdmaHandle2.tcdPool[1U]);
    EDMA_TcdSetTransferConfig(&g_lpuartRxEdmaHandle2.tcdPool[1U], &xferConfig, tcdMemoryPoolPtr);


    g_lpuartRxEdmaHandle2.tcdPool[1U].CSR |= DMA_CSR_INTMAJOR_MASK;
    EDMA_InstallTCD(g_lpuartRxEdmaHandle2.base, g_lpuartRxEdmaHandle2.channel, &g_lpuartRxEdmaHandle2.tcdPool[1U]);
    EDMA_SetCallback(&g_lpuartRxEdmaHandle2, EXAMPLE_RxEDMACallback2, NULL);
    EDMA_StartTransfer(&g_lpuartRxEdmaHandle2);
    LPUART_EnableRxDMA(EXAMPLE_LPUART2, true);
    LPUART_EnableInterrupts(EXAMPLE_LPUART2, kLPUART_IdleLineInterruptEnable);
    EnableIRQ(EXAMPLE_LPUART_IRQn2);
}

 

I am appretiate for your help.

Thanks and Regards.

 
0 Kudos