IMXRT1024 LPUART EDMA Multi Channel Usage and tcdMemoryPoolPtr

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

IMXRT1024 LPUART EDMA Multi Channel Usage and tcdMemoryPoolPtr

ソリューションへジャンプ
2,769件の閲覧回数
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 件の賞賛
返信
1 解決策
2,701件の閲覧回数
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 件の賞賛
返信
7 返答(返信)
2,702件の閲覧回数
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 件の賞賛
返信
2,694件の閲覧回数
Lukas_Frank
Senior Contributor I

Thank you Dear @jeremyzhou.

Best wishes

0 件の賞賛
返信
2,747件の閲覧回数
Lukas_Frank
Senior Contributor I

Hi Dear @jeremyzhou,

 

Could you please help me about the topic?

Thanks and Regards.

0 件の賞賛
返信
2,734件の閲覧回数
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 件の賞賛
返信
2,728件の閲覧回数
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 件の賞賛
返信
2,724件の閲覧回数
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 件の賞賛
返信
2,719件の閲覧回数
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 件の賞賛
返信