From 9cefeca5c1927c34d64e592bb4ad7ffe7c44822c Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Thu, 5 Apr 2012 17:10:33 -0400 Subject: timer: Fixes, rip out nonportable bits. Fix copy-paste errors in, and add missing, register bit definitions. For copy-paste errors that would result in source incompatibilities with past releases, add some legacy defines. Add series header and C file for STM32F1 which fills in the missing API. Much of the F1 timer.c would be repeated on F2, so also add timer_private.h to hold these. Support for timers 9 through 14 is still missing. Signed-off-by: Marti Bolivar --- libmaple/timer_private.h | 168 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 libmaple/timer_private.h (limited to 'libmaple/timer_private.h') diff --git a/libmaple/timer_private.h b/libmaple/timer_private.h new file mode 100644 index 0000000..f882f51 --- /dev/null +++ b/libmaple/timer_private.h @@ -0,0 +1,168 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011, 2012 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple/timer_private.h + * @author Marti Bolivar + * @brief Private, internal timer APIs. + */ + +#ifndef _LIBMAPLE_TIMER_PRIVATE_H_ +#define _LIBMAPLE_TIMER_PRIVATE_H_ + +/* + * Devices + */ + +/* Just like the corresponding DIER bits: + * [0] = Update handler; + * [1,2,3,4] = capture/compare 1,2,3,4 handlers, respectively; + * [5] = COM; + * [6] = TRG; + * [7] = BRK. */ +#define NR_ADV_HANDLERS 8 +/* Update, capture/compare 1,2,3,4; ; trigger. */ +#define NR_GEN_HANDLERS 7 +/* Update only. */ +#define NR_BAS_HANDLERS 1 + +#define DECLARE_ADVANCED_TIMER(name, num) \ + timer_dev name = { \ + .regs = { .adv = TIMER##num##_BASE }, \ + .clk_id = RCC_TIMER##num, \ + .type = TIMER_ADVANCED, \ + .handlers = { [NR_ADV_HANDLERS - 1] = 0 }, \ + } + +#define DECLARE_GENERAL_TIMER(name, num) \ + timer_dev name = { \ + .regs = { .gen = TIMER##num##_BASE }, \ + .clk_id = RCC_TIMER##num, \ + .type = TIMER_GENERAL, \ + .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, \ + } + +#define DECLARE_BASIC_TIMER(name, num) \ + timer_dev name = { \ + .regs = { .bas = TIMER##num##_BASE }, \ + .clk_id = RCC_TIMER##num, \ + .type = TIMER_BASIC, \ + .handlers = { [NR_BAS_HANDLERS - 1] = 0 }, \ + } + +/* + * IRQ handlers + */ + +/* Note: the following dispatch routines make use of the fact that + * DIER interrupt enable bits and SR interrupt flags have common bit + * positions. Thus, ANDing DIER and SR lets us check if an interrupt + * is enabled and if it has occurred simultaneously. + */ + +/* A special-case dispatch routine for single-interrupt NVIC lines. + * This function assumes that the interrupt corresponding to `iid' has + * in fact occurred (i.e., it doesn't check DIER & SR). */ +static __always_inline void dispatch_single_irq(timer_dev *dev, + timer_interrupt_id iid, + uint32 irq_mask) { + timer_bas_reg_map *regs = (dev->regs).bas; + void (*handler)(void) = dev->handlers[iid]; + if (handler) { + handler(); + regs->SR &= ~irq_mask; + } +} + +/* For dispatch routines which service multiple interrupts. */ +#define handle_irq(dier_sr, irq_mask, handlers, iid, handled_irq) do { \ + if ((dier_sr) & (irq_mask)) { \ + void (*__handler)(void) = (handlers)[iid]; \ + if (__handler) { \ + __handler(); \ + handled_irq |= (irq_mask); \ + } \ + } \ + } while (0) + +static __always_inline void dispatch_adv_brk(timer_dev *dev) { + dispatch_single_irq(dev, TIMER_BREAK_INTERRUPT, TIMER_SR_BIF); +} + +static __always_inline void dispatch_adv_up(timer_dev *dev) { + dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF); +} + +static __always_inline void dispatch_adv_trg_com(timer_dev *dev) { + timer_adv_reg_map *regs = (dev->regs).adv; + uint32 dsr = regs->DIER & regs->SR; + void (**hs)(void) = dev->handlers; + uint32 handled = 0; /* Logical OR of SR interrupt flags we end up + * handling. We clear these. User handlers + * must clear overcapture flags, to avoid + * wasting time in output mode. */ + + handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_COMIF, hs, TIMER_COM_INTERRUPT, handled); + + regs->SR &= ~handled; +} + +static __always_inline void dispatch_adv_cc(timer_dev *dev) { + timer_adv_reg_map *regs = (dev->regs).adv; + uint32 dsr = regs->DIER & regs->SR; + void (**hs)(void) = dev->handlers; + uint32 handled = 0; + + handle_irq(dsr, TIMER_SR_CC4IF, hs, TIMER_CC4_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC3IF, hs, TIMER_CC3_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); + + regs->SR &= ~handled; +} + +static __always_inline void dispatch_general(timer_dev *dev) { + timer_gen_reg_map *regs = (dev->regs).gen; + uint32 dsr = regs->DIER & regs->SR; + void (**hs)(void) = dev->handlers; + uint32 handled = 0; + + handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC4IF, hs, TIMER_CC4_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC3IF, hs, TIMER_CC3_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled); + + regs->SR &= ~handled; +} + +static __always_inline void dispatch_basic(timer_dev *dev) { + dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF); +} + +#endif -- cgit v1.2.3 From 42059788b4fff74fddfc7d391e82c316b6901211 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Mon, 9 Apr 2012 15:14:01 -0400 Subject: libmaple/timer_private.h: Add more explanatory comments. Hopefully these will be helpful when adding timer support for additional series in the future. Signed-off-by: Marti Bolivar --- libmaple/timer_private.h | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'libmaple/timer_private.h') diff --git a/libmaple/timer_private.h b/libmaple/timer_private.h index f882f51..54e3ea1 100644 --- a/libmaple/timer_private.h +++ b/libmaple/timer_private.h @@ -34,21 +34,30 @@ #define _LIBMAPLE_TIMER_PRIVATE_H_ /* - * Devices + * Helper macros for declaring timer_devs of various timer_types */ -/* Just like the corresponding DIER bits: +/* The indexes of user handlers in a timer_dev.handlers are just like + * the corresponding DIER bits, as follows: */ + +/* Advanced timers: * [0] = Update handler; * [1,2,3,4] = capture/compare 1,2,3,4 handlers, respectively; * [5] = COM; * [6] = TRG; * [7] = BRK. */ #define NR_ADV_HANDLERS 8 -/* Update, capture/compare 1,2,3,4; ; trigger. */ +/* General purpose timers: + * [0] = update; + * [1,2,3,4] = capture/compare 1,2,3,4; + * [5] = ; + * [6] = trigger. */ #define NR_GEN_HANDLERS 7 -/* Update only. */ +/* Basic timers: + * [0] = update. */ #define NR_BAS_HANDLERS 1 +/* For declaring advanced timers. */ #define DECLARE_ADVANCED_TIMER(name, num) \ timer_dev name = { \ .regs = { .adv = TIMER##num##_BASE }, \ @@ -57,6 +66,7 @@ .handlers = { [NR_ADV_HANDLERS - 1] = 0 }, \ } +/* For declaring full-featured general purpose timers. */ #define DECLARE_GENERAL_TIMER(name, num) \ timer_dev name = { \ .regs = { .gen = TIMER##num##_BASE }, \ @@ -65,6 +75,7 @@ .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, \ } +/* For declaring basic timers (e.g. TIM6 and TIM7). */ #define DECLARE_BASIC_TIMER(name, num) \ timer_dev name = { \ .regs = { .bas = TIMER##num##_BASE }, \ @@ -75,13 +86,21 @@ /* * IRQ handlers - */ - -/* Note: the following dispatch routines make use of the fact that - * DIER interrupt enable bits and SR interrupt flags have common bit - * positions. Thus, ANDing DIER and SR lets us check if an interrupt - * is enabled and if it has occurred simultaneously. - */ + * + * These decode TIMx_DIER and TIMx_SR, then dispatch to the user-level + * IRQ handlers. They also clean up TIMx_SR afterwards, so the user + * doesn't have to deal with register details. + * + * Notes: + * + * - These dispatch routines make use of the fact that DIER interrupt + * enable bits and SR interrupt flags have common bit positions. + * Thus, ANDing DIER and SR lets us check if an interrupt is enabled + * and if it has occurred simultaneously. + * + * - We force these routines to inline to avoid call overhead, but + * there aren't any measurements to prove that this is actually a + * good idea. Profile-directed optimizations are definitely wanted. */ /* A special-case dispatch routine for single-interrupt NVIC lines. * This function assumes that the interrupt corresponding to `iid' has @@ -97,7 +116,7 @@ static __always_inline void dispatch_single_irq(timer_dev *dev, } } -/* For dispatch routines which service multiple interrupts. */ +/* Helper macro for dispatch routines which service multiple interrupts. */ #define handle_irq(dier_sr, irq_mask, handlers, iid, handled_irq) do { \ if ((dier_sr) & (irq_mask)) { \ void (*__handler)(void) = (handlers)[iid]; \ -- cgit v1.2.3 From 378a766ec86694a6be0f8e38976473646c82702c Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Mon, 9 Apr 2012 16:05:50 -0400 Subject: libmaple/timer_private.h: Update to support TIM9-TIM14. Add DECLARE_RESTRICTED_GENERAL_TIMER(), for declaring general-purpose timers with limited interrupt support -- that is, for declaring timers 9 through 14. This helps avoid wasting space on pointers to user handlers for interrupts that don't exist. Add dispatch_tim_9_12() and dispatch_tim_10_11_13_14(), which are special purpose dispatch routines for these "restricted" general purpose timers, which only try to dispatch interrupts supported by these timers. Change dispatch_single_irq() to check the logical and of the DIER and SR registers for the timer whose interrupt it's dispatching. This is necessary due to increased muxing on the timer IRQ lines caused by the new timers. See the comment in the patch for more details. This does add overhead on medium- and high-density STM32F1s, where the extra check is unnecessary, but it doesn't change dispatch_single_irq()'s semantics, and keeps the implementation simple, so we'll live with it. These changes will also work on F2 (and F4 AFAIK), which is why they're part of the global private timer API, as opposed to libmaple/stm32f1/timer.c. Signed-off-by: Marti Bolivar --- libmaple/timer_private.h | 62 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 7 deletions(-) (limited to 'libmaple/timer_private.h') diff --git a/libmaple/timer_private.h b/libmaple/timer_private.h index 54e3ea1..0eb569d 100644 --- a/libmaple/timer_private.h +++ b/libmaple/timer_private.h @@ -75,6 +75,17 @@ .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, \ } +/* For declaring general purpose timers with limited interrupt + * capability (e.g. timers 9 through 14 on STM32F2 and XL-density + * STM32F1). */ +#define DECLARE_RESTRICTED_GENERAL_TIMER(name, num, max_dier_bit) \ + timer_dev name = { \ + .regs = { .gen = TIMER##num##_BASE }, \ + .clk_id = RCC_TIMER##num, \ + .type = TIMER_GENERAL, \ + .handlers = { [max_dier_bit] = 0 }, \ + } + /* For declaring basic timers (e.g. TIM6 and TIM7). */ #define DECLARE_BASIC_TIMER(name, num) \ timer_dev name = { \ @@ -102,17 +113,24 @@ * there aren't any measurements to prove that this is actually a * good idea. Profile-directed optimizations are definitely wanted. */ -/* A special-case dispatch routine for single-interrupt NVIC lines. - * This function assumes that the interrupt corresponding to `iid' has - * in fact occurred (i.e., it doesn't check DIER & SR). */ +/* A special-case dispatch routine for timers which only serve a + * single interrupt on a given IRQ line. + * + * This function still checks DIER & SR, as in some cases, a timer may + * only serve a single interrupt on a particular NVIC line, but that + * line may be shared with another timer. For example, the timer 1 + * update interrupt shares an IRQ line with the timer 10 interrupt on + * STM32F1 (XL-density), STM32F2, and STM32F4. */ static __always_inline void dispatch_single_irq(timer_dev *dev, timer_interrupt_id iid, uint32 irq_mask) { timer_bas_reg_map *regs = (dev->regs).bas; - void (*handler)(void) = dev->handlers[iid]; - if (handler) { - handler(); - regs->SR &= ~irq_mask; + if (regs->DIER & regs->SR & irq_mask) { + void (*handler)(void) = dev->handlers[iid]; + if (handler) { + handler(); + regs->SR &= ~irq_mask; + } } } @@ -180,6 +198,36 @@ static __always_inline void dispatch_general(timer_dev *dev) { regs->SR &= ~handled; } +/* On F1 (XL-density), F2, and F4, TIM9 and TIM12 are restricted + * general-purpose timers with update, CC1, CC2, and TRG interrupts. */ +static __always_inline void dispatch_tim_9_12(timer_dev *dev) { + timer_gen_reg_map *regs = (dev->regs).gen; + uint32 dsr = regs->DIER & regs->SR; + void (**hs)(void) = dev->handlers; + uint32 handled = 0; + + handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled); + + regs->SR &= ~handled; +} + +/* On F1 (XL-density), F2, and F4, timers 10, 11, 13, and 14 are + * restricted general-purpose timers with update and CC1 interrupts. */ +static __always_inline void dispatch_tim_10_11_13_14(timer_dev *dev) { + timer_gen_reg_map *regs = (dev->regs).gen; + uint32 dsr = regs->DIER & regs->SR; + void (**hs)(void) = dev->handlers; + uint32 handled = 0; + + handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled); + + regs->SR &= ~handled; +} + static __always_inline void dispatch_basic(timer_dev *dev) { dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF); } -- cgit v1.2.3 From 0acbcb9c50d6eeb41d6036b2706a7b3d2b5e4b3c Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Thu, 7 Jun 2012 04:39:22 -0400 Subject: Tweak some timer_private APIs. The current versions of DELARE_*_TIMER() don't play well with cscope, which is a bad sign. Fix that. Signed-off-by: Marti Bolivar --- libmaple/stm32f1/timer.c | 28 ++++++++++++++-------------- libmaple/stm32f2/timer.c | 33 ++++++++++++++------------------- libmaple/timer_private.h | 16 ++++++++-------- 3 files changed, 36 insertions(+), 41 deletions(-) (limited to 'libmaple/timer_private.h') diff --git a/libmaple/stm32f1/timer.c b/libmaple/stm32f1/timer.c index 002b9d6..8671695 100644 --- a/libmaple/stm32f1/timer.c +++ b/libmaple/stm32f1/timer.c @@ -54,10 +54,10 @@ * Defer to the timer_private API. */ -static DECLARE_ADVANCED_TIMER(timer1, 1); -static DECLARE_GENERAL_TIMER(timer2, 2); -static DECLARE_GENERAL_TIMER(timer3, 3); -static DECLARE_GENERAL_TIMER(timer4, 4); +static timer_dev timer1 = ADVANCED_TIMER(1); +static timer_dev timer2 = GENERAL_TIMER(2); +static timer_dev timer3 = GENERAL_TIMER(3); +static timer_dev timer4 = GENERAL_TIMER(4); /** Timer 1 device (advanced) */ timer_dev *TIMER1 = &timer1; @@ -69,10 +69,10 @@ timer_dev *TIMER3 = &timer3; timer_dev *TIMER4 = &timer4; #if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) -static DECLARE_GENERAL_TIMER(timer5, 5); -static DECLARE_BASIC_TIMER(timer6, 6); -static DECLARE_BASIC_TIMER(timer7, 7); -static DECLARE_ADVANCED_TIMER(timer8, 8); +static timer_dev timer5 = GENERAL_TIMER(5); +static timer_dev timer6 = BASIC_TIMER(6); +static timer_dev timer7 = BASIC_TIMER(7); +static timer_dev timer8 = ADVANCED_TIMER(8); /** Timer 5 device (general-purpose) */ timer_dev *TIMER5 = &timer5; @@ -86,17 +86,17 @@ timer_dev *TIMER8 = &timer8; #ifdef STM32_XL_DENSITY /* TIM9 has UIE, CC1IE, CC2IE, TIE bits in DIER. */ -static DECLARE_RESTRICTED_GENERAL_TIMER(timer9, 9, TIMER_DIER_TIE_BIT); +static timer_dev timer9 = RESTRICTED_GENERAL_TIMER(9, TIMER_DIER_TIE_BIT); /* TIM10 has UIE, CC1IE. */ -static DECLARE_RESTRICTED_GENERAL_TIMER(timer10, 10, TIMER_DIER_CC1IE_BIT); +static timer_dev timer10 = RESTRICTED_GENERAL_TIMER(10, TIMER_DIER_CC1IE_BIT); /* TIM11 has UIE, CC1IE. */ -static DECLARE_RESTRICTED_GENERAL_TIMER(timer11, 11, TIMER_DIER_CC1IE_BIT); +static timer_dev timer11 = RESTRICTED_GENERAL_TIMER(11, TIMER_DIER_CC1IE_BIT); /* TIM12 has UIE, CC1IE, CC2IE, TIE. */ -static DECLARE_RESTRICTED_GENERAL_TIMER(timer12, 12, TIMER_DIER_TIE_BIT); +static timer_dev timer12 = RESTRICTED_GENERAL_TIMER(12, TIMER_DIER_TIE_BIT); /* TIM13 has UIE, CC1IE. */ -static DECLARE_RESTRICTED_GENERAL_TIMER(timer13, 13, TIMER_DIER_CC1IE_BIT); +static timer_dev timer13 = RESTRICTED_GENERAL_TIMER(13, TIMER_DIER_CC1IE_BIT); /* TIM14 has UIE, CC1IE. */ -static DECLARE_RESTRICTED_GENERAL_TIMER(timer14, 14, TIMER_DIER_CC1IE_BIT); +static timer_dev timer14 = RESTRICTED_GENERAL_TIMER(14, TIMER_DIER_CC1IE_BIT); /** Timer 9 device (general-purpose) */ timer_dev *TIMER9 = &timer9; diff --git a/libmaple/stm32f2/timer.c b/libmaple/stm32f2/timer.c index f644b16..99dbf48 100644 --- a/libmaple/stm32f2/timer.c +++ b/libmaple/stm32f2/timer.c @@ -39,26 +39,26 @@ * Defer to the timer_private API for declaring these. */ -static DECLARE_ADVANCED_TIMER(timer1, 1); -static DECLARE_GENERAL_TIMER(timer2, 2); -static DECLARE_GENERAL_TIMER(timer3, 3); -static DECLARE_GENERAL_TIMER(timer4, 4); -static DECLARE_GENERAL_TIMER(timer5, 5); -static DECLARE_BASIC_TIMER(timer6, 6); -static DECLARE_BASIC_TIMER(timer7, 7); -static DECLARE_ADVANCED_TIMER(timer8, 8); +static timer_dev timer1 = ADVANCED_TIMER(1); +static timer_dev timer2 = GENERAL_TIMER(2); +static timer_dev timer3 = GENERAL_TIMER(3); +static timer_dev timer4 = GENERAL_TIMER(4); +static timer_dev timer5 = GENERAL_TIMER(5); +static timer_dev timer6 = BASIC_TIMER(6); +static timer_dev timer7 = BASIC_TIMER(7); +static timer_dev timer8 = ADVANCED_TIMER(8); /* TIM9 has UIE, CC1IE, CC2IE, TIE bits in DIER. */ -static DECLARE_RESTRICTED_GENERAL_TIMER(timer9, 9, TIMER_DIER_TIE_BIT); +static timer_dev timer9 = RESTRICTED_GENERAL_TIMER(9, TIMER_DIER_TIE_BIT); /* TIM10 has UIE, CC1IE. */ -static DECLARE_RESTRICTED_GENERAL_TIMER(timer10, 10, TIMER_DIER_CC1IE_BIT); +static timer_dev timer10 = RESTRICTED_GENERAL_TIMER(10, TIMER_DIER_CC1IE_BIT); /* TIM11 has UIE, CC1IE. */ -static DECLARE_RESTRICTED_GENERAL_TIMER(timer11, 11, TIMER_DIER_CC1IE_BIT); +static timer_dev timer11 = RESTRICTED_GENERAL_TIMER(11, TIMER_DIER_CC1IE_BIT); /* TIM12 has UIE, CC1IE, CC2IE, TIE. */ -static DECLARE_RESTRICTED_GENERAL_TIMER(timer12, 12, TIMER_DIER_TIE_BIT); +static timer_dev timer12 = RESTRICTED_GENERAL_TIMER(12, TIMER_DIER_TIE_BIT); /* TIM13 has UIE, CC1IE. */ -static DECLARE_RESTRICTED_GENERAL_TIMER(timer13, 13, TIMER_DIER_CC1IE_BIT); +static timer_dev timer13 = RESTRICTED_GENERAL_TIMER(13, TIMER_DIER_CC1IE_BIT); /* TIM14 has UIE, CC1IE. */ -static DECLARE_RESTRICTED_GENERAL_TIMER(timer14, 14, TIMER_DIER_CC1IE_BIT); +static timer_dev timer14 = RESTRICTED_GENERAL_TIMER(14, TIMER_DIER_CC1IE_BIT); /** Timer 1 device (advanced) */ timer_dev *TIMER1 = &timer1; @@ -121,11 +121,6 @@ void timer_foreach(void (*fn)(timer_dev*)) { * 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 diff --git a/libmaple/timer_private.h b/libmaple/timer_private.h index 0eb569d..320c636 100644 --- a/libmaple/timer_private.h +++ b/libmaple/timer_private.h @@ -58,8 +58,8 @@ #define NR_BAS_HANDLERS 1 /* For declaring advanced timers. */ -#define DECLARE_ADVANCED_TIMER(name, num) \ - timer_dev name = { \ +#define ADVANCED_TIMER(num) \ + { \ .regs = { .adv = TIMER##num##_BASE }, \ .clk_id = RCC_TIMER##num, \ .type = TIMER_ADVANCED, \ @@ -67,8 +67,8 @@ } /* For declaring full-featured general purpose timers. */ -#define DECLARE_GENERAL_TIMER(name, num) \ - timer_dev name = { \ +#define GENERAL_TIMER(num) \ + { \ .regs = { .gen = TIMER##num##_BASE }, \ .clk_id = RCC_TIMER##num, \ .type = TIMER_GENERAL, \ @@ -78,8 +78,8 @@ /* For declaring general purpose timers with limited interrupt * capability (e.g. timers 9 through 14 on STM32F2 and XL-density * STM32F1). */ -#define DECLARE_RESTRICTED_GENERAL_TIMER(name, num, max_dier_bit) \ - timer_dev name = { \ +#define RESTRICTED_GENERAL_TIMER(num, max_dier_bit) \ + { \ .regs = { .gen = TIMER##num##_BASE }, \ .clk_id = RCC_TIMER##num, \ .type = TIMER_GENERAL, \ @@ -87,8 +87,8 @@ } /* For declaring basic timers (e.g. TIM6 and TIM7). */ -#define DECLARE_BASIC_TIMER(name, num) \ - timer_dev name = { \ +#define BASIC_TIMER(num) \ + { \ .regs = { .bas = TIMER##num##_BASE }, \ .clk_id = RCC_TIMER##num, \ .type = TIMER_BASIC, \ -- cgit v1.2.3