aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2012-06-02 20:36:36 -0400
committerMarti Bolivar <mbolivar@leaflabs.com>2012-06-02 20:36:36 -0400
commitdaa792f486ea7ce848c37eee636c73824efec396 (patch)
tree0ea89393f2344dd6027f91d8ac888e7d8c822ddd
parentff6a1e449f6e722ca33c8a0d4131574b6efc02f9 (diff)
downloadlibrambutan-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.h1
-rw-r--r--libmaple/timer.c28
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