Updating FTM CnV and C(n+1)V registers in Teensy 3.6

Status
Not open for further replies.

Bert62

Member
Hello all,

I want the PWM waveforms from FTM0 and FTM3 to be toggled between two values each in period. I have set up the initializations of the timers and synchronized them with each other. Also, I have a separate function that does the PWM update by writing new values to the CnV registers of both FTMs. The issue I have is that between 2 specific values, the update does not occur for 1 FTM but occurs for the other. If I toggle between other values, the update works perfectly.

I don't understand the problem since some times the update happen and some times it does not.

I have the code below: [Note: MOD has the value of 599.]

FTM0:
Code:
void initFTM0(void) {
  SIM_SCGC6    |= 0x01000000; 
  SIM_SCGC5    |= 0x3E00;

  FTM0_SC       = 0x00;           
  FTM0_CONF     = 0xC0;     
  FTM0_FMS      = 0x00;            
  FTM0_MODE    |= 0x05;     

  FTM0_C0SC     = 0x28;             
  FTM0_C1SC     = 0x28;
  FTM0_C2SC     = 0x28;
  FTM0_C3SC     = 0x28;

  FTM0_COMBINE  = 0x0303;          
  FTM0_COMBINE |= 0x1010;        
  FTM0_COMBINE |= 0x2020;        
  FTM0_DEADTIME = 0x3;             

  FTM0_CNT      = 0x00;            
  FTM0_CNTIN    = 0x00;      
  FTM0_MOD      = MOD;           
  FTM0_SYNC     = 0x02;      

  PORTC_PCR1    = 0x400;          
  PORTC_PCR2    = 0x400;          
  PORTC_PCR3    = 0x400;        
  PORTC_PCR4    = 0x400;          

  FTM0_C0V      = (MOD+1)/2;          
  FTM0_C1V      = (MOD+1);    
  FTM0_C2V      = 0;                 
  FTM0_C3V      = (MOD+1)/2;       
}

FTM3:
Code:
void initFTM3(void) {
  SIM_SCGC3    |= 0x02000000; 

  FTM3_SC       = 0x00;            
  FTM3_CONF     = 0xC0;          
  FTM3_FMS      = 0x00;        
  FTM3_MODE    |= 0x05;           

  FTM3_C0SC     = 0x28;            
  FTM3_C1SC     = 0x28;         
  FTM3_C2SC     = 0x28;
  FTM3_C3SC     = 0x28;

  FTM3_C4SC     = 0x68;
  FTM3_C5SC     = 0x28;

  FTM3_COMBINE  = 0x030303;         
  FTM3_COMBINE |= 0x1010;           
  FTM3_COMBINE |= 0x202020;         
  FTM3_DEADTIME = 0x00;             

  FTM3_CNT      = 0x00;             
  FTM3_CNTIN    = 0x00;     
  FTM3_MOD      = MOD;        
  FTM3_SYNC     = 0x02;              

  PORTD_PCR0    = 0x400;            
  PORTD_PCR1    = 0x400;   
  PORTD_PCR2    = 0x400;        
  PORTD_PCR3    = 0x400;          

  PORTC_PCR8    = 0x300;        
  PORTC_PCR9    = 0x300;           
  
  FTM3_C0V      = (MOD+1)/2;         
  FTM3_C1V      = (MOD+1)/2;       
  FTM3_C2V      = 0;                  
  FTM3_C3V      = (MOD+1);         

  FTM3_C4V      = (MOD+1)/2 - 8;     
  FTM3_C5V      = (2*(MOD+1))/2 - 8;  
}

FTM syncing:
Code:
void syncFTMs(void) {
  FTM0_CONF |= 0x200;
  FTM3_CONF |= 0x200;

  FTM0_SYNCONF |= 0x80; 
  FTM3_SYNCONF |= 0x80;

  FTM0_SC = 0x48;
  FTM3_SC = 0x08;

  FTM0_CONF |= 0x400;
}

Register update:
Code:
void phase_modulator(void) {

  //toggle is a global variable with initial value of false
  if (!toggle) {
    Phi = 270;
    toggle = !toggle;
  }
  else if (toggle) {
    Phi = 240;
    toggle = !toggle;
  }

  FTM0_C0V   = (MOD+1)/2 - Phi; 
  FTM0_C1V   = (MOD+1)   - Phi; 
  FTM0_C2V   = 0;
  FTM0_C3V   = (MOD+1)/2;

  FTM3_C0V   = (MOD+1)/2 - Phi;
  FTM3_C1V   = (MOD+1)/2;
  FTM3_C2V   = 0;
  FTM3_C3V   = (MOD+1)   - Phi;

  FTM3_C4V   = ((MOD+1) - Phi)/2 - 8;         
  FTM3_C5V   = (2*(MOD+1) - Phi)/2 - 8;

  FTM0_PWMLOAD |= 0x20F;
  FTM3_PWMLOAD |= 0x20F;
}

ISR of FTM0:
Code:
void ftm0_isr(void) {
  phase_modulator();
  asm("nop");
}

In the function phase_modulator(), if I use any value other than Phi=270, sometimes only FTM0 gets the update, other times only FTM3.

This is a weird issue really and I don't know if anyone can reproduce it because it happens to me occasionally.

Does anyone know why this happens? I followed the PWM synchronization guidelines in the manual.

Thanks in advance.
 
Status
Not open for further replies.
Back
Top