diff options
author | Marti Bolivar <mbolivar@leaflabs.com> | 2012-06-02 20:36:36 -0400 |
---|---|---|
committer | Marti Bolivar <mbolivar@leaflabs.com> | 2012-06-02 20:36:36 -0400 |
commit | daa792f486ea7ce848c37eee636c73824efec396 (patch) | |
tree | 0ea89393f2344dd6027f91d8ac888e7d8c822ddd | |
parent | ff6a1e449f6e722ca33c8a0d4131574b6efc02f9 (diff) | |
download | librambutan-daa792f486ea7ce848c37eee636c73824efec396.tar.gz librambutan-daa792f486ea7ce848c37eee636c73824efec396.zip |
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 <mbolivar@leaflabs.com>
-rw-r--r-- | libmaple/include/libmaple/timer.h | 1 | ||||
-rw-r--r-- | libmaple/timer.c | 28 |
2 files changed, 29 insertions, 0 deletions
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 @@ -101,6 +101,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 * @param interrupt Interrupt number to attach to; this may be any |