help with Arduino and ctimer ISRs

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