Problem with Timer/Counter

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

Hello,

I have such a code:

__attribute__((__interrupt__)) static void tc_irq(void)
{
    tc->channel[TC_CHANNEL].sr;

    gpio_tgl_gpio_pin(AVR32_PIN_PA05);
}


void localStartPLL(void)
{
	volatile avr32_pm_t *pm = &AVR32_PM;

	// Switch the main clock to OSC0
	pm_switch_to_osc0(pm, FOSC0, OSC0_STARTUP);

	pm_pll_setup(pm, // volatile avr32_pm_t *pm
			      0, // unsigned int pll
			     10, // unsigned int mul
			      1, // unsigned int div, Sel Osc0/PLL0 or Osc1/Pll1
			      0, // unsigned int osc
			     16); // unsigned int lockcount

	pm_pll_set_option(pm,  // volatile avr32_pm_t *pm
                       0,  // unsigned int pll
                       1,  // unsigned int  pll_freq
                       1,  // unsigned int  pll_div2
                       0); // unsigned int  pll_wbwdisable

	// Enable PLL0
	pm_pll_enable(pm, 0);

	// Wait for PLL0 locked
	pm_wait_for_pll0_locked(pm) ;

	pm_cksel(pm, 1, 0, 0, 0, 0, 0);

	// one wait state at 66 Mhz
	flashc_set_wait_state(1);

	// switch to clock
	pm_switch_to_clock(pm, AVR32_PM_MCCTRL_MCSEL_PLL0);
}

/* initClock: inicjalizuje obsluge przerwania zegara
 */
void initClock(void)
{
    volatile avr32_tc_t *tc = &AVR32_TC;

    // Options for waveform genration.
    static const tc_waveform_opt_t WAVEFORM_OPT =
    {
      .channel  = TC_CHANNEL,                        // Channel selection.

      .bswtrg   = TC_EVT_EFFECT_NOOP,                // Software trigger effect on TIOB.
      .beevt    = TC_EVT_EFFECT_NOOP,                // External event effect on TIOB.
      .bcpc     = TC_EVT_EFFECT_NOOP,                // RC compare effect on TIOB.
      .bcpb     = TC_EVT_EFFECT_NOOP,                // RB compare effect on TIOB.

      .aswtrg   = TC_EVT_EFFECT_NOOP,                // Software trigger effect on TIOA.
      .aeevt    = TC_EVT_EFFECT_NOOP,                // External event effect on TIOA.
      .acpc     = TC_EVT_EFFECT_NOOP,                // RC compare effect on TIOA: toggle.
      .acpa     = TC_EVT_EFFECT_NOOP,                // RA compare effect on TIOA: toggle (other possibilities are none, set and clear).

      .wavsel   = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,// Waveform selection: Up mode with automatic trigger(reset) on RC compare.
      .enetrg   = FALSE,                             // External event trigger enable.
      .eevt     = 0,                                 // External event selection.
      .eevtedg  = TC_SEL_NO_EDGE,                    // External event edge selection.
      .cpcdis   = FALSE,                             // Counter disable when RC compare.
      .cpcstop  = FALSE,                             // Counter clock stopped with RC compare.

      .burst    = FALSE,                             // Burst signal selection.
      .clki     = FALSE,                             // Clock inversion.
      .tcclks   = TC_CLOCK_SOURCE_TC2                // Internal source clock 3.
                                                     // (TC_CLOCK_SOURCE_TC2 = fPBA / 4,
                                                     //  TC_CLOCK_SOURCE_TC3 = fPBA / 8,
                                                     //  TC_CLOCK_SOURCE_TC4 = fPBA / 16,
                                                     //  TC_CLOCK_SOURCE_TC5 = fPBA / 32)
    };

    static const tc_interrupt_t TC_INTERRUPT =
    {
      .etrgs = 0,
      .ldrbs = 0,
      .ldras = 0,
      .cpcs  = 1,
      .cpbs  = 0,
      .cpas  = 0,
      .lovrs = 0,
      .covfs = 0
    };

    Disable_global_interrupt();

    // Initialize interrupt vectors.
    INTC_init_interrupts();

    // Register the RTC interrupt handler to the interrupt controller.
    INTC_register_interrupt(&tc_irq, AVR32_TC_IRQ0, AVR32_INTC_INT0);

    Enable_global_interrupt();

    // Initialize the timer/counter.
    tc_init_waveform(tc, &WAVEFORM_OPT);         // Initialize the timer/counter waveform.


    tc_write_rc(tc, TC_CHANNEL, 200); // Set RC value, 200kHz

    tc_configure_interrupts(tc, TC_CHANNEL, &TC_INTERRUPT);

    // Start the timer/counter.
    tc_start(tc, TC_CHANNEL);                    // And start the timer/counter.
}

The problem is, that on a osciloscope I get something like this:

(green plot is AVR32_PIN_PA05 pin which is toggled in tc_irq)

As us can see, "A" is not equal "B". Why? What to do, to have "A" equal "B"?

I use AVR32 UC3B0256. There is 12MHz oscilator. The uC runs at 66MHz (nominal max speed is 60MHz, but I do need extra MHz, so I decided to overclock it).

Regards

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

Settings seems to be correct. If I'd have to guess - I'd say that you get an extra interrupt for some reason.

1. With RC value you use, what is your expected pin oscillation period? is it A? B or A+B?
2. Add a condition to your ISR so that pin toggles only if CPCS is set - if you see picture change, than it means you are getting an unexpected interrupt somewhere.
3. Try to lower the freq, see if it will affect the output.