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?
@ Kerry Zhou
Could you please have a look at my issue with Qtimer TMR1, channel0 and channel1 with DMA transfer.
Thank you!
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!
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,
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
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.
Hi Andre,
I went through your code and I found a couple of wrong things, please see my comments below.
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
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!
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:
From your new updated information, you already solve your issues, could you please also share your solution, thanks.
Best Regards,
Kerry
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
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);
}
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
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,
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
Can any NXP tech guy get back to me about my Qtimer issue discussed above? Thank you!
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!
Hello Andre,
Could you please specify a little bit more about how these two channels conflict between them?
Regards,
Victor
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.
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