# Clocks and timers

Summary:

• Same routine: power up, configure
• As before, I'll point you to the documentation
• APB1 Clock: 8 MHz
• Configuration: one shot, autoreload, prescaler
• Introduce: busy waiting while !tim7.sr.read().uif() {}
• Re-implement delay::ms

In this section, we'll re-implement the LED roulette application. I'm going to give you back the led module but this time I'm going to take away the delay module :-).

Here's the starter code. The delay function is unimplemented so if you run this program the LEDs will blink so fast that they'll appear to always be on.

#![no_std]
#![no_main]

extern crate pg;

use core::iter;

use pg::led::LEDS;
use pg::peripheral;

#[inline(never)]
fn delay(ms: u16) {
// TODO implement this
}

#[inline(never)]
#[no_mangle]
pub fn main() -> ! {
unsafe {
let rcc = peripheral::rcc_mut();
let tim7 = peripheral::tim7_mut();
}

// TODO initialize TIM7

loop {
for (current, next) in LEDS.iter()
.zip(LEDS.iter().skip(1).chain(iter::once(&LEDS[0]))) {
next.on();
delay(50);
current.off();
delay(50);
}
}
}


Functional description:

• The timer is enabled
• A counter register increments its value on each "tick"
• When the counter reaches the value held in the auto-reload register, it will reset back to zero and generate an update event.

The timer can operate in two modes:

• Continuous mode: After an update event, the timer will start counting again.
• One pulse mode: After an update event, the timer will stop.

How long does this "tick" last? That's determined by the APB1 clock and the counter and prescaler settings.

TIM6/TIM7 registers - Section 22.4 - Page 681 - Reference Manual.

Initialization is as usual: power up the peripheral then configure it.

• Use TIM7EN in RCC::APB1ENR to power up the peripheral.
• TIM7::CR1, the configuration register.
• TIM7::PSC, the prescaler register.
• TIM7::ARR, the auto-reload register.
• TIM7::CNT, the counter register.
• TIM7::SR, the status register, indicates if an update event has occurred.
• TIM7::EGR, the event generation register. Can be used to generate an update. event.

The catch: the auto-reload register is buffered. When you write to it, it won't immediately change until the next update event. You can synthesize an update event using EGR.