Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

Thread: Simultaneously start multiple timers

  1. #1
    Junior Member
    Join Date
    Sep 2015
    Posts
    19

    Simultaneously start multiple timers

    For a project which requires precise timings, I'm trying to align three PWM signals from three different timers; one 12 MHz, one 1.5 MHz and one 0.75 MHz signal.
    As far as I understand this would require all three timers to start counting at the same time from 0.
    The only problem is that I can't seem to find a way to start the timers simultaneously; when I run FTM2_SC = FTM1_SC = FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); every register is set after each other, which already creates a time offset between the timers.
    What I tried in the code below is to give the timers an specific offset before they start, which would make them align when they get started sequentially.

    For Teensy 3.6:
    Code:
    // For Teensy 3.6
    // 12 MHz on pin 3
    // 0.75 MHz on pin 29
    // 1.5 MHz on pin 35
    
    void setup() {
      FTM1_SC = 0;
      FTM1_CNT = 0;
      FTM1_MOD = 4;
      FTM1_C0SC = 0x28;
      FTM1_C0V = 2;
      CORE_PIN3_CONFIG = PORT_PCR_IRQC(1) | PORT_PCR_MUX(3);
    
    
      FTM2_SC = 0;
      FTM2_CNT = 0;
      FTM2_MOD = 79;
      FTM2_C0SC = 0x28;
      FTM2_C0V = 40;
      CORE_PIN29_CONFIG = PORT_PCR_IRQC(1) | PORT_PCR_MUX(3);
    
    
      FTM3_SC = 0;
      FTM3_CNT = 0;
      FTM3_MOD = 39;
      FTM3_C4SC = 0x28;
      FTM3_C4V = 5;
      CORE_PIN35_CONFIG = PORT_PCR_IRQC(1) | PORT_PCR_MUX(3);
    }
    
    void loop() {
      syncStart();
      delayMicroseconds(100);
      stop();
      delay(10);
    }
    
    void stop() {
      FTM1_SC = 0;
      FTM2_SC = 0;
      FTM3_SC = 0;
    }
    
    void syncStart() {
      noInterrupts();
    
      FTM2_SC = 0;
      FTM2_CNT = 0;
    
      FTM1_SC = 0;
      FTM3_SC = 0;
    
      FTM1_CNTIN = 3;
      FTM1_CNT = 0;
      FTM1_CNTIN = 0;
    
      FTM3_CNTIN = 36;
      FTM3_CNT = 0;
      FTM3_CNTIN = 0;
    
      FTM2_SC = FTM1_SC = FTM3_SC =  FTM_SC_CLKS(1) | FTM_SC_PS(0);  // start the timers
    
      interrupts();
    }
    This seems to work ok, but it produces a small error at the beginning; when starting the timers the output of the channel will always go to HIGH; the following two screenshots explain more than a thousand words:
    0.75 MHz & 12 MHz: SDS00002.BMP
    0.75 MHz & 1.5 MHz: SDS00003.BMP

    I assume there is a better way of doing this, one that also doesn't depend on the delay between the execution of timer start commands.
    I would love to hear any suggestions!
    Thanks!
    Last edited by emiel.h; 11-06-2017 at 01:35 PM.

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,782
    You could try configuring the FTM timers to use an external clock, instead of F_BUS. I believe pins 0 and 1 (PTB16 & PTB17) can be used if their config mux is set to ALT4. Look at the SIM_SOPT4 register for configuring how the timers get their clocks.

    There's also a hardware mechanism for sync'd trigger documented on section 45.1.6 on pages 1128-1129.

    I have not personally tried either of these. If you do, I hope you'll share anything you learn?

  3. #3
    Junior Member
    Join Date
    Sep 2015
    Posts
    19
    Thanks! I'll look into both options and report back

  4. #4
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,600
    I'd use the Teensy just to generate the 12MHz clock and use an external 74HC binary counter as a divider by 8 and by 16 to get 1.5 and 0.75 Mhz.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •