Expand description

Module to interface with the GBA’s four timer units.

Similar to the background layers and DMA units, there are four timer units and they’re numbered 0 through 3.

There’s two hardware addresses that control each timer.

  • The timer’s high address is the TimerControl bits.
  • The timer’s low address is a u16 which reads the timer’s “count” value, but writes the timer’s “reload” value. In this crate we actually represent that as two separate MMIO controls for improved code clarity. Just be aware that in mGBA’s debugger and in other documentation you’ll see it as a single address.

When a timer is disabled, it will continue to read the count value that it stopped at.

Reloading

When the timer goes from disabled to enabled, or when the timer overflows, the last set reload value is copied to the counter value.

Ticking

When a timer is enabled, the timer will tick every so often. Each tick increases the counter value by 1. The rate at which the timer ticks depends on the timer’s configuration:

  • If the cascade bit is set the timer will tick once per overflow of the next lower timer. For example, if timer 3 is set to cascade, it will tick once per overflow of timer 2. Note that timer 0 ignores the cascade bit, since it doesn’t have a “next lower” timer.
  • Otherwise, the timer ticks every one or more CPU cycles, according to the TimerScale set in the scale field.

Overflows

When a timer would tick above u16::MAX then an overflow occurs. This can trigger an interrupt, and will also cause the timer to copy its reload value into its counter.

If you want a timer to overflow every x ticks (where x is non-zero), then use the wrapping_neg method to easily get the right reload value to set:

let x = 7_u16;
TIMER0_RELOAD.write(x.wrapping_neg());

Using Cascade To Pause A Timer

When a timer goes from disabled to enabled it will reset the counter value to the reload value. If you want to temporarily pause a timer without having the counter value get reset when you resume the timer you can instead set the cascade bit of the timer while the next lower timer is disabled. This keeps the timer “active” but prevents it from ticking. When you turn off cascade mode the timer will resume ticking from the current counter value.

Note that this doesn’t work for timer 0, because that timer ignores the cascade bit.

Structs

Timer configuration bits.

Enums

A number of CPU cycles per timer tick.