STM32 PWM driver done.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1440 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
ce5974e5de
commit
3dea38d954
|
@ -29,14 +29,41 @@
|
||||||
|
|
||||||
#if CH_HAL_USE_PWM || defined(__DOXYGEN__)
|
#if CH_HAL_USE_PWM || defined(__DOXYGEN__)
|
||||||
|
|
||||||
/** @brief PWM1 driver identifier.*/
|
/*===========================================================================*/
|
||||||
|
/* Low Level Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PWM1 driver identifier.
|
||||||
|
* @note The driver PWM1 allocates the complex timer TIM1 when enabled.
|
||||||
|
*/
|
||||||
#if defined(USE_STM32_PWM1) || defined(__DOXYGEN__)
|
#if defined(USE_STM32_PWM1) || defined(__DOXYGEN__)
|
||||||
PWMDriver PWMD1;
|
PWMDriver PWMD1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/**
|
||||||
/* Low Level Driver exported variables. */
|
* @brief PWM2 driver identifier.
|
||||||
/*===========================================================================*/
|
* @note The driver PWM2 allocates the timer TIM2 when enabled.
|
||||||
|
*/
|
||||||
|
#if defined(USE_STM32_PWM2) || defined(__DOXYGEN__)
|
||||||
|
PWMDriver PWMD2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PWM3 driver identifier.
|
||||||
|
* @note The driver PWM3 allocates the timer TIM3 when enabled.
|
||||||
|
*/
|
||||||
|
#if defined(USE_STM32_PWM3) || defined(__DOXYGEN__)
|
||||||
|
PWMDriver PWMD3;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PWM4 driver identifier.
|
||||||
|
* @note The driver PWM4 allocates the timer TIM4 when enabled.
|
||||||
|
*/
|
||||||
|
#if defined(USE_STM32_PWM4) || defined(__DOXYGEN__)
|
||||||
|
PWMDriver PWMD4;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Low Level Driver local variables. */
|
/* Low Level Driver local variables. */
|
||||||
|
@ -63,6 +90,30 @@ void stop_channels(PWMDriver *pwmp) {
|
||||||
pwmp->pd_tim->CCMR2 = 0; /* Channels 3 and 4 frozen. */
|
pwmp->pd_tim->CCMR2 = 0; /* Channels 3 and 4 frozen. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Common TIM2...TIM4 IRQ 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.
|
||||||
|
*/
|
||||||
|
static void serve_interrupt(PWMDriver *pwmp) {
|
||||||
|
uint16_t sr;
|
||||||
|
|
||||||
|
sr = pwmp->pd_tim->SR & pwmp->pd_tim->DIER;
|
||||||
|
pwmp->pd_tim->SR = ~(TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF |
|
||||||
|
TIM_SR_CC4IF | TIM_SR_UIF);
|
||||||
|
if ((sr & TIM_SR_CC1IF) != 0)
|
||||||
|
pwmp->pd_config->pc_channels[0].pcc_callback();
|
||||||
|
if ((sr & TIM_SR_CC2IF) != 0)
|
||||||
|
pwmp->pd_config->pc_channels[1].pcc_callback();
|
||||||
|
if ((sr & TIM_SR_CC3IF) != 0)
|
||||||
|
pwmp->pd_config->pc_channels[2].pcc_callback();
|
||||||
|
if ((sr & TIM_SR_CC4IF) != 0)
|
||||||
|
pwmp->pd_config->pc_channels[3].pcc_callback();
|
||||||
|
if ((sr & TIM_SR_UIF) != 0)
|
||||||
|
pwmp->pd_config->pc_callback();
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Low Level Driver interrupt handlers. */
|
/* Low Level Driver interrupt handlers. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -110,6 +161,48 @@ CH_IRQ_HANDLER(VectorAC) {
|
||||||
}
|
}
|
||||||
#endif /* USE_STM32_PWM1 */
|
#endif /* USE_STM32_PWM1 */
|
||||||
|
|
||||||
|
#if USE_STM32_PWM2
|
||||||
|
/**
|
||||||
|
* @brief TIM2 interrupt handler.
|
||||||
|
*/
|
||||||
|
CH_IRQ_HANDLER(VectorB0) {
|
||||||
|
|
||||||
|
CH_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
serve_interrupt(&PWMD2);
|
||||||
|
|
||||||
|
CH_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif /* USE_STM32_PWM2 */
|
||||||
|
|
||||||
|
#if USE_STM32_PWM3
|
||||||
|
/**
|
||||||
|
* @brief TIM3 interrupt handler.
|
||||||
|
*/
|
||||||
|
CH_IRQ_HANDLER(VectorB4) {
|
||||||
|
|
||||||
|
CH_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
serve_interrupt(&PWMD3);
|
||||||
|
|
||||||
|
CH_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif /* USE_STM32_PWM3 */
|
||||||
|
|
||||||
|
#if USE_STM32_PWM4
|
||||||
|
/**
|
||||||
|
* @brief TIM4 interrupt handler.
|
||||||
|
*/
|
||||||
|
CH_IRQ_HANDLER(VectorB8) {
|
||||||
|
|
||||||
|
CH_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
serve_interrupt(&PWMD4);
|
||||||
|
|
||||||
|
CH_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif /* USE_STM32_PWM4 */
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Low Level Driver exported functions. */
|
/* Low Level Driver exported functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -130,6 +223,38 @@ void pwm_lld_init(void) {
|
||||||
PWMD1.pd_tim = TIM1;
|
PWMD1.pd_tim = TIM1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if USE_STM32_PWM2
|
||||||
|
/* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/
|
||||||
|
RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST;
|
||||||
|
RCC->APB1RSTR = 0;
|
||||||
|
|
||||||
|
/* Driver initialization.*/
|
||||||
|
pwmObjectInit(&PWMD2);
|
||||||
|
PWMD2.pd_enabled_channels = 0;
|
||||||
|
PWMD2.pd_tim = TIM2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_STM32_PWM3
|
||||||
|
/* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/
|
||||||
|
RCC->APB1RSTR = RCC_APB1RSTR_TIM3RST;
|
||||||
|
RCC->APB1RSTR = 0;
|
||||||
|
|
||||||
|
/* Driver initialization.*/
|
||||||
|
pwmObjectInit(&PWMD3);
|
||||||
|
PWMD3.pd_enabled_channels = 0;
|
||||||
|
PWMD3.pd_tim = TIM3;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_STM32_PWM4
|
||||||
|
/* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/
|
||||||
|
RCC->APB1RSTR = RCC_APB1RSTR_TIM4RST;
|
||||||
|
RCC->APB1RSTR = 0;
|
||||||
|
|
||||||
|
/* Driver initialization.*/
|
||||||
|
pwmObjectInit(&PWMD4);
|
||||||
|
PWMD4.pd_enabled_channels = 0;
|
||||||
|
PWMD4.pd_tim = TIM4;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -148,6 +273,24 @@ void pwm_lld_start(PWMDriver *pwmp) {
|
||||||
NVICEnableVector(TIM1_CC_IRQn, STM32_PWM1_IRQ_PRIORITY);
|
NVICEnableVector(TIM1_CC_IRQn, STM32_PWM1_IRQ_PRIORITY);
|
||||||
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if USE_STM32_PWM2
|
||||||
|
if (&PWMD2 == pwmp) {
|
||||||
|
NVICEnableVector(TIM2_IRQn, STM32_PWM2_IRQ_PRIORITY);
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if USE_STM32_PWM3
|
||||||
|
if (&PWMD3 == pwmp) {
|
||||||
|
NVICEnableVector(TIM3_IRQn, STM32_PWM3_IRQ_PRIORITY);
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if USE_STM32_PWM4
|
||||||
|
if (&PWMD4 == pwmp) {
|
||||||
|
NVICEnableVector(TIM4_IRQn, STM32_PWM4_IRQ_PRIORITY);
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/* Reset channels.*/
|
/* Reset channels.*/
|
||||||
|
@ -222,6 +365,24 @@ void pwm_lld_stop(PWMDriver *pwmp) {
|
||||||
NVICDisableVector(TIM1_CC_IRQn);
|
NVICDisableVector(TIM1_CC_IRQn);
|
||||||
RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN;
|
RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if USE_STM32_PWM2
|
||||||
|
if (&PWMD2 == pwmp) {
|
||||||
|
NVICDisableVector(TIM2_IRQn);
|
||||||
|
RCC->APB1ENR &= ~RCC_APB1ENR_TIM2EN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if USE_STM32_PWM3
|
||||||
|
if (&PWMD3 == pwmp) {
|
||||||
|
NVICDisableVector(TIM3_IRQn);
|
||||||
|
RCC->APB1ENR &= ~RCC_APB1ENR_TIM3EN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if USE_STM32_PWM2
|
||||||
|
if (&PWMD4 == pwmp) {
|
||||||
|
NVICDisableVector(TIM4_IRQn);
|
||||||
|
RCC->APB1ENR &= ~RCC_APB1ENR_TIM4EN;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,33 @@
|
||||||
#define USE_STM32_PWM1 TRUE
|
#define USE_STM32_PWM1 TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PWM2 driver enable switch.
|
||||||
|
* @details If set to @p TRUE the support for PWM2 is included.
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#if !defined(USE_STM32_PWM2) || defined(__DOXYGEN__)
|
||||||
|
#define USE_STM32_PWM2 TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PWM3 driver enable switch.
|
||||||
|
* @details If set to @p TRUE the support for PWM3 is included.
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#if !defined(USE_STM32_PWM3) || defined(__DOXYGEN__)
|
||||||
|
#define USE_STM32_PWM3 TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PWM4 driver enable switch.
|
||||||
|
* @details If set to @p TRUE the support for PWM4 is included.
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#if !defined(USE_STM32_PWM4) || defined(__DOXYGEN__)
|
||||||
|
#define USE_STM32_PWM4 TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief PWM1 interrupt priority level setting.
|
* @brief PWM1 interrupt priority level setting.
|
||||||
* @note @p BASEPRI_KERNEL >= @p STM32_PWM1_IRQ_PRIORITY > @p PRIORITY_PENDSV.
|
* @note @p BASEPRI_KERNEL >= @p STM32_PWM1_IRQ_PRIORITY > @p PRIORITY_PENDSV.
|
||||||
|
@ -59,6 +86,38 @@
|
||||||
#define STM32_PWM1_IRQ_PRIORITY 0x80
|
#define STM32_PWM1_IRQ_PRIORITY 0x80
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PWM2 interrupt priority level setting.
|
||||||
|
* @note @p BASEPRI_KERNEL >= @p STM32_PWM2_IRQ_PRIORITY > @p PRIORITY_PENDSV.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_PWM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_PWM2_IRQ_PRIORITY 0x80
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PWM3 interrupt priority level setting.
|
||||||
|
* @note @p BASEPRI_KERNEL >= @p STM32_PWM3_IRQ_PRIORITY > @p PRIORITY_PENDSV.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_PWM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_PWM3_IRQ_PRIORITY 0x80
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PWM4 interrupt priority level setting.
|
||||||
|
* @note @p BASEPRI_KERNEL >= @p STM32_PWM4_IRQ_PRIORITY > @p PRIORITY_PENDSV.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_PWM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_PWM4_IRQ_PRIORITY 0x80
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Configuration checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if USE_STM32_PWM4 && defined(STM32F10X_LD)
|
||||||
|
#error "TIM4 not present in low density STM32 devices"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver data structures and types. */
|
/* Driver data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -154,6 +213,18 @@ typedef struct {
|
||||||
extern PWMDriver PWMD1;
|
extern PWMDriver PWMD1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_STM32_PWM2)
|
||||||
|
extern PWMDriver PWMD2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_STM32_PWM3)
|
||||||
|
extern PWMDriver PWMD3;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_STM32_PWM4)
|
||||||
|
extern PWMDriver PWMD4;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,6 +29,10 @@
|
||||||
|
|
||||||
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
|
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Low Level Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#if USE_STM32_USART1 || defined(__DOXYGEN__)
|
#if USE_STM32_USART1 || defined(__DOXYGEN__)
|
||||||
/** @brief USART1 serial driver identifier.*/
|
/** @brief USART1 serial driver identifier.*/
|
||||||
SerialDriver SD1;
|
SerialDriver SD1;
|
||||||
|
@ -44,6 +48,10 @@ SerialDriver SD2;
|
||||||
SerialDriver SD3;
|
SerialDriver SD3;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Low Level Driver local variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/** @brief Driver default configuration.*/
|
/** @brief Driver default configuration.*/
|
||||||
static const SerialDriverConfig default_config =
|
static const SerialDriverConfig default_config =
|
||||||
{
|
{
|
||||||
|
|
|
@ -107,7 +107,7 @@
|
||||||
#define USART_CR2_STOP1P5_BITS (3 << 12) /**< @brief CR2 1.5 stop bit value.*/
|
#define USART_CR2_STOP1P5_BITS (3 << 12) /**< @brief CR2 1.5 stop bit value.*/
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver data structures. */
|
/* Driver data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue