summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/arch/stm32f446re-nucleo/driver/counter.h35
-rw-r--r--src/arch/stm32f446re-nucleo/arch.cc39
-rw-r--r--src/arch/stm32f446re-nucleo/driver/counter.cc14
3 files changed, 75 insertions, 13 deletions
diff --git a/include/arch/stm32f446re-nucleo/driver/counter.h b/include/arch/stm32f446re-nucleo/driver/counter.h
new file mode 100644
index 0000000..6cb329e
--- /dev/null
+++ b/include/arch/stm32f446re-nucleo/driver/counter.h
@@ -0,0 +1,35 @@
+#ifndef COUNTER_H
+#define COUNTER_H
+
+#include <libopencm3/stm32/timer.h>
+
+#include "arch.h"
+
+typedef uint32_t counter_value_t;
+typedef uint32_t counter_overflow_t;
+
+class Counter {
+ private:
+ Counter(const Counter &copy);
+
+ public:
+ counter_value_t value;
+ volatile counter_overflow_t overflow;
+
+ Counter() : overflow(0) {}
+
+ inline void start() {
+ overflow = 0;
+ timer_set_counter(TIM2, 0);
+ timer_enable_counter(TIM2);
+ }
+
+ inline void stop() {
+ timer_disable_counter(TIM2);
+ value = timer_get_counter(TIM2);
+ }
+};
+
+extern Counter counter;
+
+#endif
diff --git a/src/arch/stm32f446re-nucleo/arch.cc b/src/arch/stm32f446re-nucleo/arch.cc
index 4634088..c0e2710 100644
--- a/src/arch/stm32f446re-nucleo/arch.cc
+++ b/src/arch/stm32f446re-nucleo/arch.cc
@@ -12,24 +12,36 @@ void Arch::setup(void)
{
// NUCLEO-F443RE uses 8MHz STLINK clock as input
rcc_clock_setup_pll(&rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_168MHZ]);
-#ifdef WITH_LOOP
+
+ // counter
rcc_periph_clock_enable(RCC_TIM2);
nvic_enable_irq(NVIC_TIM2_IRQ);
rcc_periph_reset_pulse(RST_TIM2);
+ timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT,
+ TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
+ timer_set_prescaler(TIM2, 0);
+ timer_disable_preload(TIM2);
+ timer_continuous_mode(TIM2);
+ timer_set_period(TIM2, 4294967295);
+ timer_enable_irq(TIM2, TIM_DIER_UIE);
+#ifdef WITH_LOOP
+ rcc_periph_clock_enable(RCC_TIM3);
+ nvic_enable_irq(NVIC_TIM3_IRQ);
+ rcc_periph_reset_pulse(RST_TIM3);
- timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT,
+
+ timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT,
TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
// 10 kHz timer frequency
- timer_set_prescaler(TIM2, ((rcc_apb1_frequency * 2) / 10000));
+ timer_set_prescaler(TIM3, ((rcc_apb1_frequency * 2) / 10000));
- timer_disable_preload(TIM2); // ?
- timer_continuous_mode(TIM2); // ?
+ timer_continuous_mode(TIM3); // ?
- timer_set_period(TIM2, 10000);
+ timer_set_period(TIM3, 10000);
- timer_enable_counter(TIM2);
- timer_enable_irq(TIM2, TIM_DIER_UIE);
+ timer_enable_counter(TIM3);
+ timer_enable_irq(TIM3, TIM_DIER_UIE);
#endif
}
@@ -42,9 +54,10 @@ extern void loop();
volatile char run_loop = 0;
#endif
+// for 168 MHz
void Arch::delay_us(unsigned int const us)
{
- volatile int x = us * 2;
+ volatile int x = us * 37;
while (x--) {
__asm("nop");
}
@@ -52,7 +65,7 @@ void Arch::delay_us(unsigned int const us)
void Arch::delay_ms(unsigned int const ms)
{
for (unsigned int i = 0; i < ms; i++) {
- volatile int x = 2000;
+ volatile int x = 37325; // delays approx. x*4 cycles
while (x--) {
__asm("nop");
}
@@ -86,10 +99,10 @@ Arch arch;
#include "driver/uptime.h"
-void tim2_isr(void)
+void tim3_isr(void)
{
- if (timer_get_flag(TIM2, TIM_SR_UIF)) {
- timer_clear_flag(TIM2, TIM_SR_UIF);
+ if (timer_get_flag(TIM3, TIM_SR_UIF)) {
+ timer_clear_flag(TIM3, TIM_SR_UIF);
#ifdef WITH_LOOP
run_loop = 1;
#endif
diff --git a/src/arch/stm32f446re-nucleo/driver/counter.cc b/src/arch/stm32f446re-nucleo/driver/counter.cc
new file mode 100644
index 0000000..dfd22e3
--- /dev/null
+++ b/src/arch/stm32f446re-nucleo/driver/counter.cc
@@ -0,0 +1,14 @@
+#include "arch.h"
+#include "driver/counter.h"
+
+Counter counter;
+
+void tim2_isr(void)
+{
+ if (timer_get_flag(TIM2, TIM_SR_UIF)) {
+ timer_clear_flag(TIM2, TIM_SR_UIF);
+ if (counter.overflow < 4294967295) {
+ counter.overflow++;
+ }
+ }
+}