ATSAMR35J17B/ATSAML21 TIMER INTERRUPT

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

I've been trying to configure & run hardware timer over the ATSAMR35J17 wireless module (uses SAML21 MCU at its core) to generate an Overflow Interrupt at 100ms i.e. ISR is supposed to hit at every 100ms interval. But it is observed that after starting the timer, ISR is hitting at every 10us, and changing the Prescaler or the Compare value register values isn't creating any difference in the 10us interval. Please review my code and let me know where I'm doing wrong. I'm trying to configure Timer2(TC2) in 16bit mode, using GCLK_GENERATOR_1 as its clock source running at 8MHz frequency (CPU Main Clock:16MHz). The timer is expected to cause overflow interrupt every 100ms.

TcCount16 *tc_hw2 = NULL;

void init_timer2(void)
{
    struct tc_module tc_inst2;    
    struct tc_config conf_tc2;
    tc_get_config_defaults(&conf_tc2);    /*Get default configs*/
    
    conf_tc2.clock_source = GCLK_GENERATOR_1;
    conf_tc2.clock_prescaler = TC_CLOCK_PRESCALER_DIV64;               /* 8MHz/64 = 125KHz*/
    conf_tc2.reload_action = TC_RELOAD_ACTION_GCLK;
    conf_tc2.counter_size = TC_COUNTER_SIZE_16BIT;
    conf_tc2.count_direction = TC_COUNT_DIRECTION_UP;
    conf_tc2.counter_16_bit.value = 0x0000;
    conf_tc2.counter_16_bit.compare_capture_channel[TC_COMPARE_CAPTURE_CHANNEL_0] = 12500;    /* Counter top value Match */
    
    while (tc_init(&tc_inst2, TC2, &conf_tc2) != STATUS_OK){
    }
    
    /* Enable interrupt & Set Priority */
    tc_hw2 = &(tc_inst2.hw->COUNT16);
    tc_hw2->INTENSET.reg |= TC_INTFLAG_OVF;    /* Enable Overflow Interrupt */
    NVIC_SetPriority(TC2_IRQn, 2);
    NVIC_EnableIRQ(TC2_IRQn);        
    tc_enable(&tc_inst2);    /*Start The TIMER*/
}

void TC2_Handler(void)
{
    if((tc_hw2->INTFLAG.reg) & (TC_INTFLAG_OVF))
     {
        port_pin_toggle_output_level(PIN_PB03);
     }
     system_interrupt_clear_pending(SYSTEM_INTERRUPT_MODULE_TC1);
}

Debugger Information: I can see that the timer register is configured correctly but the Timer Overflow Flag bit in the INTFLAG register is always set. I'm guessing this may be causing the interrupt but can't understand why? Please help. Thanks!

 

This topic has a solution.
Last Edited: Wed. Jul 29, 2020 - 06:43 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
	tc_hw2->INTFLAG.reg = TC_INTFLAG_OVF;

is how you clear the overflow. 

system_interrupt_clear_pending(SYSTEM_INTERRUPT_MODULE_TC1);

is not needed (it's also done for the wrong timer).

/Lars

 

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

Thank you very much Lajon. It ran like a charm after implementing your suggestion. Notably writing 0 to the INTFLAG does not have any effects, the reference manual clearly mentions it but somehow I missed & earlier tried clearing OVF bit by writing 0 to it. It only lights up in my mind after your suggestion. Thanks Again!