Has anybody used Timer Overflow Flag with the QTMR?

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

Has anybody used Timer Overflow Flag with the QTMR?

3,863 Views
chriscowdery
Contributor V

Hi All,

 I am convinced that the Timer Overflow flag (Bit 13 of TMRx_SCTRLn) does not work.

I have configured my timer to count from 0x0000 to 0xffff, then overflow. I have set the Compare to 0x7fff so I can be sure that the timer is not being reset by the Compare.

I can see the TMRx_CNTR counting from 0x000 to 0xffff, but TOF is always zero.

I can see the Compare flag TCF functions as I expect.

All of the examples use the Compare flag / interrupt, none of them use the Overflow.

I have tried both TMR1 and TMR2, and different channels on both.

For reference:

SCTRL = 0x9000: TCF=1, TOFIE=1.

COMP1 = 0x7fff

CTRL = 0x3e00: CM=1, count rising of primary source, PCS=1111, Count source is IP Bus div 128, Count repeatedly, Length=0, rollover at 0xffff, count up.

ENBL = 0x000f: timers enabled.

Has anybody seen this feature actually work?

Thanks,


Chris.

Labels (1)
20 Replies

3,219 Views
TomE
Specialist II

> the 56F824X_825X and Kinetis KM3x CPUs

Google also finds the Freescale MC1322x Zigbee SOC, which dates from 2012 or maybe 2007. It also finds the MC56F8006, which has a "dual" version of this timer with only two out of the four timers implemented. It also turns up in other "56" series DSC chips.

Tom

0 Kudos

3,219 Views
TomE
Specialist II

This has been reported in the latest IMXRT1050 Errata:

https://www.nxp.com/docs/en/errata/IMXRT1050CE.pdf 

ERR050194QTMR: Overflow flag and related interrupt cannot be generated
 when the timer is configured as upward count mode


Description:
    1. Overflow flag and related interrupt cannot be generated successfully in upward count mode.
    2. When TMR_CTRL[OUTMODE] is set to 110b, OFLAG output is not cleared on counter rollover
       when the timer counts upward.

Workarounds:
    For item 1, using compare interrupt instead of overflow interrupt by setting compare value to
    0xFFFF. The compare interrupt has the same timing effect as overflow interrupt in this way.
    For item 2, there is no workaround.

Proposed Solution:
    No fix scheduled

Software Status:
    Software workaround is not in SDK
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Does this bug also exist in the IMXRT1060?

There hasn't been a new Errata released for the IMXRT1060 mentioning this if it is a problem.

Tom

 

0 Kudos

3,219 Views
TomE
Specialist II

I've just run a test with the IMXRT1060 and have verified that the QTIMER module in this chip has the same problem.

Please add this to a new version of the IMXRT1060 Errata.

Tom

0 Kudos

3,219 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello Tom,

Please download the newest version of the Errata, the problem of the QTIMER is already included (link).

Regards,

Victor

0 Kudos

3,217 Views
TomE
Specialist II

Sorry, you are correct.

Both the IMXRT1060 and IMXRT1060 Errata documents were updated in June 2019 and ERR050194 was added at that time to both of them. The IMXRT1050 errata was further updated in August 2019, and the only change was that ERR050194 was updated. ERR050194 is currently identical in both documents, so I don't know what was different in the June 2019 IMXRT1050 one that needed to be changed.

I only noticed "ERR050194" was in the August Update and assumed the item wasn't in the IMXRT1060 one when it was.

Tom

0 Kudos

3,219 Views
chriscowdery
Contributor V

Hi Tom,

 Epic answer - thanks!

You clearly have investigated much more than I have.

My solution was to switch to GPT1 as they have the more sensible W1C status flags, and appear to work correctly for my application (in which because GPT1 is 32bit, I don't need the overflow interrupt, I just need the compare interrupt)

Good point about the 'archaeology' - you wonder how many other parts have this defect.

Chris.

0 Kudos

3,219 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hi Chris,

To give you better support, could you please tell me which RT are you using?

Regards,

Victor

0 Kudos

3,219 Views
TomE
Specialist II

Victor, could you please find out if this is a known problem with this module in these i.MXRT chips and let us know?

It might also be worth finding out if the same problem is in this module in the Kinetis, DSP and Zigbee chips.

Tom

0 Kudos

3,219 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hi Tom and Chris,

I'm making some tests on my side to reproduce the behavior that Tom mentioned before (overflow only happens when counting down). I will give an update as soon as possible.

Regards,

Victor

0 Kudos

3,219 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hi Tom and Chris,

I was able to reproduce the behavior that you both mentioned. I'm currently checking with the applications team, I will give you an update when I have the final answer.

Regards,

Victor

0 Kudos

3,219 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hi Tom and Chris,

The design team confirmed that this issue is valid and is an errata. They are working on an errata for the Qtimer module, this errata will cover all the i.MXRT families.

Regards,

Victor

3,219 Views
chriscowdery
Contributor V

Thanks Victor. I wonder if there is a workaround...?

Chris.

0 Kudos

3,219 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello Chris,

Sorry for the late response, I was checking this with the design team. Besides of using counting down, you can also enable the compare event, setting the compare value to maximum value, then enable the compare
interrupt. With this method, the compare interrupt has a same result of timing as the overflow interrupt.

Best regards,

Victor

3,219 Views
johannzimmerman
Contributor II

Hi,

unfortunately it doesn't work for me:

QTMR_SetupInputCapture(BOARD_QTMR_BASEADDR, BOARD_QTMR_INPUT_CAPTURE_CHANNEL, QTMR_CounterInputPin, false, true,

kQTMR_RisingEdge);

/* Set the first channel period to be 1 millisecond */

QTMR_SetTimerPeriod(BOARD_QTMR_BASEADDR, BOARD_QTMR_INPUT_CAPTURE_CHANNEL, 0xFFFF);

// Enable at the NVIC

EnableIRQ(QTMR_IRQ_ID);

// Enable timer compare interrupt

QTMR_EnableInterrupts(BOARD_QTMR_BASEADDR, BOARD_QTMR_INPUT_CAPTURE_CHANNEL, kQTMR_EdgeInterruptEnable | kQTMR_CompareInterruptEnable);

// Start the input channel to count on rising edge of the primary source clock

QTMR_StartTimer(BOARD_QTMR_BASEADDR, BOARD_QTMR_INPUT_CAPTURE_CHANNEL, kQTMR_PriSrcRiseEdge);

Please put out an example.

Thanks in advance

0 Kudos

3,219 Views
TomE
Specialist II

> unfortunately it doesn't work for me:

Which part exactly? There are fault reports and workarounds. It isn't clear what you're doing, what you're expecting and what results you're getting. Are you expecting an overflow interrupt counting DOWN (as suggested as the workaround) or are you expecting a compare interrupt? You should include what you expect to happen and what actually is happening. Including the status registers showing interrupt request status and masks.

You include  some code, but without the details of what library you're using. I managed to locate the header that defines those functions, but it would help if you detailed what you were using, and what version, in case it has changed.

I can't see the call to "QTMR_Init()". I can't see your interrupt service routines.

Tom

0 Kudos

3,219 Views
johannzimmerman
Contributor II

Hi Tom,
thanks for the reply and sorry apologize.
that was really my mistake to have lost the QTMR_Init ().
I expect a compare interrupt when counting up.
This also works with the call from the front
QTMR_Init () function.

At low input frequencies the interrupt happens for compare and edge at the same time. What should I evaluate first so as not to falsify the value in the event of an overflow?

 

void QTMR_IRQ_HANDLER(void)
{
    uint16_t reg = BOARD_QTMR_BASEADDR->CHANNEL[BOARD_QTMR_INPUT_CAPTURE_CHANNEL].SCTRL;
    
    if ((reg & TMR_SCTRL_TOF_MASK) != 0U)
    {  // Only works with countdown
      reg &= (~TMR_SCTRL_TOF_MASK);
      tmr_capt_ovr++;
    }

  // What first evaluate compare or edge ??
    if ((reg & TMR_SCTRL_TCF_MASK) != 0U)
    {
      reg &= (~TMR_SCTRL_TCF_MASK);
      tmr_capt_ovr++;
      test++;
    }
    // Input edge flag
    if (reg & TMR_SCTRL_IEF_MASK)
    {
      reg &= (uint16_t)(~(TMR_SCTRL_IEF_MASK|TMR_SCTRL_TCF_MASK));
      tmr_capt_act = (tmr_capt_ovr<< 16) | BOARD_QTMR_BASEADDR->CHANNEL[BOARD_QTMR_INPUT_CAPTURE_CHANNEL].CAPT;
      tmr_capt_cnt++;
      
      if(++test==2)
      {
        qtmrIsrFlag = true;  // they were both active
      }
      tmr_capt_ovr = 0;
    }
     test = 0;
    /* Clear interrupt flag.*/
    BOARD_QTMR_BASEADDR->CHANNEL[BOARD_QTMR_INPUT_CAPTURE_CHANNEL].SCTRL = reg;
    /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
      exception return operation might vector to incorrect interrupt */
    __DSB();
}

thank you
Johann

0 Kudos

3,219 Views
TomE
Specialist II

> What should I evaluate first so as not to falsify the value in the event of an overflow?

I don't understand what you mean by "falsify the value". What value? The Capture Value? The relationship between two close interrupts? If you are capturing a timer value that overflows and need to know whether the capture was "just before" or "just after" the interrupt, then nothing is going to help you with that.

So I assume you mean "how do I handle one interrupt so as not to accidentally clear the other one?". If that isn't what you are asking, then you should consider it as it is a risk that needs to be dealt with.

Your code, as written, will miss and lose interrupts. But nothing in the sample code or the manuals will help you with that.

There has been a lot of old (30 years ago) modules where it wasn't possible to avoid accidentally clearing interrupts. They had "status" registers with different bits for different interrupts, and writing to those bits would set or clear them. Between reading the register (to find which interrupt had happened) and writing it to clear that interrupt, another one could be set and you would then accidentally clear it, losing that interrupt forever.

Motorola championed a standard way around this problem. When an interrupt bit was set, the only way to clear it is to write a ONE to that bit. This allows you to clear any interrupt at any time with no risk of accidentally clearing another one. This is called "W1C" in the manuals (160 instances). Most interrupt status registers in the IMXRT still work this way.

The MC68HC11, released in 1984 and documented in the 1991 68HC11K4 manual I have in front of me now worked that way. This is "the standard way it has been done" for at least 30 years.

But the Quad Timer doesn't follow this tradition.

Please read the post I made in this thread on "Jun 5, 2019 12:59 PM"  (immediately below this post) where I detail this anomaly, and give the overly complicated code that you have to use to handle this properly.

How does the NXP Sample Code clear these interrupts? Does it get it right? Yet?

If that wasn't your question, please try again with more detail about what you are trying to do.

In case you want to use PWM or generate signals or interrupts at the frequency you expect, check the following:

i.MXRT Quad Timer (QTMR): Are There Any Working Code Examples?  

> Add for ARM errata 838869, affects Cortex-M4

What CPU are you using? The IMXRT1021, 1050 and 1060 use Cortex-M7.

Tom

0 Kudos

3,220 Views
chriscowdery
Contributor V

Hi Victor,

 But that solution means you have to choose - overflow OR compare. You cannot have both. My application required both.

Regards,

Chris.

3,220 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello Chris,

If you want to use both overflow and compare the only possible way would be to count backward. Sorry for the inconvenience that this might cause you.

Best regards,

Victor

3,220 Views
chriscowdery
Contributor V

Hi Victor,

 I am using the iMXRT1021, on an MIMXRT1020-EVK. However it sounds like the same peripheral is used in the iMXRT1050 as Tom can see exactly the same issue.

Chris.

0 Kudos