diff options
Diffstat (limited to 'libmaple')
-rw-r--r-- | libmaple/timers.c | 6 | ||||
-rw-r--r-- | libmaple/timers.h | 216 |
2 files changed, 186 insertions, 36 deletions
diff --git a/libmaple/timers.c b/libmaple/timers.c index c369d1f..3a2cad7 100644 --- a/libmaple/timers.c +++ b/libmaple/timers.c @@ -289,15 +289,15 @@ void timer_set_mode(uint8 timer_num, uint8 channel, TimerMode mode) { /* This sets the compare value (aka the trigger) for a given timer * channel */ void timer_set_compare_value(uint8 timer_num, - uint8 compare_num, + uint8 channel, uint16 value) { /* The faster version of this function is the inline timer_pwm_write_ccr */ timer_port *timer = timer_dev_table[timer_num].base; - ASSERT(compare_num > 0 && compare_num <= 4); + ASSERT(channel > 0 && channel <= 4); - switch(compare_num) { + switch(channel) { case 1: timer->CCR1 = value; break; diff --git a/libmaple/timers.h b/libmaple/timers.h index d180bab..f5694ac 100644 --- a/libmaple/timers.h +++ b/libmaple/timers.h @@ -142,7 +142,7 @@ typedef enum TimerMode { TIMER_PWM, /**< This is the default mode for pins after initialization. */ TIMER_OUTPUTCOMPARE, /**< In this mode, the timer counts from 0 to - the overflow value repeatedly; every time + its reload value repeatedly; every time the counter value reaches one of the channel compare values, the corresponding interrupt is fired. */ @@ -191,8 +191,10 @@ typedef struct { uint16 RESERVED19; } timer_port; -/* timer device numbers */ -enum { +/** + * All possible timer device numbers. + */ +typedef enum { TIMER1, TIMER2, TIMER3, @@ -201,7 +203,7 @@ enum { TIMER6, // High density only; no compare TIMER7, // High density only; no compare TIMER8, // High density only -}; +} timer_num_t; /* timer descriptor */ struct timer_dev { @@ -213,37 +215,185 @@ struct timer_dev { extern struct timer_dev timer_dev_table[]; -/* Turn on timer with prescale as the divisor - * void timer_init(uint32 timer, uint16 prescale) - * timer -> {1-4} - * prescale -> {1-65535} +/** + * Turn on timer with prescale as the clock divisor. + * + * @param timer Timer number. Valid values are TIMER1, TIMER2, + * TIMER3, TIMER4, and (on high-density devices) TIMER5, TIMER8. + * + * @param prescale value in the range 1--65535 to use as a prescaler + * for timer counter increment frequency. + * + * @see timer_set_prescaler() + * @see timer_set_mode() + */ +void timer_init(uint8 timer, uint16 prescale); + +/** + * Quickly disable all timers. Calling this function is faster than, + * e.g., calling timer_set_mode() for all available timers/channels. */ -void timer_init(uint8, uint16); void timer_disable_all(void); -uint16 timer_get_count(uint8); -void timer_set_count(uint8,uint16); -void timer_pause(uint8); -void timer_resume(uint8); -void timer_set_prescaler(uint8 timer_num, uint16 prescale); -void timer_set_reload(uint8 timer_num, uint16 max_reload); -void timer_set_mode(uint8 timer_num, uint8 compare_num, uint8 mode); -void timer_set_compare_value(uint8 timer_num, uint8 compare_num, uint16 value); -void timer_attach_interrupt(uint8 timer_num, uint8 compare_num, - voidFuncPtr handler); -void timer_detach_interrupt(uint8 timer_num, uint8 compare_num); - -/* Turn on PWM with duty_cycle on the specified channel in timer. - * This function takes in a pointer to the corresponding CCR - * register for the pin cause it saves pwmWrite() a couple of - * cycles. - * - * void timer_pwm(uint8 channel, uint8 duty_cycle); - * channel -> {TIMERx_CHn_CCR} - * duty_cycle -> {0-65535} - * - * PRECONDITIONS: - * pin has been set to alternate function output - * timer has been initialized + +/** + * Returns the timer's counter value. Due to function call overhead, + * this value is likely to be inaccurate if the counter is running + * with a low prescaler. + * + * @param timer the timer whose counter to return. + */ +uint16 timer_get_count(uint8 timer); + +/** + * Sets the counter value for the given timer. + * + * @param timer the timer whose counter to set. + * + * @param value the new counter value. + */ +void timer_set_count(uint8 timer, uint16 value); + +/** + * Stops the timer's counter from incrementing. Does not modify the + * timer's mode or settings. + * + * @param timer the timer to pause. + * + * @see timer_resume() + */ +void timer_pause(uint8 timer); + +/** + * Starts the counter for the given timer. Does not modify the + * timer's mode or settings. The timer will begin counting on the + * first rising clock cycle after it has been re-enabled using this + * function. + * + * @param timer the timer to resume. + * + * @see timer_pause() + */ +void timer_resume(uint8 timer); + +/** + * Sets the prescaler for the given timer. The prescaler acts as a + * clock divider of the STM32 72MHz system clock, in that the timer's + * counter will subsequently increment with frequency equal to 72MHz / + * prescale. + * + * Note that the timer will continue with its current prescaler until + * the next time its counter reaches its overflow value, starting a + * counting cycle. The new prescale value will be in effect for that + * subsequent counting cycle. + * + * @param timer the timer whose prescaler to set. + * + * @param prescale the new prescaler, from 1--65,535. + */ +void timer_set_prescaler(uint8 timer, uint16 prescale); + +/** + * Sets the reload value for the entire timer. + * + * After this function returns, the timer's counter will reset to 0 + * after it has reached the value max_reload. + * + * @param timer the timer whose reload to set. + * + * @param max_reload the new reload value. + */ +void timer_set_reload(uint8 timer, uint16 max_reload); + +/** + * Set the mode of an individual timer channel. + * + * @param timer the timer whose channel mode to set. + * + * @param channel the channel whose mode to set (1 <= channel <= 4). + * + * @param mode the new mode value. Currently acceptable values + * include TIMER_DISABLED, TIMER_PWM, and TIMER_OUTPUTCOMPARE. Note + * that timer_disable_all() will disable all timers and all channels + * much more quickly than repeated calls to this function with mode + * TIMER_DISABLED. + * + * @see TimerMode + * + * @see timer_disable_all() + */ +void timer_set_mode(uint8 timer, uint8 channel, TimerMode mode); + +/** + * Sets the compare value for a given timer channel. Useful for + * scheduling when interrupt handlers will be called. + * + * @param timer the timer whose channel compare to set. + * + * @param channel the channel whose compare to set (1 <= channel <= 4). + * + * @param compare the new compare value. This new value must be less + * than or equal to the timer's reload value. + * + * @see timer_attach_interrupt() + * + * @see timer_detach_interrupt() + * + * @see timer_set_reload() + */ +void timer_set_compare_value(uint8 timer, uint8 channel, uint16 compare); + +/** + * Attach an interrupt handler for the given timer and channel. The + * handler will be called whenever the timer's counter reaches the + * compare value for the given timer and channel. + * + * @param timer the timer whose channel to register with an interrupt handler. + * + * @param channel the channel with which the new handler will be + * associated. timer_set_compare_value() can be used to set the value + * which the timer's counter must reach before handler is called (1 <= + * channel <= 4). + * + * @param handler the interrupt handler to call once the timer reaches + * the given channel's compare value. + * + * @pre The channel's mode must be set to TIMER_OUTPUTCOMPARE, or the + * interrupt handler will not get called. + * + * @see timer_set_compare_value() + * + * @see timer_detach_interrupt() + * + * @see timer_set_mode() + */ +void timer_attach_interrupt(uint8 timer, uint8 channel, voidFuncPtr handler); + +/** + * Detach the interrupt handler for the given timer channel, if any. + * After this function returns, any handler attached to the given + * channel will no longer be called. + * + * @param timer the timer whose channel to detach the interrupt + * handler from. + * + * @param channel the channel from which to detach the interrupt handler. + * + * @see timer_attach_interrupt() + */ +void timer_detach_interrupt(uint8 timer, uint8 channel); + +/** + * Turn on PWM with duty_cycle. + * + * @param channel TIMERx_CHn_CCR, where x goes from 1 to NR_TIMERS, + * and n goes from 1 to 4. + * + * @param duty_cycle 0--65535. duty_cycle=0 means always off; + * duty_cycle=65535 means always on. + * + * @pre Pin has been set to alternate function output. + * + * @pre Timer has been initialized. */ static inline void timer_pwm_write_ccr(TimerCCR CCR, uint16 duty_cycle) { *CCR = duty_cycle; |