stkarm/src/timer.cpp

55 lines
1.7 KiB
C++

#include <gic.h>
#include <interrupt.h>
#include <timer.h>
#include <dbg.h>
namespace Timer {
Timer timer[6] = { Timer(0), Timer(1), Timer(2), Timer(3), Timer(4), Timer(5) };
Timer::Timer(uint8_t n) {
this->n = n;
if (n >= 0 && n <= 3) this->src = 54 + n;
if (n >= 4 && n <= 5) this->src = 99 - 4 + n;
module = (TimerModule*)(TMR_MODULE_BASE + n * 4);
}
void Timer::set(uint32_t interval, Mode mode, Prescaler prescaler, ClockSource source) {
/* attach interrupt handler */
interrupt::handler[src] = handler;
/* zero fill control registers */
module->TMR_CTLR_REG = 0;
module->TMR_CUR_VALUE_REG = 0;
/* Set controls: mode, prescaler and source */
module->TMR_CTLR_REG = (mode << 7) | (prescaler << 4) | (source << 2);
/* Set timer value */
module->TMR_INTV_VALUE_REG = interval;
/* Enable interrupt in GIC and set interrupt handler */
GIC::enableInterrupt(src, GIC::CPU0T, GIC::EDGE);
peripheral->TMR_IRQ_EN_REG = peripheral->TMR_IRQ_EN_REG | (1 << n);
}
void Timer::start(void) {
/* Reload interval value and start */
module->TMR_CTLR_REG = module->TMR_CTLR_REG | 0x3;
}
void Timer::stop(void) {
/* Clear stop/pause bit */
module->TMR_CTLR_REG = module->TMR_CTLR_REG & 0xfffffffe;
}
void handler(const uint8_t cpuID, const uint16_t interruptID) {
uint16_t n;
if (interruptID >= 54 && interruptID <= 57) n = interruptID - 54;
if (interruptID >= 99 && interruptID <= 100) n = interruptID - 99 + 4;
peripheral->TMR_IRQ_STA_REG = peripheral->TMR_IRQ_STA_REG | (1 << n);
}
}