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

Thread: FTM MOD register update on Teensy 3

  1. #1
    Junior Member
    Join Date
    Jan 2020
    Posts
    6

    FTM MOD register update on Teensy 3

    Hi, I'm trying to update the MOD register of FTM1 during the interrupt routine ftm1_isr(). From the NXP datasheet it seems that a software trigger is needed, but I just can't work it out. Can someone help me understand why my approach is not working, and help fix it?

    Here is a MCVE where I am trying to output 5x 7 microsecond pulses at 50 us intervals (20 kHz PWM), followed by 5x 7 microsecond pulses at 100 us intervals (10 kHz PWM). All of the pulses are at 50 us intervals - so I conclude that the MOD register update is not working. Tested with T3.5 + Teensyduino.


    Code:
    volatile unsigned int counter1, counter2, state;
    
    void setup(){
      pinMode(3,OUTPUT);  digitalWrite(3,LOW);   // Pulse output
      state=0;
    }
    
    void loop(){
      switch (state){
        case 0: 
        delay(500);            // Duty period
        counter1=0;
        counter2=0;
        state=1;
        ftm1_enable(2999);    // Enable PWM at 20 kHz
        break;
      
        case 1:
        // Time to do something
        break;
        
        case 2:
        // Time to do something else
        break;
    
        default:
          break;
      }
    }
    
    void ftm1_enable(unsigned int FTM1_tov){ 
    digitalWrite(3,LOW);  
    FTM1_MODE = 0x0D;         
    FTM1_SC = 0x00;           
    FTM1_CNT = 0x0000;        
    FTM1_MOD = FTM1_tov;      // Timer overflow value minus 1
    FTM1_C0SC = 0x28;         // EA-PWM-HighTrue
    PORTA_PCR12 |= 0x300;     // Alternative function 3 on FTM1_CH0 = Teensy Pin 3
    FTM1_C0V = 419;           // 7 us to clear output, set on CNT=0
    
    NVIC_SET_PRIORITY(IRQ_FTM1, 0);
    NVIC_ENABLE_IRQ(IRQ_FTM1);
    FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE;
    }
    
    void ftm1_update_MOD(unsigned int modval){            // This does not seem to work
    FTM1_MODE = 0x0D;
    FTM1_MOD = modval;
    FTM1_C0V = 819;      
    FTM1_SYNC |= 0x80;
    }
    
    void ftm1_disable(){
    FTM1_SC &= ~FTM_SC_TOF;    
    NVIC_DISABLE_IRQ(IRQ_FTM1);
    FTM1_C0SC = 0;     
    pinMode(3,OUTPUT); digitalWrite(3,LOW);
    }
    
    void ftm1_isr(void){
      FTM1_SC &= ~FTM_SC_TOF;
      if(state==2) {
        counter2++;
        if(counter2>5){ftm1_disable(); state=0;} 
        }
      if(state==1) {
        counter1++;   
        if(counter1>5){ftm1_update_MOD(5999); state=2;}   // Reduce the PWM frequency to 10 kHz
        }
    }
    Here is a screenshot of the output, on an oscilloscope:
    Click image for larger version. 

Name:	Untitled.jpg 
Views:	4 
Size:	94.7 KB 
ID:	19054
    Last edited by MichaelT; 02-13-2020 at 11:00 AM. Reason: Added image

Posting Permissions

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