Hello,
I am looking for some help getting CTIMER ISRs to fire from an arduino sketch. I am sure there is something I am overlooking in the configuration of the timer and/or ISR. Any help would be appreciated. Here is what I have so far…
#include "Arduino.h"
#include <stdint.h>
void setup()
{
pinMode(LED_BUILTIN,OUTPUT); //arduino stuff
//set up ctimer 5A
am_hal_ctimer_config_single(
5, // timer 5
AM_HAL_CTIMER_TIMERA, // segment A
AM_HAL_CTIMER_FN_REPEAT // repeatedly count up to the compare.
| AM_HAL_CTIMER_RTC_100HZ // use the realtime clock at 100 counts / sec
| AM_HAL_CTIMER_INT_ENABLE); // enable interupts on this timer 5A
am_hal_ctimer_compare_set(5,AM_HAL_CTIMER_TIMERA,0,100); // set compare0 value for 5A
am_hal_ctimer_int_register(AM_HAL_CTIMER_INT_TIMERA5C0,CTIMER_IRQHandler); // set the interrupt for 5A compare0
am_hal_ctimer_int_set(AM_HAL_CTIMER_INT_TIMERA5C0);
am_hal_ctimer_int_enable(AM_HAL_CTIMER_INT_TIMERA5C0); // enable the 5A compare0 interrupt
/* working with NVIC directly here prevents the sketch from running
//NVIC_ClearPendingIRQ(CTIMER_IRQn);
//NVIC_EnableIRQ(CTIMER_IRQn);
//NVIC_SetVector(CTIMER_IRQn,(uint32_t)&CTIMER_IRQHandler);
*/
am_hal_interrupt_master_enable(); // make sure master interupts are enabled
am_hal_ctimer_clear(5,AM_HAL_CTIMER_TIMERA); // clear the timer
am_hal_ctimer_start(5,AM_HAL_CTIMER_TIMERA); //start the timer
}
volatile uint32_t state = 1; //start the LED in the on state
extern "C" void CTIMER_IRQHandler(void){
// I would expect this to be called after 1 second and turn off the led
AM_CRITICAL_BEGIN;
state = 0;
//if(state == 0){
// state = 1;
// }
// else {
// state = 0;
// }
AM_CRITICAL_END;
}
void loop()
{
digitalWrite(LED_BUILTIN,state);
}
Ok, I think I got myself confused by looking at the apollo 1 and 2 examples. for (my own) future reference: This blinky_isr.ino seems to work:
#include "Arduino.h"
#include <stdint.h>
void setupTimer5(){
am_hal_ctimer_clear(5,AM_HAL_CTIMER_TIMERA); // clear the timer
//config the timer
am_hal_ctimer_config_single(
5, // timer 5
AM_HAL_CTIMER_TIMERA, // segment A
AM_HAL_CTIMER_FN_REPEAT // repeatedly count up to the compare.
| AM_HAL_CTIMER_RTC_100HZ // use the realtime clock at 100 counts / sec
| AM_HAL_CTIMER_INT_ENABLE); // enable interupts on this timer 5A
am_hal_ctimer_compare_set(5,AM_HAL_CTIMER_TIMERA,0,100); // set compare0 value for 5A
am_hal_ctimer_int_clear(AM_HAL_CTIMER_INT_TIMERA5C0); // clear existing
//this is different than the apollo1,2 which seems to use am_hal_interrupt_enable
am_hal_ctimer_int_enable(AM_HAL_CTIMER_INT_TIMERA5C0); // enable the interrupt.
}
void setupTimerInterrupts(){
NVIC_EnableIRQ(IRQn_Type::CTIMER_IRQn);
am_hal_interrupt_master_enable();
}
void setup()
{
pinMode(LED_BUILTIN,OUTPUT); //arduino stuff
setupTimer5();
setupTimerInterrupts();
am_hal_ctimer_start(5,AM_HAL_CTIMER_TIMERA); //start the timer
}
volatile uint32_t state = 1; //start the LED in the on state
//extern C so that it will be added to the table correcly.
extern "C" void am_ctimer_isr(void){
am_hal_ctimer_int_clear(AM_HAL_CTIMER_INT_TIMERA5C0);
AM_CRITICAL_BEGIN;
if(state == 0){
state = 1;
}
else {
state = 0;
}
AM_CRITICAL_END;
}
void loop()
{
digitalWrite(LED_BUILTIN,state);
}
and one last thing… because I am going to forget it later… the am_*_isr names can be found in ~/Library/arduino15/packages/SparkFun/hardware/apollo3/1.0.6/cores/arduino/am_sdk_ap3/CMSIS/AmbiqMicro/Source /startup_apollo3.s
I am sure there is real documentation with these names somewhere. If you know where it is… let me know.
Nice work! I don’t know of any documentation besides the Apollo3 datasheet (https://cdn.sparkfun.com/assets/d/a/7/c … v0_9_1.pdf) and the HAL source code itself. I tend to look at ‘startup_gcc.c’ myself when looking for the ISR names, but recently one user created this wiki page: https://github.com/sparkfun/Arduino_Apo … Interrupts
You’ve already figure this out but using ISRs is basically a three step process: enable the peripheral to generate interrupt flag, enable the core NVIC to respond to the flag, and finally make sure that global interrupts are enabled
am_hal_*_int_enable(MASK)
NVIC_EnableIRQ(IRQ_TYPE)
am_hal_interrupt_master_enable()
Thanks for the links! I will check it out