Flexio multiple timers

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

Flexio multiple timers

2,473 Views
bbergquist
Contributor I

Simple question on setting up 2 Flexio timers, with each one driving the other.  We are trying this on a IMXRT1060 eval board.

We are having trouble setting up a 16 bit count down timer such that after it is enabled and counts down, that it disables on the compare and triggers a second 16 bit count down timer and then it disables on the compare and enables the first timer again.

Basically time 1 active, timer 2 active, time 1 active, etc.

We are having trouble configuring this simple example and any help will be appreciated.

Tags (1)
0 Kudos
Reply
6 Replies

2,174 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Brett Bergquist,

    Thank you for your interest in NXP MIMXRT product, I would like to provide service for you.

    Maybe you try this method, configure flexio timer1, and timer 2.

   Enable the timer 1 and timer 2 interrupt in register TIMIEN.

   Then disable the timer 2, start the timer1, when the 16 bit timer counter equals zeros the interrupt will happens, in the interrupt code, you can disable the timer 1, and enable timer2.

  In the timer 2 interrupt code, you can disable the timer 2, and enable timer1.

   This method will realize you function: time 1 active, timer 2 active, time 1 active, etc.

You can try it on your side, you can control the register directly in your code.

If you still have questions after you try it, please let me know.

Have a great day,
Kerry

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply

2,174 Views
bbergquist
Contributor I

So we are trying to do this without an interrupt as the CPU is really busy already.  I should have put more into the question :smileywink:

We have a need to write/read an I/O pin in this manner

  • (0) repeat forever
    • (1) drive N pin high for 100 usec
    • repeat 28 times
      • (2) drive pin N low for 1 usec
      • (3) drive pin N high for 1 usec
      • (4) set pin N output disabled for 5 usec
      • (5) read pin N into shifter configured for 28 bit word
        this will transfer the 28bit word via DMA

So I have been able to simulate a timer chain for 2 -> 3 -> 4 

  • timer 2 as a 16 bit counter with "trigger on timer 4 active low, decrement on Flexio clock, disable on timer compare and trigger low, always enabled"
  • timer 3 as 16 bit counter with "trigger on timer 2 both edge, decrement on Flexio clock, disable on timer compare and trigger low, enable on trigger both edge"
  • timer 4 as 16 bit counter with "trigger on timer 3 both edge, decrement on Flexio clock, disable on timer compare and trigger low, enable on trigger both edge"

I think I can have the bit counter/timer 5 be inserted into the chain the same way with changing timer to "trigger on timer 5 active low" and timer 5 to be "trigger on timer 4 both edge, decrement on trigger (?), disable on timer compare, enable on trigger both edge"

I am struggling with getting this back to state 0 (the repeat forever). 

Maybe this explains better what I am trying to do with just FlexIO and not involving the CPU except though a DMA transfer of the 28 bit work received into the shift buffer.

0 Kudos
Reply

2,174 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Brett,

   I will communicate your question with my colleagues, whether there have some good way to realize your function, please give me more time.

   Any updated information, will let you know.


Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply

2,174 Views
bbergquist
Contributor I

Ok thanks.  One more thing.  We are still having trouble with just a delay timer outputting a pin and then disabling and triggering the next timer.   For example, I have the code below which does in fact trigger the timers in order but the delay times are not correct and I think that is related to the "kFLEXIO_TimerDisableOnTimerCompareTriggerLow" and the "kFLEXIO_TimerEnableOnTriggerBothEdge" settings but without these then the next timer in the chain is not triggered.  I can see and measure this on a oscilloscope.

The simplest thing to have a timer output on a pin for a period of time and then disable and trigger the next timer is something that seems should be simple but I cannot get to work correctly.  Some guidance on just this simple requirement would be very useful.  None of the samples have anything like this.   Unfortunately the device that we are trying to communicate with is a one-wire device and the timings required are not regular (ie. output high for 100 usec, and repeat "output low for 1 usec, output high for 1 usec, change to input and wait 5 usec, read 1 bit" for 28 bits total and then repeat the whole thing.

static void flexio_timer0_config(void) {

    flexio_timer_config_t fxioTimerConfig;

    fxioTimerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(DEMO_FLEXIO_TIMER2_CH);

    fxioTimerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;

    fxioTimerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;

    fxioTimerConfig.pinConfig = kFLEXIO_PinConfigOutput;

    fxioTimerConfig.pinPolarity = kFLEXIO_PinActiveHigh;

    fxioTimerConfig.pinSelect = DEMO_FLEXIO_OUTPUTPIN1;

    fxioTimerConfig.timerMode = kFLEXIO_TimerModeDisabled;

    fxioTimerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;

    fxioTimerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;

    fxioTimerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompareTriggerLow ;

    fxioTimerConfig.timerEnable = kFLEXIO_TimerEnabledAlways;

    fxioTimerConfig.timerReset = kFLEXIO_TimerResetNever;

    fxioTimerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;

    fxioTimerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;

    fxioTimerConfig.timerCompare = 15000;

    FLEXIO_SetTimerConfig(DEMO_FLEXIO_BASEADDR, DEMO_FLEXIO_TIMER0_CH, &fxioTimerConfig);

}

static void flexio_timer1_config(void) {

    flexio_timer_config_t fxioTimerConfig;

    fxioTimerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(DEMO_FLEXIO_TIMER0_CH);

    fxioTimerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;

    fxioTimerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;

    fxioTimerConfig.pinConfig = kFLEXIO_PinConfigOutput;

    fxioTimerConfig.pinPolarity = kFLEXIO_PinActiveHigh;

    fxioTimerConfig.pinSelect = DEMO_FLEXIO_OUTPUTPIN2;

    fxioTimerConfig.timerMode = kFLEXIO_TimerModeDisabled;

    fxioTimerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;

    fxioTimerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;

    fxioTimerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompareTriggerLow ;

    fxioTimerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerBothEdge;

    fxioTimerConfig.timerReset = kFLEXIO_TimerResetNever;

    fxioTimerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;

    fxioTimerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;

    fxioTimerConfig.timerCompare = 750;

    FLEXIO_SetTimerConfig(DEMO_FLEXIO_BASEADDR, DEMO_FLEXIO_TIMER1_CH, &fxioTimerConfig);

}

static void flexio_timer2_config(void) {

    flexio_timer_config_t fxioTimerConfig;

    fxioTimerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(DEMO_FLEXIO_TIMER1_CH);

    fxioTimerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;

    fxioTimerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;

    fxioTimerConfig.pinConfig = kFLEXIO_PinConfigOutput;

    fxioTimerConfig.pinPolarity = kFLEXIO_PinActiveHigh;

    fxioTimerConfig.pinSelect = DEMO_FLEXIO_OUTPUTPIN3;

    fxioTimerConfig.timerMode = kFLEXIO_TimerModeDisabled;

    fxioTimerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;

    fxioTimerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;

    fxioTimerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompareTriggerLow;

    fxioTimerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerBothEdge;

    fxioTimerConfig.timerReset = kFLEXIO_TimerResetNever;

    fxioTimerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;

    fxioTimerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;

    fxioTimerConfig.timerCompare = 960;

    FLEXIO_SetTimerConfig(DEMO_FLEXIO_BASEADDR, DEMO_FLEXIO_TIMER2_CH, &fxioTimerConfig);

}

static void flexio_timer0_start(void)

{

    /* Set Timer mode to kFLEXIO_TimerModeDual8BitPWM to start timer */

    DEMO_FLEXIO_BASEADDR->TIMCTL[DEMO_FLEXIO_TIMER0_CH] |= FLEXIO_TIMCTL_TIMOD(kFLEXIO_TimerModeSingle16Bit);

}

static void flexio_timer1_start(void)

{

    /* Set Timer mode to kFLEXIO_TimerModeDual8BitPWM to start timer */

    DEMO_FLEXIO_BASEADDR->TIMCTL[DEMO_FLEXIO_TIMER1_CH] |= FLEXIO_TIMCTL_TIMOD(kFLEXIO_TimerModeSingle16Bit);

}

static void flexio_timer2_start(void)

{

    /* Set Timer mode to kFLEXIO_TimerModeDual8BitPWM to start timer */

    DEMO_FLEXIO_BASEADDR->TIMCTL[DEMO_FLEXIO_TIMER2_CH] |= FLEXIO_TIMCTL_TIMOD(kFLEXIO_TimerModeSingle16Bit);

}

...

    flexio_timer0_config();

    flexio_timer1_config();

    flexio_timer2_config();

    flexio_timer2_start();

    flexio_timer1_start();

    flexio_timer0_start();

    while (1)

    {

__NOP();

    }

0 Kudos
Reply

2,174 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Brett,

   Thank you for your updated information.

   You said, your code the delay times are not correct, could you also give me the test result in the oscilloscope, and can you share the whole test project to me?

   If you can draw the wave you want to realize, it will be better.

   When I have time, I will  help you to debug your code, and check the details.


Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply

2,174 Views
bbergquist
Contributor I

The issue that I see is with the "fxioTimerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompareTriggerLow ;".  This causes the timer0 to run through 2 iterations causing the delay to be incorrect.  Ideally I would like "fxioTimerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare" but when configured like that the next timer is not triggered correctly.

I guess the simplest thing that could be done would be to first figure out how to have 3 timers configured such that

  • timer0 is configured to drive a pin high for x time and stops on compare
  • timer1 is configured to be triggered by timer0 stopping on timer compare.  It is configured to drive a pin high for y time and stops on compare
  • timer2 is configured to be triggered on timer1 stopping on timer compare.  It is configured to drive a pin high for z timer and stops on compare

Starting timer0 should show that state transition of timer0 running, stopping, and triggering timer1 which should run, stop, and trigger timer 2 which should run and stop.

Proving that out would be the first step of using the Flexio timers as delay timers driving a pin for a certain amount of timer.

The next step would be to configure time0 such that it can be triggered to start again when timer2 stops.  To observe this it is likely that it would have have the pin output toggled so that the scope could see it, but this would need to be done carefully as it makes it had to distinguish this case from the case where the original timer kept running through multiple transitions.

 

A couple other things would be very useful would be to understand the logic behind when a timer is evaluated to be started/enabled.  Take the scenario where you configure a timer as

  • enabled always
  • disabled on compare
  • triggered by timer N 
  • Mode disabled

So in this case from my thinking that when I start the timer by setting the mode to 16 bit countdown timer, the timer will run until it counts down to 0 and will become disabled.  Then at some later time, it might be triggered again by timer N.   That is my thinking by I can find no documentation that identifies when the conditions of a timer are evaluated.  It is just a guess on my part.

A second thing that would be useful to understand is that if you have a timer configured as

  • enabled always
  • disabled on compare
  • output logical one

and a second timer

  • triggered by first time on timer low

When the first timer runs and compares to 0 and disabled, does its state change to output logical zero and trigger the second timer?

0 Kudos
Reply