iMX RT1062 Qtimer configuration

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

iMX RT1062 Qtimer configuration

3,322 Views
farid_mabrouk
Contributor II

I have two GPIOs that I configured as Qtimers so that I can generated a PWM with different duty cycles per channel: 

IOMUXC_SetPinMux(
       IOMUXC_GPIO_B0_00_QTIMER1_TIMER0,       /* GPIO_B0_00 is configured as QTIMER1_TIMER0 */
       0U);                                    /* Software Input On Field: Input Path is determined by functionality */
   IOMUXC_SetPinMux(
       IOMUXC_GPIO_B0_01_QTIMER1_TIMER1,       /* GPIO_B0_01 is configured as QTIMER1_TIMER1 */
       0U);                                    /* Software Input On Field: Input Path is determined by functionality */

I found out that the configurations of these channels conflict, see below. Can anyone tells me how this should be configured? how can I configure cmpld1/2 for both GPIO pins ( TMR1 channel 0 and TMR1 channel1) so that they don't conflict?

#define QTMR_EDMA_REQUEST_CMPLD2_SOURCE    kDmaRequestMuxQTIMER1Cmpld1Timer0Cmpld2Timer1
#define QTMR_EDMA_REQUEST_CMPLD1_SOURCE    kDmaRequestMuxQTIMER1Cmpld1Timer1Cmpld2Timer0
#define QTMR_EDMA_REQUEST_LD2CMPLD1_SOURCE kDmaRequestMuxQTIMER1Cmpld1Timer0Cmpld2Timer1
#define QTMR_EDMA_REQUEST_LD2CMPLD2_SOURCE   kDmaRequestMuxQTIMER1Cmpld1Timer1Cmpld2Timer0
Labels (1)
0 Kudos
19 Replies

2,956 Views
farid_mabrouk
Contributor II

@ Kerry Zhou 

Could you please have a look at my issue with Qtimer TMR1, channel0 and channel1 with DMA transfer. 

Thank you! 

0 Kudos

2,956 Views
farid_mabrouk
Contributor II

I’m still waiting for an answer to my question above. Looking at the example you guys have is not taking me anywhere. In my case, again, I’m using two Qtimer channels, not one. It appears the DMA transfer does not work property (data gets corrupted) if the two channels are configured to do dMa transfer, 

can anyone else from NXP take a look this discussion and help out, I need to put this into a closure. 

Thank you!

0 Kudos

2,956 Views
farid_mabrouk
Contributor II

you can ignore my issue for TMR1 channel2.

As you can see in the files I sent you: I configured TMR1 channel0 and channel1; and these channels transfer data via DMA. I noticed that when these channels are configured to run both in a single application, they conflict with each other: data transferred by DMA gets corrupted, and I am using noncache sdram to hold these data.

i am using two call back functions per channel because I have two buffers per channel: one for upper count and the other for lower count. I dont see anything different here than what the example code does. It appears to me that the two channels cant work independently when DMA is involved. It may need to use only one channel at a time looks like. Do you think this is what needs to be done.

Hope you or someone else can help put this issue to a close.

Cheers,

0 Kudos

2,956 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hi Andre,

 

Thanks for the additional information. On one of your previous replies you mentioned the following:

The two Qtimer pins I figured generate different pwm signals. I noticed when both channels are configured, pwms gets distorted

And in your last reply, you mentioned that the data that you transferred through DMA gets corrupted. So, what's the behavior that you are actually seeing, the PWM gets distorted or DMA data gets corrupted?  What is exactly what you are transferring with the DMA? Are you updating the duty cycle of the PWM with the DMA?

 

Also, you mentioned the following: It appears to me that the two channels cant work independently when DMA is involved. Does this mean that if you don't use the DMA both channels can work properly? Did you make this test?

 

Regards,

Victor

0 Kudos

2,956 Views
farid_mabrouk
Contributor II

And in your last reply, you mentioned that the data that you transferred through DMA gets corrupted. So, what's the behavior that you are actually seeing, the PWM gets distorted or DMA data gets corrupted?  What is exactly what you are transferring with the DMA? Are you updating the duty cycle of the PWM with the DMA?

Yes, I want to generate a different PWM duty cycle at each PWM period. I was seeing on my scope that the PWMs coming out are not correct, my assumption is that the DMA transfer was not correct. When I configure only one channel, I can see the PWM cycle coming as I want them to be, but not when both channels are configured for DMA transfer.

All I am asking you or someone else is to look at the way I configured my channels. That could be the issue, unless you qtimer channels are not meant to be configured for DMA transfer.

Also, you mentioned the following: It appears to me that the two channels cant work independently when DMA is involved. Does this mean that if you don't use the DMA both channels can work properly? Did you make this test?

Again this is just an assumption that hope you can help me confirm.

0 Kudos

2,956 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hi Andre, 

I went through your code and I found a couple of wrong things, please see my comments below. 

  1. Before calling the function EDMA_Init you never configured the userConfig1/userConfig2 structure. This can be done with the function EDMA_GetDefaultConfig. 
  2. You are initializing four times the DMA0 module, two times on the function QTimerPWM_Ch1config and two more on the function QTimerPWM_Ch2config. This is wrong, you only need to initialize this module once. 
  3. The same applies to the DMAMUX, you are initializing it two times. One in the function QTimerPWM_Ch1config and the second time in the function QTimerPWM_Ch2config. This module has to be initialized only once. 

Additional to this, you are using two channels to update the duty cycle of one PWM (you are using a total of 4 DMA channels). In the example that we provide within the SDK, we use only one DMA channel to update the PWM cycle instead of two. I recommend you following this application, this way you will use only two DMA channels. 

I understand that the SDK example outputs only one PWM, however, it's a good reference point on how to make the configurations for your application. 

Regards, 

Victor 

0 Kudos

2,956 Views
farid_mabrouk
Contributor II

Hi Victor,

Thanks for your reply!

You commented this: "Additional to this, you are using two channels to update the duty cycle of one PWM (you are using a total of 4 DMA channels). In the example that we provide within the SDK, we use only one DMA channel to update the PWM cycle instead of two. I recommend you following this application, this way you will use only two DMA channels."

why your colleague on the thread below recommended the use of 2 channels: I am confused!

https://community.nxp.com/thread/509721 

Can you please tell me why she used two channels. My understanding is that is she using one for upcount and the other for lower count.

Cheers!

0 Kudos

2,956 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Andre marcus,

  Thanks a lot for your effort.

 My method is to use the QTIMR Variable-Frequency PWM Mode, then configure the CMPLD1 and CMPLD2 in pairs, then keep the different PWM has the same frequency but duty can be changed.  The original customer wants to change the PWM duty for each continuous PWM, that's why I use two-channel to trigger and load the CMPLD1 and CMPLD2 separately and continuously.

AT_NONCACHEABLE_SECTION_INIT(volatile uint16_t g_Cmpld1buf[10]) = {338, 300, 263, 225, 188, 150, 112, 75, 37, 188};//10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%,90%, 50%
AT_NONCACHEABLE_SECTION_INIT(volatile uint16_t g_Cmpld2buf[10]) = {37 , 75 , 112, 150, 187, 225, 263, 300, 338, 187};//10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%,90%, 50%

As the CMPLD1 and CMPLD2 is the different MUX channel, then I used two DMA mux channel:

pastedImage_1.png

  From your new updated information, you already solve your issues, could you please also share your solution, thanks.

Best Regards,

Kerry

0 Kudos

2,956 Views
farid_mabrouk
Contributor II

Hi VIctor

While waiting to hear back from you about my Qtimer issue; I came to another issue configuring Qtimer TMR1 channel 2 (GPIO_B0_02). Could you please have a look at the the attached files. I hope you can direct me to the cause of the issue.

Regards,

0 Kudos

2,956 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hi Andre, 

Could you please give more information about the behavior you are facing with TMR1 channel 2? Additional to that, I checked your function QTimerPWM_Ch1config and I found something that got my attention, why are you using two different configurations and tow different callbacks for channel 1? Within the latest version of the SDK, we provide an example named "qtmr_inputcapture_outputpwm_dma" I recommend you to refer to this example to see how to make the configuration for the DMA. 

Regards, 

Victor 

0 Kudos

2,956 Views
farid_mabrouk
Contributor II

Hi Victor!

in my main function I am calling these two functions: 

QTimerPWM_Ch1config(); 
QTimerPWM_Ch2config(); 

These functions are defined in the C file that I attached previously. The issue is that I cant have these functions defined both at the same time. I have to comment one them in order for me to see a one PWM on a single IO. if I dont comment one of them, I dont see any PWM anymore. Don't know if this makes sense or not. I found out that the lines in bold colors below are the source of the issue( which is the DMA). 

My issue is the way the DMA is configured for cmpl1, and cmpl2 for TMR1 channel0 ; an d cmpl1,cmpl2 for TMR1 channel1.

with the scope i was able to see that DMA data gets corrupted as soon as a enable dma transfer for the above channels.

I hope you or someone can look closely at my c file that I attached before and tell me whats wrong with my DMA configuration?

/* Qtimer configuration for PWM count*/
void QTimerPWM_Ch1config(void)
{
qtmr_config_t qtmrConfig;
edma_config_t userConfig2,userConfig1;

EDMA_Init(QTMR_DMA, &userConfig1);
EDMA_CreateHandle(&LED1_EDMA_Handle1, QTMR_DMA, 1);
EDMA_SetCallback(&LED1_EDMA_Handle1, EDMA_LED1_Callback1, NULL);

EDMA_Init(QTMR_DMA, &userConfig2);
EDMA_CreateHandle(&LED1_EDMA_Handle2, QTMR_DMA, 0);
EDMA_SetCallback(&LED1_EDMA_Handle2, EDMA_LED1_Callback2, NULL);

/*
* qtmrConfig.debugMode = kQTMR_RunNormalInDebug;
* qtmrConfig.enableExternalForce = false;
* qtmrConfig.enableMasterMode = false;
* qtmrConfig.faultFilterCount = 0;
* qtmrConfig.faultFilterPeriod = 0;
* qtmrConfig.primarySource = kQTMR_ClockDivide_2;
* qtmrConfig.secondarySource = kQTMR_Counter0InputPin;
*/

//added
QTMR_GetDefaultConfig(&qtmrConfig);
qtmrConfig.primarySource = kQTMR_ClockDivide_1;

DMAMUX_Init(QTMR_DMA_MUX);
DMAMUX_SetSource(QTMR_DMA_MUX, 0, QTMR_EDMA_REQUEST_LED1CMPLD2_SOURCE);
DMAMUX_EnableChannel(QTMR_DMA_MUX, 0);

DMAMUX_SetSource(QTMR_DMA_MUX, 1, QTMR_EDMA_REQUEST_LED1CMPLD1_SOURCE);
DMAMUX_EnableChannel(QTMR_DMA_MUX, 1);

QTMR_Init(QTMR_BASEADDR, QTMR_PWM_CHANNEL1, &qtmrConfig);

/* Generate a 800Khz PWM signal with 0% dutycycle */

QTMR_SetupPwm(QTMR_BASEADDR, QTMR_PWM_CHANNEL1, 800000, 0, false, QTMR_SOURCE_CLOCK / 1);

// /* Enable comparator preload register 1 DMA */
// QTMR_EnableDma(QTMR_BASEADDR, QTMR_PWM_CHANNEL1, kQTMR_ComparatorPreload1DmaEnable);
// /* Enable comparator preload register 2 DMA */
// QTMR_EnableDma(QTMR_BASEADDR, QTMR_PWM_CHANNEL1, kQTMR_ComparatorPreload2DmaEnable);
// /* Start the counter */
// QTMR_StartTimer(QTMR_BASEADDR, QTMR_PWM_CHANNEL1, kQTMR_PriSrcRiseEdge);

}

0 Kudos

2,956 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hi Andre, 

Thanks for the clarification! I will make an example code to replicate this on my side so I can make some tests to see what might be the cause of this behavior. Currently, we are under a heavy load of work so I will need at least a couple of days to do this. I will get back to you as soon as possible. Thanks a lot for your patience. 

Regards, 

Victor 

0 Kudos

2,956 Views
farid_mabrouk
Contributor II

More debugging of my code revealed that I am having issues with my DMA. I have two DMAs one for cmpld1, cmpld2 transfer for TMR1-Channle0, and the other DMA is for cmpld1,cmpld2 transfer for TMR1-channel1. I attached a copy of how I did my dma configuration. now, i am able to run my code only with one DMA enabled, cannot rin the code with DMA for both TMR1 channels enabled. \

Could someone have a look and tell me why I am having this DMA conflict between the two channels.

Cheers,

0 Kudos

2,956 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hi Andre, 

You mentioned the following: "now, i am able to run my code only with one DMA enabled, cannot rin the code with DMA for both TMR1 channels enabled.". Could you please specify what is the problem that you are facing? Is your program crashing at some point? If so, could you please specify where? 

Regards, 

Victor 

0 Kudos

2,956 Views
farid_mabrouk
Contributor II

Can any NXP tech guy get back to me about my Qtimer issue discussed above? Thank you! 

0 Kudos

2,956 Views
farid_mabrouk
Contributor II

Hi vector, 

I used the qtmr_inputcapture_outputpwm example as starting point to get to where I m now. I have two qtimer channels pins. One channel is working fine, but not the other. I can only configure one channel at a time in my application. I can;t configure them one after the other other in one application: I get a corrupted PWM output. I am using DMA0 to handle this pwm output. Can anybody says what I can be missing.

Thank you in advance!

0 Kudos

2,956 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello Andre, 

Could you please specify a little bit more about how these two channels conflict between them? 

Regards, 

Victor 

0 Kudos

2,956 Views
farid_mabrouk
Contributor II

The two Qtimer pins I figured generate different pwm signals. I noticed when both channels are configured, pwms gets distorted. But when only one channel is configured one pwm signal comes out the way it should ( while the other channel is not configured) 

i m having issue about which channels for compld1 and cmpld2 to assign to each Qtimer? Now both cmpld1 and cmpld2 are the same for both Qtimers. 

0 Kudos

2,956 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hi Andre, 

Have you taken a look into the qtmr_inputcapture_outputpwm example project that we provide within the SDK? This example demonstrates how to configure a channel of the QTMR as a PWM output. The function QTMR_SetupPwm manages all the compare values for you, so you don't have to worry about this. 

Regards,

Victor 

0 Kudos