From 0d4751a2aece4ea63e493331787bf5a98da716c2 Mon Sep 17 00:00:00 2001 From: utzig Date: Mon, 17 Nov 2014 18:19:57 +0000 Subject: [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 --- os/hal/ports/AVR/pwm_lld.c | 72 +++++++++++++++++++++++++++++++++++++++++++++- os/hal/ports/AVR/pwm_lld.h | 19 ++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) (limited to 'os/hal') 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 @@ -89,6 +89,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. */ @@ -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 -- cgit v1.2.3