timers

This module exposes the GBA’s 4 hardware timers.

Each timer holds a 16-bit value which ticks up by 1 after a certain number of CPU cycles (determined by the the timer’s frequency setting).

When this value overflows, it will reset to the timer’s start value and an interrupt will be raised if one has been requested.

Example:

import natu/[irq, timers, mgba]

proc myHandler() =
  mgba.printf("Bonk!")

irq.put(iiTimer3, myHandler)      # Register the handler.

tmcnt[3].init(
  freq = tf16kHz,
  start = cast[uint16](-0x4000),  # 2^14 ticks at 16 kHz = 1 second
  active = true,                  # Enable the timer.
  irq = true,                     # Fire an interrupt when the timer overflows.
)

Note

Timer 0 is used by maxmod for audio, so don’t touch it unless you know what you’re doing.


Types

type TimerFreq = enum
  • tf17MHz1 cycle per tick (16.78 Mhz)
  • tf262kHz64 cycles per tick (262.21 kHz)
  • tf66kHz256 cycles per tick (65.536 kHz)
  • tf16kHz1024 cycles per tick (16.384 kHz)
  • tfCascadeTimer ticks when the preceding timer overflows.
type Timer = object

Provides access to a timer data register and the corresponding timer control register.

    Field    

    Type    

    Description    

data uint16

Timer data. Since reading and writing this value do different things, it is accessed via the count and start= procs.

freq TimerFreq

Frequency of the timer.

_ uint16
irq bool

Enables the overflow interrupt for this timer. When using the irq module you don’t have to set this directly.

active bool

Enables the timer and resets it to its start value.


I/O Registers

var tmcnt: array[4, Timer]

Array of timer data + control registers.

proc count(timer: Timer): uint16

Get the current value of the timer.

proc `start=`(timer: var Timer, val: uint16)

Set the initial value of the timer.

The timer will reset to this value when it overflows or when the active bit is changed from false to true.

template init(r: Timer, args: varargs[untyped])

Initialise a timer with desired fields.

# Set up timer 3 to overflow once per second.

tmcnt[3].init(
  freq = tf16kHz,
  start = cast[uint16](-0x4000),  # 2^14 ticks at 16 kHz = 1 second
  active = true,                  # Enable the timer.
  irq = true,                     # Fire an interrupt when the timer overflows.
)
template edit(r: Timer, args: varargs[untyped])

Profiling Helpers

These procedures allow you to measure exactly how many CPU cycles a section of code takes to execute.

proc profileStart()

Start a profiling run.

Note

Routine uses timers 2 and 3; if you’re already using these somewhere, chaos is going to ensue.

proc profileStop(): uint

Stop a profiling run and return the time since its start.

Returns number of CPU cycles elapsed since profileStart was called.