Pulse width and frequency capture from 4 pins

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

I've configured my XmegaE5 to capture duty cycle and frequency using the built in event action (control register D) on two timers (TCC4 and TCC5).  Configuration code below :

 

    // map event channels to PORTA pins
		EVSYS.CH4MUX = EVSYS_CHMUX_PORTA_PIN4_gc;
		EVSYS.CH3MUX = EVSYS_CHMUX_PORTA_PIN5_gc;
		EVSYS.CH2MUX = EVSYS_CHMUX_PORTA_PIN6_gc;
		EVSYS.CH1MUX = EVSYS_CHMUX_PORTA_PIN7_gc;

	// enable input capture mode for CCA & CCB on TCC4 and TCC5
		TCC4.CTRLE = 0b00001010;
		TCC5.CTRLE = 0b00001010;

	// set TCC4 and TCC5 event action to pulse width & frequency capture, on event channels 1 and 3 respectively
		TCC4.CTRLD = 0b11001001;
		TCC5.CTRLD = 0b11001011;

	// set CCA interrupt levels to 1 on both timers
		TCC4.INTCTRLB = 0b00000001;
		TCC5.INTCTRLB = 0b00000001;

	// set prescaler to same as system clock and start timer
		TCC4.CTRLA = 0x01;
		TCC5.CTRLA = 0x01;

If I am only reading two input pins, I use the two ISRs (below) to store the captured values from both CCA (frequency) and CCB (duty) 

ISR(TCC4_CCA_vect) {
    ch1_freq = TCC4.CCA;
    ch1_duty = TCC4.CCB;
}

ISR(TCC5_CCA_vect) {

	ch3_freq = TCC5.CCA;
	ch3_duty = TCC5.CCB;
}

And it works beautifully (I'm using a 1kHZ waveform)..  My issue is that I need to read 4 channels, rather than 2, and I only have access to these two timers.  So I have added code to the ISRs to toggle the event channels in the control register D (below) after saving each reading.  But this toggling results in very erratic and incorrect readings.  There is some responsiveness, but often the readings seem quite random.   I'm thinking the issue may have to do with the timer needing to synchronise after being updated with a new event channel.. Any help would be appreciated..

 

Below is my unworking code from the TCC4 ISR, which is attempting to read the duty cycle and frequency from PORTA pin 6 & 7 by toggling between the two event channels. 

ISR(TCC4_CCA_vect) {

	if (pin_mux == 0b11001001) {
		ch1_duty = TCC4.CCB;
		ch1_freq = TCC4.CCA;
		pin_mux = 0b11001010;
		TCC4.CTRLD = pin_mux;
	} else if (pin_mux == 0b11001010) {
		ch2_duty = TCC4.CCB;
		ch2_freq = TCC4.CCA;
		pin_mux = 0b11001001
		TCC4.CTRLD = pin_mux;
	}
}

Thanks to anyone who has read this far..

 

 

Last Edited: Tue. Oct 24, 2017 - 09:31 PM