diff options
-rw-r--r-- | include/arch/msp430fr5969lp/driver/timer.h | 49 | ||||
-rw-r--r-- | src/app/timertest/Makefile.inc | 3 | ||||
-rw-r--r-- | src/app/timertest/main.cc | 43 |
3 files changed, 88 insertions, 7 deletions
diff --git a/include/arch/msp430fr5969lp/driver/timer.h b/include/arch/msp430fr5969lp/driver/timer.h index 34feb12..9585a64 100644 --- a/include/arch/msp430fr5969lp/driver/timer.h +++ b/include/arch/msp430fr5969lp/driver/timer.h @@ -1,8 +1,21 @@ #include <msp430.h> +#include <stdint.h> #define ON_TIMER_INTERRUPT_head __attribute__((interrupt(TIMER0_A1_VECTOR))) __attribute__((wakeup)) void handle_timer0_overflow() { if (TA0IV == 0x0e) { #define ON_TIMER_INTERRUPT_tail } } +#if F_CPU == 16000000UL +#define _TA0_MAIN_DIV ID__8 +#elif F_CPU == 8000000UL +#define _TA0_MAIN_DIV ID__4 +#elif F_CPU == 4000000UL +#define _TA0_MAIN_DIV ID__2 +#elif F_CPU == 1000000UL +#define _TA0_MAIN_DIV ID__1 +#else +#error Unsupported F_CPU +#endif + class Timer { private: Timer(const Timer ©); @@ -10,19 +23,41 @@ class Timer { public: Timer() {} +#if F_CPU == 1000000UL + inline void setup_khz(uint16_t const frequency) { + TA0CTL = TASSEL__SMCLK | ID__1 | MC__UP; // -> 1 MHz base + TA0EX0 = 0; + TA0CCR0 = 1000UL / frequency; + TA0CTL |= TACLR; + } + + inline void setup_hz(uint16_t const frequency) { // 1 MHz base + if (frequency < 20) { + TA0CTL = TASSEL__SMCLK | ID__8 | MC__UP; // /8 + TA0EX0 = 1; // /2 -> /16 -> 62500 Hz + TA0CCR0 = 62500UL / frequency; + } else { + TA0CTL = TASSEL__SMCLK | ID__1 | MC__UP; + TA0EX0 = 0; + TA0CCR0 = 1000000UL / frequency; + } + TA0CTL |= TACLR; + } +#else inline void setup_khz(uint16_t const frequency) { - TA0CTL = TASSEL__SMCLK | ID__8 | MC__UP; - TA0EX0 = 1; - TA0CCR0 = 1000 / frequency; + TA0CTL = TASSEL__SMCLK | _TA0_MAIN_DIV | MC__UP; // -> 2 MHz base + TA0EX0 = 0; + TA0CCR0 = 2000UL / frequency; TA0CTL |= TACLR; } - inline void setup_hz(uint16_t const frequency) { - TA0CTL = TASSEL__SMCLK | ID__8 | MC__UP; - TA0EX0 = 1; - TA0CCR0 = 1000000 / frequency; + inline void setup_hz(uint16_t const frequency) { // 2 MHz base + TA0CTL = TASSEL__SMCLK | _TA0_MAIN_DIV | MC__UP; + TA0EX0 = 0; + TA0CCR0 = 2000000UL / frequency; TA0CTL |= TACLR; } +#endif inline void start(unsigned char const interrupt) { if (interrupt) { diff --git a/src/app/timertest/Makefile.inc b/src/app/timertest/Makefile.inc new file mode 100644 index 0000000..9d375f1 --- /dev/null +++ b/src/app/timertest/Makefile.inc @@ -0,0 +1,3 @@ +loop ?= 1 +timer_s ?= 1 +arch_drivers += ,timer diff --git a/src/app/timertest/main.cc b/src/app/timertest/main.cc new file mode 100644 index 0000000..23f0b60 --- /dev/null +++ b/src/app/timertest/main.cc @@ -0,0 +1,43 @@ +#include "arch.h" +#include "driver/gpio.h" +#include "driver/stdout.h" +#include "driver/timer.h" +#include "driver/uptime.h" + +#ifndef F_TIMER +#define F_TIMER 100000 +#endif + +volatile unsigned long int timer_val = 0; + +void loop(void) +{ + gpio.led_toggle(1); + kout << "Actual frequency: approx. " << timer_val << " Hz" << endl; + timer_val = 0; +} + +int main(void) +{ + arch.setup(); + gpio.setup(); + kout.setup(); +#if F_TIMER > 999 + timer.setup_khz(F_TIMER / 1000); +#else + timer.setup_hz(F_TIMER); +#endif + timer.start(1); + + gpio.led_on(0); + kout << "Timer running at " << dec << F_TIMER << " Hz" << endl; + + arch.idle_loop(); + + return 0; +} + +ON_TIMER_INTERRUPT_head + gpio.led_toggle(0); + timer_val++; +ON_TIMER_INTERRUPT_tail |