aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorutzig <utzig@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-11-17 18:19:57 +0000
committerutzig <utzig@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-11-17 18:19:57 +0000
commit0d4751a2aece4ea63e493331787bf5a98da716c2 (patch)
tree82806ee1d1fb7ca9fa1010583492f32047a1b821 /os/hal
parent0f253d11b622ca6a0408f7edbc26ec6553f34178 (diff)
downloadChibiOS-0d4751a2aece4ea63e493331787bf5a98da716c2.tar.gz
ChibiOS-0d4751a2aece4ea63e493331787bf5a98da716c2.tar.bz2
ChibiOS-0d4751a2aece4ea63e493331787bf5a98da716c2.zip
[AVR] Updated PWM driver for 3.0 compatibility
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7519 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/ports/AVR/pwm_lld.c72
-rw-r--r--os/hal/ports/AVR/pwm_lld.h19
2 files changed, 90 insertions, 1 deletions
diff --git a/os/hal/ports/AVR/pwm_lld.c b/os/hal/ports/AVR/pwm_lld.c
index 7a5dc014e..14d78739a 100644
--- a/os/hal/ports/AVR/pwm_lld.c
+++ b/os/hal/ports/AVR/pwm_lld.c
@@ -305,30 +305,35 @@ void pwm_lld_init(void)
{
#if AVR_PWM_USE_TIM1 || defined(__DOXYGEN__)
pwmObjectInit(&PWMD1);
+ PWMD1.channels = PWM_CHANNELS;
TCCR1A = (1 << WGM11) | (1 << WGM10);
TCCR1B = (0 << WGM13) | (1 << WGM12);
#endif
#if AVR_PWM_USE_TIM2 || defined(__DOXYGEN__)
pwmObjectInit(&PWMD2);
+ PWMD2.channels = PWM_CHANNELS;
TCCR2A = (1 << WGM21) | (1 << WGM20);
TCCR2B = (0 << WGM22);
#endif
#if AVR_PWM_USE_TIM3 || defined(__DOXYGEN__)
pwmObjectInit(&PWMD3);
+ PWMD3.channels = PWM_CHANNELS;
TCCR3A = (1 << WGM31) | (1 << WGM30);
TCCR3B = (0 << WGM33) | (1 << WGM32);
#endif
#if AVR_PWM_USE_TIM4 || defined(__DOXYGEN__)
pwmObjectInit(&PWMD4);
+ PWMD4.channels = PWM_CHANNELS;
TCCR4A = (1 << WGM41) | (1 << WGM40);
TCCR4B = (0 << WGM43) | (1 << WGM42);
#endif
#if AVR_PWM_USE_TIM5 || defined(__DOXYGEN__)
pwmObjectInit(&PWMD5);
+ PWMD5.channels = PWM_CHANNELS;
TCCR5A = (1 << WGM51) | (1 << WGM50);
TCCR5B = (0 << WGM53) | (1 << WGM52);
#endif
@@ -355,9 +360,10 @@ void pwm_lld_start(PWMDriver *pwmp)
}
#endif
+ uint8_t i = timer_index(pwmp);
+
/* TODO: support other prescaler options */
- uint8_t i = timer_index(pwmp);
*regs_table[i].tccrb &= ~(1 << CS11);
*regs_table[i].tccrb |= (1 << CS12) | (1 << CS10);
*regs_table[i].timsk = (1 << TOIE1);
@@ -490,6 +496,70 @@ void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel)
*regs_table[i].timsk &= ~(1 << (channel + 1));
}
+/**
+ * @brief Enables the periodic activation edge notification.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @note If the notification is already enabled then the call has no effect.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ *
+ * @notapi
+ */
+void pwm_lld_enable_periodic_notification(PWMDriver *pwmp) {
+ uint8_t i = timer_index(pwmp);
+ *regs_table[i].timsk |= (1 << TOIE1);
+}
+
+/**
+ * @brief Disables the periodic activation edge notification.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @note If the notification is already disabled then the call has no effect.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ *
+ * @notapi
+ */
+void pwm_lld_disable_periodic_notification(PWMDriver *pwmp) {
+ uint8_t i = timer_index(pwmp);
+ *regs_table[i].timsk &= ~(1 << TOIE1);
+}
+
+/**
+ * @brief Enables a channel de-activation edge notification.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @pre The channel must have been activated using @p pwmEnableChannel().
+ * @note If the notification is already enabled then the call has no effect.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] channel PWM channel identifier (0...channels-1)
+ *
+ * @notapi
+ */
+void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
+ pwmchannel_t channel) {
+ uint8_t i = timer_index(pwmp);
+ *regs_table[i].timsk |= (1 << (channel + 1));
+}
+
+/**
+ * @brief Disables a channel de-activation edge notification.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @pre The channel must have been activated using @p pwmEnableChannel().
+ * @note If the notification is already disabled then the call has no effect.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] channel PWM channel identifier (0...channels-1)
+ *
+ * @notapi
+ */
+void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
+ pwmchannel_t channel) {
+
+ uint8_t i = timer_index(pwmp);
+ *regs_table[i].timsk &= ~(1 << (channel + 1));
+}
+
+
#endif /* HAL_USE_PWM */
/** @} */
diff --git a/os/hal/ports/AVR/pwm_lld.h b/os/hal/ports/AVR/pwm_lld.h
index eb72f05da..e11ac6a10 100644
--- a/os/hal/ports/AVR/pwm_lld.h
+++ b/os/hal/ports/AVR/pwm_lld.h
@@ -90,6 +90,11 @@ typedef uint8_t pwmmode_t;
typedef uint8_t pwmchannel_t;
/**
+ * @brief Type of a channels mask.
+ */
+typedef uint8_t pwmchnmsk_t;
+
+/**
* @brief PWM counter type.
*/
typedef uint16_t pwmcnt_t;
@@ -162,6 +167,14 @@ struct PWMDriver {
* @brief Current PWM period in ticks.
*/
pwmcnt_t period;
+ /**
+ * @brief Mask of the enabled channels.
+ */
+ pwmchnmsk_t enabled;
+ /**
+ * @brief Number of channels in this instance.
+ */
+ pwmchannel_t channels;
#if defined(PWM_DRIVER_EXT_FIELDS)
PWM_DRIVER_EXT_FIELDS
#endif
@@ -203,6 +216,12 @@ extern "C" {
pwmchannel_t channel,
pwmcnt_t width);
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
+ void pwm_lld_enable_periodic_notification(PWMDriver *pwmp);
+ void pwm_lld_disable_periodic_notification(PWMDriver *pwmp);
+ void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
+ pwmchannel_t channel);
+ void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
+ pwmchannel_t channel);
#ifdef __cplusplus
}
#endif