1

I'm writing a program for the SAML21G18B using AtmelStart and ASF4 HAL libraries. My timer is intended to simply count up until it overflows, at which point a handler increments a count OVF and restarts the timer. My understanding is that the HAL libraries i.e. timer_start(timerInstance)(see API documentation here) should start the timer, and I need to override the TC0_Handler function so that it increments my count OVF. However, the timer_start function never returns, and it appears that the handler is repeatedly called despite the timer count register not changing from zero. It appears that every time the OVF bit is cleared via hri_tc_clear_interrupt_OVF_bit, it gets reset on the next step when stepping through in debug mode.

I have changed a couple of things in the configuration of the timer, namely:

  1. I have changed it to be 16 bit rather than the 32 bit that the AtmelStart generates, i.e. #define CONF_TC0_MODE TC_CTRLA_MODE_COUNT16_Val
  2. The timer is running at 16MHz (CPU speed) and thus the timer tick period is <1us, where the AtmelStart configuration only seems to allow integers, so I have overridden that to be a float.
  3. I am not wanting to use the timer tasks provided by the API as I am trying to keep my code as close to legacy as possible.

Is someone able to point me in the right direction here? Is there some timer configuration I'm missing? All examples I can find use the tasks. I'm not too familiar with posting SO questions so if you need more information I am happy to provide.

Edit: the code in question:

int main(void)
{
    /* Initializes MCU, drivers and middleware */
    atmel_start_init();
    ext_irq_register(MCU_SWI, TurnOff_Handler);
    
    //TODO make this separate driver init func.
    timerInit(&Timer0, &TIMER_0, COUNT_UP, 0);
    timerStart(&Timer0);
}
eles
  • 31
  • 7
  • 1
    Please show a [mre] of your code, which demonstrates the behaviour you describe. You may assume that readers have the hardware for being able to actually reproduce, but this is otherwise also for providing necessary info. – Yunnosch Jun 06 '23 at 10:13
  • 2
    I assume (because of lack of MRE) you used `TIMER_TASK_REPEAT`. What happens if you use the alternative, one-shot, `TIMER_TASK_ONE_SHOT`? I ask because if the period (whereever it results from) is too short, you might never leave interrupt context. That would explain the non-returning and the repeated calling of the handler. – Yunnosch Jun 06 '23 at 10:19
  • "so I have overridden that to be a float" Without knowing that device, I doubt that timer registers take floating point values. – Gerhardh Jun 06 '23 at 14:09
  • @Yunnosch My understanding is that I do not need to use either of those, as they are constants used when initialising tasks? The period register is zeroed as I believe it is only used when it is an 8 bit timer – eles Jun 06 '23 at 21:07
  • @Gerhardh I've had a look and it's just a constant used to calculate elapsed time in the HAL, not an actual hardware register – eles Jun 06 '23 at 21:08

1 Answers1

0

I found the solution is due to the count requiring a read sync. See here for solution on the SAMD21, which has identical solution for the SAML21.

eles
  • 31
  • 7
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 07 '23 at 09:03