git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1425 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
ba37ee4f4b
commit
494cd0f095
|
@ -46,10 +46,64 @@ PWMDriver PWMD1;
|
|||
/* Low Level Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Stops all channels.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
*/
|
||||
void stop_channels(PWMDriver *pwmp) {
|
||||
|
||||
pwmp->pd_enabled_channels = 0; /* All channels disabled. */
|
||||
pwmp->pd_tim->CCER = 0; /* Outputs disabled. */
|
||||
pwmp->pd_tim->CCMR1 = 0; /* Channels 1 and 2 frozen. */
|
||||
pwmp->pd_tim->CCMR2 = 0; /* Channels 3 and 4 frozen. */
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if USE_STM32_PWM1
|
||||
/**
|
||||
* @brief TIM1 update interrupt handler.
|
||||
* @note It is assumed that this interrupt is only activated if the callback
|
||||
* pointer is not equal to @p NULL in order to not perform an extra
|
||||
* check in a potentially critical interrupt handler.
|
||||
*/
|
||||
CH_IRQ_HANDLER(VectorA4) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
PWMD1.pd_config->pc_callback();
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM1 compare interrupt handler.
|
||||
* @note It is assumed that the various sources are only activated if the
|
||||
* associated callback pointer is not equal to @p NULL in order to not
|
||||
* perform an extra check in a potentially critical interrupt handler.
|
||||
*/
|
||||
CH_IRQ_HANDLER(VectorAC) {
|
||||
uint16_t sr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
sr = TIM1->SR;
|
||||
TIM1->SR &= ~(TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF | TIM_SR_CC4IF);
|
||||
if ((sr & TIM_SR_CC1IF) != 0)
|
||||
PWMD1.pd_channel_configs[0]->pcc_callback();
|
||||
if ((sr & TIM_SR_CC2IF) != 0)
|
||||
PWMD1.pd_channel_configs[1]->pcc_callback();
|
||||
if ((sr & TIM_SR_CC3IF) != 0)
|
||||
PWMD1.pd_channel_configs[2]->pcc_callback();
|
||||
if ((sr & TIM_SR_CC4IF) != 0)
|
||||
PWMD1.pd_channel_configs[3]->pcc_callback();
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif /* USE_STM32_PWM1 */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
@ -66,6 +120,8 @@ void pwm_lld_init(void) {
|
|||
|
||||
/* Driver initialization.*/
|
||||
pwmObjectInit(&PWMD1);
|
||||
PWMD1.pd_enabled_channels = 0;
|
||||
PWMD1.pd_tim = TIM1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -81,12 +137,28 @@ void pwm_lld_start(PWMDriver *pwmp) {
|
|||
/* Clock activation.*/
|
||||
#if USE_STM32_PWM1
|
||||
if (&PWMD1 == pwmp) {
|
||||
NVICEnableVector(TIM1_UP_IRQn, STM32_PWM1_IRQ_PRIORITY);
|
||||
NVICEnableVector(TIM1_CC_IRQn, STM32_PWM1_IRQ_PRIORITY);
|
||||
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* Configuration.*/
|
||||
/* Reset channels.*/
|
||||
stop_channels(pwmp);
|
||||
|
||||
/* Configuration or reconfiguration.*/
|
||||
pwmp->pd_tim->CR1 = pwmp->pd_config->pc_cr1;
|
||||
pwmp->pd_tim->CR2 = pwmp->pd_config->pc_cr2;
|
||||
pwmp->pd_tim->PSC = pwmp->pd_config->pc_psc;
|
||||
pwmp->pd_tim->ARR = pwmp->pd_config->pc_arr;
|
||||
pwmp->pd_tim->CNT = 0;
|
||||
pwmp->pd_tim->EGR = TIM_EGR_UG; /* Update event. */
|
||||
pwmp->pd_tim->SR = 0; /* Clear pending IRQs. */
|
||||
if (pwmp->pd_config->pc_callback == NULL)
|
||||
pwmp->pd_tim->DIER = 0; /* No IRQs. */
|
||||
else
|
||||
pwmp->pd_tim->DIER = TIM_DIER_UIE; /* IRQ on update event. */
|
||||
pwmp->pd_tim->CR1 |= TIM_CR1_CEN; /* Starts the timer. */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,11 +172,16 @@ void pwm_lld_stop(PWMDriver *pwmp) {
|
|||
if (pwmp->pd_state == PWM_READY) {
|
||||
#if USE_STM32_PWM1
|
||||
if (&PWMD1 == pwmp) {
|
||||
NVICDisableVector(TIM1_UP_IRQn);
|
||||
NVICDisableVector(TIM1_CC_IRQn);
|
||||
RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
stop_channels(pwmp);
|
||||
pwmp->pd_tim->CR1 = 0;
|
||||
pwmp->pd_tim->DIER = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -85,6 +85,24 @@ typedef struct {
|
|||
*/
|
||||
pwmcallback_t pc_callback;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief TIM PSC (pre-scaler) register initialization data.
|
||||
*/
|
||||
uint16_t pc_psc;
|
||||
/**
|
||||
* @brief TIM ARR (auto-reload) register initialization data.
|
||||
*/
|
||||
uint16_t pc_arr;
|
||||
/**
|
||||
* @brief TIM CR1 register initialization data.
|
||||
* @note The value of this field should normally be equal to zero.
|
||||
*/
|
||||
uint16_t pc_cr1;
|
||||
/**
|
||||
* @brief TIM CR2 register initialization data.
|
||||
* @note The value of this field should normally be equal to zero.
|
||||
*/
|
||||
uint16_t pc_cr2;
|
||||
} PWMConfig;
|
||||
|
||||
/**
|
||||
|
@ -126,6 +144,10 @@ typedef struct {
|
|||
* @brief Bit mask of the enabled channels.
|
||||
*/
|
||||
uint32_t pd_enabled_channels;
|
||||
/**
|
||||
* @brief Pointer to the TIMx registers block.
|
||||
*/
|
||||
TIM_TypeDef *pd_tim;
|
||||
} PWMDriver;
|
||||
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -88,6 +88,9 @@ void pwmStop(PWMDriver *pwmp) {
|
|||
|
||||
/**
|
||||
* @brief Setups a PWM channel.
|
||||
* @details Associates a configuration to a PWM channel, this operation is
|
||||
* required before a channel can be enabled using
|
||||
* @p pwmEnableChannel().
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier
|
||||
|
@ -123,7 +126,8 @@ void pwmEnableChannel(PWMDriver *pwmp,
|
|||
"pwmEnableChannel");
|
||||
|
||||
chSysLock();
|
||||
chDbgAssert(pwmp->pd_state == PWM_READY,
|
||||
chDbgAssert((pwmp->pd_state == PWM_READY) &&
|
||||
(pwmp->pd_channel_configs[channel] != NULL),
|
||||
"pwmEnableChannel(), #1", "invalid state");
|
||||
pwm_lld_enable_channel(pwmp, channel, width);
|
||||
chSysUnlock();
|
||||
|
@ -143,7 +147,8 @@ void pwmDisableChannel(PWMDriver *pwmp, pwmchannel_t channel) {
|
|||
"pwmEnableChannel");
|
||||
|
||||
chSysLock();
|
||||
chDbgAssert(pwmp->pd_state == PWM_READY,
|
||||
chDbgAssert((pwmp->pd_state == PWM_READY) &&
|
||||
(pwmp->pd_channel_configs[channel] != NULL),
|
||||
"pwmDisableChannel(), #1", "invalid state");
|
||||
pwm_lld_disable_channel(pwmp, channel);
|
||||
chSysUnlock();
|
||||
|
|
Loading…
Reference in New Issue