git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6153 35acf78f-673a-0410-8e92-d51de3d6d3f4

master
gdisirio 2013-08-15 08:29:40 +00:00
parent 82583b0748
commit d9e22836cd
7 changed files with 79 additions and 43 deletions

View File

@ -593,10 +593,12 @@ void gpt_lld_start(GPTDriver *gptp) {
"invalid frequency"); "invalid frequency");
/* Timer configuration.*/ /* Timer configuration.*/
gptp->tim->CR1 = 0; /* Initially stopped. */ gptp->tim->CR1 = 0; /* Initially stopped. */
gptp->tim->CR2 = STM32_TIM_CR2_CCDS; /* DMA on UE (if any). */ gptp->tim->CR2 = STM32_TIM_CR2_CCDS; /* DMA on UE (if any). */
gptp->tim->PSC = psc; /* Prescaler value. */ gptp->tim->PSC = psc; /* Prescaler value. */
gptp->tim->DIER = 0; gptp->tim->DIER = gptp->config->dier & /* DMA-related DIER bits. */
STM32_TIM_DIER_IRQ_MASK;
gptp->tim->SR = 0; /* Clear pending IRQs. */
} }
/** /**
@ -609,9 +611,9 @@ void gpt_lld_start(GPTDriver *gptp) {
void gpt_lld_stop(GPTDriver *gptp) { void gpt_lld_stop(GPTDriver *gptp) {
if (gptp->state == GPT_READY) { if (gptp->state == GPT_READY) {
gptp->tim->CR1 = 0; /* Timer disabled. */ gptp->tim->CR1 = 0; /* Timer disabled. */
gptp->tim->DIER = 0; /* All IRQs disabled. */ gptp->tim->DIER = 0; /* All IRQs disabled. */
gptp->tim->SR = 0; /* Clear eventual pending IRQs. */ gptp->tim->SR = 0; /* Clear pending IRQs. */
#if STM32_GPT_USE_TIM1 #if STM32_GPT_USE_TIM1
if (&GPTD1 == gptp) { if (&GPTD1 == gptp) {
@ -698,16 +700,16 @@ void gpt_lld_stop(GPTDriver *gptp) {
*/ */
void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) { void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
gptp->tim->ARR = interval - 1; /* Time constant. */ gptp->tim->ARR = (uint32_t)(interval - 1); /* Time constant. */
gptp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */ gptp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */
gptp->tim->CNT = 0; /* Reset counter. */ gptp->tim->CNT = 0; /* Reset counter. */
/* NOTE: After generating the UG event it takes several clock cycles before /* NOTE: After generating the UG event it takes several clock cycles before
SR bit 0 goes to 1. This is because the clearing of CNT has been inserted SR bit 0 goes to 1. This is because the clearing of CNT has been inserted
before the clearing of SR, to give it some time.*/ before the clearing of SR, to give it some time.*/
gptp->tim->SR = 0; /* Clear pending IRQs (if any). */ gptp->tim->SR = 0; /* Clear pending IRQs. */
gptp->tim->DIER = STM32_TIM_DIER_UIE; /* Update Event IRQ enabled. */ gptp->tim->DIER |= STM32_TIM_DIER_UIE; /* Update Event IRQ enabled.*/
gptp->tim->CR1 = STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN; gptp->tim->CR1 = STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN;
} }
/** /**
@ -719,9 +721,11 @@ void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
*/ */
void gpt_lld_stop_timer(GPTDriver *gptp) { void gpt_lld_stop_timer(GPTDriver *gptp) {
gptp->tim->CR1 = 0; /* Initially stopped. */ gptp->tim->CR1 = 0; /* Initially stopped. */
gptp->tim->SR = 0; /* Clear pending IRQs (if any). */ gptp->tim->SR = 0; /* Clear pending IRQs. */
gptp->tim->DIER = 0; /* Interrupts disabled. */
/* All interrupts disabled.*/
gptp->tim->DIER &= ~STM32_TIM_DIER_IRQ_MASK;
} }
/** /**
@ -737,9 +741,9 @@ void gpt_lld_stop_timer(GPTDriver *gptp) {
*/ */
void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) { void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
gptp->tim->ARR = interval - 1; /* Time constant. */ gptp->tim->ARR = (uint32_t)(interval - 1); /* Time constant. */
gptp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */ gptp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */
gptp->tim->SR = 0; /* Clear pending IRQs (if any). */ gptp->tim->SR = 0; /* Clear pending IRQs. */
gptp->tim->CR1 = STM32_TIM_CR1_OPM | STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN; gptp->tim->CR1 = STM32_TIM_CR1_OPM | STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN;
while (!(gptp->tim->SR & STM32_TIM_SR_UIF)) while (!(gptp->tim->SR & STM32_TIM_SR_UIF))
; ;

View File

@ -367,7 +367,7 @@ typedef uint32_t gptfreq_t;
/** /**
* @brief GPT counter type. * @brief GPT counter type.
*/ */
typedef uint16_t gptcnt_t; typedef uint32_t gptcnt_t;
/** /**
* @brief Driver configuration structure. * @brief Driver configuration structure.
@ -386,6 +386,12 @@ typedef struct {
*/ */
gptcallback_t callback; gptcallback_t callback;
/* End of the mandatory fields.*/ /* End of the mandatory fields.*/
/**
* @brief TIM DIER register initialization data.
* @note The value of this field should normally be equal to zero.
* @note Only the DMA-related bits can be specified in this field.
*/
uint32_t dier;
} GPTConfig; } GPTConfig;
/** /**
@ -432,7 +438,7 @@ struct GPTDriver {
* @notapi * @notapi
*/ */
#define gpt_lld_change_interval(gptp, interval) \ #define gpt_lld_change_interval(gptp, interval) \
((gptp)->tim->ARR = (uint16_t)((interval) - 1)) ((gptp)->tim->ARR = (uint32_t)((interval) - 1))
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */

View File

@ -111,7 +111,7 @@ static void icu_lld_serve_interrupt(ICUDriver *icup) {
uint16_t sr; uint16_t sr;
sr = icup->tim->SR; sr = icup->tim->SR;
sr &= icup->tim->DIER; sr &= icup->tim->DIER & STM32_TIM_DIER_IRQ_MASK;
icup->tim->SR = ~sr; icup->tim->SR = ~sr;
if (icup->config->channel == ICU_CHANNEL_1) { if (icup->config->channel == ICU_CHANNEL_1) {
if ((sr & STM32_TIM_SR_CC1IF) != 0) if ((sr & STM32_TIM_SR_CC1IF) != 0)
@ -458,7 +458,8 @@ void icu_lld_start(ICUDriver *icup) {
else { else {
/* Driver re-configuration scenario, it must be stopped first.*/ /* Driver re-configuration scenario, it must be stopped first.*/
icup->tim->CR1 = 0; /* Timer disabled. */ icup->tim->CR1 = 0; /* Timer disabled. */
icup->tim->DIER = 0; /* All IRQs disabled. */ icup->tim->DIER = icup->config->dier &/* DMA-related DIER settings. */
~STM32_TIM_DIER_IRQ_MASK;
icup->tim->SR = 0; /* Clear eventual pending IRQs. */ icup->tim->SR = 0; /* Clear eventual pending IRQs. */
icup->tim->CCR[0] = 0; /* Comparator 1 disabled. */ icup->tim->CCR[0] = 0; /* Comparator 1 disabled. */
icup->tim->CCR[1] = 0; /* Comparator 2 disabled. */ icup->tim->CCR[1] = 0; /* Comparator 2 disabled. */
@ -621,9 +622,11 @@ void icu_lld_enable(ICUDriver *icup) {
*/ */
void icu_lld_disable(ICUDriver *icup) { void icu_lld_disable(ICUDriver *icup) {
icup->tim->CR1 = 0; /* Initially stopped. */ icup->tim->CR1 = 0; /* Initially stopped. */
icup->tim->SR = 0; /* Clear pending IRQs (if any). */ icup->tim->SR = 0; /* Clear pending IRQs (if any). */
icup->tim->DIER = 0; /* Interrupts disabled. */
/* All interrupts disabled.*/
icup->tim->DIER &= ~STM32_TIM_DIER_IRQ_MASK;
} }
#endif /* HAL_USE_ICU */ #endif /* HAL_USE_ICU */

View File

@ -291,6 +291,12 @@ typedef struct {
* @note Only inputs TIMx 1 and 2 are supported. * @note Only inputs TIMx 1 and 2 are supported.
*/ */
icuchannel_t channel; icuchannel_t channel;
/**
* @brief TIM DIER register initialization data.
* @note The value of this field should normally be equal to zero.
* @note Only the DMA-related bits can be specified in this field.
*/
uint32_t dier;
} ICUConfig; } ICUConfig;
/** /**

View File

@ -112,7 +112,7 @@ static void pwm_lld_serve_interrupt(PWMDriver *pwmp) {
uint16_t sr; uint16_t sr;
sr = pwmp->tim->SR; sr = pwmp->tim->SR;
sr &= pwmp->tim->DIER; sr &= pwmp->tim->DIER & STM32_TIM_DIER_IRQ_MASK;
pwmp->tim->SR = ~sr; pwmp->tim->SR = ~sr;
if ((sr & STM32_TIM_SR_CC1IF) != 0) if ((sr & STM32_TIM_SR_CC1IF) != 0)
pwmp->config->channels[0].callback(pwmp); pwmp->config->channels[0].callback(pwmp);
@ -169,9 +169,8 @@ OSAL_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) {
OSAL_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
sr = STM32_TIM1->SR & STM32_TIM1->DIER; sr = STM32_TIM1->SR & STM32_TIM1->DIER & STM32_TIM_DIER_IRQ_MASK;
STM32_TIM1->SR = ~(STM32_TIM_SR_CC1IF | STM32_TIM_SR_CC2IF | STM32_TIM1->SR = ~sr;
STM32_TIM_SR_CC3IF | STM32_TIM_SR_CC4IF);
if ((sr & STM32_TIM_SR_CC1IF) != 0) if ((sr & STM32_TIM_SR_CC1IF) != 0)
PWMD1.config->channels[0].callback(&PWMD1); PWMD1.config->channels[0].callback(&PWMD1);
if ((sr & STM32_TIM_SR_CC2IF) != 0) if ((sr & STM32_TIM_SR_CC2IF) != 0)
@ -299,9 +298,8 @@ OSAL_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) {
OSAL_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
sr = STM32_TIM8->SR & STM32_TIM8->DIER; sr = STM32_TIM8->SR & STM32_TIM8->DIER & STM32_TIM_DIER_IRQ_MASK;
STM32_TIM8->SR = ~(STM32_TIM_SR_CC1IF | STM32_TIM_SR_CC2IF | STM32_TIM8->SR = ~sr;
STM32_TIM_SR_CC3IF | STM32_TIM_SR_CC4IF);
if ((sr & STM32_TIM_SR_CC1IF) != 0) if ((sr & STM32_TIM_SR_CC1IF) != 0)
PWMD8.config->channels[0].callback(&PWMD8); PWMD8.config->channels[0].callback(&PWMD8);
if ((sr & STM32_TIM_SR_CC2IF) != 0) if ((sr & STM32_TIM_SR_CC2IF) != 0)
@ -473,7 +471,8 @@ void pwm_lld_start(PWMDriver *pwmp) {
else { else {
/* Driver re-configuration scenario, it must be stopped first.*/ /* Driver re-configuration scenario, it must be stopped first.*/
pwmp->tim->CR1 = 0; /* Timer disabled. */ pwmp->tim->CR1 = 0; /* Timer disabled. */
pwmp->tim->DIER = 0; /* All IRQs disabled. */ pwmp->tim->DIER = pwmp->config->dier &/* DMA-related DIER settings. */
~STM32_TIM_DIER_IRQ_MASK;
pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */ pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */
pwmp->tim->CCR[0] = 0; /* Comparator 1 disabled. */ pwmp->tim->CCR[0] = 0; /* Comparator 1 disabled. */
pwmp->tim->CCR[1] = 0; /* Comparator 2 disabled. */ pwmp->tim->CCR[1] = 0; /* Comparator 2 disabled. */
@ -562,19 +561,20 @@ void pwm_lld_start(PWMDriver *pwmp) {
} }
#endif /* STM32_PWM_USE_ADVANCED*/ #endif /* STM32_PWM_USE_ADVANCED*/
pwmp->tim->CCER = ccer; pwmp->tim->CCER = ccer;
pwmp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */ pwmp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */
pwmp->tim->DIER = pwmp->config->callback == NULL ? 0 : STM32_TIM_DIER_UIE; pwmp->tim->DIER |= pwmp->config->callback == NULL ? 0 : STM32_TIM_DIER_UIE;
pwmp->tim->SR = 0; /* Clear pending IRQs. */ pwmp->tim->SR = 0; /* Clear pending IRQs. */
#if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8 #if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8
#if STM32_PWM_USE_ADVANCED #if STM32_PWM_USE_ADVANCED
pwmp->tim->BDTR = pwmp->config->bdtr | STM32_TIM_BDTR_MOE; pwmp->tim->BDTR = pwmp->config->bdtr | STM32_TIM_BDTR_MOE;
#else #else
pwmp->tim->BDTR = STM32_TIM_BDTR_MOE; pwmp->tim->BDTR = STM32_TIM_BDTR_MOE;
#endif #endif
#endif #endif
/* Timer configured and started.*/ /* Timer configured and started.*/
pwmp->tim->CR1 = STM32_TIM_CR1_ARPE | STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN; pwmp->tim->CR1 = STM32_TIM_CR1_ARPE | STM32_TIM_CR1_URS |
STM32_TIM_CR1_CEN;
} }
/** /**

View File

@ -345,14 +345,20 @@ typedef struct {
* @brief TIM CR2 register initialization data. * @brief TIM CR2 register initialization data.
* @note The value of this field should normally be equal to zero. * @note The value of this field should normally be equal to zero.
*/ */
uint16_t cr2; uint32_t cr2;
#if STM32_PWM_USE_ADVANCED || defined(__DOXYGEN__) #if STM32_PWM_USE_ADVANCED || defined(__DOXYGEN__)
/** /**
* @brief TIM BDTR (break & dead-time) register initialization data. * @brief TIM BDTR (break & dead-time) register initialization data.
* @note The value of this field should normally be equal to zero. * @note The value of this field should normally be equal to zero.
*/ \ */ \
uint16_t bdtr; uint32_t bdtr;
#endif #endif
/**
* @brief TIM DIER register initialization data.
* @note The value of this field should normally be equal to zero.
* @note Only the DMA-related bits can be specified in this field.
*/
uint32_t dier;
} PWMConfig; } PWMConfig;
/** /**

View File

@ -121,6 +121,17 @@
#define STM32_TIM_DIER_CC4DE (1U << 12) #define STM32_TIM_DIER_CC4DE (1U << 12)
#define STM32_TIM_DIER_COMDE (1U << 13) #define STM32_TIM_DIER_COMDE (1U << 13)
#define STM32_TIM_DIER_TDE (1U << 14) #define STM32_TIM_DIER_TDE (1U << 14)
#define STM32_TIM_DIER_IRQ_MASK (STM32_TIM_DIER_UIE | \
STM32_TIM_DIER_CC1IE | \
STM32_TIM_DIER_CC2IE | \
STM32_TIM_DIER_CC3IE | \
STM32_TIM_DIER_CC4IE | \
STM32_TIM_DIER_COMIE | \
STM32_TIM_DIER_TIE | \
STM32_TIM_DIER_BIE | \
STM32_TIM_DIER_UDE)
/** @} */ /** @} */
/** /**