aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/include/pwm.h4
-rw-r--r--os/hal/platforms/STM32/pwm_lld.c173
-rw-r--r--os/hal/platforms/STM32/pwm_lld.h7
-rw-r--r--os/hal/src/pwm.c13
-rw-r--r--os/hal/templates/pwm_lld.c30
-rw-r--r--os/hal/templates/pwm_lld.h7
6 files changed, 104 insertions, 130 deletions
diff --git a/os/hal/include/pwm.h b/os/hal/include/pwm.h
index 867cc1de6..ff1ba575f 100644
--- a/os/hal/include/pwm.h
+++ b/os/hal/include/pwm.h
@@ -82,7 +82,7 @@ typedef enum {
* @iclass
*/
#define pwmEnableChannelI(pwmp, channel, width) { \
- pwm_lld_enable_channel(pwmp, channel, width); \
+ pwm_lld_set_channel(pwmp, channel, width); \
}
/**
@@ -97,7 +97,7 @@ typedef enum {
* @iclass
*/
#define pwmDisableChannelI(pwmp, channel) { \
- pwm_lld_disable_channel(pwmp, channel); \
+ pwm_lld_set_channel(pwmp, channel, 0); \
}
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/pwm_lld.c b/os/hal/platforms/STM32/pwm_lld.c
index 335c0c8bd..f3588123a 100644
--- a/os/hal/platforms/STM32/pwm_lld.c
+++ b/os/hal/platforms/STM32/pwm_lld.c
@@ -414,115 +414,102 @@ void pwm_lld_stop(PWMDriver *pwmp) {
}
/**
- * @brief Enables a PWM channel.
+ * @brief Disables, enables or reprograms a PWM channel.
*
* @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1])
- * @param[in] width PWM pulse width as clock pulses number
+ * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
+ * @param[in] width PWM pulse width as clock pulses number, note that
+ * specifying zero disables the channel and enforces
+ * the output to the idle state.
*
* @notapi
*/
-void pwm_lld_enable_channel(PWMDriver *pwmp,
- pwmchannel_t channel,
- pwmcnt_t width) {
-
- /*
- * Changes the pulse width.
- */
- switch (channel) {
- case 0:
- pwmp->pd_tim->CCR1 = width;
- break;
- case 1:
- pwmp->pd_tim->CCR2 = width;
- break;
- case 2:
- pwmp->pd_tim->CCR3 = width;
- break;
- case 3:
- pwmp->pd_tim->CCR4 = width;
- break;
- }
- if ((pwmp->pd_enabled_channels & (1 << channel)) == 0) {
- /*
- * The channel is not enabled yet.
- */
- pwmp->pd_enabled_channels |= (1 << channel);
- /*
- * Setup the comparator, the channel is configured as PWM mode 1 with
- * preload enabled.
- */
+void pwm_lld_set_channel(PWMDriver *pwmp,
+ pwmchannel_t channel,
+ pwmcnt_t width) {
+
+ if (width == 0) {
+ /* Channel disable mode.*/
+ pwmp->pd_enabled_channels &= ~(1 << channel);
switch (channel) {
case 0:
- pwmp->pd_tim->CCMR1 = (pwmp->pd_tim->CCMR1 & 0xFF00) |
- TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
- TIM_CCMR1_OC1PE;
- pwmp->pd_tim->SR = ~TIM_SR_CC1IF;
- pwmp->pd_tim->DIER |= pwmp->pd_config->pc_channels[0].pcc_callback == NULL
- ? 0 : TIM_DIER_CC1IE;
+ pwmp->pd_tim->CCR1 = 0;
+ pwmp->pd_tim->CCMR1 = (pwmp->pd_tim->CCMR1 & 0xFF00) | TIM_CCMR1_OC1M_2;
+ pwmp->pd_tim->DIER &= ~TIM_DIER_CC1IE;
break;
case 1:
- pwmp->pd_tim->CCMR1 = (pwmp->pd_tim->CCMR1 & 0x00FF) |
- TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 |
- TIM_CCMR1_OC2PE;
- pwmp->pd_tim->SR = ~TIM_SR_CC2IF;
- pwmp->pd_tim->DIER |= pwmp->pd_config->pc_channels[1].pcc_callback == NULL
- ? 0 : TIM_DIER_CC2IE;
+ pwmp->pd_tim->CCR2 = 0;
+ pwmp->pd_tim->CCMR1 = (pwmp->pd_tim->CCMR1 & 0x00FF) | TIM_CCMR1_OC2M_2;
+ pwmp->pd_tim->DIER &= ~TIM_DIER_CC2IE;
break;
case 2:
- pwmp->pd_tim->CCMR2 = (pwmp->pd_tim->CCMR2 & 0xFF00) |
- TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 |
- TIM_CCMR2_OC3PE;
- pwmp->pd_tim->SR = ~TIM_SR_CC3IF;
- pwmp->pd_tim->DIER |= pwmp->pd_config->pc_channels[2].pcc_callback == NULL
- ? 0 : TIM_DIER_CC3IE;
+ pwmp->pd_tim->CCR3 = 0;
+ pwmp->pd_tim->CCMR2 = (pwmp->pd_tim->CCMR2 & 0xFF00) | TIM_CCMR2_OC3M_2;
+ pwmp->pd_tim->DIER &= ~TIM_DIER_CC3IE;
break;
case 3:
- pwmp->pd_tim->CCMR2 = (pwmp->pd_tim->CCMR2 & 0x00FF) |
- TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 |
- TIM_CCMR2_OC4PE;
- pwmp->pd_tim->SR = ~TIM_SR_CC4IF;
- pwmp->pd_tim->DIER |= pwmp->pd_config->pc_channels[3].pcc_callback == NULL
- ? 0 : TIM_DIER_CC4IE;
+ pwmp->pd_tim->CCR4 = 0;
+ pwmp->pd_tim->CCMR2 = (pwmp->pd_tim->CCMR2 & 0x00FF) | TIM_CCMR2_OC4M_2;
+ pwmp->pd_tim->DIER &= ~TIM_DIER_CC4IE;
break;
}
}
-}
-
-/**
- * @brief Disables a PWM channel.
- * @details The channel is disabled and its output line returned to the
- * idle state.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1])
- *
- * @notapi
- */
-void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
-
- pwmp->pd_enabled_channels &= ~(1 << channel);
- switch (channel) {
- case 0:
- pwmp->pd_tim->CCR1 = 0;
- pwmp->pd_tim->CCMR1 = (pwmp->pd_tim->CCMR1 & 0xFF00) | TIM_CCMR1_OC1M_2;
- pwmp->pd_tim->DIER &= ~TIM_DIER_CC1IE;
- break;
- case 1:
- pwmp->pd_tim->CCR2 = 0;
- pwmp->pd_tim->CCMR1 = (pwmp->pd_tim->CCMR1 & 0x00FF) | TIM_CCMR1_OC2M_2;
- pwmp->pd_tim->DIER &= ~TIM_DIER_CC2IE;
- break;
- case 2:
- pwmp->pd_tim->CCR3 = 0;
- pwmp->pd_tim->CCMR2 = (pwmp->pd_tim->CCMR2 & 0xFF00) | TIM_CCMR2_OC3M_2;
- pwmp->pd_tim->DIER &= ~TIM_DIER_CC3IE;
- break;
- case 3:
- pwmp->pd_tim->CCR4 = 0;
- pwmp->pd_tim->CCMR2 = (pwmp->pd_tim->CCMR2 & 0x00FF) | TIM_CCMR2_OC4M_2;
- pwmp->pd_tim->DIER &= ~TIM_DIER_CC4IE;
- break;
+ else {
+ /* Channel enable or reprogram mode.*/
+ switch (channel) {
+ case 0:
+ pwmp->pd_tim->CCR1 = width;
+ break;
+ case 1:
+ pwmp->pd_tim->CCR2 = width;
+ break;
+ case 2:
+ pwmp->pd_tim->CCR3 = width;
+ break;
+ case 3:
+ pwmp->pd_tim->CCR4 = width;
+ break;
+ }
+ if ((pwmp->pd_enabled_channels & (1 << channel)) == 0) {
+ /* The channel is not enabled yet.*/
+ pwmp->pd_enabled_channels |= (1 << channel);
+ /* Setup the comparator, the channel is configured as PWM mode 1 with
+ preload enabled.*/
+ switch (channel) {
+ case 0:
+ pwmp->pd_tim->CCMR1 = (pwmp->pd_tim->CCMR1 & 0xFF00) |
+ TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
+ TIM_CCMR1_OC1PE;
+ pwmp->pd_tim->SR = ~TIM_SR_CC1IF;
+ pwmp->pd_tim->DIER |= pwmp->pd_config->pc_channels[0].pcc_callback == NULL
+ ? 0 : TIM_DIER_CC1IE;
+ break;
+ case 1:
+ pwmp->pd_tim->CCMR1 = (pwmp->pd_tim->CCMR1 & 0x00FF) |
+ TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 |
+ TIM_CCMR1_OC2PE;
+ pwmp->pd_tim->SR = ~TIM_SR_CC2IF;
+ pwmp->pd_tim->DIER |= pwmp->pd_config->pc_channels[1].pcc_callback == NULL
+ ? 0 : TIM_DIER_CC2IE;
+ break;
+ case 2:
+ pwmp->pd_tim->CCMR2 = (pwmp->pd_tim->CCMR2 & 0xFF00) |
+ TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 |
+ TIM_CCMR2_OC3PE;
+ pwmp->pd_tim->SR = ~TIM_SR_CC3IF;
+ pwmp->pd_tim->DIER |= pwmp->pd_config->pc_channels[2].pcc_callback == NULL
+ ? 0 : TIM_DIER_CC3IE;
+ break;
+ case 3:
+ pwmp->pd_tim->CCMR2 = (pwmp->pd_tim->CCMR2 & 0x00FF) |
+ TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 |
+ TIM_CCMR2_OC4PE;
+ pwmp->pd_tim->SR = ~TIM_SR_CC4IF;
+ pwmp->pd_tim->DIER |= pwmp->pd_config->pc_channels[3].pcc_callback == NULL
+ ? 0 : TIM_DIER_CC4IE;
+ break;
+ }
+ }
}
}
diff --git a/os/hal/platforms/STM32/pwm_lld.h b/os/hal/platforms/STM32/pwm_lld.h
index 194e60b48..4c3b99e4d 100644
--- a/os/hal/platforms/STM32/pwm_lld.h
+++ b/os/hal/platforms/STM32/pwm_lld.h
@@ -344,10 +344,9 @@ extern "C" {
void pwm_lld_init(void);
void pwm_lld_start(PWMDriver *pwmp);
void pwm_lld_stop(PWMDriver *pwmp);
- void pwm_lld_enable_channel(PWMDriver *pwmp,
- pwmchannel_t channel,
- pwmcnt_t width);
- void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
+ void pwm_lld_set_channel(PWMDriver *pwmp,
+ pwmchannel_t channel,
+ pwmcnt_t width);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/src/pwm.c b/os/hal/src/pwm.c
index 79cc73b30..ecf9eba3f 100644
--- a/os/hal/src/pwm.c
+++ b/os/hal/src/pwm.c
@@ -117,8 +117,9 @@ void pwmStop(PWMDriver *pwmp) {
* @details Programs (or reprograms) a PWM channel.
*
* @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1])
- * @param[in] width PWM pulse width as clock pulses number
+ * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
+ * @param[in] width PWM pulse width as clock pulses number, setting the
+ * width at zero is equivalent to disabling the channel
*
* @api
*/
@@ -132,17 +133,17 @@ void pwmEnableChannel(PWMDriver *pwmp,
chSysLock();
chDbgAssert(pwmp->pd_state == PWM_READY,
"pwmEnableChannel(), #1", "not ready");
- pwm_lld_enable_channel(pwmp, channel, width);
+ pwm_lld_set_channel(pwmp, channel, width);
chSysUnlock();
}
/**
- * @brief Disables a PWM channel.
+ * @brief Disables a PWM channel.
* @details The channel is disabled and its output line returned to the
* idle state.
*
* @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1])
+ * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
*
* @api
*/
@@ -154,7 +155,7 @@ void pwmDisableChannel(PWMDriver *pwmp, pwmchannel_t channel) {
chSysLock();
chDbgAssert(pwmp->pd_state == PWM_READY,
"pwmDisableChannel(), #1", "not ready");
- pwm_lld_disable_channel(pwmp, channel);
+ pwm_lld_set_channel(pwmp, channel, 0);
chSysUnlock();
}
diff --git a/os/hal/templates/pwm_lld.c b/os/hal/templates/pwm_lld.c
index 4f9aab29b..5a4838ade 100644
--- a/os/hal/templates/pwm_lld.c
+++ b/os/hal/templates/pwm_lld.c
@@ -102,31 +102,19 @@ bool_t pwm_lld_is_enabled(PWMDriver *pwmp, pwmchannel_t channel) {
}
/**
- * @brief Enables a PWM channel.
+ * @brief Disables, enables or reprograms a PWM channel.
*
- * @param[in] pwmp pointer to the @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1])
- * @param[in] width PWM pulse width as clock pulses number
- *
- * @notapi
- */
-void pwm_lld_enable_channel(PWMDriver *pwmp,
- pwmchannel_t channel,
- pwmcnt_t width) {
-
-}
-
-/**
- * @brief Disables a PWM channel.
- * @details The channel is disabled and its output line returned to the
- * idle state.
- *
- * @param[in] pwmp pointer to the @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1])
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
+ * @param[in] width PWM pulse width as clock pulses number, note that
+ * specifying zero disables the channel and enforces
+ * the output to the idle state.
*
* @notapi
*/
-void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
+void pwm_lld_set_channel(PWMDriver *pwmp,
+ pwmchannel_t channel,
+ pwmcnt_t width) {
}
diff --git a/os/hal/templates/pwm_lld.h b/os/hal/templates/pwm_lld.h
index 2b8cf294f..3e81959e7 100644
--- a/os/hal/templates/pwm_lld.h
+++ b/os/hal/templates/pwm_lld.h
@@ -195,10 +195,9 @@ extern "C" {
void pwm_lld_start(PWMDriver *pwmp);
void pwm_lld_stop(PWMDriver *pwmp);
bool_t pwm_lld_is_enabled(PWMDriver *pwmp, pwmchannel_t channel);
- void pwm_lld_enable_channel(PWMDriver *pwmp,
- pwmchannel_t channel,
- pwmcnt_t width);
- void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
+ void pwm_lld_set_channel(PWMDriver *pwmp,
+ pwmchannel_t channel,
+ pwmcnt_t width);
#ifdef __cplusplus
}
#endif