MSPM0G3507: Prevent TIMA1 event on re-enable

Part Number: MSPM0G3507

Tool/software:

Hey. I am having an issue with some pwm timers - let me describe what I am doing:
(forgive the long description - it's as short as I could make it).

I am creating four interleaved center-aligned pwm signals, using TIMA0, TIMG7, TIMA1 and TIMG6.
TIMA0 uses its second channel at 50% duty cycle to generate events to trigger TIMG7 at 90 degree phase shift, and cross-trigger TIMA1 at 180 degree phase shift.
TIMA1 likewise uses a second channel to trigger TIMG6 at 270 degree phase shift from TIMA0.
So far so good.
These pwm's are driving four mosfets, and I need to measure their current, in the middle of their duty-cycle (at their LOAD event).
I am using TIMA1 to generate ZERO, CCU1, LOAD and CCD1 events, to trigger the ADC.
The ADC is set up to use a FIFO, and fire an interrupt when four samples have been converted.

Now - the problem arises when I change pwm frequency, since this messes up the synchronization in which timer get's sampled when.
In order to try to fix this, I first implemented shadow load/compare.
Now, I call a function for changing frequency, where I first calculate the new LOAD and Compare values (global variables). Then I enable an interrupt on CCD1 for TIMA0.
In the ISR I first disable this interrupt, so it only runs this once. Next, I disable repeats for all timers, so they finish their current cycle, then stop.
I also disable the IMASK for the ZERO event for TIMA1 (since this would trigger an ADC measurement of TIMA0 after it has stopped...)
Last, I enable an interrupt for TIMG6 at it's CCD0 event.

In this second ISR, I again first disable this interrupt.
Then I try to disable TIMA1 and clear any of it's events, and set it's counter to 0, before re-enabling it's events.
I do the same for TIMG6.

Lastly, I re-enable TIMA0.
In my mind this should work to "restart" the whole pwm machine, exactly like when the program starts up. This works perfectly, untill I try to change frequency.
More specifically, when I re-enable TIMA0, TIMA1 immediately fires an event, which triggers an ADC sampling, which now is at TIMA0's Zero, thus throwing the whole ADC synchronization out the window.

My question:
Why does TIMA1 fire an event at this point, when it does not do so originally? (it should start untill it is cross-triggered by TIMA0's LOAD event.)

Here is a screenshot of the initial start:



And here is one where the change frequency function is called:


(Mind you - here I have not re-enabled repeats, which is why it is only a one-shot when starting up again.)
The marker "2" shows the event that I'm trying to avoid, which is ruining the synchronization.

Here is the code for the TIMA0 ISR (sorry for the messy code)

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void TIMA0_IRQHandler()
{
GPIOB->DOUTTGL31_0 = DL_GPIO_PIN_17;
// Disable this IRQ
NVIC_DisableIRQ(TIMA0_INT_IRQn);
// Halt the timer
//DL_Timer_disableClock(TIMA0);
//TIMA0->COMMONREGS.CCLKCTL = GPTIMER_CCLKCTL_CLKEN_DISABLED;
TIMA0->COUNTERREGS.CTRCTL &= ~GPTIMER_CTRCTL_REPEAT_MASK;
TIMG7->COUNTERREGS.CTRCTL &= ~GPTIMER_CTRCTL_REPEAT_MASK;
TIMA1->COUNTERREGS.CTRCTL &= ~GPTIMER_CTRCTL_REPEAT_MASK;
TIMG6->COUNTERREGS.CTRCTL &= ~GPTIMER_CTRCTL_REPEAT_MASK;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
TIMA1->COUNTERREGS.LOAD = new_load_value;
TIMG6->COUNTERREGS.LOAD = new_load_value;
TIMA1->COUNTERREGS.CC_01[0] = new_compare_value;
TIMG6->COUNTERREGS.CC_01[0] = new_compare_value;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


And here is the code for the TIMG6 ISR:
Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void TIMG6_IRQHandler()
{
GPIOB->DOUTTGL31_0 = DL_GPIO_PIN_3;
// Disable this IRQ
NVIC_DisableIRQ(TIMG6_INT_IRQn);
TIMA1->COUNTERREGS.CTRCTL &= ~GPTIMER_CTRCTL_EN_ENABLED;
TIMA1->GEN_EVENT1.IMASK = 0;
TIMA1->GEN_EVENT1.IIDX;
TIMA1->GEN_EVENT1.ICLR = 0xFFFFFF;
TIMA1->COUNTERREGS.CTR = 400;
TIMA1->GEN_EVENT1.IMASK |= (DL_TIMER_EVENT_CC1_UP_EVENT |
DL_TIMER_EVENT_CC1_DN_EVENT |
DL_TIMER_EVENT_LOAD_EVENT |
DL_TIMER_EVENT_ZERO_EVENT);
TIMG6->COUNTERREGS.CTRCTL &= ~GPTIMER_CTRCTL_EN_ENABLED;
TIMG6->GEN_EVENT1.IMASK = 0;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Hi,

    I thin you can try reinit the timerA0 and timerA1 before changing the frequency. I think some of the registers are not cleared completely and caused this issue.

    Best regards,

    Cash Hao

  • What's the significance of the number 400? Is this intended to be 1/4th of the period? Would it be affected by new_load_value?

    It would probably be informative to know which event triggered (TIMA1->GEN_EVENT1.MIS).