Xmega32A4U Input Capture problem

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey guys,

 

I trying configurate Input Capture mode on my xmega 32A4U, but for my its just not work.. Maybe you have some minds what is wrong?

 

#include <asf.h>

 

#define Buffer                             100
#define TIMER_PERIOD                     50000

 

void cca_callback(void);
uint16_t cca_capture[Buffer];
uint16_t counter;

 

void cca_callback(void)
{
    cca_capture[counter++] = tc_read_cc(&TCC0, TC_CCA);
    
    if(counter == Buffer)
    {
        counter = 0;
    }
}

int main (void)
{
    board_init();
    
    sysclk_init();

 

    ioport_configure_port_pin(ioport_pin_to_port(IOPORT_CREATE_PIN(PORTC,1)), ioport_pin_to_mask(IOPORT_CREATE_PIN(PORTC,1)), PORT_ISC_BOTHEDGES_gc);

 

    EVSYS_CH0MUX = EVSYS_CHMUX_PORTC_PIN1_gc;

    sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS);

    tc_write_clock_source(&TCC0, TC_CLKSEL_DIV64_gc);

    tc_write_period(&TCC0, TIMER_PERIOD);

    tc_enable_cc_channels(&TCC0, TC0_CCAEN_bm);

    tc_clear_cc_interrupt(&TCC0, TC_CCA);

    tc_set_input_capture(&TCC0, TC_EVSEL_CH0_gc, TC_EVACT_FRQ_gc);

    tc_set_cca_interrupt_callback(&TCC0, &cca_callback);

    pmic_init();

 

    tc_set_cca_interrupt_level(&TCC0, TC_CCAINTLVL_LO_gc);
    pmic_enable_level(PMIC_LOLVLEN_bm);

 

    tc_enable(&TCC0);

    cpu_irq_enable();

 

    while(1)
    {
    }
}

 

This topic has a solution.
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Move
 

	sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS);
	tc_enable(&TCC0);

to before using the modules, e.g., right after sysclk_init();
The problem is that the clocks are turned off in sysclk_init so the modules can not be used (not even configured). Anyway, this is what it looks like in the simulator.

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you, it's work!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okey, with TC_EVACT_FRQ_gc (measure frequence)  it's work good.

 

But if I change it to TC_EVACT_CAPT_gc (Input capture), It's not give back timer value then it was hit by Pin edge.. Where it could be problem?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How do you know it does not work? How are you testing it?. I modified your code a bit and added some output on USART and it looks ok.

 
 

#include <asf.h>
#include <stdio.h>
#define F_CPU 32E6

void cca_callback(void);
int usartStdioTx(char data, FILE *stream);

uint16_t cca_capture[64];
#define BUFFER_SIZE (sizeof(cca_capture) / sizeof(cca_capture[0]))
volatile uint16_t counter;

#define USART_SERIAL_EXAMPLE            &USARTC1
#define USART_SERIAL_EXAMPLE_BAUDRATE   115200
#define USART_SERIAL_CHAR_LENGTH        USART_CHSIZE_8BIT_gc
#define USART_SERIAL_PARITY             USART_PMODE_DISABLED_gc
#define USART_SERIAL_STOP_BIT           false

static FILE mystdout = FDEV_SETUP_STREAM(usartStdioTx, 0,_FDEV_SETUP_WRITE);

void cca_callback(void)
{	
    uint16_t cap = tc_read_cc(&TCC0, TC_CCA);
    if (counter < BUFFER_SIZE) {
        cca_capture[counter++] = cap;
    }
}

int main (void)
{
    board_init();
    sysclk_init();
    sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS);
    tc_enable(&TCC0);

    static usart_rs232_options_t USART_SERIAL_OPTIONS = {
        .baudrate = USART_SERIAL_EXAMPLE_BAUDRATE,
	.charlength = USART_SERIAL_CHAR_LENGTH,
	.paritytype = USART_SERIAL_PARITY,
	.stopbits = USART_SERIAL_STOP_BIT
    };

    // Initialize usart driver in RS232 mode
    usart_init_rs232(USART_SERIAL_EXAMPLE, &USART_SERIAL_OPTIONS);
    stdout = &mystdout;
	
    ioport_configure_port_pin(ioport_pin_to_port(IOPORT_CREATE_PIN(PORTC,1)), ioport_pin_to_mask(IOPORT_CREATE_PIN(PORTC,1)), PORT_ISC_BOTHEDGES_gc);
    EVSYS_CH0MUX = EVSYS_CHMUX_PORTC_PIN1_gc;
    tc_write_clock_source(&TCC0, TC_CLKSEL_DIV64_gc);
    tc_enable_cc_channels(&TCC0, TC0_CCAEN_bm);
    tc_clear_cc_interrupt(&TCC0, TC_CCA);
    tc_set_input_capture(&TCC0, TC_EVSEL_CH0_gc, TC_EVACT_CAPT_gc);
    tc_set_cca_interrupt_callback(&TCC0, &cca_callback);

    pmic_init();

    tc_set_cca_interrupt_level(&TCC0, TC_CCAINTLVL_LO_gc);
    pmic_enable_level(PMIC_LOLVLEN_bm);

    cpu_irq_enable();
	
    while(1) {
        if (counter == BUFFER_SIZE) {
            size_t i;
	    for (i = 0; i < BUFFER_SIZE; ++i) {
	        printf("%8u", cca_capture[i]);
	        if (((i+1)&7) == 0) {
	            putchar('\n');
	        }
	    }
	    putchar('\n');
            putchar('\n');
            counter = 0;
	}
    }
}

int usartStdioTx(char data, FILE *stream)
{
    if (data == '\n') {
        usartStdioTx('\r', stream);
    }
    usart_putchar(USART_SERIAL_EXAMPLE, data);
    return 0;
}

With 500Hz 20% duty cycle on the pin I get output like this
 

   34616   34823   35653   35861   36691   36899   37729   37937
   38767   38975   39806   40013   40843   41051   41881   42089
   42919   43127   43957   44164   44995   45202   46032   46240
   47070   47277   48107   48315   49145   49352   50182   50390
   51220   51427   52257   52465   53294   53502   54332   54539
   55370   55577   56407   56615   57445   57652   58482   58689
   59520   59727   60557   60765   61596   61803   62633   62841
   63671   63878   64708   64916     210     417    1247    1454


   25107   25315   26145   26352   27182   27390   28220   28428
   29258   29465   30295   30503   31333   31540   32370   32577
   33407   33615   34444   34652   35482   35689   36519   36726
   37556   37764   38593   38801   39631   39838   40668   40875
   41705   41912   42743   42950   43780   43988   44818   45025
   45855   46063   46892   47100   47930   48137   48968   49175
   50005   50212   51042   51250   52080   52287   53117   53325
   54154   54362   55192   55399   56229   56436   57266   57474
   

which I think matches my settings (notice I have 32Mhz clock), e.g, (35653-34616) should be the period and in seconds this is (35653-34616) * 1 / (32Mhz/64). About 482 Hz. (34823-34616) is also about 1/5 or 20% of (35653-34616).
/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

He doesn't know it does not work. He just posted above that Lajon's suggestion solved the problem.

274,207,281-1 The largest known Mersenne Prime

Measure twice, cry, go back to the hardware store