From 6c97d4f6fb4184c41f6283ce025a7030280a1802 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 31 Aug 2014 17:21:02 +0000 Subject: Enhanced ICU driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7211 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/icu.h | 7 +++---- os/hal/ports/STM32/LLD/TIMv1/icu_lld.c | 26 +++++++++++++++++++------- os/hal/ports/STM32/LLD/TIMv1/pwm_lld.c | 2 +- testhal/STM32/STM32F0xx/PWM-ICU/main.c | 9 +++++---- testhal/STM32/STM32F1xx/PWM-ICU/main.c | 9 +++++---- testhal/STM32/STM32F30x/PWM-ICU/main.c | 1 + testhal/STM32/STM32F37x/PWM-ICU/.cproject | 1 + testhal/STM32/STM32F37x/PWM-ICU/main.c | 9 +++++---- testhal/STM32/STM32F4xx/PWM-ICU/main.c | 9 +++++---- testhal/STM32/STM32L1xx/PWM-ICU/main.c | 9 +++++---- 10 files changed, 50 insertions(+), 32 deletions(-) diff --git a/os/hal/include/icu.h b/os/hal/include/icu.h index 1839c214f..0b85aa97b 100644 --- a/os/hal/include/icu.h +++ b/os/hal/include/icu.h @@ -183,7 +183,7 @@ typedef void (*icucallback_t)(ICUDriver *icup); * @notapi */ #define _icu_isr_invoke_width_cb(icup) do { \ - if (((icup)->state != ICU_WAITING) && \ + if (((icup)->state == ICU_ACTIVE) && \ ((icup)->config->period_cb != NULL)) \ (icup)->config->width_cb(icup); \ } while (0) @@ -196,11 +196,10 @@ typedef void (*icucallback_t)(ICUDriver *icup); * @notapi */ #define _icu_isr_invoke_period_cb(icup) do { \ - icustate_t previous_state = (icup)->state; \ - (icup)->state = ICU_ACTIVE; \ - if ((previous_state != ICU_WAITING) && \ + if (((icup)->state == ICU_ACTIVE) && \ ((icup)->config->period_cb != NULL)) \ (icup)->config->period_cb(icup); \ + (icup)->state = ICU_ACTIVE; \ } while (0) /** diff --git a/os/hal/ports/STM32/LLD/TIMv1/icu_lld.c b/os/hal/ports/STM32/LLD/TIMv1/icu_lld.c index 1602ac1d1..6ee7ff293 100644 --- a/os/hal/ports/STM32/LLD/TIMv1/icu_lld.c +++ b/os/hal/ports/STM32/LLD/TIMv1/icu_lld.c @@ -108,17 +108,18 @@ ICUDriver ICUD9; * @param[in] icup pointer to the @p ICUDriver object */ static void icu_lld_serve_interrupt(ICUDriver *icup) { - uint16_t sr; + uint32_t sr; sr = icup->tim->SR; sr &= icup->tim->DIER & STM32_TIM_DIER_IRQ_MASK; icup->tim->SR = ~sr; if (icup->config->channel == ICU_CHANNEL_1) { - if ((sr & STM32_TIM_SR_CC1IF) != 0) - _icu_isr_invoke_period_cb(icup); if ((sr & STM32_TIM_SR_CC2IF) != 0) _icu_isr_invoke_width_cb(icup); - } else { + if ((sr & STM32_TIM_SR_CC1IF) != 0) + _icu_isr_invoke_period_cb(icup); + } + else { if ((sr & STM32_TIM_SR_CC1IF) != 0) _icu_isr_invoke_width_cb(icup); if ((sr & STM32_TIM_SR_CC2IF) != 0) @@ -506,7 +507,8 @@ void icu_lld_start(ICUDriver *icup) { data faster from within callbacks.*/ icup->wccrp = &icup->tim->CCR[1]; icup->pccrp = &icup->tim->CCR[0]; - } else { + } + else { /* Selected input 2. CCMR1_CC1S = 10 = CH1 Input on TI2. CCMR1_CC2S = 01 = CH2 Input on TI2.*/ @@ -618,6 +620,7 @@ void icu_lld_start_capture(ICUDriver *icup) { * brings the driver in the @p ICU_ACTIVE state. * @note If notifications are enabled then the transition to the * @p ICU_ACTIVE state is done automatically on the first edge. + * @note The wait is performed in polled mode. * * @param[in] icup pointer to the @p ICUDriver object * @@ -625,6 +628,14 @@ void icu_lld_start_capture(ICUDriver *icup) { */ void icu_lld_wait_capture(ICUDriver *icup) { + if (icup->config->channel == ICU_CHANNEL_1) { + while ((icup->tim->SR & STM32_TIM_SR_CC1IF) == 0) + ; + } + else { + while ((icup->tim->SR & STM32_TIM_SR_CC2IF) == 0) + ; + } } /** @@ -658,7 +669,7 @@ void icu_enable_notifications(ICUDriver *icup) { /* If interrupts were already enabled then the operation is skipped. This is done in order to avoid clearing the SR and risk losing pending interrupts.*/ - if ((dier & STM32_TIM_DIER_IRQ_MASK) != 0) { + if ((dier & STM32_TIM_DIER_IRQ_MASK) == 0) { /* Previously triggered IRQs are ignored, status cleared.*/ icup->tim->SR = 0; @@ -669,7 +680,8 @@ void icu_enable_notifications(ICUDriver *icup) { /* Optionally enabling width callback on CC2.*/ if (icup->config->width_cb != NULL) dier |= STM32_TIM_DIER_CC2IE; - } else { + } + else { /* Enabling periodic callback on CC2.*/ dier |= STM32_TIM_DIER_CC2IE; diff --git a/os/hal/ports/STM32/LLD/TIMv1/pwm_lld.c b/os/hal/ports/STM32/LLD/TIMv1/pwm_lld.c index 2b633c2e2..50884c5c8 100644 --- a/os/hal/ports/STM32/LLD/TIMv1/pwm_lld.c +++ b/os/hal/ports/STM32/LLD/TIMv1/pwm_lld.c @@ -109,7 +109,7 @@ PWMDriver PWMD9; * @param[in] pwmp pointer to a @p PWMDriver object */ static void pwm_lld_serve_interrupt(PWMDriver *pwmp) { - uint16_t sr; + uint32_t sr; sr = pwmp->tim->SR; sr &= pwmp->tim->DIER & STM32_TIM_DIER_IRQ_MASK; diff --git a/testhal/STM32/STM32F0xx/PWM-ICU/main.c b/testhal/STM32/STM32F0xx/PWM-ICU/main.c index 661635c95..c2f1a9e0b 100644 --- a/testhal/STM32/STM32F0xx/PWM-ICU/main.c +++ b/testhal/STM32/STM32F0xx/PWM-ICU/main.c @@ -48,13 +48,13 @@ icucnt_t last_width, last_period; static void icuwidthcb(ICUDriver *icup) { palSetPad(GPIOC, GPIOC_LED3); - last_width = icuGetWidth(icup); + last_width = icuGetWidthX(icup); } static void icuperiodcb(ICUDriver *icup) { palClearPad(GPIOC, GPIOC_LED3); - last_period = icuGetPeriod(icup); + last_period = icuGetPeriodX(icup); } static void icuoverflowcb(ICUDriver *icup) { @@ -98,7 +98,8 @@ int main(void) { palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(2)); icuStart(&ICUD3, &icucfg); palSetPadMode(GPIOA, 6, PAL_MODE_ALTERNATE(1)); - icuEnable(&ICUD3); + icuStartCapture(&ICUD3); + icuEnableNotifications(&ICUD3); chThdSleepMilliseconds(2000); /* @@ -132,7 +133,7 @@ int main(void) { */ pwmDisableChannel(&PWMD1, 0); pwmStop(&PWMD1); - icuDisable(&ICUD3); + icuStopCapture(&ICUD3); icuStop(&ICUD3); palClearPad(GPIOC, GPIOC_LED3); palClearPad(GPIOC, GPIOC_LED4); diff --git a/testhal/STM32/STM32F1xx/PWM-ICU/main.c b/testhal/STM32/STM32F1xx/PWM-ICU/main.c index 92805fec4..2700dea7f 100644 --- a/testhal/STM32/STM32F1xx/PWM-ICU/main.c +++ b/testhal/STM32/STM32F1xx/PWM-ICU/main.c @@ -50,12 +50,12 @@ icucnt_t last_width, last_period; static void icuwidthcb(ICUDriver *icup) { - last_width = icuGetWidth(icup); + last_width = icuGetWidthX(icup); } static void icuperiodcb(ICUDriver *icup) { - last_period = icuGetPeriod(icup); + last_period = icuGetPeriodX(icup); } static ICUConfig icucfg = { @@ -95,7 +95,8 @@ int main(void) { pwmEnablePeriodicNotification(&PWMD1); palSetPadMode(IOPORT1, 8, PAL_MODE_STM32_ALTERNATE_PUSHPULL); icuStart(&ICUD4, &icucfg); - icuEnable(&ICUD4); + icuStartCapture(&ICUD4); + icuEnableNotifications(&ICUD4); chThdSleepMilliseconds(2000); /* @@ -129,7 +130,7 @@ int main(void) { */ pwmDisableChannel(&PWMD1, 0); pwmStop(&PWMD1); - icuDisable(&ICUD4); + icuStopCapture(&ICUD4); icuStop(&ICUD4); palSetPad(IOPORT3, GPIOC_LED); diff --git a/testhal/STM32/STM32F30x/PWM-ICU/main.c b/testhal/STM32/STM32F30x/PWM-ICU/main.c index df25de24d..ef67fdcf1 100644 --- a/testhal/STM32/STM32F30x/PWM-ICU/main.c +++ b/testhal/STM32/STM32F30x/PWM-ICU/main.c @@ -94,6 +94,7 @@ int main(void) { icuStart(&ICUD3, &icucfg); palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2)); icuStartCapture(&ICUD3); + icuEnableNotifications(&ICUD3); chThdSleepMilliseconds(2000); /* diff --git a/testhal/STM32/STM32F37x/PWM-ICU/.cproject b/testhal/STM32/STM32F37x/PWM-ICU/.cproject index 42e9f611b..fc26faa3d 100644 --- a/testhal/STM32/STM32F37x/PWM-ICU/.cproject +++ b/testhal/STM32/STM32F37x/PWM-ICU/.cproject @@ -48,4 +48,5 @@ + diff --git a/testhal/STM32/STM32F37x/PWM-ICU/main.c b/testhal/STM32/STM32F37x/PWM-ICU/main.c index 0178af14a..04b144dcd 100644 --- a/testhal/STM32/STM32F37x/PWM-ICU/main.c +++ b/testhal/STM32/STM32F37x/PWM-ICU/main.c @@ -48,13 +48,13 @@ icucnt_t last_width, last_period; static void icuwidthcb(ICUDriver *icup) { palSetPad(GPIOC, GPIOC_LED2); - last_width = icuGetWidth(icup); + last_width = icuGetWidthX(icup); } static void icuperiodcb(ICUDriver *icup) { palClearPad(GPIOC, GPIOC_LED2); - last_period = icuGetPeriod(icup); + last_period = icuGetPeriodX(icup); } static ICUConfig icucfg = { @@ -93,7 +93,8 @@ int main(void) { palSetPadMode(GPIOC, 0, PAL_MODE_ALTERNATE(2)); icuStart(&ICUD3, &icucfg); palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2)); - icuEnable(&ICUD3); + icuStartCapture(&ICUD3); + icuEnableNotifications(&ICUD3); chThdSleepMilliseconds(2000); /* @@ -127,7 +128,7 @@ int main(void) { */ pwmDisableChannel(&PWMD5, 0); pwmStop(&PWMD5); - icuDisable(&ICUD3); + icuStopCapture(&ICUD3); icuStop(&ICUD3); /* diff --git a/testhal/STM32/STM32F4xx/PWM-ICU/main.c b/testhal/STM32/STM32F4xx/PWM-ICU/main.c index 64da60b1d..2b5a992b0 100644 --- a/testhal/STM32/STM32F4xx/PWM-ICU/main.c +++ b/testhal/STM32/STM32F4xx/PWM-ICU/main.c @@ -48,13 +48,13 @@ icucnt_t last_width, last_period; static void icuwidthcb(ICUDriver *icup) { palSetPad(GPIOD, GPIOD_LED4); - last_width = icuGetWidth(icup); + last_width = icuGetWidthX(icup); } static void icuperiodcb(ICUDriver *icup) { palClearPad(GPIOD, GPIOD_LED4); - last_period = icuGetPeriod(icup); + last_period = icuGetPeriodX(icup); } static ICUConfig icucfg = { @@ -93,7 +93,8 @@ int main(void) { palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(1)); icuStart(&ICUD3, &icucfg); palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2)); - icuEnable(&ICUD3); + icuStartCapture(&ICUD3); + icuEnableNotifications(&ICUD3); chThdSleepMilliseconds(2000); /* @@ -127,7 +128,7 @@ int main(void) { */ pwmDisableChannel(&PWMD1, 0); pwmStop(&PWMD1); - icuDisable(&ICUD3); + icuStopCapture(&ICUD3); icuStop(&ICUD3); palClearPad(GPIOD, GPIOD_LED4); palClearPad(GPIOD, GPIOD_LED5); diff --git a/testhal/STM32/STM32L1xx/PWM-ICU/main.c b/testhal/STM32/STM32L1xx/PWM-ICU/main.c index 654f23379..450899049 100644 --- a/testhal/STM32/STM32L1xx/PWM-ICU/main.c +++ b/testhal/STM32/STM32L1xx/PWM-ICU/main.c @@ -48,13 +48,13 @@ icucnt_t last_width, last_period; static void icuwidthcb(ICUDriver *icup) { palSetPad(GPIOB, GPIOB_LED3); - last_width = icuGetWidth(icup); + last_width = icuGetWidthX(icup); } static void icuperiodcb(ICUDriver *icup) { palClearPad(GPIOB, GPIOB_LED3); - last_period = icuGetPeriod(icup); + last_period = icuGetPeriodX(icup); } static ICUConfig icucfg = { @@ -93,7 +93,8 @@ int main(void) { palSetPadMode(GPIOA, 15, PAL_MODE_ALTERNATE(1)); icuStart(&ICUD3, &icucfg); palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2)); - icuEnable(&ICUD3); + icuStartCapture(&ICUD3); + icuEnableNotifications(&ICUD3); chThdSleepMilliseconds(2000); /* @@ -127,7 +128,7 @@ int main(void) { */ pwmDisableChannel(&PWMD2, 0); pwmStop(&PWMD2); - icuDisable(&ICUD3); + icuStopCapture(&ICUD3); icuStop(&ICUD3); palClearPad(GPIOB, GPIOB_LED3); palClearPad(GPIOB, GPIOB_LED4); -- cgit v1.2.3