From daa792f486ea7ce848c37eee636c73824efec396 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Sat, 2 Jun 2012 20:36:36 -0400 Subject: Add timer_has_cc_channel(). This is a convenience function for deciding whether a timer supports a particular capture/compare channel. It's necessary because of those nuisance "general purpose" timers that only have a subset of the channels. Signed-off-by: Marti Bolivar --- libmaple/include/libmaple/timer.h | 1 + libmaple/timer.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) (limited to 'libmaple') diff --git a/libmaple/include/libmaple/timer.h b/libmaple/include/libmaple/timer.h index 887b7eb..5d9650c 100644 --- a/libmaple/include/libmaple/timer.h +++ b/libmaple/include/libmaple/timer.h @@ -599,6 +599,7 @@ void timer_init(timer_dev *dev); void timer_disable(timer_dev *dev); void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode); void timer_foreach(void (*fn)(timer_dev*)); +int timer_has_cc_channel(timer_dev *dev, uint8 channel); /** * @brief Timer interrupt number. diff --git a/libmaple/timer.c b/libmaple/timer.c index d204fef..cd9448a 100644 --- a/libmaple/timer.c +++ b/libmaple/timer.c @@ -100,6 +100,34 @@ void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) { } } +/** + * @brief Determine whether a timer has a particular capture/compare channel. + * + * Different timers have different numbers of capture/compare channels + * (and some have none at all). Use this function to test whether a + * given timer/channel combination will work. + * + * @param dev Timer device + * @param channel Capture/compare channel, from 1 to 4 + * @return Nonzero if dev has channel, zero otherwise. + */ +int timer_has_cc_channel(timer_dev *dev, uint8 channel) { + /* On all currently supported series: advanced and "full-featured" + * general purpose timers have all four channels. Of the + * restricted general timers, timers 9 and 12 have channels 1 and + * 2; the others have channel 1 only. Basic timers have none. */ + rcc_clk_id id = dev->clk_id; + ASSERT((1 <= channel) && (channel <= 4)); + if (id <= RCC_TIMER5 || id == RCC_TIMER8) { + return 1; /* 1 and 8 are advanced, 2-5 are "full" general */ + } else if (id <= RCC_TIMER7) { + return 0; /* 6 and 7 are basic */ + } + /* The rest are restricted general. */ + return (((id == RCC_TIMER9 || id == RCC_TIMER12) && channel <= 2) || + channel == 1); +} + /** * @brief Attach a timer interrupt. * @param dev Timer device -- cgit v1.2.3