TCC0 and freq. capture mode

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

Hello,
I want make this application:

1/ constant freq. pulses go to the input pin PC0 and I count them by TCC0.
2/ after some time go 'trigger pulse' to the input PC1 and I want capture TCC0 and restart it.
3/ if there is a new value in capture reg.A I'll make an interrupt.

I have written some code but it doesn't work well.
In simulator:
1/ If I trigger PC0 to high, the TCC0 counts +2 times (???)
2/ If I trigger PC0 to low, the TCC0 counts +1 time (???)
3/ If the interrupt happens, it remains forever, is not auto-clear (???)

What's wrong ?

#include 
#include 
#include "avr_compiler.h"
#include "pmic_driver.h"

// chip: Atxmega16A4
// AVR Studio 4.18 
// build 684

void init2( void);

volatile uint8_t ibn;
volatile uint16_t  timerC0;

int main( void)
{
 init2();
 PMIC_EnableLowLevel();
 sei();
do{
  timerC0 = TCC0.CNTL; 
  timerC0 |= (TCC0.CNTH<<8);
  nop(); // here I watch the timer value
} while(1);

return(0);
}

ISR(TCC0_CCA_vect){
  ibn++;
}

void init2( void)
{
// init
// - - - - -
// PC0 -> rising edge goes to EVSYS ch. 0 and makes clock for a timer
// PC1 -> rising edge goes to EVSYS ch. 1 and makes trig. for capture A 
// in freq. mode for a timer

// this capture makes interrupt TCC0_CCA_vect


//          0b76543210
PORTC.DIR = 0b00000000;

PORTC.PIN0CTRL =    PORT_ISC_RISING_gc;
PORTC.PIN1CTRL =    PORT_ISC_RISING_gc;

EVSYS.CH0CTRL =    EVSYS_DIGFILT_1SAMPLE_gc; // 0.5us@2Mhz
EVSYS.CH1CTRL =    EVSYS_DIGFILT_1SAMPLE_gc; // 0.5us@2Mhz

EVSYS.CH0MUX =    0b01100000 | PIN0_bp;  // channel 0 src. is PORTC PIN0
EVSYS.CH1MUX =    0b01100000 | PIN1_bp;  // channel 1 src. is PORTC PIN1


TCC0.CTRLD =    TC_EVACT_FRW_gc | TC_EVSEL_CH1_gc;
// frequency capture trig. is at EV channel 1

TCC0.CTRLB =    TC_WGMODE_NORMAL_gc | TC0_CCAEN_bm; // enable CCA module
TCC0.CTRLA =    TC_CLKSEL_EVCH0_gc;  // clock input is EV channel 0
TCC0.INTFLAGS =    0xff;  // clear all flags
TCC0.INTCTRLB =    TC_CCAINTLVL_LO_gc; // enable interrupt low level
}