git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2417 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
955425572d
commit
2c644359b5
|
@ -74,23 +74,6 @@ PWMDriver PWMD4;
|
||||||
/* Driver local functions. */
|
/* Driver local functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Stops all channels.
|
|
||||||
*
|
|
||||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
|
||||||
*/
|
|
||||||
static void stop_channels(PWMDriver *pwmp) {
|
|
||||||
|
|
||||||
pwmp->pd_enabled_channels = 0; /* All channels disabled. */
|
|
||||||
pwmp->pd_tim->CCER = 0; /* Outputs disabled. */
|
|
||||||
pwmp->pd_tim->CCR1 = 0; /* Comparator 1 disabled. */
|
|
||||||
pwmp->pd_tim->CCR2 = 0; /* Comparator 2 disabled. */
|
|
||||||
pwmp->pd_tim->CCR3 = 0; /* Comparator 3 disabled. */
|
|
||||||
pwmp->pd_tim->CCR4 = 0; /* Comparator 4 disabled. */
|
|
||||||
pwmp->pd_tim->CCMR1 = 0; /* Channels 1 and 2 frozen. */
|
|
||||||
pwmp->pd_tim->CCMR2 = 0; /* Channels 3 and 4 frozen. */
|
|
||||||
}
|
|
||||||
|
|
||||||
#if STM32_PWM_USE_TIM2 || STM32_PWM_USE_TIM3 || STM32_PWM_USE_TIM4 || \
|
#if STM32_PWM_USE_TIM2 || STM32_PWM_USE_TIM3 || STM32_PWM_USE_TIM4 || \
|
||||||
defined(__DOXYGEN__)
|
defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
|
@ -283,45 +266,73 @@ void pwm_lld_init(void) {
|
||||||
void pwm_lld_start(PWMDriver *pwmp) {
|
void pwm_lld_start(PWMDriver *pwmp) {
|
||||||
uint16_t ccer;
|
uint16_t ccer;
|
||||||
|
|
||||||
|
/* Reset channels.*/
|
||||||
|
pwmp->pd_enabled_channels = 0; /* All channels disabled. */
|
||||||
|
|
||||||
if (pwmp->pd_state == PWM_STOP) {
|
if (pwmp->pd_state == PWM_STOP) {
|
||||||
/* Clock activation.*/
|
/* Clock activation and timer reset.*/
|
||||||
#if STM32_PWM_USE_TIM1
|
#if STM32_PWM_USE_TIM1
|
||||||
if (&PWMD1 == pwmp) {
|
if (&PWMD1 == pwmp) {
|
||||||
|
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
||||||
|
RCC->APB2RSTR = RCC_APB2RSTR_TIM1RST;
|
||||||
|
RCC->APB2RSTR = 0;
|
||||||
NVICEnableVector(TIM1_UP_IRQn,
|
NVICEnableVector(TIM1_UP_IRQn,
|
||||||
CORTEX_PRIORITY_MASK(STM32_PWM_PWM1_IRQ_PRIORITY));
|
CORTEX_PRIORITY_MASK(STM32_PWM_PWM1_IRQ_PRIORITY));
|
||||||
NVICEnableVector(TIM1_CC_IRQn,
|
NVICEnableVector(TIM1_CC_IRQn,
|
||||||
CORTEX_PRIORITY_MASK(STM32_PWM_PWM1_IRQ_PRIORITY));
|
CORTEX_PRIORITY_MASK(STM32_PWM_PWM1_IRQ_PRIORITY));
|
||||||
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if STM32_PWM_USE_TIM2
|
#if STM32_PWM_USE_TIM2
|
||||||
if (&PWMD2 == pwmp) {
|
if (&PWMD2 == pwmp) {
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
|
||||||
|
RCC->APB1RSTR = RCC_APB1RSTR_TIM1RST;
|
||||||
|
RCC->APB1RSTR = 0;
|
||||||
NVICEnableVector(TIM2_IRQn,
|
NVICEnableVector(TIM2_IRQn,
|
||||||
CORTEX_PRIORITY_MASK(STM32_PWM_PWM2_IRQ_PRIORITY));
|
CORTEX_PRIORITY_MASK(STM32_PWM_PWM2_IRQ_PRIORITY));
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if STM32_PWM_USE_TIM3
|
#if STM32_PWM_USE_TIM3
|
||||||
if (&PWMD3 == pwmp) {
|
if (&PWMD3 == pwmp) {
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||||
|
RCC->APB1RSTR = RCC_APB1RSTR_TIM3RST;
|
||||||
|
RCC->APB1RSTR = 0;
|
||||||
NVICEnableVector(TIM3_IRQn,
|
NVICEnableVector(TIM3_IRQn,
|
||||||
CORTEX_PRIORITY_MASK(STM32_PWM_PWM3_IRQ_PRIORITY));
|
CORTEX_PRIORITY_MASK(STM32_PWM_PWM3_IRQ_PRIORITY));
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if STM32_PWM_USE_TIM4
|
#if STM32_PWM_USE_TIM4
|
||||||
if (&PWMD4 == pwmp) {
|
if (&PWMD4 == pwmp) {
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
|
||||||
|
RCC->APB1RSTR = RCC_APB1RSTR_TIM4RST;
|
||||||
|
RCC->APB1RSTR = 0;
|
||||||
NVICEnableVector(TIM4_IRQn,
|
NVICEnableVector(TIM4_IRQn,
|
||||||
CORTEX_PRIORITY_MASK(STM32_PWM_PWM4_IRQ_PRIORITY));
|
CORTEX_PRIORITY_MASK(STM32_PWM_PWM4_IRQ_PRIORITY));
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* All channels configured in PWM1 mode with preload enabled and will
|
||||||
|
stay that way until the driver is stopped.*/
|
||||||
|
pwmp->pd_tim->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
|
||||||
|
TIM_CCMR1_OC1PE |
|
||||||
|
TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 |
|
||||||
|
TIM_CCMR1_OC2PE;
|
||||||
|
pwmp->pd_tim->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 |
|
||||||
|
TIM_CCMR2_OC3PE |
|
||||||
|
TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 |
|
||||||
|
TIM_CCMR2_OC4PE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Driver re-configuration scenario, it must be stopped first.*/
|
||||||
|
/* Really required ?????????? */
|
||||||
|
pwmp->pd_tim->CR1 = 0; /* Timer stopped. */
|
||||||
|
pwmp->pd_tim->CR2 = 0; /* Timer stopped. */
|
||||||
|
pwmp->pd_tim->SMCR = 0; /* Slave mode disabled. */
|
||||||
|
pwmp->pd_tim->CCR1 = 0; /* Comparator 1 disabled. */
|
||||||
|
pwmp->pd_tim->CCR2 = 0; /* Comparator 2 disabled. */
|
||||||
|
pwmp->pd_tim->CCR3 = 0; /* Comparator 3 disabled. */
|
||||||
|
pwmp->pd_tim->CCR4 = 0; /* Comparator 4 disabled. */
|
||||||
}
|
}
|
||||||
/* Reset channels.*/
|
|
||||||
stop_channels(pwmp);
|
|
||||||
|
|
||||||
/* Configuration or reconfiguration.*/
|
/* Timer configuration.*/
|
||||||
pwmp->pd_tim->CR1 = 0; /* Timer stopped. */
|
|
||||||
pwmp->pd_tim->SMCR = 0; /* Slave mode disabled. */
|
|
||||||
pwmp->pd_tim->CR2 = pwmp->pd_config->pc_cr2;
|
pwmp->pd_tim->CR2 = pwmp->pd_config->pc_cr2;
|
||||||
pwmp->pd_tim->PSC = pwmp->pd_config->pc_psc;
|
pwmp->pd_tim->PSC = pwmp->pd_config->pc_psc;
|
||||||
pwmp->pd_tim->CNT = 0;
|
pwmp->pd_tim->CNT = 0;
|
||||||
|
@ -365,8 +376,8 @@ void pwm_lld_start(PWMDriver *pwmp) {
|
||||||
pwmp->pd_tim->SR = 0; /* Clear pending IRQs. */
|
pwmp->pd_tim->SR = 0; /* Clear pending IRQs. */
|
||||||
pwmp->pd_tim->DIER = pwmp->pd_config->pc_callback == NULL ? 0 : TIM_DIER_UIE;
|
pwmp->pd_tim->DIER = pwmp->pd_config->pc_callback == NULL ? 0 : TIM_DIER_UIE;
|
||||||
pwmp->pd_tim->BDTR = TIM_BDTR_MOE;
|
pwmp->pd_tim->BDTR = TIM_BDTR_MOE;
|
||||||
pwmp->pd_tim->CR1 = TIM_CR1_ARPE | TIM_CR1_URS |
|
/* Timer configured and started.*/
|
||||||
TIM_CR1_CEN; /* Timer configured and started.*/
|
pwmp->pd_tim->CR1 = TIM_CR1_ARPE | TIM_CR1_URS | TIM_CR1_CEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -379,10 +390,18 @@ void pwm_lld_start(PWMDriver *pwmp) {
|
||||||
void pwm_lld_stop(PWMDriver *pwmp) {
|
void pwm_lld_stop(PWMDriver *pwmp) {
|
||||||
/* If in ready state then disables the PWM clock.*/
|
/* If in ready state then disables the PWM clock.*/
|
||||||
if (pwmp->pd_state == PWM_READY) {
|
if (pwmp->pd_state == PWM_READY) {
|
||||||
stop_channels(pwmp);
|
pwmp->pd_enabled_channels = 0; /* All channels disabled. */
|
||||||
pwmp->pd_tim->CR1 = 0;
|
pwmp->pd_tim->CR1 = 0;
|
||||||
pwmp->pd_tim->BDTR = 0;
|
pwmp->pd_tim->CR2 = 0;
|
||||||
pwmp->pd_tim->DIER = 0;
|
pwmp->pd_tim->CCER = 0; /* Outputs disabled. */
|
||||||
|
pwmp->pd_tim->CCR1 = 0; /* Comparator 1 disabled. */
|
||||||
|
pwmp->pd_tim->CCR2 = 0; /* Comparator 2 disabled. */
|
||||||
|
pwmp->pd_tim->CCR3 = 0; /* Comparator 3 disabled. */
|
||||||
|
pwmp->pd_tim->CCR4 = 0; /* Comparator 4 disabled. */
|
||||||
|
pwmp->pd_tim->BDTR = 0;
|
||||||
|
pwmp->pd_tim->DIER = 0;
|
||||||
|
pwmp->pd_tim->SR = 0;
|
||||||
|
pwmp->pd_tim->EGR = TIM_EGR_UG; /* Update event. */
|
||||||
|
|
||||||
#if STM32_PWM_USE_TIM1
|
#if STM32_PWM_USE_TIM1
|
||||||
if (&PWMD1 == pwmp) {
|
if (&PWMD1 == pwmp) {
|
||||||
|
@ -425,58 +444,15 @@ void pwm_lld_enable_channel(PWMDriver *pwmp,
|
||||||
pwmchannel_t channel,
|
pwmchannel_t channel,
|
||||||
pwmcnt_t width) {
|
pwmcnt_t width) {
|
||||||
|
|
||||||
switch (channel) {
|
*(&pwmp->pd_tim->CCR1 + (channel * 2)) = width; /* New duty cycle. */
|
||||||
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) {
|
if ((pwmp->pd_enabled_channels & (1 << channel)) == 0) {
|
||||||
/* The channel is not enabled yet.*/
|
/* The channel is not enabled yet.*/
|
||||||
pwmp->pd_enabled_channels |= (1 << channel);
|
pwmp->pd_enabled_channels |= (1 << channel);
|
||||||
/* Setup the comparator, the channel is configured as PWM mode 1 with
|
/* If there is a callback associated to the channel then the proper
|
||||||
preload enabled.*/
|
interrupt is cleared and enabled.*/
|
||||||
switch (channel) {
|
if (pwmp->pd_config->pc_channels[0].pcc_callback) {
|
||||||
case 0:
|
pwmp->pd_tim->SR = ~(2 << channel);
|
||||||
pwmp->pd_tim->CCMR1 = (pwmp->pd_tim->CCMR1 & 0xFF00) |
|
pwmp->pd_tim->DIER |= (2 << channel);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,29 +467,9 @@ void pwm_lld_enable_channel(PWMDriver *pwmp,
|
||||||
*/
|
*/
|
||||||
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
|
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
|
||||||
|
|
||||||
|
*(&pwmp->pd_tim->CCR1 + (channel * 2)) = 0;
|
||||||
|
pwmp->pd_tim->DIER = ~(2 << channel);
|
||||||
pwmp->pd_enabled_channels &= ~(1 << 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;
|
|
||||||
pwmp->pd_tim->DIER &= ~TIM_DIER_CC1IE;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
pwmp->pd_tim->CCR2 = 0;
|
|
||||||
pwmp->pd_tim->CCMR1 = pwmp->pd_tim->CCMR1 & 0x00FF;
|
|
||||||
pwmp->pd_tim->DIER &= ~TIM_DIER_CC2IE;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
pwmp->pd_tim->CCR3 = 0;
|
|
||||||
pwmp->pd_tim->CCMR2 = pwmp->pd_tim->CCMR2 & 0xFF00;
|
|
||||||
pwmp->pd_tim->DIER &= ~TIM_DIER_CC3IE;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
pwmp->pd_tim->CCR4 = 0;
|
|
||||||
pwmp->pd_tim->CCMR2 = pwmp->pd_tim->CCMR2 & 0x00FF;
|
|
||||||
pwmp->pd_tim->DIER &= ~TIM_DIER_CC4IE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAL_USE_PWM */
|
#endif /* HAL_USE_PWM */
|
||||||
|
|
Loading…
Reference in New Issue