Example: Blink with timer

Here’s an example that might help someone else learn the counter timer’s capability to interface directly with GPIO. This example causes the builtin LED to blink without writing anything in the loop routine.

//
//   Author: Nic Ivy
//   Created: February 23, 2020
//   License: MIT
//
//   This example demonstrates how to pulse an output pin using a counter timer
//   (i.e. CTIMER) on the Apollo3. The example uses the Ambiq Micro hardware
//   abstraction layer provided with the SparkFun Arduino core for their Artemis
//   line of microcontrollers.
//

//
//   On the Artemis ATP, the builtin LED is on pad 5. If you change the pad number,
//   you probably need to change the timer number too. See Table 813 in the
//   Apollo3 Blue MCU data sheet. Timer A2C0 can be mapped to pad 5.
//
static int myTimer = 2;
static int myPad = 5;

void setup( ) {
  Serial.begin(115200);
  while (!Serial) {
    ; // Wait for serial port to connect. Needed for native USB port only.
  }
  Serial.println("CTIMER will drive an output directly.");

  setupTimerA(myTimer, 15, myPad); // timerNum, period, padNum
  am_hal_ctimer_start(myTimer, AM_HAL_CTIMER_TIMERA);
}

void loop( ) {
  // Nothing happening here.
}

void setupTimerA(int timerNum, uint32_t periodTicks, int padNum)
{
  //
  //  Configure one timer.
  //
  //  Refer to Ambiq Micro Apollo3 Blue MCU datasheet section 13.2.2
  //  and am_hal_ctimer.c line 710 of 2210.
  //
  am_hal_ctimer_config_single(timerNum, AM_HAL_CTIMER_TIMERA,
                              AM_HAL_CTIMER_LFRC_32HZ |
                              AM_HAL_CTIMER_FN_REPEAT);

  //
  //  Set the timing parameters.
  //  32 Hz * 0.5 seconds = 16 ticks = 15 ticks off and 1 tick of high output
  //
  //  Repeated Count: Periodic 1-clock-cycle wide pulses with optional interrupts.
  //  The last parameter to am_hal_ctimer_period_set() has no effect in this mode.
  //
  am_hal_ctimer_period_set(timerNum, AM_HAL_CTIMER_TIMERA, periodTicks, 1);

  //
  //  Enable pin output.
  //
  //  Refer to Ambiq Micro Apollo3 Blue MCU datasheet section 13.20
  //  and am_hal_ctimer.c line 1234 of 2210.
  //
  am_hal_ctimer_output_config(timerNum,
                              AM_HAL_CTIMER_TIMERA,
                              padNum,
                              AM_HAL_CTIMER_OUTPUT_NORMAL,
                              AM_HAL_GPIO_PIN_DRIVESTRENGTH_2MA);

  Serial.print("Timer A");
  Serial.print(timerNum);
  Serial.println(" configured");
}

Thanks for writing this! So far this is the only documentation I’ve found on how to use timers on Artemis (outside the Ambiq datasheets). Even though I was well versed in low level Arduino timers, this architecture has my head spinning :frowning:

Here’s what I want to achieve. I have all this working in Arduino just fine, but I’m lost on how to do it on Artemis.

Single pulse timer with a clock rate of about 500 Hz

The timer output will be tied to a pin

I will set the pulse width and counter value to trigger timer as part of a separate function

A separate ISR will be responsible for starting the timer

What I’ve been able to glean so far from datasheet surfing

For single shot, I set FN = 2

CMPR0 and CMPR1 control the pulse start and end times

Clock rate is set by ???

I have no idea how to actually set these registers in C++ (since the datasheets are language agnostic). Any help would be appreciated :slight_smile: