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

master
gdisirio 2013-08-11 14:20:52 +00:00
parent 094e7be39a
commit 3fb6b81233
12 changed files with 89 additions and 3640 deletions

View File

@ -26,7 +26,6 @@
* @{ * @{
*/ */
#include "ch.h"
#include "hal.h" #include "hal.h"
#if HAL_USE_ICU || defined(__DOXYGEN__) #if HAL_USE_ICU || defined(__DOXYGEN__)
@ -145,13 +144,13 @@ static void icu_lld_serve_interrupt(ICUDriver *icup) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD1); icu_lld_serve_interrupt(&ICUD1);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#if !defined(STM32_TIM1_CC_HANDLER) #if !defined(STM32_TIM1_CC_HANDLER)
@ -165,13 +164,13 @@ CH_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD1); icu_lld_serve_interrupt(&ICUD1);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_ICU_USE_TIM1 */ #endif /* STM32_ICU_USE_TIM1 */
@ -187,13 +186,13 @@ CH_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM2_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM2_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD2); icu_lld_serve_interrupt(&ICUD2);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_ICU_USE_TIM2 */ #endif /* STM32_ICU_USE_TIM2 */
@ -209,13 +208,13 @@ CH_IRQ_HANDLER(STM32_TIM2_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM3_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM3_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD3); icu_lld_serve_interrupt(&ICUD3);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_ICU_USE_TIM3 */ #endif /* STM32_ICU_USE_TIM3 */
@ -231,13 +230,13 @@ CH_IRQ_HANDLER(STM32_TIM3_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM4_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM4_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD4); icu_lld_serve_interrupt(&ICUD4);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_ICU_USE_TIM4 */ #endif /* STM32_ICU_USE_TIM4 */
@ -253,13 +252,13 @@ CH_IRQ_HANDLER(STM32_TIM4_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM5_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM5_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD5); icu_lld_serve_interrupt(&ICUD5);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_ICU_USE_TIM5 */ #endif /* STM32_ICU_USE_TIM5 */
@ -275,13 +274,13 @@ CH_IRQ_HANDLER(STM32_TIM5_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD8); icu_lld_serve_interrupt(&ICUD8);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#if !defined(STM32_TIM8_CC_HANDLER) #if !defined(STM32_TIM8_CC_HANDLER)
@ -295,13 +294,13 @@ CH_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD8); icu_lld_serve_interrupt(&ICUD8);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_ICU_USE_TIM8 */ #endif /* STM32_ICU_USE_TIM8 */
@ -317,13 +316,13 @@ CH_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM9_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM9_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD9); icu_lld_serve_interrupt(&ICUD9);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_ICU_USE_TIM9 */ #endif /* STM32_ICU_USE_TIM9 */
@ -391,9 +390,9 @@ void icu_lld_init(void) {
void icu_lld_start(ICUDriver *icup) { void icu_lld_start(ICUDriver *icup) {
uint32_t psc; uint32_t psc;
chDbgAssert((icup->config->channel == ICU_CHANNEL_1) || osalDbgAssert((icup->config->channel == ICU_CHANNEL_1) ||
(icup->config->channel == ICU_CHANNEL_2), (icup->config->channel == ICU_CHANNEL_2),
"icu_lld_start(), #1", "invalid input"); "invalid input");
if (icup->state == ICU_STOP) { if (icup->state == ICU_STOP) {
/* Clock activation and timer reset.*/ /* Clock activation and timer reset.*/
@ -401,10 +400,8 @@ void icu_lld_start(ICUDriver *icup) {
if (&ICUD1 == icup) { if (&ICUD1 == icup) {
rccEnableTIM1(FALSE); rccEnableTIM1(FALSE);
rccResetTIM1(); rccResetTIM1();
nvicEnableVector(STM32_TIM1_UP_NUMBER, nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_ICU_TIM1_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_ICU_TIM1_IRQ_PRIORITY)); nvicEnableVector(STM32_TIM1_CC_NUMBER, STM32_ICU_TIM1_IRQ_PRIORITY);
nvicEnableVector(STM32_TIM1_CC_NUMBER,
CORTEX_PRIORITY_MASK(STM32_ICU_TIM1_IRQ_PRIORITY));
icup->clock = STM32_TIMCLK2; icup->clock = STM32_TIMCLK2;
} }
#endif #endif
@ -412,8 +409,7 @@ void icu_lld_start(ICUDriver *icup) {
if (&ICUD2 == icup) { if (&ICUD2 == icup) {
rccEnableTIM2(FALSE); rccEnableTIM2(FALSE);
rccResetTIM2(); rccResetTIM2();
nvicEnableVector(STM32_TIM2_NUMBER, nvicEnableVector(STM32_TIM2_NUMBER, STM32_ICU_TIM2_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_ICU_TIM2_IRQ_PRIORITY));
icup->clock = STM32_TIMCLK1; icup->clock = STM32_TIMCLK1;
} }
#endif #endif
@ -421,8 +417,7 @@ void icu_lld_start(ICUDriver *icup) {
if (&ICUD3 == icup) { if (&ICUD3 == icup) {
rccEnableTIM3(FALSE); rccEnableTIM3(FALSE);
rccResetTIM3(); rccResetTIM3();
nvicEnableVector(STM32_TIM3_NUMBER, nvicEnableVector(STM32_TIM3_NUMBER, STM32_ICU_TIM3_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_ICU_TIM3_IRQ_PRIORITY));
icup->clock = STM32_TIMCLK1; icup->clock = STM32_TIMCLK1;
} }
#endif #endif
@ -430,8 +425,7 @@ void icu_lld_start(ICUDriver *icup) {
if (&ICUD4 == icup) { if (&ICUD4 == icup) {
rccEnableTIM4(FALSE); rccEnableTIM4(FALSE);
rccResetTIM4(); rccResetTIM4();
nvicEnableVector(STM32_TIM4_NUMBER, nvicEnableVector(STM32_TIM4_NUMBER, STM32_ICU_TIM4_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_ICU_TIM4_IRQ_PRIORITY));
icup->clock = STM32_TIMCLK1; icup->clock = STM32_TIMCLK1;
} }
#endif #endif
@ -439,8 +433,7 @@ void icu_lld_start(ICUDriver *icup) {
if (&ICUD5 == icup) { if (&ICUD5 == icup) {
rccEnableTIM5(FALSE); rccEnableTIM5(FALSE);
rccResetTIM5(); rccResetTIM5();
nvicEnableVector(STM32_TIM5_NUMBER, nvicEnableVector(STM32_TIM5_NUMBER, STM32_ICU_TIM5_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_ICU_TIM5_IRQ_PRIORITY));
icup->clock = STM32_TIMCLK1; icup->clock = STM32_TIMCLK1;
} }
#endif #endif
@ -448,10 +441,8 @@ void icu_lld_start(ICUDriver *icup) {
if (&ICUD8 == icup) { if (&ICUD8 == icup) {
rccEnableTIM8(FALSE); rccEnableTIM8(FALSE);
rccResetTIM8(); rccResetTIM8();
nvicEnableVector(STM32_TIM8_UP_NUMBER, nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_ICU_TIM8_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_ICU_TIM8_IRQ_PRIORITY)); nvicEnableVector(STM32_TIM8_CC_NUMBER, STM32_ICU_TIM8_IRQ_PRIORITY);
nvicEnableVector(STM32_TIM8_CC_NUMBER,
CORTEX_PRIORITY_MASK(STM32_ICU_TIM8_IRQ_PRIORITY));
icup->clock = STM32_TIMCLK2; icup->clock = STM32_TIMCLK2;
} }
#endif #endif
@ -459,8 +450,7 @@ void icu_lld_start(ICUDriver *icup) {
if (&ICUD9 == icup) { if (&ICUD9 == icup) {
rccEnableTIM9(FALSE); rccEnableTIM9(FALSE);
rccResetTIM9(); rccResetTIM9();
nvicEnableVector(STM32_TIM9_NUMBER, nvicEnableVector(STM32_TIM9_NUMBER, STM32_ICU_TIM9_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_ICU_TIM9_IRQ_PRIORITY));
icup->clock = STM32_TIMCLK1; icup->clock = STM32_TIMCLK1;
} }
#endif #endif
@ -477,9 +467,9 @@ void icu_lld_start(ICUDriver *icup) {
/* Timer configuration.*/ /* Timer configuration.*/
psc = (icup->clock / icup->config->frequency) - 1; psc = (icup->clock / icup->config->frequency) - 1;
chDbgAssert((psc <= 0xFFFF) && osalDbgAssert((psc <= 0xFFFF) &&
((psc + 1) * icup->config->frequency) == icup->clock, ((psc + 1) * icup->config->frequency) == icup->clock,
"icu_lld_start(), #1", "invalid frequency"); "invalid frequency");
icup->tim->PSC = (uint16_t)psc; icup->tim->PSC = (uint16_t)psc;
icup->tim->ARR = 0xFFFF; icup->tim->ARR = 0xFFFF;

View File

@ -25,10 +25,10 @@
#ifndef _ICU_LLD_H_ #ifndef _ICU_LLD_H_
#define _ICU_LLD_H_ #define _ICU_LLD_H_
#include "stm32_tim.h"
#if HAL_USE_ICU || defined(__DOXYGEN__) #if HAL_USE_ICU || defined(__DOXYGEN__)
#include "stm32_tim.h"
/*===========================================================================*/ /*===========================================================================*/
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -22,7 +22,6 @@
* @{ * @{
*/ */
#include "ch.h"
#include "hal.h" #include "hal.h"
#if HAL_USE_PWM || defined(__DOXYGEN__) #if HAL_USE_PWM || defined(__DOXYGEN__)
@ -144,14 +143,14 @@ static void pwm_lld_serve_interrupt(PWMDriver *pwmp) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
STM32_TIM1->SR = ~STM32_TIM_SR_UIF; STM32_TIM1->SR = ~STM32_TIM_SR_UIF;
PWMD1.config->callback(&PWMD1); PWMD1.config->callback(&PWMD1);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#if !defined(STM32_TIM1_CC_HANDLER) #if !defined(STM32_TIM1_CC_HANDLER)
@ -165,10 +164,10 @@ CH_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) {
uint16_t sr; uint16_t sr;
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
sr = STM32_TIM1->SR & STM32_TIM1->DIER; sr = STM32_TIM1->SR & STM32_TIM1->DIER;
STM32_TIM1->SR = ~(STM32_TIM_SR_CC1IF | STM32_TIM_SR_CC2IF | STM32_TIM1->SR = ~(STM32_TIM_SR_CC1IF | STM32_TIM_SR_CC2IF |
@ -182,7 +181,7 @@ CH_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) {
if ((sr & STM32_TIM_SR_CC4IF) != 0) if ((sr & STM32_TIM_SR_CC4IF) != 0)
PWMD1.config->channels[3].callback(&PWMD1); PWMD1.config->channels[3].callback(&PWMD1);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_PWM_USE_TIM1 */ #endif /* STM32_PWM_USE_TIM1 */
@ -195,13 +194,13 @@ CH_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM2_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM2_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
pwm_lld_serve_interrupt(&PWMD2); pwm_lld_serve_interrupt(&PWMD2);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_PWM_USE_TIM2 */ #endif /* STM32_PWM_USE_TIM2 */
@ -214,13 +213,13 @@ CH_IRQ_HANDLER(STM32_TIM2_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM3_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM3_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
pwm_lld_serve_interrupt(&PWMD3); pwm_lld_serve_interrupt(&PWMD3);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_PWM_USE_TIM3 */ #endif /* STM32_PWM_USE_TIM3 */
@ -233,13 +232,13 @@ CH_IRQ_HANDLER(STM32_TIM3_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM4_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM4_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
pwm_lld_serve_interrupt(&PWMD4); pwm_lld_serve_interrupt(&PWMD4);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_PWM_USE_TIM4 */ #endif /* STM32_PWM_USE_TIM4 */
@ -252,13 +251,13 @@ CH_IRQ_HANDLER(STM32_TIM4_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM5_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM5_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
pwm_lld_serve_interrupt(&PWMD5); pwm_lld_serve_interrupt(&PWMD5);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_PWM_USE_TIM5 */ #endif /* STM32_PWM_USE_TIM5 */
@ -274,14 +273,14 @@ CH_IRQ_HANDLER(STM32_TIM5_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
STM32_TIM8->SR = ~TIM_SR_UIF; STM32_TIM8->SR = ~TIM_SR_UIF;
PWMD8.config->callback(&PWMD8); PWMD8.config->callback(&PWMD8);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#if !defined(STM32_TIM8_CC_HANDLER) #if !defined(STM32_TIM8_CC_HANDLER)
@ -295,10 +294,10 @@ CH_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) {
uint16_t sr; uint16_t sr;
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
sr = STM32_TIM8->SR & STM32_TIM8->DIER; sr = STM32_TIM8->SR & STM32_TIM8->DIER;
STM32_TIM8->SR = ~(STM32_TIM_SR_CC1IF | STM32_TIM_SR_CC2IF | STM32_TIM8->SR = ~(STM32_TIM_SR_CC1IF | STM32_TIM_SR_CC2IF |
@ -312,7 +311,7 @@ CH_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) {
if ((sr & STM32_TIM_SR_CC4IF) != 0) if ((sr & STM32_TIM_SR_CC4IF) != 0)
PWMD8.config->channels[3].callback(&PWMD8); PWMD8.config->channels[3].callback(&PWMD8);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_PWM_USE_TIM8 */ #endif /* STM32_PWM_USE_TIM8 */
@ -325,13 +324,13 @@ CH_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) {
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(STM32_TIM9_HANDLER) { OSAL_IRQ_HANDLER(STM32_TIM9_HANDLER) {
CH_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
pwm_lld_serve_interrupt(&PWMD9); pwm_lld_serve_interrupt(&PWMD9);
CH_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
} }
#endif /* STM32_PWM_USE_TIM9 */ #endif /* STM32_PWM_USE_TIM9 */
@ -408,10 +407,8 @@ void pwm_lld_start(PWMDriver *pwmp) {
if (&PWMD1 == pwmp) { if (&PWMD1 == pwmp) {
rccEnableTIM1(FALSE); rccEnableTIM1(FALSE);
rccResetTIM1(); rccResetTIM1();
nvicEnableVector(STM32_TIM1_UP_NUMBER, nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_PWM_TIM1_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_PWM_TIM1_IRQ_PRIORITY)); nvicEnableVector(STM32_TIM1_CC_NUMBER, STM32_PWM_TIM1_IRQ_PRIORITY);
nvicEnableVector(STM32_TIM1_CC_NUMBER,
CORTEX_PRIORITY_MASK(STM32_PWM_TIM1_IRQ_PRIORITY));
pwmp->clock = STM32_TIMCLK2; pwmp->clock = STM32_TIMCLK2;
} }
#endif #endif
@ -419,8 +416,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
if (&PWMD2 == pwmp) { if (&PWMD2 == pwmp) {
rccEnableTIM2(FALSE); rccEnableTIM2(FALSE);
rccResetTIM2(); rccResetTIM2();
nvicEnableVector(STM32_TIM2_NUMBER, nvicEnableVector(STM32_TIM2_NUMBER, STM32_PWM_TIM2_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_PWM_TIM2_IRQ_PRIORITY));
pwmp->clock = STM32_TIMCLK1; pwmp->clock = STM32_TIMCLK1;
} }
#endif #endif
@ -428,8 +424,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
if (&PWMD3 == pwmp) { if (&PWMD3 == pwmp) {
rccEnableTIM3(FALSE); rccEnableTIM3(FALSE);
rccResetTIM3(); rccResetTIM3();
nvicEnableVector(STM32_TIM3_NUMBER, nvicEnableVector(STM32_TIM3_NUMBER, STM32_PWM_TIM3_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_PWM_TIM3_IRQ_PRIORITY));
pwmp->clock = STM32_TIMCLK1; pwmp->clock = STM32_TIMCLK1;
} }
#endif #endif
@ -437,8 +432,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
if (&PWMD4 == pwmp) { if (&PWMD4 == pwmp) {
rccEnableTIM4(FALSE); rccEnableTIM4(FALSE);
rccResetTIM4(); rccResetTIM4();
nvicEnableVector(STM32_TIM4_NUMBER, nvicEnableVector(STM32_TIM4_NUMBER, STM32_PWM_TIM4_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_PWM_TIM4_IRQ_PRIORITY));
pwmp->clock = STM32_TIMCLK1; pwmp->clock = STM32_TIMCLK1;
} }
#endif #endif
@ -447,8 +441,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
if (&PWMD5 == pwmp) { if (&PWMD5 == pwmp) {
rccEnableTIM5(FALSE); rccEnableTIM5(FALSE);
rccResetTIM5(); rccResetTIM5();
nvicEnableVector(STM32_TIM5_NUMBER, nvicEnableVector(STM32_TIM5_NUMBER, STM32_PWM_TIM5_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_PWM_TIM5_IRQ_PRIORITY));
pwmp->clock = STM32_TIMCLK1; pwmp->clock = STM32_TIMCLK1;
} }
#endif #endif
@ -456,10 +449,8 @@ void pwm_lld_start(PWMDriver *pwmp) {
if (&PWMD8 == pwmp) { if (&PWMD8 == pwmp) {
rccEnableTIM8(FALSE); rccEnableTIM8(FALSE);
rccResetTIM8(); rccResetTIM8();
nvicEnableVector(STM32_TIM8_UP_NUMBER, nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_PWM_TIM8_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_PWM_TIM8_IRQ_PRIORITY)); nvicEnableVector(STM32_TIM8_CC_NUMBER, STM32_PWM_TIM8_IRQ_PRIORITY);
nvicEnableVector(STM32_TIM8_CC_NUMBER,
CORTEX_PRIORITY_MASK(STM32_PWM_TIM8_IRQ_PRIORITY));
pwmp->clock = STM32_TIMCLK2; pwmp->clock = STM32_TIMCLK2;
} }
#endif #endif
@ -467,8 +458,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
if (&PWMD9 == pwmp) { if (&PWMD9 == pwmp) {
rccEnableTIM9(FALSE); rccEnableTIM9(FALSE);
rccResetTIM9(); rccResetTIM9();
nvicEnableVector(STM32_TIM9_NUMBER, nvicEnableVector(STM32_TIM9_NUMBER, STM32_PWM_TIM9_IRQ_PRIORITY);
CORTEX_PRIORITY_MASK(STM32_PWM_TIM9_IRQ_PRIORITY));
pwmp->clock = STM32_TIMCLK1; pwmp->clock = STM32_TIMCLK1;
} }
#endif #endif
@ -494,9 +484,9 @@ void pwm_lld_start(PWMDriver *pwmp) {
/* Timer configuration.*/ /* Timer configuration.*/
psc = (pwmp->clock / pwmp->config->frequency) - 1; psc = (pwmp->clock / pwmp->config->frequency) - 1;
chDbgAssert((psc <= 0xFFFF) && osalDbgAssert((psc <= 0xFFFF) &&
((psc + 1) * pwmp->config->frequency) == pwmp->clock, ((psc + 1) * pwmp->config->frequency) == pwmp->clock,
"pwm_lld_start(), #1", "invalid frequency"); "invalid frequency");
pwmp->tim->PSC = (uint16_t)psc; pwmp->tim->PSC = (uint16_t)psc;
pwmp->tim->ARR = (uint16_t)(pwmp->period - 1); pwmp->tim->ARR = (uint16_t)(pwmp->period - 1);
pwmp->tim->CR2 = pwmp->config->cr2; pwmp->tim->CR2 = pwmp->config->cr2;

View File

@ -25,10 +25,10 @@
#ifndef _PWM_LLD_H_ #ifndef _PWM_LLD_H_
#define _PWM_LLD_H_ #define _PWM_LLD_H_
#include "stm32_tim.h"
#if HAL_USE_PWM || defined(__DOXYGEN__) #if HAL_USE_PWM || defined(__DOXYGEN__)
#include "stm32_tim.h"
/*===========================================================================*/ /*===========================================================================*/
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -1,762 +0,0 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32/gpt_lld.c
* @brief STM32 GPT subsystem low level driver source.
*
* @addtogroup GPT
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_GPT || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief GPTD1 driver identifier.
* @note The driver GPTD1 allocates the complex timer TIM1 when enabled.
*/
#if STM32_GPT_USE_TIM1 || defined(__DOXYGEN__)
GPTDriver GPTD1;
#endif
/**
* @brief GPTD2 driver identifier.
* @note The driver GPTD2 allocates the timer TIM2 when enabled.
*/
#if STM32_GPT_USE_TIM2 || defined(__DOXYGEN__)
GPTDriver GPTD2;
#endif
/**
* @brief GPTD3 driver identifier.
* @note The driver GPTD3 allocates the timer TIM3 when enabled.
*/
#if STM32_GPT_USE_TIM3 || defined(__DOXYGEN__)
GPTDriver GPTD3;
#endif
/**
* @brief GPTD4 driver identifier.
* @note The driver GPTD4 allocates the timer TIM4 when enabled.
*/
#if STM32_GPT_USE_TIM4 || defined(__DOXYGEN__)
GPTDriver GPTD4;
#endif
/**
* @brief GPTD5 driver identifier.
* @note The driver GPTD5 allocates the timer TIM5 when enabled.
*/
#if STM32_GPT_USE_TIM5 || defined(__DOXYGEN__)
GPTDriver GPTD5;
#endif
/**
* @brief GPTD6 driver identifier.
* @note The driver GPTD6 allocates the timer TIM6 when enabled.
*/
#if STM32_GPT_USE_TIM6 || defined(__DOXYGEN__)
GPTDriver GPTD6;
#endif
/**
* @brief GPTD7 driver identifier.
* @note The driver GPTD7 allocates the timer TIM7 when enabled.
*/
#if STM32_GPT_USE_TIM7 || defined(__DOXYGEN__)
GPTDriver GPTD7;
#endif
/**
* @brief GPTD8 driver identifier.
* @note The driver GPTD8 allocates the timer TIM8 when enabled.
*/
#if STM32_GPT_USE_TIM8 || defined(__DOXYGEN__)
GPTDriver GPTD8;
#endif
/**
* @brief GPTD9 driver identifier.
* @note The driver GPTD9 allocates the timer TIM9 when enabled.
*/
#if STM32_GPT_USE_TIM9 || defined(__DOXYGEN__)
GPTDriver GPTD9;
#endif
/**
* @brief GPTD11 driver identifier.
* @note The driver GPTD11 allocates the timer TIM11 when enabled.
*/
#if STM32_GPT_USE_TIM11 || defined(__DOXYGEN__)
GPTDriver GPTD11;
#endif
/**
* @brief GPTD12 driver identifier.
* @note The driver GPTD12 allocates the timer TIM12 when enabled.
*/
#if STM32_GPT_USE_TIM12 || defined(__DOXYGEN__)
GPTDriver GPTD12;
#endif
/**
* @brief GPTD14 driver identifier.
* @note The driver GPTD14 allocates the timer TIM14 when enabled.
*/
#if STM32_GPT_USE_TIM14 || defined(__DOXYGEN__)
GPTDriver GPTD14;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief Shared IRQ handler.
*
* @param[in] gptp pointer to a @p GPTDriver object
*/
static void gpt_lld_serve_interrupt(GPTDriver *gptp) {
gptp->tim->SR = 0;
if (gptp->state == GPT_ONESHOT) {
gptp->state = GPT_READY; /* Back in GPT_READY state. */
gpt_lld_stop_timer(gptp); /* Timer automatically stopped. */
}
gptp->config->callback(gptp);
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if STM32_GPT_USE_TIM1
#if !defined(STM32_TIM1_UP_HANDLER)
#error "STM32_TIM1_UP_HANDLER not defined"
#endif
/**
* @brief TIM2 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD1);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_GPT_USE_TIM1 */
#if STM32_GPT_USE_TIM2
#if !defined(STM32_TIM2_HANDLER)
#error "STM32_TIM2_HANDLER not defined"
#endif
/**
* @brief TIM2 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM2_HANDLER) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD2);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_GPT_USE_TIM2 */
#if STM32_GPT_USE_TIM3
#if !defined(STM32_TIM3_HANDLER)
#error "STM32_TIM3_HANDLER not defined"
#endif
/**
* @brief TIM3 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM3_HANDLER) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD3);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_GPT_USE_TIM3 */
#if STM32_GPT_USE_TIM4
#if !defined(STM32_TIM4_HANDLER)
#error "STM32_TIM4_HANDLER not defined"
#endif
/**
* @brief TIM4 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM4_HANDLER) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD4);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_GPT_USE_TIM4 */
#if STM32_GPT_USE_TIM5
#if !defined(STM32_TIM5_HANDLER)
#error "STM32_TIM5_HANDLER not defined"
#endif
/**
* @brief TIM5 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM5_HANDLER) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD5);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_GPT_USE_TIM5 */
#if STM32_GPT_USE_TIM6
#if !defined(STM32_TIM6_HANDLER)
#error "STM32_TIM6_HANDLER not defined"
#endif
/**
* @brief TIM6 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM6_HANDLER) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD6);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_GPT_USE_TIM6 */
#if STM32_GPT_USE_TIM7
#if !defined(STM32_TIM7_HANDLER)
#error "STM32_TIM7_HANDLER not defined"
#endif
/**
* @brief TIM7 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM7_HANDLER) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD7);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_GPT_USE_TIM7 */
#if STM32_GPT_USE_TIM8
#if !defined(STM32_TIM8_UP_HANDLER)
#error "STM32_TIM8_UP_HANDLER not defined"
#endif
/**
* @brief TIM8 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD8);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_GPT_USE_TIM8 */
#if STM32_GPT_USE_TIM9
#if !defined(STM32_TIM9_HANDLER)
#error "STM32_TIM9_HANDLER not defined"
#endif
/**
* @brief TIM9 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM9_HANDLER) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD9);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_GPT_USE_TIM9 */
#if STM32_GPT_USE_TIM11
#if !defined(STM32_TIM11_HANDLER)
#error "STM32_TIM11_HANDLER not defined"
#endif
/**
* @brief TIM11 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM11_HANDLER) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD11);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_GPT_USE_TIM11 */
#if STM32_GPT_USE_TIM12
#if !defined(STM32_TIM12_HANDLER)
#error "STM32_TIM12_HANDLER not defined"
#endif
/**
* @brief TIM12 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM12_HANDLER) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD12);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_GPT_USE_TIM12 */
#if STM32_GPT_USE_TIM14
#if !defined(STM32_TIM14_HANDLER)
#error "STM32_TIM14_HANDLER not defined"
#endif
/**
* @brief TIM14 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM14_HANDLER) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD14);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_GPT_USE_TIM14 */
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level GPT driver initialization.
*
* @notapi
*/
void gpt_lld_init(void) {
#if STM32_GPT_USE_TIM1
/* Driver initialization.*/
GPTD1.tim = STM32_TIM1;
gptObjectInit(&GPTD1);
#endif
#if STM32_GPT_USE_TIM2
/* Driver initialization.*/
GPTD2.tim = STM32_TIM2;
gptObjectInit(&GPTD2);
#endif
#if STM32_GPT_USE_TIM3
/* Driver initialization.*/
GPTD3.tim = STM32_TIM3;
gptObjectInit(&GPTD3);
#endif
#if STM32_GPT_USE_TIM4
/* Driver initialization.*/
GPTD4.tim = STM32_TIM4;
gptObjectInit(&GPTD4);
#endif
#if STM32_GPT_USE_TIM5
/* Driver initialization.*/
GPTD5.tim = STM32_TIM5;
gptObjectInit(&GPTD5);
#endif
#if STM32_GPT_USE_TIM6
/* Driver initialization.*/
GPTD6.tim = STM32_TIM6;
gptObjectInit(&GPTD6);
#endif
#if STM32_GPT_USE_TIM7
/* Driver initialization.*/
GPTD7.tim = STM32_TIM7;
gptObjectInit(&GPTD7);
#endif
#if STM32_GPT_USE_TIM8
/* Driver initialization.*/
GPTD8.tim = STM32_TIM8;
gptObjectInit(&GPTD8);
#endif
#if STM32_GPT_USE_TIM9
/* Driver initialization.*/
GPTD9.tim = STM32_TIM9;
gptObjectInit(&GPTD9);
#endif
#if STM32_GPT_USE_TIM11
/* Driver initialization.*/
GPTD11.tim = STM32_TIM11;
gptObjectInit(&GPTD11);
#endif
#if STM32_GPT_USE_TIM12
/* Driver initialization.*/
GPTD12.tim = STM32_TIM12;
gptObjectInit(&GPTD12);
#endif
#if STM32_GPT_USE_TIM14
/* Driver initialization.*/
GPTD14.tim = STM32_TIM14;
gptObjectInit(&GPTD14);
#endif
}
/**
* @brief Configures and activates the GPT peripheral.
*
* @param[in] gptp pointer to the @p GPTDriver object
*
* @notapi
*/
void gpt_lld_start(GPTDriver *gptp) {
uint16_t psc;
if (gptp->state == GPT_STOP) {
/* Clock activation.*/
#if STM32_GPT_USE_TIM1
if (&GPTD1 == gptp) {
rccEnableTIM1(FALSE);
rccResetTIM1();
nvicEnableVector(STM32_TIM1_UP_NUMBER,
CORTEX_PRIORITY_MASK(STM32_GPT_TIM1_IRQ_PRIORITY));
gptp->clock = STM32_TIMCLK2;
}
#endif
#if STM32_GPT_USE_TIM2
if (&GPTD2 == gptp) {
rccEnableTIM2(FALSE);
rccResetTIM2();
nvicEnableVector(STM32_TIM2_NUMBER,
CORTEX_PRIORITY_MASK(STM32_GPT_TIM2_IRQ_PRIORITY));
gptp->clock = STM32_TIMCLK1;
}
#endif
#if STM32_GPT_USE_TIM3
if (&GPTD3 == gptp) {
rccEnableTIM3(FALSE);
rccResetTIM3();
nvicEnableVector(STM32_TIM3_NUMBER,
CORTEX_PRIORITY_MASK(STM32_GPT_TIM3_IRQ_PRIORITY));
gptp->clock = STM32_TIMCLK1;
}
#endif
#if STM32_GPT_USE_TIM4
if (&GPTD4 == gptp) {
rccEnableTIM4(FALSE);
rccResetTIM4();
nvicEnableVector(STM32_TIM4_NUMBER,
CORTEX_PRIORITY_MASK(STM32_GPT_TIM4_IRQ_PRIORITY));
gptp->clock = STM32_TIMCLK1;
}
#endif
#if STM32_GPT_USE_TIM5
if (&GPTD5 == gptp) {
rccEnableTIM5(FALSE);
rccResetTIM5();
nvicEnableVector(STM32_TIM5_NUMBER,
CORTEX_PRIORITY_MASK(STM32_GPT_TIM5_IRQ_PRIORITY));
gptp->clock = STM32_TIMCLK1;
}
#endif
#if STM32_GPT_USE_TIM6
if (&GPTD6 == gptp) {
rccEnableTIM6(FALSE);
rccResetTIM6();
nvicEnableVector(STM32_TIM6_NUMBER,
CORTEX_PRIORITY_MASK(STM32_GPT_TIM6_IRQ_PRIORITY));
gptp->clock = STM32_TIMCLK1;
}
#endif
#if STM32_GPT_USE_TIM7
if (&GPTD7 == gptp) {
rccEnableTIM7(FALSE);
rccResetTIM7();
nvicEnableVector(STM32_TIM7_NUMBER,
CORTEX_PRIORITY_MASK(STM32_GPT_TIM7_IRQ_PRIORITY));
gptp->clock = STM32_TIMCLK1;
}
#endif
#if STM32_GPT_USE_TIM8
if (&GPTD8 == gptp) {
rccEnableTIM8(FALSE);
rccResetTIM8();
nvicEnableVector(STM32_TIM8_UP_NUMBER,
CORTEX_PRIORITY_MASK(STM32_GPT_TIM8_IRQ_PRIORITY));
gptp->clock = STM32_TIMCLK2;
}
#endif
#if STM32_GPT_USE_TIM9
if (&GPTD9 == gptp) {
rccEnableTIM9(FALSE);
rccResetTIM9();
nvicEnableVector(STM32_TIM9_NUMBER,
CORTEX_PRIORITY_MASK(STM32_GPT_TIM9_IRQ_PRIORITY));
gptp->clock = STM32_TIMCLK2;
}
#endif
#if STM32_GPT_USE_TIM11
if (&GPTD11 == gptp) {
rccEnableTIM11(FALSE);
rccResetTIM11();
nvicEnableVector(STM32_TIM11_NUMBER,
CORTEX_PRIORITY_MASK(STM32_GPT_TIM11_IRQ_PRIORITY));
gptp->clock = STM32_TIMCLK2;
}
#endif
#if STM32_GPT_USE_TIM12
if (&GPTD12 == gptp) {
rccEnableTIM12(FALSE);
rccResetTIM12();
nvicEnableVector(STM32_TIM12_NUMBER,
CORTEX_PRIORITY_MASK(STM32_GPT_TIM12_IRQ_PRIORITY));
gptp->clock = STM32_TIMCLK1;
}
#endif
#if STM32_GPT_USE_TIM14
if (&GPTD14 == gptp) {
rccEnableTIM14(FALSE);
rccResetTIM14();
nvicEnableVector(STM32_TIM14_NUMBER,
CORTEX_PRIORITY_MASK(STM32_GPT_TIM14_IRQ_PRIORITY));
gptp->clock = STM32_TIMCLK1;
}
#endif
}
/* Prescaler value calculation.*/
psc = (uint16_t)((gptp->clock / gptp->config->frequency) - 1);
chDbgAssert(((uint32_t)(psc + 1) * gptp->config->frequency) == gptp->clock,
"gpt_lld_start(), #1", "invalid frequency");
/* Timer configuration.*/
gptp->tim->CR1 = 0; /* Initially stopped. */
gptp->tim->CR2 = TIM_CR2_CCDS; /* DMA on UE (if any). */
gptp->tim->PSC = psc; /* Prescaler value. */
gptp->tim->DIER = 0;
}
/**
* @brief Deactivates the GPT peripheral.
*
* @param[in] gptp pointer to the @p GPTDriver object
*
* @notapi
*/
void gpt_lld_stop(GPTDriver *gptp) {
if (gptp->state == GPT_READY) {
gptp->tim->CR1 = 0; /* Timer disabled. */
gptp->tim->DIER = 0; /* All IRQs disabled. */
gptp->tim->SR = 0; /* Clear eventual pending IRQs. */
#if STM32_GPT_USE_TIM1
if (&GPTD1 == gptp) {
nvicDisableVector(STM32_TIM1_UP_NUMBER);
rccDisableTIM1(FALSE);
}
#endif
#if STM32_GPT_USE_TIM2
if (&GPTD2 == gptp) {
nvicDisableVector(STM32_TIM2_NUMBER);
rccDisableTIM2(FALSE);
}
#endif
#if STM32_GPT_USE_TIM3
if (&GPTD3 == gptp) {
nvicDisableVector(STM32_TIM3_NUMBER);
rccDisableTIM3(FALSE);
}
#endif
#if STM32_GPT_USE_TIM4
if (&GPTD4 == gptp) {
nvicDisableVector(STM32_TIM4_NUMBER);
rccDisableTIM4(FALSE);
}
#endif
#if STM32_GPT_USE_TIM5
if (&GPTD5 == gptp) {
nvicDisableVector(STM32_TIM5_NUMBER);
rccDisableTIM5(FALSE);
}
#endif
#if STM32_GPT_USE_TIM6
if (&GPTD6 == gptp) {
nvicDisableVector(STM32_TIM6_NUMBER);
rccDisableTIM6(FALSE);
}
#endif
#if STM32_GPT_USE_TIM7
if (&GPTD7 == gptp) {
nvicDisableVector(STM32_TIM7_NUMBER);
rccDisableTIM7(FALSE);
}
#endif
#if STM32_GPT_USE_TIM8
if (&GPTD8 == gptp) {
nvicDisableVector(STM32_TIM8_UP_NUMBER);
rccDisableTIM8(FALSE);
}
#endif
#if STM32_GPT_USE_TIM9
if (&GPTD9 == gptp) {
nvicDisableVector(STM32_TIM9_NUMBER);
rccDisableTIM9(FALSE);
}
#endif
#if STM32_GPT_USE_TIM11
if (&GPTD11 == gptp) {
nvicDisableVector(STM32_TIM11_NUMBER);
rccDisableTIM11(FALSE);
}
#endif
#if STM32_GPT_USE_TIM12
if (&GPTD12 == gptp) {
nvicDisableVector(STM32_TIM12_NUMBER);
rccDisableTIM12(FALSE);
}
#endif
#if STM32_GPT_USE_TIM14
if (&GPTD14 == gptp) {
nvicDisableVector(STM32_TIM14_NUMBER);
rccDisableTIM14(FALSE);
}
#endif
}
}
/**
* @brief Starts the timer in continuous mode.
*
* @param[in] gptp pointer to the @p GPTDriver object
* @param[in] interval period in ticks
*
* @notapi
*/
void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
gptp->tim->ARR = interval - 1; /* Time constant. */
gptp->tim->EGR = TIM_EGR_UG; /* Update event. */
gptp->tim->CNT = 0; /* Reset counter. */
/* 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
before the clearing of SR, to give it some time.*/
gptp->tim->SR = 0; /* Clear pending IRQs (if any). */
gptp->tim->DIER = TIM_DIER_UIE; /* Update Event IRQ enabled. */
gptp->tim->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
}
/**
* @brief Stops the timer.
*
* @param[in] gptp pointer to the @p GPTDriver object
*
* @notapi
*/
void gpt_lld_stop_timer(GPTDriver *gptp) {
gptp->tim->CR1 = 0; /* Initially stopped. */
gptp->tim->SR = 0; /* Clear pending IRQs (if any). */
gptp->tim->DIER = 0; /* Interrupts disabled. */
}
/**
* @brief Starts the timer in one shot mode and waits for completion.
* @details This function specifically polls the timer waiting for completion
* in order to not have extra delays caused by interrupt servicing,
* this function is only recommended for short delays.
*
* @param[in] gptp pointer to the @p GPTDriver object
* @param[in] interval time interval in ticks
*
* @notapi
*/
void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
gptp->tim->ARR = interval - 1; /* Time constant. */
gptp->tim->EGR = TIM_EGR_UG; /* Update event. */
gptp->tim->SR = 0; /* Clear pending IRQs (if any). */
gptp->tim->CR1 = TIM_CR1_OPM | TIM_CR1_URS | TIM_CR1_CEN;
while (!(gptp->tim->SR & TIM_SR_UIF))
;
}
#endif /* HAL_USE_GPT */
/** @} */

View File

@ -1,504 +0,0 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32/gpt_lld.h
* @brief STM32 GPT subsystem low level driver header.
*
* @addtogroup GPT
* @{
*/
#ifndef _GPT_LLD_H_
#define _GPT_LLD_H_
#if HAL_USE_GPT || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief GPTD1 driver enable switch.
* @details If set to @p TRUE the support for GPTD1 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_GPT_USE_TIM1) || defined(__DOXYGEN__)
#define STM32_GPT_USE_TIM1 FALSE
#endif
/**
* @brief GPTD2 driver enable switch.
* @details If set to @p TRUE the support for GPTD2 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_GPT_USE_TIM2) || defined(__DOXYGEN__)
#define STM32_GPT_USE_TIM2 FALSE
#endif
/**
* @brief GPTD3 driver enable switch.
* @details If set to @p TRUE the support for GPTD3 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_GPT_USE_TIM3) || defined(__DOXYGEN__)
#define STM32_GPT_USE_TIM3 FALSE
#endif
/**
* @brief GPTD4 driver enable switch.
* @details If set to @p TRUE the support for GPTD4 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_GPT_USE_TIM4) || defined(__DOXYGEN__)
#define STM32_GPT_USE_TIM4 FALSE
#endif
/**
* @brief GPTD5 driver enable switch.
* @details If set to @p TRUE the support for GPTD5 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_GPT_USE_TIM5) || defined(__DOXYGEN__)
#define STM32_GPT_USE_TIM5 FALSE
#endif
/**
* @brief GPTD6 driver enable switch.
* @details If set to @p TRUE the support for GPTD6 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_GPT_USE_TIM6) || defined(__DOXYGEN__)
#define STM32_GPT_USE_TIM6 FALSE
#endif
/**
* @brief GPTD7 driver enable switch.
* @details If set to @p TRUE the support for GPTD7 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_GPT_USE_TIM7) || defined(__DOXYGEN__)
#define STM32_GPT_USE_TIM7 FALSE
#endif
/**
* @brief GPTD8 driver enable switch.
* @details If set to @p TRUE the support for GPTD8 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_GPT_USE_TIM8) || defined(__DOXYGEN__)
#define STM32_GPT_USE_TIM8 FALSE
#endif
/**
* @brief GPTD9 driver enable switch.
* @details If set to @p TRUE the support for GPTD9 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_GPT_USE_TIM9) || defined(__DOXYGEN__)
#define STM32_GPT_USE_TIM9 FALSE
#endif
/**
* @brief GPTD11 driver enable switch.
* @details If set to @p TRUE the support for GPTD11 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_GPT_USE_TIM11) || defined(__DOXYGEN__)
#define STM32_GPT_USE_TIM11 FALSE
#endif
/**
* @brief GPTD12 driver enable switch.
* @details If set to @p TRUE the support for GPTD12 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_GPT_USE_TIM12) || defined(__DOXYGEN__)
#define STM32_GPT_USE_TIM12 FALSE
#endif
/**
* @brief GPTD14 driver enable switch.
* @details If set to @p TRUE the support for GPTD14 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_GPT_USE_TIM14) || defined(__DOXYGEN__)
#define STM32_GPT_USE_TIM14 FALSE
#endif
/**
* @brief GPTD1 interrupt priority level setting.
*/
#if !defined(STM32_GPT_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_GPT_TIM1_IRQ_PRIORITY 7
#endif
/**
* @brief GPTD2 interrupt priority level setting.
*/
#if !defined(STM32_GPT_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_GPT_TIM2_IRQ_PRIORITY 7
#endif
/**
* @brief GPTD3 interrupt priority level setting.
*/
#if !defined(STM32_GPT_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_GPT_TIM3_IRQ_PRIORITY 7
#endif
/**
* @brief GPTD4 interrupt priority level setting.
*/
#if !defined(STM32_GPT_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_GPT_TIM4_IRQ_PRIORITY 7
#endif
/**
* @brief GPTD5 interrupt priority level setting.
*/
#if !defined(STM32_GPT_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_GPT_TIM5_IRQ_PRIORITY 7
#endif
/**
* @brief GPTD6 interrupt priority level setting.
*/
#if !defined(STM32_GPT_TIM6_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_GPT_TIM6_IRQ_PRIORITY 7
#endif
/**
* @brief GPTD7 interrupt priority level setting.
*/
#if !defined(STM32_GPT_TIM7_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_GPT_TIM7_IRQ_PRIORITY 7
#endif
/**
* @brief GPTD8 interrupt priority level setting.
*/
#if !defined(STM32_GPT_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_GPT_TIM8_IRQ_PRIORITY 7
#endif
/**
* @brief GPTD9 interrupt priority level setting.
*/
#if !defined(STM32_GPT_TIM9_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_GPT_TIM9_IRQ_PRIORITY 7
#endif
/**
* @brief GPTD11 interrupt priority level setting.
*/
#if !defined(STM32_GPT_TIM11_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_GPT_TIM11_IRQ_PRIORITY 7
#endif
/**
* @brief GPTD12 interrupt priority level setting.
*/
#if !defined(STM32_GPT_TIM12_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_GPT_TIM12_IRQ_PRIORITY 7
#endif
/**
* @brief GPTD14 interrupt priority level setting.
*/
#if !defined(STM32_GPT_TIM14_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_GPT_TIM14_IRQ_PRIORITY 7
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if STM32_GPT_USE_TIM1 && !STM32_HAS_TIM1
#error "TIM1 not present in the selected device"
#endif
#if STM32_GPT_USE_TIM2 && !STM32_HAS_TIM2
#error "TIM2 not present in the selected device"
#endif
#if STM32_GPT_USE_TIM3 && !STM32_HAS_TIM3
#error "TIM3 not present in the selected device"
#endif
#if STM32_GPT_USE_TIM4 && !STM32_HAS_TIM4
#error "TIM4 not present in the selected device"
#endif
#if STM32_GPT_USE_TIM5 && !STM32_HAS_TIM5
#error "TIM5 not present in the selected device"
#endif
#if STM32_GPT_USE_TIM6 && !STM32_HAS_TIM6
#error "TIM6 not present in the selected device"
#endif
#if STM32_GPT_USE_TIM7 && !STM32_HAS_TIM7
#error "TIM7 not present in the selected device"
#endif
#if STM32_GPT_USE_TIM8 && !STM32_HAS_TIM8
#error "TIM8 not present in the selected device"
#endif
#if STM32_GPT_USE_TIM9 && !STM32_HAS_TIM9
#error "TIM9 not present in the selected device"
#endif
#if STM32_GPT_USE_TIM11 && !STM32_HAS_TIM11
#error "TIM11 not present in the selected device"
#endif
#if STM32_GPT_USE_TIM12 && !STM32_HAS_TIM12
#error "TIM12 not present in the selected device"
#endif
#if STM32_GPT_USE_TIM14 && !STM32_HAS_TIM14
#error "TIM14 not present in the selected device"
#endif
#if !STM32_GPT_USE_TIM1 && !STM32_GPT_USE_TIM2 && \
!STM32_GPT_USE_TIM3 && !STM32_GPT_USE_TIM4 && \
!STM32_GPT_USE_TIM5 && !STM32_GPT_USE_TIM6 && \
!STM32_GPT_USE_TIM7 && !STM32_GPT_USE_TIM8 && \
!STM32_GPT_USE_TIM9 && !STM32_GPT_USE_TIM11 && \
!STM32_GPT_USE_TIM12 && !STM32_GPT_USE_TIM14
#error "GPT driver activated but no TIM peripheral assigned"
#endif
#if STM32_GPT_USE_TIM1 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_GPT_TIM1_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM1"
#endif
#if STM32_GPT_USE_TIM2 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_GPT_TIM2_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM2"
#endif
#if STM32_GPT_USE_TIM3 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_GPT_TIM3_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM3"
#endif
#if STM32_GPT_USE_TIM4 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_GPT_TIM4_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM4"
#endif
#if STM32_GPT_USE_TIM5 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_GPT_TIM5_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM5"
#endif
#if STM32_GPT_USE_TIM6 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_GPT_TIM6_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM6"
#endif
#if STM32_GPT_USE_TIM7 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_GPT_TIM7_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM7"
#endif
#if STM32_GPT_USE_TIM8 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_GPT_TIM8_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM8"
#endif
#if STM32_GPT_USE_TIM9 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_GPT_TIM9_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM9"
#endif
#if STM32_GPT_USE_TIM11 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_GPT_TIM11_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM11"
#endif
#if STM32_GPT_USE_TIM12 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_GPT_TIM12_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM12"
#endif
#if STM32_GPT_USE_TIM14 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_GPT_TIM14_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM14"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief GPT frequency type.
*/
typedef uint32_t gptfreq_t;
/**
* @brief GPT counter type.
*/
typedef uint16_t gptcnt_t;
/**
* @brief Driver configuration structure.
* @note It could be empty on some architectures.
*/
typedef struct {
/**
* @brief Timer clock in Hz.
* @note The low level can use assertions in order to catch invalid
* frequency specifications.
*/
gptfreq_t frequency;
/**
* @brief Timer callback pointer.
* @note This callback is invoked on GPT counter events.
*/
gptcallback_t callback;
/* End of the mandatory fields.*/
} GPTConfig;
/**
* @brief Structure representing a GPT driver.
*/
struct GPTDriver {
/**
* @brief Driver state.
*/
gptstate_t state;
/**
* @brief Current configuration data.
*/
const GPTConfig *config;
#if defined(GPT_DRIVER_EXT_FIELDS)
GPT_DRIVER_EXT_FIELDS
#endif
/* End of the mandatory fields.*/
/**
* @brief Timer base clock.
*/
uint32_t clock;
/**
* @brief Pointer to the TIMx registers block.
*/
stm32_tim_t *tim;
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Changes the interval of GPT peripheral.
* @details This function changes the interval of a running GPT unit.
* @pre The GPT unit must have been activated using @p gptStart().
* @pre The GPT unit must have been running in continuous mode using
* @p gptStartContinuous().
* @post The GPT unit interval is changed to the new value.
* @note The function has effect at the next cycle start.
*
* @param[in] gptp pointer to a @p GPTDriver object
* @param[in] interval new cycle time in timer ticks
* @notapi
*/
#define gpt_lld_change_interval(gptp, interval) \
((gptp)->tim->ARR = (uint16_t)((interval) - 1))
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if STM32_GPT_USE_TIM1 && !defined(__DOXYGEN__)
extern GPTDriver GPTD1;
#endif
#if STM32_GPT_USE_TIM2 && !defined(__DOXYGEN__)
extern GPTDriver GPTD2;
#endif
#if STM32_GPT_USE_TIM3 && !defined(__DOXYGEN__)
extern GPTDriver GPTD3;
#endif
#if STM32_GPT_USE_TIM4 && !defined(__DOXYGEN__)
extern GPTDriver GPTD4;
#endif
#if STM32_GPT_USE_TIM5 && !defined(__DOXYGEN__)
extern GPTDriver GPTD5;
#endif
#if STM32_GPT_USE_TIM6 && !defined(__DOXYGEN__)
extern GPTDriver GPTD6;
#endif
#if STM32_GPT_USE_TIM7 && !defined(__DOXYGEN__)
extern GPTDriver GPTD7;
#endif
#if STM32_GPT_USE_TIM8 && !defined(__DOXYGEN__)
extern GPTDriver GPTD8;
#endif
#if STM32_GPT_USE_TIM9 && !defined(__DOXYGEN__)
extern GPTDriver GPTD9;
#endif
#if STM32_GPT_USE_TIM11 && !defined(__DOXYGEN__)
extern GPTDriver GPTD11;
#endif
#if STM32_GPT_USE_TIM12 && !defined(__DOXYGEN__)
extern GPTDriver GPTD12;
#endif
#if STM32_GPT_USE_TIM14 && !defined(__DOXYGEN__)
extern GPTDriver GPTD14;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void gpt_lld_init(void);
void gpt_lld_start(GPTDriver *gptp);
void gpt_lld_stop(GPTDriver *gptp);
void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period);
void gpt_lld_stop_timer(GPTDriver *gptp);
void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_GPT */
#endif /* _GPT_LLD_H_ */
/** @} */

View File

@ -1,629 +0,0 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Concepts and parts of this file have been contributed by Fabio Utzig and
Xo Wang.
*/
/**
* @file STM32/icu_lld.c
* @brief STM32 ICU subsystem low level driver header.
*
* @addtogroup ICU
* @{
*/
#include "hal.h"
#if HAL_USE_ICU || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief ICUD1 driver identifier.
* @note The driver ICUD1 allocates the complex timer TIM1 when enabled.
*/
#if STM32_ICU_USE_TIM1 || defined(__DOXYGEN__)
ICUDriver ICUD1;
#endif
/**
* @brief ICUD2 driver identifier.
* @note The driver ICUD1 allocates the timer TIM2 when enabled.
*/
#if STM32_ICU_USE_TIM2 || defined(__DOXYGEN__)
ICUDriver ICUD2;
#endif
/**
* @brief ICUD3 driver identifier.
* @note The driver ICUD1 allocates the timer TIM3 when enabled.
*/
#if STM32_ICU_USE_TIM3 || defined(__DOXYGEN__)
ICUDriver ICUD3;
#endif
/**
* @brief ICUD4 driver identifier.
* @note The driver ICUD4 allocates the timer TIM4 when enabled.
*/
#if STM32_ICU_USE_TIM4 || defined(__DOXYGEN__)
ICUDriver ICUD4;
#endif
/**
* @brief ICUD5 driver identifier.
* @note The driver ICUD5 allocates the timer TIM5 when enabled.
*/
#if STM32_ICU_USE_TIM5 || defined(__DOXYGEN__)
ICUDriver ICUD5;
#endif
/**
* @brief ICUD8 driver identifier.
* @note The driver ICUD8 allocates the timer TIM8 when enabled.
*/
#if STM32_ICU_USE_TIM8 || defined(__DOXYGEN__)
ICUDriver ICUD8;
#endif
/**
* @brief ICUD9 driver identifier.
* @note The driver ICUD9 allocates the timer TIM9 when enabled.
*/
#if STM32_ICU_USE_TIM9 || defined(__DOXYGEN__)
ICUDriver ICUD9;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief Shared IRQ handler.
*
* @param[in] icup pointer to the @p ICUDriver object
*/
static void icu_lld_serve_interrupt(ICUDriver *icup) {
uint16_t sr;
sr = icup->tim->SR;
sr &= icup->tim->DIER;
icup->tim->SR = ~sr;
if (icup->config->channel == ICU_CHANNEL_1) {
if ((sr & TIM_SR_CC1IF) != 0)
_icu_isr_invoke_period_cb(icup);
if ((sr & TIM_SR_CC2IF) != 0)
_icu_isr_invoke_width_cb(icup);
} else {
if ((sr & TIM_SR_CC1IF) != 0)
_icu_isr_invoke_width_cb(icup);
if ((sr & TIM_SR_CC2IF) != 0)
_icu_isr_invoke_period_cb(icup);
}
if ((sr & TIM_SR_UIF) != 0)
_icu_isr_invoke_overflow_cb(icup);
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if STM32_ICU_USE_TIM1
#if !defined(STM32_TIM1_UP_HANDLER)
#error "STM32_TIM1_UP_HANDLER not defined"
#endif
/**
* @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.
*
* @isr
*/
OSAL_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) {
OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD1);
OSAL_IRQ_EPILOGUE();
}
#if !defined(STM32_TIM1_CC_HANDLER)
#error "STM32_TIM1_CC_HANDLER not defined"
#endif
/**
* @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.
*
* @isr
*/
OSAL_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) {
OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD1);
OSAL_IRQ_EPILOGUE();
}
#endif /* STM32_ICU_USE_TIM1 */
#if STM32_ICU_USE_TIM2
#if !defined(STM32_TIM2_HANDLER)
#error "STM32_TIM2_HANDLER not defined"
#endif
/**
* @brief TIM2 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.
*
* @isr
*/
OSAL_IRQ_HANDLER(STM32_TIM2_HANDLER) {
OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD2);
OSAL_IRQ_EPILOGUE();
}
#endif /* STM32_ICU_USE_TIM2 */
#if STM32_ICU_USE_TIM3
#if !defined(STM32_TIM3_HANDLER)
#error "STM32_TIM3_HANDLER not defined"
#endif
/**
* @brief TIM3 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.
*
* @isr
*/
OSAL_IRQ_HANDLER(STM32_TIM3_HANDLER) {
OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD3);
OSAL_IRQ_EPILOGUE();
}
#endif /* STM32_ICU_USE_TIM3 */
#if STM32_ICU_USE_TIM4
#if !defined(STM32_TIM4_HANDLER)
#error "STM32_TIM4_HANDLER not defined"
#endif
/**
* @brief TIM4 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.
*
* @isr
*/
OSAL_IRQ_HANDLER(STM32_TIM4_HANDLER) {
OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD4);
OSAL_IRQ_EPILOGUE();
}
#endif /* STM32_ICU_USE_TIM4 */
#if STM32_ICU_USE_TIM5
#if !defined(STM32_TIM5_HANDLER)
#error "STM32_TIM5_HANDLER not defined"
#endif
/**
* @brief TIM5 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.
*
* @isr
*/
OSAL_IRQ_HANDLER(STM32_TIM5_HANDLER) {
OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD5);
OSAL_IRQ_EPILOGUE();
}
#endif /* STM32_ICU_USE_TIM5 */
#if STM32_ICU_USE_TIM8
#if !defined(STM32_TIM8_UP_HANDLER)
#error "STM32_TIM8_UP_HANDLER not defined"
#endif
/**
* @brief TIM8 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.
*
* @isr
*/
OSAL_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) {
OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD8);
OSAL_IRQ_EPILOGUE();
}
#if !defined(STM32_TIM8_CC_HANDLER)
#error "STM32_TIM8_CC_HANDLER not defined"
#endif
/**
* @brief TIM8 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.
*
* @isr
*/
OSAL_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) {
OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD8);
OSAL_IRQ_EPILOGUE();
}
#endif /* STM32_ICU_USE_TIM8 */
#if STM32_ICU_USE_TIM9
#if !defined(STM32_TIM9_HANDLER)
#error "STM32_TIM9_HANDLER not defined"
#endif
/**
* @brief TIM9 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.
*
* @isr
*/
OSAL_IRQ_HANDLER(STM32_TIM9_HANDLER) {
OSAL_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD9);
OSAL_IRQ_EPILOGUE();
}
#endif /* STM32_ICU_USE_TIM9 */
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level ICU driver initialization.
*
* @notapi
*/
void icu_lld_init(void) {
#if STM32_ICU_USE_TIM1
/* Driver initialization.*/
icuObjectInit(&ICUD1);
ICUD1.tim = STM32_TIM1;
#endif
#if STM32_ICU_USE_TIM2
/* Driver initialization.*/
icuObjectInit(&ICUD2);
ICUD2.tim = STM32_TIM2;
#endif
#if STM32_ICU_USE_TIM3
/* Driver initialization.*/
icuObjectInit(&ICUD3);
ICUD3.tim = STM32_TIM3;
#endif
#if STM32_ICU_USE_TIM4
/* Driver initialization.*/
icuObjectInit(&ICUD4);
ICUD4.tim = STM32_TIM4;
#endif
#if STM32_ICU_USE_TIM5
/* Driver initialization.*/
icuObjectInit(&ICUD5);
ICUD5.tim = STM32_TIM5;
#endif
#if STM32_ICU_USE_TIM8
/* Driver initialization.*/
icuObjectInit(&ICUD8);
ICUD8.tim = STM32_TIM8;
#endif
#if STM32_ICU_USE_TIM9
/* Driver initialization.*/
icuObjectInit(&ICUD9);
ICUD9.tim = STM32_TIM9;
#endif
}
/**
* @brief Configures and activates the ICU peripheral.
*
* @param[in] icup pointer to the @p ICUDriver object
*
* @notapi
*/
void icu_lld_start(ICUDriver *icup) {
uint32_t psc;
osalDbgAssert((icup->config->channel == ICU_CHANNEL_1) ||
(icup->config->channel == ICU_CHANNEL_2),
"invalid input");
if (icup->state == ICU_STOP) {
/* Clock activation and timer reset.*/
#if STM32_ICU_USE_TIM1
if (&ICUD1 == icup) {
rccEnableTIM1(FALSE);
rccResetTIM1();
nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_ICU_TIM1_IRQ_PRIORITY);
nvicEnableVector(STM32_TIM1_CC_NUMBER, STM32_ICU_TIM1_IRQ_PRIORITY);
icup->clock = STM32_TIMCLK2;
}
#endif
#if STM32_ICU_USE_TIM2
if (&ICUD2 == icup) {
rccEnableTIM2(FALSE);
rccResetTIM2();
nvicEnableVector(STM32_TIM2_NUMBER, STM32_ICU_TIM2_IRQ_PRIORITY);
icup->clock = STM32_TIMCLK1;
}
#endif
#if STM32_ICU_USE_TIM3
if (&ICUD3 == icup) {
rccEnableTIM3(FALSE);
rccResetTIM3();
nvicEnableVector(STM32_TIM3_NUMBER, STM32_ICU_TIM3_IRQ_PRIORITY);
icup->clock = STM32_TIMCLK1;
}
#endif
#if STM32_ICU_USE_TIM4
if (&ICUD4 == icup) {
rccEnableTIM4(FALSE);
rccResetTIM4();
nvicEnableVector(STM32_TIM4_NUMBER, STM32_ICU_TIM4_IRQ_PRIORITY);
icup->clock = STM32_TIMCLK1;
}
#endif
#if STM32_ICU_USE_TIM5
if (&ICUD5 == icup) {
rccEnableTIM5(FALSE);
rccResetTIM5();
nvicEnableVector(STM32_TIM5_NUMBER, STM32_ICU_TIM5_IRQ_PRIORITY);
icup->clock = STM32_TIMCLK1;
}
#endif
#if STM32_ICU_USE_TIM8
if (&ICUD8 == icup) {
rccEnableTIM8(FALSE);
rccResetTIM8();
nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_ICU_TIM8_IRQ_PRIORITY);
nvicEnableVector(STM32_TIM8_CC_NUMBER, STM32_ICU_TIM8_IRQ_PRIORITY);
icup->clock = STM32_TIMCLK2;
}
#endif
#if STM32_ICU_USE_TIM9
if (&ICUD9 == icup) {
rccEnableTIM9(FALSE);
rccResetTIM9();
nvicEnableVector(STM32_TIM9_NUMBER, STM32_ICU_TIM9_IRQ_PRIORITY);
icup->clock = STM32_TIMCLK1;
}
#endif
}
else {
/* Driver re-configuration scenario, it must be stopped first.*/
icup->tim->CR1 = 0; /* Timer disabled. */
icup->tim->DIER = 0; /* All IRQs disabled. */
icup->tim->SR = 0; /* Clear eventual pending IRQs. */
icup->tim->CCR[0] = 0; /* Comparator 1 disabled. */
icup->tim->CCR[1] = 0; /* Comparator 2 disabled. */
icup->tim->CNT = 0; /* Counter reset to zero. */
}
/* Timer configuration.*/
psc = (icup->clock / icup->config->frequency) - 1;
osalDbgAssert((psc <= 0xFFFF) &&
((psc + 1) * icup->config->frequency) == icup->clock,
"invalid frequency");
icup->tim->PSC = (uint16_t)psc;
icup->tim->ARR = 0xFFFF;
if (icup->config->channel == ICU_CHANNEL_1) {
/* Selected input 1.
CCMR1_CC1S = 01 = CH1 Input on TI1.
CCMR1_CC2S = 10 = CH2 Input on TI1.*/
icup->tim->CCMR1 = TIM_CCMR1_CC1S_0 |
TIM_CCMR1_CC2S_1;
/* SMCR_TS = 101, input is TI1FP1.
SMCR_SMS = 100, reset on rising edge.*/
icup->tim->SMCR = TIM_SMCR_TS_2 | TIM_SMCR_TS_0 |
TIM_SMCR_SMS_2;
/* The CCER settings depend on the selected trigger mode.
ICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge.
ICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.*/
if (icup->config->mode == ICU_INPUT_ACTIVE_HIGH)
icup->tim->CCER = TIM_CCER_CC1E |
TIM_CCER_CC2E | TIM_CCER_CC2P;
else
icup->tim->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P |
TIM_CCER_CC2E;
/* Direct pointers to the capture registers in order to make reading
data faster from within callbacks.*/
icup->wccrp = &icup->tim->CCR[1];
icup->pccrp = &icup->tim->CCR[0];
} else {
/* Selected input 2.
CCMR1_CC1S = 10 = CH1 Input on TI2.
CCMR1_CC2S = 01 = CH2 Input on TI2.*/
icup->tim->CCMR1 = TIM_CCMR1_CC1S_1 |
TIM_CCMR1_CC2S_0;
/* SMCR_TS = 110, input is TI2FP2.
SMCR_SMS = 100, reset on rising edge.*/
icup->tim->SMCR = TIM_SMCR_TS_2 | TIM_SMCR_TS_1 |
TIM_SMCR_SMS_2;
/* The CCER settings depend on the selected trigger mode.
ICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge.
ICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.*/
if (icup->config->mode == ICU_INPUT_ACTIVE_HIGH)
icup->tim->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P |
TIM_CCER_CC2E;
else
icup->tim->CCER = TIM_CCER_CC1E |
TIM_CCER_CC2E | TIM_CCER_CC2P;
/* Direct pointers to the capture registers in order to make reading
data faster from within callbacks.*/
icup->wccrp = &icup->tim->CCR[0];
icup->pccrp = &icup->tim->CCR[1];
}
}
/**
* @brief Deactivates the ICU peripheral.
*
* @param[in] icup pointer to the @p ICUDriver object
*
* @notapi
*/
void icu_lld_stop(ICUDriver *icup) {
if (icup->state == ICU_READY) {
/* Clock deactivation.*/
icup->tim->CR1 = 0; /* Timer disabled. */
icup->tim->DIER = 0; /* All IRQs disabled. */
icup->tim->SR = 0; /* Clear eventual pending IRQs. */
#if STM32_ICU_USE_TIM1
if (&ICUD1 == icup) {
nvicDisableVector(STM32_TIM1_UP_NUMBER);
nvicDisableVector(STM32_TIM1_CC_NUMBER);
rccDisableTIM1(FALSE);
}
#endif
#if STM32_ICU_USE_TIM2
if (&ICUD2 == icup) {
nvicDisableVector(STM32_TIM2_NUMBER);
rccDisableTIM2(FALSE);
}
#endif
#if STM32_ICU_USE_TIM3
if (&ICUD3 == icup) {
nvicDisableVector(STM32_TIM3_NUMBER);
rccDisableTIM3(FALSE);
}
#endif
#if STM32_ICU_USE_TIM4
if (&ICUD4 == icup) {
nvicDisableVector(STM32_TIM4_NUMBER);
rccDisableTIM4(FALSE);
}
#endif
#if STM32_ICU_USE_TIM5
if (&ICUD5 == icup) {
nvicDisableVector(STM32_TIM5_NUMBER);
rccDisableTIM5(FALSE);
}
#endif
#if STM32_ICU_USE_TIM8
if (&ICUD8 == icup) {
nvicDisableVector(STM32_TIM8_UP_NUMBER);
nvicDisableVector(STM32_TIM8_CC_NUMBER);
rccDisableTIM8(FALSE);
}
#endif
#if STM32_ICU_USE_TIM9
if (&ICUD9 == icup) {
nvicDisableVector(STM32_TIM9_NUMBER);
rccDisableTIM9(FALSE);
}
#endif
}
}
/**
* @brief Enables the input capture.
*
* @param[in] icup pointer to the @p ICUDriver object
*
* @notapi
*/
void icu_lld_enable(ICUDriver *icup) {
icup->tim->SR = 0; /* Clear pending IRQs (if any). */
if (icup->config->channel == ICU_CHANNEL_1) {
if (icup->config->period_cb != NULL)
icup->tim->DIER |= TIM_DIER_CC1IE;
if (icup->config->width_cb != NULL)
icup->tim->DIER |= TIM_DIER_CC2IE;
} else {
if (icup->config->width_cb != NULL)
icup->tim->DIER |= TIM_DIER_CC1IE;
if (icup->config->period_cb != NULL)
icup->tim->DIER |= TIM_DIER_CC2IE;
}
if (icup->config->overflow_cb != NULL)
icup->tim->DIER |= TIM_DIER_UIE;
icup->tim->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
}
/**
* @brief Disables the input capture.
*
* @param[in] icup pointer to the @p ICUDriver object
*
* @notapi
*/
void icu_lld_disable(ICUDriver *icup) {
icup->tim->CR1 = 0; /* Initially stopped. */
icup->tim->SR = 0; /* Clear pending IRQs (if any). */
icup->tim->DIER = 0; /* Interrupts disabled. */
}
#endif /* HAL_USE_ICU */
/** @} */

View File

@ -1,404 +0,0 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32/icu_lld.h
* @brief STM32 ICU subsystem low level driver header.
*
* @addtogroup ICU
* @{
*/
#ifndef _ICU_LLD_H_
#define _ICU_LLD_H_
#if HAL_USE_ICU || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief ICUD1 driver enable switch.
* @details If set to @p TRUE the support for ICUD1 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_ICU_USE_TIM1) || defined(__DOXYGEN__)
#define STM32_ICU_USE_TIM1 FALSE
#endif
/**
* @brief ICUD2 driver enable switch.
* @details If set to @p TRUE the support for ICUD2 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_ICU_USE_TIM2) || defined(__DOXYGEN__)
#define STM32_ICU_USE_TIM2 FALSE
#endif
/**
* @brief ICUD3 driver enable switch.
* @details If set to @p TRUE the support for ICUD3 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_ICU_USE_TIM3) || defined(__DOXYGEN__)
#define STM32_ICU_USE_TIM3 FALSE
#endif
/**
* @brief ICUD4 driver enable switch.
* @details If set to @p TRUE the support for ICUD4 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_ICU_USE_TIM4) || defined(__DOXYGEN__)
#define STM32_ICU_USE_TIM4 FALSE
#endif
/**
* @brief ICUD5 driver enable switch.
* @details If set to @p TRUE the support for ICUD5 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_ICU_USE_TIM5) || defined(__DOXYGEN__)
#define STM32_ICU_USE_TIM5 FALSE
#endif
/**
* @brief ICUD8 driver enable switch.
* @details If set to @p TRUE the support for ICUD8 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_ICU_USE_TIM8) || defined(__DOXYGEN__)
#define STM32_ICU_USE_TIM8 FALSE
#endif
/**
* @brief ICUD9 driver enable switch.
* @details If set to @p TRUE the support for ICUD9 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_ICU_USE_TIM9) || defined(__DOXYGEN__)
#define STM32_ICU_USE_TIM9 FALSE
#endif
/**
* @brief ICUD1 interrupt priority level setting.
*/
#if !defined(STM32_ICU_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ICU_TIM1_IRQ_PRIORITY 7
#endif
/**
* @brief ICUD2 interrupt priority level setting.
*/
#if !defined(STM32_ICU_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ICU_TIM2_IRQ_PRIORITY 7
#endif
/**
* @brief ICUD3 interrupt priority level setting.
*/
#if !defined(STM32_ICU_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ICU_TIM3_IRQ_PRIORITY 7
#endif
/**
* @brief ICUD4 interrupt priority level setting.
*/
#if !defined(STM32_ICU_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ICU_TIM4_IRQ_PRIORITY 7
#endif
/**
* @brief ICUD5 interrupt priority level setting.
*/
#if !defined(STM32_ICU_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ICU_TIM5_IRQ_PRIORITY 7
#endif
/**
* @brief ICUD8 interrupt priority level setting.
*/
#if !defined(STM32_ICU_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ICU_TIM8_IRQ_PRIORITY 7
#endif
/**
* @brief ICUD9 interrupt priority level setting.
*/
#if !defined(STM32_ICU_TIM9_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ICU_TIM9_IRQ_PRIORITY 7
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if STM32_ICU_USE_TIM1 && !STM32_HAS_TIM1
#error "TIM1 not present in the selected device"
#endif
#if STM32_ICU_USE_TIM2 && !STM32_HAS_TIM2
#error "TIM2 not present in the selected device"
#endif
#if STM32_ICU_USE_TIM3 && !STM32_HAS_TIM3
#error "TIM3 not present in the selected device"
#endif
#if STM32_ICU_USE_TIM4 && !STM32_HAS_TIM4
#error "TIM4 not present in the selected device"
#endif
#if STM32_ICU_USE_TIM5 && !STM32_HAS_TIM5
#error "TIM5 not present in the selected device"
#endif
#if STM32_ICU_USE_TIM8 && !STM32_HAS_TIM8
#error "TIM8 not present in the selected device"
#endif
#if STM32_ICU_USE_TIM9 && !STM32_HAS_TIM9
#error "TIM9 not present in the selected device"
#endif
#if !STM32_ICU_USE_TIM1 && !STM32_ICU_USE_TIM2 && \
!STM32_ICU_USE_TIM3 && !STM32_ICU_USE_TIM4 && \
!STM32_ICU_USE_TIM5 && !STM32_ICU_USE_TIM8 && \
!STM32_ICU_USE_TIM9
#error "ICU driver activated but no TIM peripheral assigned"
#endif
#if STM32_ICU_USE_TIM1 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ICU_TIM1_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM1"
#endif
#if STM32_ICU_USE_TIM2 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ICU_TIM2_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM2"
#endif
#if STM32_ICU_USE_TIM3 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ICU_TIM3_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM3"
#endif
#if STM32_ICU_USE_TIM4 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ICU_TIM4_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM4"
#endif
#if STM32_ICU_USE_TIM5 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ICU_TIM5_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM5"
#endif
#if STM32_ICU_USE_TIM8 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ICU_TIM8_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM8"
#endif
#if STM32_ICU_USE_TIM9 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ICU_TIM9_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM9"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief ICU driver mode.
*/
typedef enum {
ICU_INPUT_ACTIVE_HIGH = 0, /**< Trigger on rising edge. */
ICU_INPUT_ACTIVE_LOW = 1, /**< Trigger on falling edge. */
} icumode_t;
/**
* @brief ICU frequency type.
*/
typedef uint32_t icufreq_t;
/**
* @brief ICU channel type.
*/
typedef enum {
ICU_CHANNEL_1 = 0, /**< Use TIMxCH1. */
ICU_CHANNEL_2 = 1, /**< Use TIMxCH2. */
} icuchannel_t;
/**
* @brief ICU counter type.
*/
typedef uint16_t icucnt_t;
/**
* @brief Driver configuration structure.
* @note It could be empty on some architectures.
*/
typedef struct {
/**
* @brief Driver mode.
*/
icumode_t mode;
/**
* @brief Timer clock in Hz.
* @note The low level can use assertions in order to catch invalid
* frequency specifications.
*/
icufreq_t frequency;
/**
* @brief Callback for pulse width measurement.
*/
icucallback_t width_cb;
/**
* @brief Callback for cycle period measurement.
*/
icucallback_t period_cb;
/**
* @brief Callback for timer overflow.
*/
icucallback_t overflow_cb;
/* End of the mandatory fields.*/
/**
* @brief Timer input channel to be used.
* @note Only inputs TIMx 1 and 2 are supported.
*/
icuchannel_t channel;
} ICUConfig;
/**
* @brief Structure representing an ICU driver.
*/
struct ICUDriver {
/**
* @brief Driver state.
*/
icustate_t state;
/**
* @brief Current configuration data.
*/
const ICUConfig *config;
#if defined(ICU_DRIVER_EXT_FIELDS)
ICU_DRIVER_EXT_FIELDS
#endif
/* End of the mandatory fields.*/
/**
* @brief Timer base clock.
*/
uint32_t clock;
/**
* @brief Pointer to the TIMx registers block.
*/
stm32_tim_t *tim;
/**
* @brief CCR register used for width capture.
*/
volatile uint32_t *wccrp;
/**
* @brief CCR register used for period capture.
*/
volatile uint32_t *pccrp;
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Returns the width of the latest pulse.
* @details The pulse width is defined as number of ticks between the start
* edge and the stop edge.
*
* @param[in] icup pointer to the @p ICUDriver object
* @return The number of ticks.
*
* @notapi
*/
#define icu_lld_get_width(icup) (*((icup)->wccrp) + 1)
/**
* @brief Returns the width of the latest cycle.
* @details The cycle width is defined as number of ticks between a start
* edge and the next start edge.
*
* @param[in] icup pointer to the @p ICUDriver object
* @return The number of ticks.
*
* @notapi
*/
#define icu_lld_get_period(icup) (*((icup)->pccrp) + 1)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if STM32_ICU_USE_TIM1 && !defined(__DOXYGEN__)
extern ICUDriver ICUD1;
#endif
#if STM32_ICU_USE_TIM2 && !defined(__DOXYGEN__)
extern ICUDriver ICUD2;
#endif
#if STM32_ICU_USE_TIM3 && !defined(__DOXYGEN__)
extern ICUDriver ICUD3;
#endif
#if STM32_ICU_USE_TIM4 && !defined(__DOXYGEN__)
extern ICUDriver ICUD4;
#endif
#if STM32_ICU_USE_TIM5 && !defined(__DOXYGEN__)
extern ICUDriver ICUD5;
#endif
#if STM32_ICU_USE_TIM8 && !defined(__DOXYGEN__)
extern ICUDriver ICUD8;
#endif
#if STM32_ICU_USE_TIM9 && !defined(__DOXYGEN__)
extern ICUDriver ICUD9;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void icu_lld_init(void);
void icu_lld_start(ICUDriver *icup);
void icu_lld_stop(ICUDriver *icup);
void icu_lld_enable(ICUDriver *icup);
void icu_lld_disable(ICUDriver *icup);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_ICU */
#endif /* _ICU_LLD_H_ */
/** @} */

View File

@ -1,699 +0,0 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32/pwm_lld.c
* @brief STM32 PWM subsystem low level driver header.
*
* @addtogroup PWM
* @{
*/
#include "hal.h"
#if HAL_USE_PWM || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief PWMD1 driver identifier.
* @note The driver PWMD1 allocates the complex timer TIM1 when enabled.
*/
#if STM32_PWM_USE_TIM1 || defined(__DOXYGEN__)
PWMDriver PWMD1;
#endif
/**
* @brief PWMD2 driver identifier.
* @note The driver PWMD2 allocates the timer TIM2 when enabled.
*/
#if STM32_PWM_USE_TIM2 || defined(__DOXYGEN__)
PWMDriver PWMD2;
#endif
/**
* @brief PWMD3 driver identifier.
* @note The driver PWMD3 allocates the timer TIM3 when enabled.
*/
#if STM32_PWM_USE_TIM3 || defined(__DOXYGEN__)
PWMDriver PWMD3;
#endif
/**
* @brief PWMD4 driver identifier.
* @note The driver PWMD4 allocates the timer TIM4 when enabled.
*/
#if STM32_PWM_USE_TIM4 || defined(__DOXYGEN__)
PWMDriver PWMD4;
#endif
/**
* @brief PWMD5 driver identifier.
* @note The driver PWMD5 allocates the timer TIM5 when enabled.
*/
#if STM32_PWM_USE_TIM5 || defined(__DOXYGEN__)
PWMDriver PWMD5;
#endif
/**
* @brief PWMD8 driver identifier.
* @note The driver PWMD8 allocates the timer TIM8 when enabled.
*/
#if STM32_PWM_USE_TIM8 || defined(__DOXYGEN__)
PWMDriver PWMD8;
#endif
/**
* @brief PWMD9 driver identifier.
* @note The driver PWMD9 allocates the timer TIM9 when enabled.
*/
#if STM32_PWM_USE_TIM9 || defined(__DOXYGEN__)
PWMDriver PWMD9;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
#if STM32_PWM_USE_TIM2 || STM32_PWM_USE_TIM3 || STM32_PWM_USE_TIM4 || \
STM32_PWM_USE_TIM5 || STM32_PWM_USE_TIM9 || defined(__DOXYGEN__)
/**
* @brief Common TIM2...TIM5,TIM9 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.
*
* @param[in] pwmp pointer to a @p PWMDriver object
*/
static void pwm_lld_serve_interrupt(PWMDriver *pwmp) {
uint16_t sr;
sr = pwmp->tim->SR;
sr &= pwmp->tim->DIER;
pwmp->tim->SR = ~sr;
if ((sr & TIM_SR_CC1IF) != 0)
pwmp->config->channels[0].callback(pwmp);
if ((sr & TIM_SR_CC2IF) != 0)
pwmp->config->channels[1].callback(pwmp);
if ((sr & TIM_SR_CC3IF) != 0)
pwmp->config->channels[2].callback(pwmp);
if ((sr & TIM_SR_CC4IF) != 0)
pwmp->config->channels[3].callback(pwmp);
if ((sr & TIM_SR_UIF) != 0)
pwmp->config->callback(pwmp);
}
#endif
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if STM32_PWM_USE_TIM1
#if !defined(STM32_TIM1_UP_HANDLER)
#error "STM32_TIM1_UP_HANDLER not defined"
#endif
/**
* @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.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) {
CH_IRQ_PROLOGUE();
STM32_TIM1->SR = ~TIM_SR_UIF;
PWMD1.config->callback(&PWMD1);
CH_IRQ_EPILOGUE();
}
#if !defined(STM32_TIM1_CC_HANDLER)
#error "STM32_TIM1_CC_HANDLER not defined"
#endif
/**
* @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.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) {
uint16_t sr;
CH_IRQ_PROLOGUE();
sr = STM32_TIM1->SR & STM32_TIM1->DIER;
STM32_TIM1->SR = ~(TIM_SR_CC1IF | TIM_SR_CC2IF |
TIM_SR_CC3IF | TIM_SR_CC4IF);
if ((sr & TIM_SR_CC1IF) != 0)
PWMD1.config->channels[0].callback(&PWMD1);
if ((sr & TIM_SR_CC2IF) != 0)
PWMD1.config->channels[1].callback(&PWMD1);
if ((sr & TIM_SR_CC3IF) != 0)
PWMD1.config->channels[2].callback(&PWMD1);
if ((sr & TIM_SR_CC4IF) != 0)
PWMD1.config->channels[3].callback(&PWMD1);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_PWM_USE_TIM1 */
#if STM32_PWM_USE_TIM2
#if !defined(STM32_TIM2_HANDLER)
#error "STM32_TIM2_HANDLER not defined"
#endif
/**
* @brief TIM2 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM2_HANDLER) {
CH_IRQ_PROLOGUE();
pwm_lld_serve_interrupt(&PWMD2);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_PWM_USE_TIM2 */
#if STM32_PWM_USE_TIM3
#if !defined(STM32_TIM3_HANDLER)
#error "STM32_TIM3_HANDLER not defined"
#endif
/**
* @brief TIM3 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM3_HANDLER) {
CH_IRQ_PROLOGUE();
pwm_lld_serve_interrupt(&PWMD3);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_PWM_USE_TIM3 */
#if STM32_PWM_USE_TIM4
#if !defined(STM32_TIM4_HANDLER)
#error "STM32_TIM4_HANDLER not defined"
#endif
/**
* @brief TIM4 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM4_HANDLER) {
CH_IRQ_PROLOGUE();
pwm_lld_serve_interrupt(&PWMD4);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_PWM_USE_TIM4 */
#if STM32_PWM_USE_TIM5
#if !defined(STM32_TIM5_HANDLER)
#error "STM32_TIM5_HANDLER not defined"
#endif
/**
* @brief TIM5 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM5_HANDLER) {
CH_IRQ_PROLOGUE();
pwm_lld_serve_interrupt(&PWMD5);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_PWM_USE_TIM5 */
#if STM32_PWM_USE_TIM8
#if !defined(STM32_TIM8_UP_HANDLER)
#error "STM32_TIM8_UP_HANDLER not defined"
#endif
/**
* @brief TIM8 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.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) {
CH_IRQ_PROLOGUE();
STM32_TIM8->SR = ~TIM_SR_UIF;
PWMD8.config->callback(&PWMD8);
CH_IRQ_EPILOGUE();
}
#if !defined(STM32_TIM8_CC_HANDLER)
#error "STM32_TIM8_CC_HANDLER not defined"
#endif
/**
* @brief TIM8 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.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) {
uint16_t sr;
CH_IRQ_PROLOGUE();
sr = STM32_TIM8->SR & STM32_TIM8->DIER;
STM32_TIM8->SR = ~(TIM_SR_CC1IF | TIM_SR_CC2IF |
TIM_SR_CC3IF | TIM_SR_CC4IF);
if ((sr & TIM_SR_CC1IF) != 0)
PWMD8.config->channels[0].callback(&PWMD8);
if ((sr & TIM_SR_CC2IF) != 0)
PWMD8.config->channels[1].callback(&PWMD8);
if ((sr & TIM_SR_CC3IF) != 0)
PWMD8.config->channels[2].callback(&PWMD8);
if ((sr & TIM_SR_CC4IF) != 0)
PWMD8.config->channels[3].callback(&PWMD8);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_PWM_USE_TIM8 */
#if STM32_PWM_USE_TIM9
#if !defined(STM32_TIM9_HANDLER)
#error "STM32_TIM9_HANDLER not defined"
#endif
/**
* @brief TIM9 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(STM32_TIM9_HANDLER) {
CH_IRQ_PROLOGUE();
pwm_lld_serve_interrupt(&PWMD9);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_PWM_USE_TIM9 */
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level PWM driver initialization.
*
* @notapi
*/
void pwm_lld_init(void) {
#if STM32_PWM_USE_TIM1
/* Driver initialization.*/
pwmObjectInit(&PWMD1);
PWMD1.tim = STM32_TIM1;
#endif
#if STM32_PWM_USE_TIM2
/* Driver initialization.*/
pwmObjectInit(&PWMD2);
PWMD2.tim = STM32_TIM2;
#endif
#if STM32_PWM_USE_TIM3
/* Driver initialization.*/
pwmObjectInit(&PWMD3);
PWMD3.tim = STM32_TIM3;
#endif
#if STM32_PWM_USE_TIM4
/* Driver initialization.*/
pwmObjectInit(&PWMD4);
PWMD4.tim = STM32_TIM4;
#endif
#if STM32_PWM_USE_TIM5
/* Driver initialization.*/
pwmObjectInit(&PWMD5);
PWMD5.tim = STM32_TIM5;
#endif
#if STM32_PWM_USE_TIM8
/* Driver initialization.*/
pwmObjectInit(&PWMD8);
PWMD8.tim = STM32_TIM8;
#endif
#if STM32_PWM_USE_TIM9
/* Driver initialization.*/
pwmObjectInit(&PWMD9);
PWMD9.tim = STM32_TIM9;
#endif
}
/**
* @brief Configures and activates the PWM peripheral.
* @note Starting a driver that is already in the @p PWM_READY state
* disables all the active channels.
*
* @param[in] pwmp pointer to a @p PWMDriver object
*
* @notapi
*/
void pwm_lld_start(PWMDriver *pwmp) {
uint32_t psc;
uint16_t ccer;
if (pwmp->state == PWM_STOP) {
/* Clock activation and timer reset.*/
#if STM32_PWM_USE_TIM1
if (&PWMD1 == pwmp) {
rccEnableTIM1(FALSE);
rccResetTIM1();
nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_PWM_TIM1_IRQ_PRIORITY);
nvicEnableVector(STM32_TIM1_CC_NUMBER, STM32_PWM_TIM1_IRQ_PRIORITY);
pwmp->clock = STM32_TIMCLK2;
}
#endif
#if STM32_PWM_USE_TIM2
if (&PWMD2 == pwmp) {
rccEnableTIM2(FALSE);
rccResetTIM2();
nvicEnableVector(STM32_TIM2_NUMBER, STM32_PWM_TIM2_IRQ_PRIORITY);
pwmp->clock = STM32_TIMCLK1;
}
#endif
#if STM32_PWM_USE_TIM3
if (&PWMD3 == pwmp) {
rccEnableTIM3(FALSE);
rccResetTIM3();
nvicEnableVector(STM32_TIM3_NUMBER, STM32_PWM_TIM3_IRQ_PRIORITY);
pwmp->clock = STM32_TIMCLK1;
}
#endif
#if STM32_PWM_USE_TIM4
if (&PWMD4 == pwmp) {
rccEnableTIM4(FALSE);
rccResetTIM4();
nvicEnableVector(STM32_TIM4_NUMBER, STM32_PWM_TIM4_IRQ_PRIORITY);
pwmp->clock = STM32_TIMCLK1;
}
#endif
#if STM32_PWM_USE_TIM5
if (&PWMD5 == pwmp) {
rccEnableTIM5(FALSE);
rccResetTIM5();
nvicEnableVector(STM32_TIM5_NUMBER, STM32_PWM_TIM5_IRQ_PRIORITY);
pwmp->clock = STM32_TIMCLK1;
}
#endif
#if STM32_PWM_USE_TIM8
if (&PWMD8 == pwmp) {
rccEnableTIM8(FALSE);
rccResetTIM8();
nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_PWM_TIM8_IRQ_PRIORITY);
nvicEnableVector(STM32_TIM8_CC_NUMBER, STM32_PWM_TIM8_IRQ_PRIORITY);
pwmp->clock = STM32_TIMCLK2;
}
#endif
#if STM32_PWM_USE_TIM9
if (&PWMD9 == pwmp) {
rccEnableTIM9(FALSE);
rccResetTIM9();
nvicEnableVector(STM32_TIM9_NUMBER, STM32_PWM_TIM9_IRQ_PRIORITY);
pwmp->clock = STM32_TIMCLK1;
}
#endif
/* All channels configured in PWM1 mode with preload enabled and will
stay that way until the driver is stopped.*/
pwmp->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->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.*/
pwmp->tim->CR1 = 0; /* Timer disabled. */
pwmp->tim->DIER = 0; /* All IRQs disabled. */
pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */
pwmp->tim->CCR[0] = 0; /* Comparator 1 disabled. */
pwmp->tim->CCR[1] = 0; /* Comparator 2 disabled. */
pwmp->tim->CCR[2] = 0; /* Comparator 3 disabled. */
pwmp->tim->CCR[3] = 0; /* Comparator 4 disabled. */
pwmp->tim->CNT = 0; /* Counter reset to zero. */
}
/* Timer configuration.*/
psc = (pwmp->clock / pwmp->config->frequency) - 1;
osalDbgAssert((psc <= 0xFFFF) &&
((psc + 1) * pwmp->config->frequency) == pwmp->clock,
"invalid frequency");
pwmp->tim->PSC = (uint16_t)psc;
pwmp->tim->ARR = (uint16_t)(pwmp->period - 1);
pwmp->tim->CR2 = pwmp->config->cr2;
/* Output enables and polarities setup.*/
ccer = 0;
switch (pwmp->config->channels[0].mode & PWM_OUTPUT_MASK) {
case PWM_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC1P;
case PWM_OUTPUT_ACTIVE_HIGH:
ccer |= TIM_CCER_CC1E;
default:
;
}
switch (pwmp->config->channels[1].mode & PWM_OUTPUT_MASK) {
case PWM_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC2P;
case PWM_OUTPUT_ACTIVE_HIGH:
ccer |= TIM_CCER_CC2E;
default:
;
}
switch (pwmp->config->channels[2].mode & PWM_OUTPUT_MASK) {
case PWM_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC3P;
case PWM_OUTPUT_ACTIVE_HIGH:
ccer |= TIM_CCER_CC3E;
default:
;
}
switch (pwmp->config->channels[3].mode & PWM_OUTPUT_MASK) {
case PWM_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC4P;
case PWM_OUTPUT_ACTIVE_HIGH:
ccer |= TIM_CCER_CC4E;
default:
;
}
#if STM32_PWM_USE_ADVANCED
#if STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8
if (&PWMD1 == pwmp) {
#endif
#if !STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8
if (&PWMD8 == pwmp) {
#endif
#if STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8
if ((&PWMD1 == pwmp) || (&PWMD8 == pwmp)) {
#endif
switch (pwmp->config->channels[0].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC1NP;
case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
ccer |= TIM_CCER_CC1NE;
default:
;
}
switch (pwmp->config->channels[1].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC2NP;
case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
ccer |= TIM_CCER_CC2NE;
default:
;
}
switch (pwmp->config->channels[2].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC3NP;
case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
ccer |= TIM_CCER_CC3NE;
default:
;
}
}
#endif /* STM32_PWM_USE_ADVANCED*/
pwmp->tim->CCER = ccer;
pwmp->tim->EGR = TIM_EGR_UG; /* Update event. */
pwmp->tim->DIER = pwmp->config->callback == NULL ? 0 : TIM_DIER_UIE;
pwmp->tim->SR = 0; /* Clear pending IRQs. */
#if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8
#if STM32_PWM_USE_ADVANCED
pwmp->tim->BDTR = pwmp->config->bdtr | TIM_BDTR_MOE;
#else
pwmp->tim->BDTR = TIM_BDTR_MOE;
#endif
#endif
/* Timer configured and started.*/
pwmp->tim->CR1 = TIM_CR1_ARPE | TIM_CR1_URS | TIM_CR1_CEN;
}
/**
* @brief Deactivates the PWM peripheral.
*
* @param[in] pwmp pointer to a @p PWMDriver object
*
* @notapi
*/
void pwm_lld_stop(PWMDriver *pwmp) {
/* If in ready state then disables the PWM clock.*/
if (pwmp->state == PWM_READY) {
pwmp->tim->CR1 = 0; /* Timer disabled. */
pwmp->tim->DIER = 0; /* All IRQs disabled. */
pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */
#if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8
pwmp->tim->BDTR = 0;
#endif
#if STM32_PWM_USE_TIM1
if (&PWMD1 == pwmp) {
nvicDisableVector(STM32_TIM1_UP_NUMBER);
nvicDisableVector(STM32_TIM1_CC_NUMBER);
rccDisableTIM1(FALSE);
}
#endif
#if STM32_PWM_USE_TIM2
if (&PWMD2 == pwmp) {
nvicDisableVector(STM32_TIM2_NUMBER);
rccDisableTIM2(FALSE);
}
#endif
#if STM32_PWM_USE_TIM3
if (&PWMD3 == pwmp) {
nvicDisableVector(STM32_TIM3_NUMBER);
rccDisableTIM3(FALSE);
}
#endif
#if STM32_PWM_USE_TIM4
if (&PWMD4 == pwmp) {
nvicDisableVector(STM32_TIM4_NUMBER);
rccDisableTIM4(FALSE);
}
#endif
#if STM32_PWM_USE_TIM5
if (&PWMD5 == pwmp) {
nvicDisableVector(STM32_TIM5_NUMBER);
rccDisableTIM5(FALSE);
}
#endif
#if STM32_PWM_USE_TIM8
if (&PWMD8 == pwmp) {
nvicDisableVector(STM32_TIM8_UP_NUMBER);
nvicDisableVector(STM32_TIM8_CC_NUMBER);
rccDisableTIM8(FALSE);
}
#endif
#if STM32_PWM_USE_TIM9
if (&PWMD9 == pwmp) {
nvicDisableVector(STM32_TIM9_NUMBER);
rccDisableTIM9(FALSE);
}
#endif
}
}
/**
* @brief Enables a PWM channel.
* @pre The PWM unit must have been activated using @p pwmStart().
* @post The channel is active using the specified configuration.
* @note The function has effect at the next cycle start.
*
* @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
*
* @notapi
*/
void pwm_lld_enable_channel(PWMDriver *pwmp,
pwmchannel_t channel,
pwmcnt_t width) {
pwmp->tim->CCR[channel] = width; /* New duty cycle. */
/* If there is a callback defined for the channel then the associated
interrupt must be enabled.*/
if (pwmp->config->channels[channel].callback != NULL) {
uint32_t dier = pwmp->tim->DIER;
/* If the IRQ is not already enabled care must be taken to clear it,
it is probably already pending because the timer is running.*/
if ((dier & (2 << channel)) == 0) {
pwmp->tim->DIER = dier | (2 << channel);
pwmp->tim->SR = ~(2 << channel);
}
}
}
/**
* @brief Disables a PWM channel.
* @pre The PWM unit must have been activated using @p pwmStart().
* @post The channel is disabled and its output line returned to the
* idle state.
* @note The function has effect at the next cycle start.
*
* @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->tim->CCR[channel] = 0;
pwmp->tim->DIER &= ~(2 << channel);
}
#endif /* HAL_USE_PWM */
/** @} */

View File

@ -1,472 +0,0 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32/pwm_lld.h
* @brief STM32 PWM subsystem low level driver header.
*
* @addtogroup PWM
* @{
*/
#ifndef _PWM_LLD_H_
#define _PWM_LLD_H_
#if HAL_USE_PWM || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Number of PWM channels per PWM driver.
*/
#define PWM_CHANNELS 4
/**
* @brief Complementary output modes mask.
* @note This is an STM32-specific setting.
*/
#define PWM_COMPLEMENTARY_OUTPUT_MASK 0xF0
/**
* @brief Complementary output not driven.
* @note This is an STM32-specific setting.
*/
#define PWM_COMPLEMENTARY_OUTPUT_DISABLED 0x00
/**
* @brief Complementary output, active is logic level one.
* @note This is an STM32-specific setting.
* @note This setting is only available if the configuration option
* @p STM32_PWM_USE_ADVANCED is set to TRUE and only for advanced
* timers TIM1 and TIM8.
*/
#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH 0x10
/**
* @brief Complementary output, active is logic level zero.
* @note This is an STM32-specific setting.
* @note This setting is only available if the configuration option
* @p STM32_PWM_USE_ADVANCED is set to TRUE and only for advanced
* timers TIM1 and TIM8.
*/
#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW 0x20
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief If advanced timer features switch.
* @details If set to @p TRUE the advanced features for TIM1 and TIM8 are
* enabled.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_ADVANCED) || defined(__DOXYGEN__)
#define STM32_PWM_USE_ADVANCED FALSE
#endif
/**
* @brief PWMD1 driver enable switch.
* @details If set to @p TRUE the support for PWMD1 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM1) || defined(__DOXYGEN__)
#define STM32_PWM_USE_TIM1 FALSE
#endif
/**
* @brief PWMD2 driver enable switch.
* @details If set to @p TRUE the support for PWMD2 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM2) || defined(__DOXYGEN__)
#define STM32_PWM_USE_TIM2 FALSE
#endif
/**
* @brief PWMD3 driver enable switch.
* @details If set to @p TRUE the support for PWMD3 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM3) || defined(__DOXYGEN__)
#define STM32_PWM_USE_TIM3 FALSE
#endif
/**
* @brief PWMD4 driver enable switch.
* @details If set to @p TRUE the support for PWMD4 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM4) || defined(__DOXYGEN__)
#define STM32_PWM_USE_TIM4 FALSE
#endif
/**
* @brief PWMD5 driver enable switch.
* @details If set to @p TRUE the support for PWMD5 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM5) || defined(__DOXYGEN__)
#define STM32_PWM_USE_TIM5 FALSE
#endif
/**
* @brief PWMD8 driver enable switch.
* @details If set to @p TRUE the support for PWMD8 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM8) || defined(__DOXYGEN__)
#define STM32_PWM_USE_TIM8 FALSE
#endif
/**
* @brief PWMD9 driver enable switch.
* @details If set to @p TRUE the support for PWMD9 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM9) || defined(__DOXYGEN__)
#define STM32_PWM_USE_TIM9 FALSE
#endif
/**
* @brief PWMD1 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM1_IRQ_PRIORITY 7
#endif
/**
* @brief PWMD2 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM2_IRQ_PRIORITY 7
#endif
/**
* @brief PWMD3 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM3_IRQ_PRIORITY 7
#endif
/**
* @brief PWMD4 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM4_IRQ_PRIORITY 7
#endif
/**
* @brief PWMD5 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM5_IRQ_PRIORITY 7
#endif
/**
* @brief PWMD8 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM8_IRQ_PRIORITY 7
#endif
/** @} */
/**
* @brief PWMD9 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM9_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM9_IRQ_PRIORITY 7
#endif
/** @} */
/*===========================================================================*/
/* Configuration checks. */
/*===========================================================================*/
#if STM32_PWM_USE_TIM1 && !STM32_HAS_TIM1
#error "TIM1 not present in the selected device"
#endif
#if STM32_PWM_USE_TIM2 && !STM32_HAS_TIM2
#error "TIM2 not present in the selected device"
#endif
#if STM32_PWM_USE_TIM3 && !STM32_HAS_TIM3
#error "TIM3 not present in the selected device"
#endif
#if STM32_PWM_USE_TIM4 && !STM32_HAS_TIM4
#error "TIM4 not present in the selected device"
#endif
#if STM32_PWM_USE_TIM5 && !STM32_HAS_TIM5
#error "TIM5 not present in the selected device"
#endif
#if STM32_PWM_USE_TIM8 && !STM32_HAS_TIM8
#error "TIM8 not present in the selected device"
#endif
#if STM32_PWM_USE_TIM9 && !STM32_HAS_TIM9
#error "TIM9 not present in the selected device"
#endif
#if !STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM2 && \
!STM32_PWM_USE_TIM3 && !STM32_PWM_USE_TIM4 && \
!STM32_PWM_USE_TIM5 && !STM32_PWM_USE_TIM8 && \
!STM32_PWM_USE_TIM9
#error "PWM driver activated but no TIM peripheral assigned"
#endif
#if STM32_PWM_USE_ADVANCED && !STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8
#error "advanced mode selected but no advanced timer assigned"
#endif
#if STM32_PWM_USE_TIM1 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_PWM_TIM1_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM1"
#endif
#if STM32_PWM_USE_TIM2 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_PWM_TIM2_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM2"
#endif
#if STM32_PWM_USE_TIM3 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_PWM_TIM3_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM3"
#endif
#if STM32_PWM_USE_TIM4 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_PWM_TIM4_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM4"
#endif
#if STM32_PWM_USE_TIM5 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_PWM_TIM5_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM5"
#endif
#if STM32_PWM_USE_TIM8 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_PWM_TIM8_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM8"
#endif
#if STM32_PWM_USE_TIM9 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_PWM_TIM9_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to TIM9"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief PWM mode type.
*/
typedef uint32_t pwmmode_t;
/**
* @brief PWM channel type.
*/
typedef uint8_t pwmchannel_t;
/**
* @brief PWM counter type.
*/
typedef uint16_t pwmcnt_t;
/**
* @brief PWM driver channel configuration structure.
*/
typedef struct {
/**
* @brief Channel active logic level.
*/
pwmmode_t mode;
/**
* @brief Channel callback pointer.
* @note This callback is invoked on the channel compare event. If set to
* @p NULL then the callback is disabled.
*/
pwmcallback_t callback;
/* End of the mandatory fields.*/
} PWMChannelConfig;
/**
* @brief PWM driver configuration structure.
*/
typedef struct {
/**
* @brief Timer clock in Hz.
* @note The low level can use assertions in order to catch invalid
* frequency specifications.
*/
uint32_t frequency;
/**
* @brief PWM period in ticks.
* @note The low level can use assertions in order to catch invalid
* period specifications.
*/
pwmcnt_t period;
/**
* @brief Periodic callback pointer.
* @note This callback is invoked on PWM counter reset. If set to
* @p NULL then the callback is disabled.
*/
pwmcallback_t callback;
/**
* @brief Channels configurations.
*/
PWMChannelConfig channels[PWM_CHANNELS];
/* End of the mandatory fields.*/
/**
* @brief TIM CR2 register initialization data.
* @note The value of this field should normally be equal to zero.
*/
uint16_t cr2;
#if STM32_PWM_USE_ADVANCED || defined(__DOXYGEN__)
/**
* @brief TIM BDTR (break & dead-time) register initialization data.
* @note The value of this field should normally be equal to zero.
*/ \
uint16_t bdtr;
#endif
} PWMConfig;
/**
* @brief Structure representing a PWM driver.
*/
struct PWMDriver {
/**
* @brief Driver state.
*/
pwmstate_t state;
/**
* @brief Current driver configuration data.
*/
const PWMConfig *config;
/**
* @brief Current PWM period in ticks.
*/
pwmcnt_t period;
#if defined(PWM_DRIVER_EXT_FIELDS)
PWM_DRIVER_EXT_FIELDS
#endif
/* End of the mandatory fields.*/
/**
* @brief Timer base clock.
*/
uint32_t clock;
/**
* @brief Pointer to the TIMx registers block.
*/
stm32_tim_t *tim;
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Changes the period the PWM peripheral.
* @details This function changes the period of a PWM unit that has already
* been activated using @p pwmStart().
* @pre The PWM unit must have been activated using @p pwmStart().
* @post The PWM unit period is changed to the new value.
* @note The function has effect at the next cycle start.
* @note If a period is specified that is shorter than the pulse width
* programmed in one of the channels then the behavior is not
* guaranteed.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] period new cycle time in ticks
*
* @notapi
*/
#define pwm_lld_change_period(pwmp, period) \
((pwmp)->tim->ARR = (uint16_t)((period) - 1))
/**
* @brief Returns a PWM channel status.
* @pre The PWM unit must have been activated using @p pwmStart().
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
*
* @notapi
*/
#define pwm_lld_is_channel_enabled(pwmp, channel) \
(((pwmp)->tim->CCR[channel] != 0) || \
(((pwmp)->tim->DIER & (2 << channel)) != 0))
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if STM32_PWM_USE_TIM1 && !defined(__DOXYGEN__)
extern PWMDriver PWMD1;
#endif
#if STM32_PWM_USE_TIM2 && !defined(__DOXYGEN__)
extern PWMDriver PWMD2;
#endif
#if STM32_PWM_USE_TIM3 && !defined(__DOXYGEN__)
extern PWMDriver PWMD3;
#endif
#if STM32_PWM_USE_TIM4 && !defined(__DOXYGEN__)
extern PWMDriver PWMD4;
#endif
#if STM32_PWM_USE_TIM5 && !defined(__DOXYGEN__)
extern PWMDriver PWMD5;
#endif
#if STM32_PWM_USE_TIM8 && !defined(__DOXYGEN__)
extern PWMDriver PWMD8;
#endif
#if STM32_PWM_USE_TIM9 && !defined(__DOXYGEN__)
extern PWMDriver PWMD9;
#endif
#ifdef __cplusplus
extern "C" {
#endif
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);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_PWM */
#endif /* _PWM_LLD_H_ */
/** @} */

View File

@ -87,72 +87,10 @@
/* Driver data structures and types. */ /* Driver data structures and types. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @brief STM32 TIM registers block.
* @note Redefined from the ST headers because the non uniform
* declaration of the CCR registers among the various
* sub-families.
*/
typedef struct {
volatile uint16_t CR1;
uint16_t _resvd0;
volatile uint16_t CR2;
uint16_t _resvd1;
volatile uint16_t SMCR;
uint16_t _resvd2;
volatile uint16_t DIER;
uint16_t _resvd3;
volatile uint16_t SR;
uint16_t _resvd4;
volatile uint16_t EGR;
uint16_t _resvd5;
volatile uint16_t CCMR1;
uint16_t _resvd6;
volatile uint16_t CCMR2;
uint16_t _resvd7;
volatile uint16_t CCER;
uint16_t _resvd8;
volatile uint32_t CNT;
volatile uint16_t PSC;
uint16_t _resvd9;
volatile uint32_t ARR;
volatile uint16_t RCR;
uint16_t _resvd10;
volatile uint32_t CCR[4];
volatile uint16_t BDTR;
uint16_t _resvd11;
volatile uint16_t DCR;
uint16_t _resvd12;
volatile uint16_t DMAR;
uint16_t _resvd13;
volatile uint16_t OR;
uint16_t _resvd14;
} stm32_tim_t;
/*===========================================================================*/ /*===========================================================================*/
/* Driver macros. */ /* Driver macros. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name TIM units references
* @{
*/
#define STM32_TIM1 ((stm32_tim_t *)TIM1_BASE)
#define STM32_TIM2 ((stm32_tim_t *)TIM2_BASE)
#define STM32_TIM3 ((stm32_tim_t *)TIM3_BASE)
#define STM32_TIM4 ((stm32_tim_t *)TIM4_BASE)
#define STM32_TIM5 ((stm32_tim_t *)TIM5_BASE)
#define STM32_TIM6 ((stm32_tim_t *)TIM6_BASE)
#define STM32_TIM7 ((stm32_tim_t *)TIM7_BASE)
#define STM32_TIM8 ((stm32_tim_t *)TIM8_BASE)
#define STM32_TIM9 ((stm32_tim_t *)TIM9_BASE)
#define STM32_TIM10 ((stm32_tim_t *)TIM10_BASE)
#define STM32_TIM11 ((stm32_tim_t *)TIM11_BASE)
#define STM32_TIM12 ((stm32_tim_t *)TIM12_BASE)
#define STM32_TIM13 ((stm32_tim_t *)TIM13_BASE)
#define STM32_TIM14 ((stm32_tim_t *)TIM14_BASE)
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -6,14 +6,14 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/common/ARMCMx/nvic.c \
${CHIBIOS}/os/hal/platforms/STM32F30x/ext_lld_isr.c \ ${CHIBIOS}/os/hal/platforms/STM32F30x/ext_lld_isr.c \
${CHIBIOS}/os/hal/platforms/STM32/can_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/can_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/ext_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/ext_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/icu_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/pwm_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/st_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/st_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/I2Cv2/i2c_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/I2Cv2/i2c_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/RTCv2/rtc_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/RTCv2/rtc_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/SPIv2/spi_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/SPIv2/spi_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/TIMv1/gpt_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/TIMv1/icu_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/TIMv1/pwm_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/USARTv2/serial_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/USARTv2/serial_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/USARTv2/uart_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/USARTv2/uart_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/USBv1/usb_lld.c ${CHIBIOS}/os/hal/platforms/STM32/USBv1/usb_lld.c
@ -26,5 +26,6 @@ PLATFORMINC = ${CHIBIOS}/os/hal/platforms/common/ARMCMx \
${CHIBIOS}/os/hal/platforms/STM32/I2Cv2 \ ${CHIBIOS}/os/hal/platforms/STM32/I2Cv2 \
${CHIBIOS}/os/hal/platforms/STM32/RTCv2 \ ${CHIBIOS}/os/hal/platforms/STM32/RTCv2 \
${CHIBIOS}/os/hal/platforms/STM32/SPIv2 \ ${CHIBIOS}/os/hal/platforms/STM32/SPIv2 \
${CHIBIOS}/os/hal/platforms/STM32/TIMv1 \
${CHIBIOS}/os/hal/platforms/STM32/USARTv2 \ ${CHIBIOS}/os/hal/platforms/STM32/USARTv2 \
${CHIBIOS}/os/hal/platforms/STM32/USBv1 ${CHIBIOS}/os/hal/platforms/STM32/USBv1