IMX RT1170 DMA on CM4 Core #67903
Replies: 10 comments 3 replies
-
I think I can get this to work by using the Zephyr DMA API as well as the NXP SDK. Basically I can request a periodic DMA channel and initialise it. After that, I can call the SDK function to make that channel periodic and initialise the appropriate timers to do the triggering. I have seen this work when doing MEMORY_TO_MEMORY transfers. The issue I now have is transferring data from memory to peripheral. The code below works fine until I change 'dma_cfg.channel_direction = MEMORY_TO_MEMORY' to 'dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL'. By the way, the sample below isn't calling any SDK functions directly. It is a modified version of the DMA test code found in Zephyr. Does anyone know why changing the direction to MEMORY_TO_PERIPHERAL stops the code from working? |
Beta Was this translation helpful? Give feedback.
-
I think I have found the issue. In the case of memory to peripheral transfer, dma_mcux_edma_configure in dma_mcux_edma.c is setting the dmamux source to the slot. My code doesn't work because I didn't set any slot that would generate the transfer request. Even though I'm setting it to memory to peripheral, I do need the DMAMUX to be in always on mode so I can do periodic trigger using a PIT timer. I guess I will have to mod the driver somehow to add this support. |
Beta Was this translation helpful? Give feedback.
-
Hi @danielb-tkjcy3rq , It seems you are on the right path, and getting close. Thank you for sharing your updates. You are right, the driver dma_mcux_edma.c does not yet enable the DMAMUX periodic trigger feature you are trying to use. To setup the channel for Always On and periodic triggering, you just need to configure the CHCFG register in the DMAMUX. Updating the dma_mcux_edma.c driver to do that would be ideal, especially if you contribute that back to the Zephyr Community. But another option is like you said: use the Zephyr DMA APIs to configure the channel, and then call the HAL APIs in the MCUXpresso SDK to configure the DMAMUX register as you need. For example, DMAMUX_EnablePeriodTrigger() and DMAMUX_EnableAlwaysOn() can be called after the DMA channel is configured. Also, you seem to be aware since you are using channel 0, but for others, the periodic trigger feature of the DMAMUX is only available on the first 4 channels in the RT1170. Also FYI since you are using the PIT, we have an open PR #66336 to add the PIT driver to Zephyr. Please let us know how this goes for you. Best regards |
Beta Was this translation helpful? Give feedback.
-
Thank you @DerekSnell! I took the easy route for now and used the HAL API just to see it working. The DMA is transferring periodically but the timing isn't quite right. I've attached a screenshot of a Saleae capture for reference. I am configuring it to transfer data every 416us but it seems like PIT is triggering every 624us. Any idea why this could be? I suspect clock configuration issue but not sure how to check that in Zephyr. I would use clock_config.c/h in MCUXpresso. I've edited this comment because there were some issues with the code I posted originally.
|
Beta Was this translation helpful? Give feedback.
-
@DerekSnell, I just gave kCLOCK_Root_Bus_Lpsr a go and period seems a bit erratic now. |
Beta Was this translation helpful? Give feedback.
-
Hi @danielb-tkjcy3rq , My guess is still that the PIT2 period register is not configured correctly given the timer clock. On the RT1170, there is a clock output pin you can use to output these root clocks and confirm their frequency, which could help here. And I would use a debugger to confirm the PIT2 registers after it is configured, specifically the bits that configure the trigger period. Confirm they should give the clock period you want. Also, since you have it working with the MCUXpresso SDK code base without Zephyr, you can compare the PIT2 registers with that application to see how they differ. Please let us know what you find. Best regards |
Beta Was this translation helpful? Give feedback.
-
Thanks for the details, @danielb-tkjcy3rq , I would first focus on configuring the root clocks to the valid frequencies given your voltage supply. And ideally, confirm those clocks with the CCM_CLKO pins. And if the PIT period issue still remains, then confirm the PIT register configuration. Let us know what you find. Best regards |
Beta Was this translation helpful? Give feedback.
-
Thanks @DerekSnell, I've made some progress on this and I'm now seeing consistent 416us period on PIT2. I set the CM7 frequency to 600MHz and CM4 to 240MHz. Also started using clock kCLOCK_Root_Bus_Lpsr for PIT2. I also managed to fix the issue where ethernet on CM7 was breaking after CM4 core started. I basically I skip clock_init() in soc_rt11xx.c by returning early if CONFIG_CPU_CORTEX_M4 is defined because I have a suspicion that the CM7 is configuring the clocks as I expect but then the CM4 starts and initialises the clocks again. For example, the code below configures PLL2 PFD3 differently depending on CONFIG_ETH_MCUX - my CM7 project uses ethernet but not the CM4 project. For my project, I think it makes sense for the master project to configure the clocks before launching the slave core. Unless I'm missing something obvious?
|
Beta Was this translation helpful? Give feedback.
-
Hi @danielb-tkjcy3rq , If you have other questions that are still open, I suggest you create a new Discussion focused on that topic, and we can address them there. Best regards |
Beta Was this translation helpful? Give feedback.
-
Thank you very much for all your help @DerekSnell! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi All,
I'm working on a project using imx rt1170 based custom board. I'm hoping to use the eDMA peripheral on the chip in periodic trigger mode to throttle the data DMA is transferring. I need to do this because I'm generating custom protocol signal by using DMA to transfer data to a GPIO data register. The plan is to use the CM4 for this as the CM7 will be used for application level stuff like Ethernet.
I understand that Zephyr doesn't currently support the periodic triggering I'm trying to do so I will use the NXP SDK to do this. I will use DMAMUX1 channel 0 in always on mode with eDMA LPSR channel 0 and PIT2 channel 0. I have seen this work on MCUXPresso by modifying the edma_memory_to_memory sample to add periodic triggering. But no luck when I port the code to Zephyr. The ported code builds and flashes OK but the DMA TX interrupt doesn't fire.
I also attempted removing the periodic triggering just to see DMA working but still no interrupt. I used dma_request_channel to make sure the DMA channel I'm trying to use isn't already in use.
I'm using Zephyr 3.5.0-rc3 and I've setup a multicore project based on the openamp sample.
Can someone please help with this?
Thanks,
Daniel
Beta Was this translation helpful? Give feedback.
All reactions