Feed Emios PWM with DMA not working

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

Feed Emios PWM with DMA not working

Jump to solution
1,339 Views
h_bouchard
Contributor III

Hi,

I'm trying to use Emios PWM (OPWMB mode) and feed them with DMA. I have set up a test application that has two DMA buffers configured in scatter gather mode. When the first one is finished playing, the second one is being played. Right now, I don't update the buffers but in the final application, while a buffer is being played, the other one will get updated and buffers will be played in loop.

I'm using S32 Design Studio 3.5 and S32K3XX Real-Time Drivers AUTOSAR R21-11 Version 5.0.0.

I've set up the DMA channel 0 in scatter gather mode with 2 elements (2 buffers of 128 elements each). The source is a buffer of int16 therefore the "source signed offset" is set to 2 and "transfer size" is also set to 2. The destination is an Emios register (IP_EMIOS_0->CH.UC[1].B) therefore, the "destination signed offset" is set to 0 and "transfer size" is set to 2. Since the source buffers have 128 elements, the "source last address adjustment" is set to -256 (128 * sizeof(int16)).

The PWM is set to trigger a DMA request (Flag Event response -> EMIOS_PWM_IP_DMA_REQUEST).

I've attached my test application which runs on a S32K312EVB-Q172 board. Right now, the buffers don't play in a loop, they should be played only once but they are not being played at all. I check with an oscilloscope and I don't see the PWM duty cycle changing

My question is how to configure the DMAMUX to link Emios PWM with DMA channel 0? I don't see where I can configure this. Is it even possible what I'm trying to do? If not, do you have another solution to propose?

Thanks for your help!
Hugo

 

 

 

Tags (3)
0 Kudos
Reply
1 Solution
983 Views
h_bouchard
Contributor III

Hi Senlent,

After some tests, I figured that the ISR is called only when both buffers are played (every ~8.72 ms) on my side unlike on your oscilloscope screenshot. It seems normal to me because the "Enable Major Interrupt" check box is not set for scatter/gather channel 0. When I set it, it now works fine and the buffer is played properly. Here is the modification I made for scatter/gather configuration on both channels:

h_bouchard_0-1737044280053.png

I've attached the final version of my test application if someone needs to do the same thing.

Thanks a lot for your help!!! It is really appreciated!

Regards,
Hugo

View solution in original post

0 Kudos
Reply
11 Replies
1,117 Views
h_bouchard
Contributor III

Hi Senlent,

Thanks for your help. However, the DMA doesn't seem to work properly. The first element of the buffer is written in the B register of the eMIOS channel but the source address is not incremented and I get an interrupt twice within the PWM period while I should get one every 128 PWM period (the minor loop size is set to 256 for a 2 bytes transfer). To see that, I've added a pin toggle in the DMA ISR function.

Here is a screenshot of the TCD registers and eMIOS settings:

h_bouchard_0-1736511805565.png

h_bouchard_2-1736512200807.png

 

And here is a screenshot of the oscilloscope:

h_bouchard_1-1736511911998.png

As you can see, I get two interrupts within a few microseconds when I should get only one every 0.00436907 seconds (1 / 29296.875 KHz (PWM frenquency) * 128).

Do you have any idea why?

Regards,
Hugo

0 Kudos
Reply
1,089 Views
Senlent
NXP TechSupport
NXP TechSupport

Hi@h_bouchard

Could you please modified it like below shows.

Senlent_0-1736762224024.png

Senlent_1-1736762252732.png

 

Senlent_2-1736762447652.png

0 Kudos
Reply
1,077 Views
h_bouchard
Contributor III

Hi Senlent,

Thank you for your answer. However, that doesn't do what it should. I should get an interrupt when minor loop has done all its DMA transfers, which is set to 128 (at major loop iteration). Therefore, with a PWM period of (1 / 29296.875 KHz) * 128 transfers = 4.369067 ms. I can see on your screenshot that the period is ~3.413 us.

Also, the DMA is not reading from the buffer, only the first element is read and played. I don't see the TCDx_SADDR being incremented. Any idea why?

Regards,
Hugo

0 Kudos
Reply
1,054 Views
Senlent
NXP TechSupport
NXP TechSupport

Hi@h_bouchard

I don't know why you want to do this, I changed your configuration according to your idea

And I added a PWM output as a reference comparison

Senlent_2-1736849996377.png

Senlent_0-1736848226636.png

Senlent_1-1736848276566.png

 

0 Kudos
Reply
1,024 Views
h_bouchard
Contributor III

Hi Senlent,

Thank you for your answer. I want to do that to avoid having to have an interrupt at PWM frequency to write P_EMIOS_0->CH.UC[1].B. By having two buffers of 128 samples each allows me to play one buffer while updating the second. When one buffer is played, I get the ISR and then I can fill the other one with new PWM values. At the next ISR, the new values are played and then I can update the other buffer. In the sample application I provided, the PWM duty cycle values are constants but this was just for a test.

I'm working from home now so I don't have an oscilloscope to test but will test tomorrow. Thanks again for your help so far!

Regards,
Hugo

0 Kudos
Reply
984 Views
h_bouchard
Contributor III

Hi Senlent,

After some tests, I figured that the ISR is called only when both buffers are played (every ~8.72 ms) on my side unlike on your oscilloscope screenshot. It seems normal to me because the "Enable Major Interrupt" check box is not set for scatter/gather channel 0. When I set it, it now works fine and the buffer is played properly. Here is the modification I made for scatter/gather configuration on both channels:

h_bouchard_0-1737044280053.png

I've attached the final version of my test application if someone needs to do the same thing.

Thanks a lot for your help!!! It is really appreciated!

Regards,
Hugo

0 Kudos
Reply
1,206 Views
h_bouchard
Contributor III

Hi Senlent,

Sorry, here it is.

Regards,
Hugo

0 Kudos
Reply
1,287 Views
Senlent
NXP TechSupport
NXP TechSupport

Hi@h_bouchard

My question is how to configure the DMAMUX to link Emios PWM with DMA channel 0? 

this can be done in "RM"

Senlent_0-1735029393132.png

 

0 Kudos
Reply
1,234 Views
h_bouchard
Contributor III

Hi Senlent,

Thank you for your answer. I did add the RM and set it up as you suggested:

h_bouchard_0-1735919002338.png

However, I'm still not able to generate DMA request from EMIOS0 CH 1. Here is my setting of the DMA channel. Both elements ID are set up the same except that Element ID 0 links to Element ID 1 and Element ID 1 links to Element ID 0 to create a double buffering which never stops.

h_bouchard_1-1735919117751.png

The "Enable Start" option is set for both Element ID. The DMA interrupt is triggered right after the DMA channel is configured (call to Mcl_SetDmaChannelScatterGatherConfig()). The PWM is initialized after that. Even if I comment out the PWM_Init function, the DMA interrupt is triggered which tells me that something else is triggering the DMA instead of EMIOS0 CH 1 as it is set up in "RM". Do you have any idea what else can trigger the DMA?

I've updated the test firmware with the latest changes (see firmware_test2.zip).

Thanks,
Regards,
Hugo

Tags (4)
0 Kudos
Reply
1,184 Views
Senlent
NXP TechSupport
NXP TechSupport

Hi@h_bouchard

Sorry for the later reply cause we're in overload.

 

please disable this option

Senlent_0-1736247215316.png

 

enable emios0_ch1->FEN otherwise it won't generate a DMA request.

IP_EMIOS_0->CH.UC[1].C = (IP_EMIOS_0->CH.UC[1].C & ~(eMIOS_C_FEN_MASK)) | eMIOS_C_FEN(1);

(it should be have api to enable FEN bit but i don't fimilar with MCAL API)

Senlent_1-1736247284630.png

 

0 Kudos
Reply
1,217 Views
Senlent
NXP TechSupport
NXP TechSupport

Hi@h_bouchard

"I've updated the test firmware with the latest changes (see firmware_test2.zip)."

Could you please double check it, because i did not see "firmware_test2.zip"

0 Kudos
Reply