aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmaple/stm32f2/include/series/timer.h7
-rw-r--r--libmaple/stm32f2/timer.c45
-rw-r--r--wirish/stm32f2/wirish_digital.cpp32
3 files changed, 53 insertions, 31 deletions
diff --git a/libmaple/stm32f2/include/series/timer.h b/libmaple/stm32f2/include/series/timer.h
index 0d959d0..ed473b4 100644
--- a/libmaple/stm32f2/include/series/timer.h
+++ b/libmaple/stm32f2/include/series/timer.h
@@ -34,6 +34,7 @@
#define _LIBMAPLE_STM32F2_TIMER_H_
#include <libmaple/libmaple_types.h>
+#include <libmaple/gpio.h> /* for gpio_af */
/*
* Register maps and base pointers
@@ -167,4 +168,10 @@ extern struct timer_dev *TIMER12;
extern struct timer_dev *TIMER13;
extern struct timer_dev *TIMER14;
+/*
+ * Routines
+ */
+
+gpio_af timer_get_af(struct timer_dev *dev);
+
#endif
diff --git a/libmaple/stm32f2/timer.c b/libmaple/stm32f2/timer.c
index 3f9a8d2..f644b16 100644
--- a/libmaple/stm32f2/timer.c
+++ b/libmaple/stm32f2/timer.c
@@ -114,6 +114,51 @@ void timer_foreach(void (*fn)(timer_dev*)) {
fn(TIMER14);
}
+/**
+ * @brief Get the GPIO alternate function corresponding to a timer.
+ *
+ * For example, if dev is TIMER1, this function returns
+ * GPIO_AF_TIM_1_2. This is useful for e.g. using gpio_set_af() to set
+ * a pin's alternate function to a timer.
+ *
+ * Note that the timer gpio_afs are shared with other timers (and
+ * sometimes with CAN). For example, timers 1 and 2 both use
+ * GPIO_AF_TIM_1_2. Because of that, it can pay to e.g not point two
+ * timers at the same pin.
+ *
+ * @param dev Timer device, must not be TIMER6 or TIMER7.
+ * @return gpio_af corresponding to dev
+ * @see gpio_set_af
+ * @see gpio_af
+ */
+gpio_af timer_get_af(timer_dev *dev) {
+ rcc_clk_id clk_id = dev->clk_id;
+ /* Timers 6 and 7 don't have any capture/compare, so they can't do
+ * PWM (and in fact have no AF values). */
+ ASSERT(clk_id != RCC_TIMER6 && clk_id != RCC_TIMER7);
+ switch(dev->clk_id) {
+ case RCC_TIMER1: // fall-through
+ case RCC_TIMER2:
+ return GPIO_AF_TIM_1_2;
+ case RCC_TIMER3: // fall-through
+ case RCC_TIMER4: // ...
+ case RCC_TIMER5:
+ return GPIO_AF_TIM_3_4_5;
+ case RCC_TIMER8: // fall-through
+ case RCC_TIMER9: // ...
+ case RCC_TIMER10: // ...
+ case RCC_TIMER11:
+ return GPIO_AF_TIM_8_9_10_11;
+ case RCC_TIMER12: // fall-through
+ case RCC_TIMER13: // ...
+ case RCC_TIMER14:
+ return GPIO_AF_CAN_1_2_TIM_12_13_14;
+ default:
+ ASSERT(0); // Can't happen
+ return (gpio_af)-1;
+ }
+}
+
/*
* IRQ handlers
*
diff --git a/wirish/stm32f2/wirish_digital.cpp b/wirish/stm32f2/wirish_digital.cpp
index bf9dcf5..4d46f1c 100644
--- a/wirish/stm32f2/wirish_digital.cpp
+++ b/wirish/stm32f2/wirish_digital.cpp
@@ -91,37 +91,7 @@ void pinMode(uint8 pin, WiringPinMode w_mode) {
if (info->timer_device == NULL) {
return;
}
- gpio_af timer_af;
- /* TODO make this code a <libmaple/timer.h> convenience
- * routine for series that support GPIO alternate
- * functions. */
- switch(info->timer_device->clk_id) {
- case RCC_TIMER1: // fall-through
- case RCC_TIMER2:
- timer_af = GPIO_AF_TIM_1_2;
- break;
- case RCC_TIMER3: // fall-through
- case RCC_TIMER4: // ...
- case RCC_TIMER5:
- timer_af = GPIO_AF_TIM_3_4_5;
- break;
- /* Timers 6 and 7 don't have any capture/compare, so they
- * can't do PWM (and in fact have no AF values). */
- case RCC_TIMER8: // fall-through
- case RCC_TIMER9: // ...
- case RCC_TIMER10: // ...
- case RCC_TIMER11:
- timer_af = GPIO_AF_TIM_8_9_10_11;
- break;
- case RCC_TIMER12: // fall-through
- case RCC_TIMER13: // ...
- case RCC_TIMER14:
- timer_af = GPIO_AF_CAN_1_2_TIM_12_13_14;
- break;
- default:
- ASSERT(0); // Can't happen
- return;
- }
+ gpio_af timer_af = timer_get_af(info->timer_device);
timer_set_mode(info->timer_device, info->timer_channel, TIMER_PWM);
gpio_set_af(info->gpio_device, info->gpio_bit, timer_af);
}