aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple/stm32f1
diff options
context:
space:
mode:
Diffstat (limited to 'libmaple/stm32f1')
-rw-r--r--libmaple/stm32f1/include/series/timer.h42
-rw-r--r--libmaple/stm32f1/timer.c83
2 files changed, 117 insertions, 8 deletions
diff --git a/libmaple/stm32f1/include/series/timer.h b/libmaple/stm32f1/include/series/timer.h
index 9bd273e..2551f70 100644
--- a/libmaple/stm32f1/include/series/timer.h
+++ b/libmaple/stm32f1/include/series/timer.h
@@ -33,11 +33,10 @@
#ifndef _LIBMAPLE_STM32F1_TIMER_H_
#define _LIBMAPLE_STM32F1_TIMER_H_
-#include <libmaple/libmaple.h>
-#include <series/timer.h>
+#include <libmaple/libmaple_types.h>
/*
- * Register maps and devices
+ * Register maps and base pointers
*/
/** STM32F1 general purpose timer register map type */
@@ -64,6 +63,10 @@ typedef struct timer_gen_reg_map {
__io uint32 DMAR; /**< DMA address for full transfer */
} timer_gen_reg_map;
+struct timer_adv_reg_map;
+struct timer_gen_reg_map;
+struct timer_bas_reg_map;
+
/** Timer 1 register map base pointer */
#define TIMER1_BASE ((struct timer_adv_reg_map*)0x40012C00)
/** Timer 2 register map base pointer */
@@ -72,7 +75,6 @@ typedef struct timer_gen_reg_map {
#define TIMER3_BASE ((struct timer_gen_reg_map*)0x40000400)
/** Timer 4 register map base pointer */
#define TIMER4_BASE ((struct timer_gen_reg_map*)0x40000800)
-#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
/** Timer 5 register map base pointer */
#define TIMER5_BASE ((struct timer_gen_reg_map*)0x40000C00)
/** Timer 6 register map base pointer */
@@ -81,7 +83,29 @@ typedef struct timer_gen_reg_map {
#define TIMER7_BASE ((struct timer_bas_reg_map*)0x40001400)
/** Timer 8 register map base pointer */
#define TIMER8_BASE ((struct timer_adv_reg_map*)0x40013400)
-#endif
+/** Timer 9 register map base pointer */
+#define TIMER9_BASE ((struct timer_gen_reg_map*)0x40014C00)
+/** Timer 10 register map base pointer */
+#define TIMER10_BASE ((struct timer_gen_reg_map*)0x40015000)
+/** Timer 11 register map base pointer */
+#define TIMER11_BASE ((struct timer_gen_reg_map*)0x40015400)
+/** Timer 12 register map base pointer */
+#define TIMER12_BASE ((struct timer_gen_reg_map*)0x40001800)
+/** Timer 13 register map base pointer */
+#define TIMER13_BASE ((struct timer_gen_reg_map*)0x40001C00)
+/** Timer 14 register map base pointer */
+#define TIMER14_BASE ((struct timer_gen_reg_map*)0x40002000)
+
+/*
+ * Device pointers
+ *
+ * We only declare device pointers to timers which actually exist on
+ * the target MCU. This helps when porting programs to STM32F1 (or
+ * within F1 to a lower density MCU), as attempts to use nonexistent
+ * timers cause build errors instead of undefined behavior.
+ */
+
+struct timer_dev;
extern struct timer_dev *TIMER1;
extern struct timer_dev *TIMER2;
@@ -93,5 +117,13 @@ extern struct timer_dev *TIMER6;
extern struct timer_dev *TIMER7;
extern struct timer_dev *TIMER8;
#endif
+#ifdef STM32_XL_DENSITY
+extern struct timer_dev *TIMER9;
+extern struct timer_dev *TIMER10;
+extern struct timer_dev *TIMER11;
+extern struct timer_dev *TIMER12;
+extern struct timer_dev *TIMER13;
+extern struct timer_dev *TIMER14;
+#endif
#endif
diff --git a/libmaple/stm32f1/timer.c b/libmaple/stm32f1/timer.c
index 7506cb6..899abbc 100644
--- a/libmaple/stm32f1/timer.c
+++ b/libmaple/stm32f1/timer.c
@@ -30,14 +30,30 @@
* @brief STM32F1 timer support.
*/
+/* Notes:
+ *
+ * - We use STM32F1 density test macros throughout to avoid defining
+ * symbols or linking in code that would use timers that are
+ * unavailable in a given density. For example, TIM5 doesn't exist
+ * on medium-density, and TIM9 doesn't exist on high-density, so we
+ * don't define or use TIM5 when being compiled for medium-density,
+ * and similarly for TIM9 and high-density.
+ *
+ * This makes a mess, but helps avoid bloat and ensures backwards
+ * compatibility. Since the mess is manageable and there don't seem
+ * to be any plans on ST's part to add new STM32F1 lines or
+ * densities, we'll live with it.
+ */
+
#include <libmaple/timer.h>
#include "timer_private.h"
/*
* Devices
+ *
+ * Defer to the timer_private API.
*/
-/* Use timer_private macros to save typing. */
static DECLARE_ADVANCED_TIMER(timer1, 1);
static DECLARE_GENERAL_TIMER(timer2, 2);
static DECLARE_GENERAL_TIMER(timer3, 3);
@@ -66,7 +82,35 @@ timer_dev *TIMER6 = &timer6;
timer_dev *TIMER7 = &timer7;
/** Timer 8 device (advanced) */
timer_dev *TIMER8 = &timer8;
-#endif
+#endif /* defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) */
+
+#ifdef STM32_XL_DENSITY
+/* TIM9 has UIE, CC1IE, CC2IE, TIE bits in DIER. */
+static DECLARE_RESTRICTED_GENERAL_TIMER(timer9, 9, TIMER_DIER_TIE_BIT);
+/* TIM10 has UIE, CC1IE. */
+static DECLARE_RESTRICTED_GENERAL_TIMER(timer10, 10, TIMER_DIER_CC1IE_BIT);
+/* TIM11 has UIE, CC1IE. */
+static DECLARE_RESTRICTED_GENERAL_TIMER(timer11, 11, TIMER_DIER_CC1IE_BIT);
+/* TIM12 has UIE, CC1IE, CC2IE, TIE. */
+static DECLARE_RESTRICTED_GENERAL_TIMER(timer12, 12, TIMER_DIER_TIE_BIT);
+/* TIM13 has UIE, CC1IE. */
+static DECLARE_RESTRICTED_GENERAL_TIMER(timer13, 13, TIMER_DIER_CC1IE_BIT);
+/* TIM14 has UIE, CC1IE. */
+static DECLARE_RESTRICTED_GENERAL_TIMER(timer14, 14, TIMER_DIER_CC1IE_BIT);
+
+/** Timer 9 device (general-purpose) */
+timer_dev *TIMER9 = &timer9;
+/** Timer 10 device (general-purpose) */
+timer_dev *TIMER10 = &timer10;
+/** Timer 11 device (general-purpose) */
+timer_dev *TIMER11 = &timer11;
+/** Timer 12 device (general-purpose) */
+timer_dev *TIMER12 = &timer12;
+/** Timer 13 device (general-purpose) */
+timer_dev *TIMER13 = &timer13;
+/** Timer 14 device (general-purpose) */
+timer_dev *TIMER14 = &timer14;
+#endif /* STM32_XL_DENSITY */
/*
* Routines
@@ -87,22 +131,46 @@ void timer_foreach(void (*fn)(timer_dev*)) {
fn(TIMER7);
fn(TIMER8);
#endif
+#ifdef STM32_XL_DENSITY
+ fn(TIMER9);
+ fn(TIMER10);
+ fn(TIMER11);
+ fn(TIMER12);
+ fn(TIMER13);
+ fn(TIMER14);
+#endif
}
/*
* IRQ handlers
+ *
+ * Defer to the timer_private dispatch API.
+ *
+ * FIXME: The names of these handlers are inaccurate since XL-density
+ * devices came out. Update these to match the STM32F2 names, maybe
+ * using some weak symbol magic to preserve backwards compatibility if
+ * possible.
*/
void __irq_tim1_brk(void) {
dispatch_adv_brk(TIMER1);
+#ifdef STM32_XL_DENSITY
+ dispatch_tim_9_12(TIMER9);
+#endif
}
void __irq_tim1_up(void) {
dispatch_adv_up(TIMER1);
+#ifdef STM32_XL_DENSITY
+ dispatch_tim_10_11_13_14(TIMER10);
+#endif
}
void __irq_tim1_trg_com(void) {
dispatch_adv_trg_com(TIMER1);
+#ifdef STM32_XL_DENSITY
+ dispatch_tim_10_11_13_14(TIMER11);
+#endif
}
void __irq_tim1_cc(void) {
@@ -136,17 +204,26 @@ void __irq_tim7(void) {
void __irq_tim8_brk(void) {
dispatch_adv_brk(TIMER8);
+#ifdef STM32_XL_DENSITY
+ dispatch_tim_9_12(TIMER12);
+#endif
}
void __irq_tim8_up(void) {
dispatch_adv_up(TIMER8);
+#ifdef STM32_XL_DENSITY
+ dispatch_tim_10_11_13_14(TIMER13);
+#endif
}
void __irq_tim8_trg_com(void) {
dispatch_adv_trg_com(TIMER8);
+#ifdef STM32_XL_DENSITY
+ dispatch_tim_10_11_13_14(TIMER14);
+#endif
}
void __irq_tim8_cc(void) {
dispatch_adv_cc(TIMER8);
}
-#endif
+#endif /* defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) */