MWCT controller DMA configuration for continuous transfer

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

MWCT controller DMA configuration for continuous transfer

1,064 Views
amitavadas
Contributor I

Hello,

I've a question regarding MWCT1013 controller DMA and PWM module.

I want to load the PWM module VALx registers with the contents stored at a memory location. The DMA is configured to get a trigger every PWM period to start the transfer of values from memory to 4 of the VALx registers. To do this, BCR register is loaded with 4. This indicates the DMA module to make 4 transfers. The issue is that the BCR value decrements to 0 after those 4 transfers. Then the BCR registers have to be reinitialized. How can I overcome this issue? Using the interrupt is one option. But is there a way to avoid using interrupt and the BCR is loaded with 4 after the completion of the transfers? e.g. by configuring different DMA channel which can load 0x4 from some other memory location?

Thanks

Tags (1)
0 Kudos
5 Replies

831 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Das,

Regarding your question that you want to load BCR automatically, the DMA supports the method to load BCR automatically by DMA channel link.

For example, you can set the DMA CH0 to transfer data from mmeory to Valuex registers after triggering from eFlexPWM_SMx, after the BCR reaches to zero, another DMA channel starts automatically by the channel link function.

Pls refer to the part.

You can set the LNKCC to 2b'11, LCH1 to 2b'01, initialize the DMA CH1 so that it can transfer a data from memory(whose contents is 4) to BCR.

Hope it can help you

BR

Xiangjun rong

pastedImage_1.png

0 Kudos

830 Views
sdass
Contributor I

Hi Xiangjun,

Thank you for your suggestion.

How do we handle the scenario where we would also need to clear the bit 24 (DONE) in the DMA_DSR_BCRn register at the end of the transfers (for DMA channel triggered from the PWM requests)?

Technically the BCR value can only be loaded after the DONE bit is cleared; NOTE: when clearing the DONE bit, it also clears the BCR value so setting BCR would definitely have to be done after.

Please advise.

Thanks!

0 Kudos

830 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Saurabh,

Regarding your question, you are right, you have to clear the DONE bit before you initialize the BCR register. I think you can use two DMA channels to finish the link.

DMA0 is used to transfer data to multiple eFlexPWM Valuex register, aftter the BCR of DMA reaches to zero, as we discussed above, it triggers DMA1 via the DMA0 link, the DMA1 write the DSR register of DMA0 to clear the DONE bit, you can set the LINKCC of DMA1 as 2b'10, and set the LCH1 to 2b'10. The DMA1 cycle steal event can trigger DMA2, you can use DMA2 to write BCR register of DMA0 from a memory.

But i have to admit it is a bit complicated, I suggest you use interrupt mechanism  to write the eFlexPWM Valuex registers.

BR

Xiangjun Rong

0 Kudos

830 Views
sdass
Contributor I

Hi Xianjun,

 

Thank you for your suggestion in the past about using the link channel feature of the DMA on the MWCT1013A.  

We were able to up update duty cycles every 2MHz frame by utilizing all four DMA channels on PWMA channel 2.

 

We used DMA channel 2 to write to the associated PWMA channel 2 registers (so that the PWM duty cycles could update every 2MHz).  Then we used DMA channel 0 to clear DMA channel 2's done bit; then DMA channel 1 to reset DMA channel 2's BCR value; then finally DMA channel 3 to re-enable peripheral requests in DMA channel 2's DCR register.

So basically the following chain:

  1. DMA 2 -> PWMA Channel 2 registers
  2. DMA 0 -> DMA2 clear bit (DCR)

3 DMA 1 -> DMA2 set BCR 

4 DMA3 -> DMA2 set DREQ (DCR)

 

All DMAs are setup for 32-bit transfers.

BCR value for DMA channel 2 is set to 32 bytes.

BCR values for DMA channel 0, 1 and 3 are set to 0xFFFFFC (16777212) bytes which is the maximum possible value I could put to keep the circular  flow going as long as possible without intervention from the core.

 

This works pretty well except for when the DMA channel 0 BCR exhausts and we need to utilize the interrupt to go in and reset the BCR values for DMA channel 0, 1, 3.

The DMA channel 0 interrupt is setup as a fast interrupt; there is no other application level code that is running other than a while(1) loop.

 

What we've noticed is that when the program enters the DMA channel 0 interrupt, there is one PWMA channel 2 duty cycle pulse that is repeated for one frame.  In the interrupt we have to disable the (PWM) peripheral  interrupt request to DMA CH2 then update all the BCR values for DMA CH 0, 1, 2, 3 and re-enable the DMA CH2 (PWM) peripheral requests.

 

Unfortunately the system being developed is extremely sensitive to incorrect PWM pulses so we'd like to figure out how to avoid this type of glitch if at all possible with this micro.

 

It'd be ideal if no manual intervention was required to reset the BCR so that the DMA-PWM data transfers could occur completely autonomously.  We've tried to forgo the interrupt option to update the BCRs and just update the value every so often in the main application level while loop but that really throws things off as it has to work to access the peripheral bus and update DMA registers while the DMAs are already running.  In this scenario, many PWM pulses are effected which is extremely undesirable.

 

Based on the reference manual, it doesn't look like there are any options available to get past this issue but if there are, please advise.

It doesn't look like the MWCT1011 would be any better for us as it has the same number of DMA channels (4).  We literally need one more DMA channel it seems to be able to reset the DMA CH 0, 1, 3 BCRs.

 

We were looking at the MWCT101xSF.pdf and these micros look like it could be a good solution as there are 16 DMA channels and 8 flex timers that we can utilize for the PWM functionality desired.

Please advise.

 

Thanks!

0 Kudos

830 Views
amitavadas
Contributor I

Xiangjun,

Thank you. We will look into this.

We also prefer to use Interrupt but time it takes for ISR is too long for us and doesn’t leave any time for computation and other tasks. Besides DMA or Interrupt, is there any other mechanism to load valuex register every cycle without burning a lot of time. We can precompute the values to be loaded in valuex register and store it in a table but we need to load it every cycle and we are switching at 2MHz.

Any other suggestion would be very welcome.

Thanks.

0 Kudos