From 39fa1818ffe52d04832d5f5d25ae01fb7b6d514f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 18 Feb 2012 16:46:21 +0000 Subject: Improvements to the STM32 ICU driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3955 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/icu_lld.c | 101 +++++++++++++++++++++++++++++---------- 1 file changed, 76 insertions(+), 25 deletions(-) (limited to 'os/hal/platforms/STM32/icu_lld.c') diff --git a/os/hal/platforms/STM32/icu_lld.c b/os/hal/platforms/STM32/icu_lld.c index 3d362a3be..2c641280f 100644 --- a/os/hal/platforms/STM32/icu_lld.c +++ b/os/hal/platforms/STM32/icu_lld.c @@ -101,10 +101,17 @@ static void icu_lld_serve_interrupt(ICUDriver *icup) { sr = icup->tim->SR & icup->tim->DIER; icup->tim->SR = 0; - if ((sr & TIM_SR_CC1IF) != 0) - _icu_isr_invoke_period_cb(icup); - if ((sr & TIM_SR_CC2IF) != 0) - _icu_isr_invoke_width_cb(icup); + 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); + } } /*===========================================================================*/ @@ -283,6 +290,10 @@ void icu_lld_init(void) { void icu_lld_start(ICUDriver *icup) { uint32_t psc; + chDbgAssert((icup->config->channel == ICU_CHANNEL_1) || + (icup->config->channel == ICU_CHANNEL_2), + "icu_lld_start(), #1", "invalid input"); + if (icup->state == ICU_STOP) { /* Clock activation and timer reset.*/ #if STM32_ICU_USE_TIM1 @@ -359,23 +370,56 @@ void icu_lld_start(ICUDriver *icup) { icup->tim->PSC = (uint16_t)psc; icup->tim->ARR = 0xFFFF; - /* 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; + chDbgAssert((icup->config->channel != ICU_CHANNEL_1) && + (icup->config->channel != ICU_CHANNEL_2), + "icu_lld_start(), #2", "invalid channel"); + 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]; + } } /** @@ -442,10 +486,17 @@ void icu_lld_stop(ICUDriver *icup) { void icu_lld_enable(ICUDriver *icup) { icup->tim->SR = 0; /* Clear pending IRQs (if any). */ - if (icup->config->period_cb != NULL) - icup->tim->DIER |= TIM_DIER_CC1IE; - if (icup->config->width_cb != NULL) - icup->tim->DIER |= TIM_DIER_CC2IE; + 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; + } icup->tim->CR1 = TIM_CR1_URS | TIM_CR1_CEN; } -- cgit v1.2.3